blob: 1d9fcc971d488380beb1401fd232370567725236 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
31#include "linklist.h"
32#include "plist.h"
33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_table.h"
36#include "bgpd/bgp_dump.h"
37#include "bgpd/bgp_attr.h"
38#include "bgpd/bgp_debug.h"
39#include "bgpd/bgp_fsm.h"
40#include "bgpd/bgp_route.h"
41#include "bgpd/bgp_packet.h"
42#include "bgpd/bgp_open.h"
43#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_community.h"
45#include "bgpd/bgp_ecommunity.h"
46#include "bgpd/bgp_network.h"
47#include "bgpd/bgp_mplsvpn.h"
48#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000049#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000050
51int stream_put_prefix (struct stream *, struct prefix *);
52
53/* Set up BGP packet marker and packet type. */
54static int
55bgp_packet_set_marker (struct stream *s, u_char type)
56{
57 int i;
58
59 /* Fill in marker. */
60 for (i = 0; i < BGP_MARKER_SIZE; i++)
61 stream_putc (s, 0xff);
62
63 /* Dummy total length. This field is should be filled in later on. */
64 stream_putw (s, 0);
65
66 /* BGP packet type. */
67 stream_putc (s, type);
68
69 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000070 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000071}
72
73/* Set BGP packet header size entry. If size is zero then use current
74 stream size. */
75static int
76bgp_packet_set_size (struct stream *s)
77{
78 int cp;
79
80 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000081 cp = stream_get_endp (s);
82 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000083
84 return cp;
85}
86
87/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000088static void
paul718e3742002-12-13 20:15:29 +000089bgp_packet_add (struct peer *peer, struct stream *s)
90{
91 /* Add packet to the end of list. */
92 stream_fifo_push (peer->obuf, s);
93}
94
95/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000096static void
paul718e3742002-12-13 20:15:29 +000097bgp_packet_delete (struct peer *peer)
98{
99 stream_free (stream_fifo_pop (peer->obuf));
100}
101
paul718e3742002-12-13 20:15:29 +0000102/* Check file descriptor whether connect is established. */
103static void
104bgp_connect_check (struct peer *peer)
105{
106 int status;
paul5228ad22004-06-04 17:58:18 +0000107 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000108 int ret;
109
110 /* Anyway I have to reset read and write thread. */
111 BGP_READ_OFF (peer->t_read);
112 BGP_WRITE_OFF (peer->t_write);
113
114 /* Check file descriptor. */
115 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000116 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000117
118 /* If getsockopt is fail, this is fatal error. */
119 if (ret < 0)
120 {
121 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
122 BGP_EVENT_ADD (peer, TCP_fatal_error);
123 return;
124 }
125
126 /* When status is 0 then TCP connection is established. */
127 if (status == 0)
128 {
129 BGP_EVENT_ADD (peer, TCP_connection_open);
130 }
131 else
132 {
133 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000134 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000135 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000136 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
137 }
138}
139
140/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000141static struct stream *
paul718e3742002-12-13 20:15:29 +0000142bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
143{
144 struct stream *s;
145 struct bgp_adj_out *adj;
146 struct bgp_advertise *adv;
147 struct stream *packet;
148 struct bgp_node *rn = NULL;
149 struct bgp_info *binfo = NULL;
150 bgp_size_t total_attr_len = 0;
151 unsigned long pos;
152 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000153
154 s = peer->work;
155 stream_reset (s);
156
157 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
158
159 while (adv)
160 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000161 assert (adv->rn);
162 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000163 adj = adv->adj;
164 if (adv->binfo)
165 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000166
167 /* When remaining space can't include NLRI and it's length. */
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000168 if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
paul718e3742002-12-13 20:15:29 +0000169 break;
170
171 /* If packet is empty, set attribute. */
172 if (stream_empty (s))
173 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000174 struct prefix_rd *prd = NULL;
175 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000176 struct peer *from = NULL;
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000177
178 if (rn->prn)
179 prd = (struct prefix_rd *) &rn->prn->p;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400180 if (binfo)
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000182 from = binfo->peer;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400183 if (binfo->extra)
184 tag = binfo->extra->tag;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000185 }
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000186
paul718e3742002-12-13 20:15:29 +0000187 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
188 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000189 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000190 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000191 total_attr_len = bgp_packet_attribute (NULL, peer, s,
192 adv->baa->attr,
193 &rn->p, afi, safi,
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000194 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000195 stream_putw_at (s, pos, total_attr_len);
196 }
197
198 if (afi == AFI_IP && safi == SAFI_UNICAST)
199 stream_put_prefix (s, &rn->p);
200
201 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000202 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000203 peer->host,
204 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
205 rn->p.prefixlen);
206
207 /* Synchnorize attribute. */
208 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000209 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000210 else
211 peer->scount[afi][safi]++;
212
213 adj->attr = bgp_attr_intern (adv->baa->attr);
214
215 adv = bgp_advertise_clean (peer, adj, afi, safi);
216
217 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
218 break;
219 }
220
221 if (! stream_empty (s))
222 {
223 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000224 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000225 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000226 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000227 stream_reset (s);
228 return packet;
229 }
230 return NULL;
hasso93406d82005-02-02 14:40:33 +0000231}
paul718e3742002-12-13 20:15:29 +0000232
paul94f2b392005-06-28 12:44:16 +0000233static struct stream *
hasso93406d82005-02-02 14:40:33 +0000234bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
235{
236 struct stream *s;
237 struct stream *packet;
238
Paul Jakma750e8142008-07-22 21:11:48 +0000239 if (DISABLE_BGP_ANNOUNCE)
240 return NULL;
hasso93406d82005-02-02 14:40:33 +0000241
242 if (BGP_DEBUG (normal, NORMAL))
243 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
244
245 s = stream_new (BGP_MAX_PACKET_SIZE);
246
247 /* Make BGP update packet. */
248 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
249
250 /* Unfeasible Routes Length */
251 stream_putw (s, 0);
252
253 if (afi == AFI_IP && safi == SAFI_UNICAST)
254 {
255 /* Total Path Attribute Length */
256 stream_putw (s, 0);
257 }
258 else
259 {
260 /* Total Path Attribute Length */
261 stream_putw (s, 6);
262 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
263 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
264 stream_putc (s, 3);
265 stream_putw (s, afi);
266 stream_putc (s, safi);
267 }
268
269 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000270 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000271 bgp_packet_add (peer, packet);
272 stream_free (s);
273 return packet;
paul718e3742002-12-13 20:15:29 +0000274}
275
276/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000277static struct stream *
paul718e3742002-12-13 20:15:29 +0000278bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
279{
280 struct stream *s;
281 struct stream *packet;
282 struct bgp_adj_out *adj;
283 struct bgp_advertise *adv;
284 struct bgp_node *rn;
285 unsigned long pos;
286 bgp_size_t unfeasible_len;
287 bgp_size_t total_attr_len;
288 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000289
290 s = peer->work;
291 stream_reset (s);
292
293 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
294 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000295 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000296 adj = adv->adj;
297 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000298
299 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000300 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000301 break;
302
303 if (stream_empty (s))
304 {
305 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
306 stream_putw (s, 0);
307 }
308
309 if (afi == AFI_IP && safi == SAFI_UNICAST)
310 stream_put_prefix (s, &rn->p);
311 else
312 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000313 struct prefix_rd *prd = NULL;
314
315 if (rn->prn)
316 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000317 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000318 stream_putw (s, 0);
319 total_attr_len
320 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
321
322 /* Set total path attribute length. */
323 stream_putw_at (s, pos, total_attr_len);
324 }
325
326 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000327 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000328 peer->host,
329 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
330 rn->p.prefixlen);
331
332 peer->scount[afi][safi]--;
333
334 bgp_adj_out_remove (rn, adj, peer, afi, safi);
335 bgp_unlock_node (rn);
336
337 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
338 break;
339 }
340
341 if (! stream_empty (s))
342 {
343 if (afi == AFI_IP && safi == SAFI_UNICAST)
344 {
345 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000346 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000347 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
348 stream_putw (s, 0);
349 }
350 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000351 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000352 bgp_packet_add (peer, packet);
353 stream_reset (s);
354 return packet;
355 }
356
357 return NULL;
358}
359
360void
361bgp_default_update_send (struct peer *peer, struct attr *attr,
362 afi_t afi, safi_t safi, struct peer *from)
363{
364 struct stream *s;
365 struct stream *packet;
366 struct prefix p;
367 unsigned long pos;
368 bgp_size_t total_attr_len;
369 char attrstr[BUFSIZ];
370 char buf[BUFSIZ];
371
Paul Jakma750e8142008-07-22 21:11:48 +0000372 if (DISABLE_BGP_ANNOUNCE)
373 return;
paul718e3742002-12-13 20:15:29 +0000374
375 if (afi == AFI_IP)
376 str2prefix ("0.0.0.0/0", &p);
377#ifdef HAVE_IPV6
378 else
379 str2prefix ("::/0", &p);
380#endif /* HAVE_IPV6 */
381
382 /* Logging the attribute. */
383 if (BGP_DEBUG (update, UPDATE_OUT))
384 {
385 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000386 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000387 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
388 p.prefixlen, attrstr);
389 }
390
391 s = stream_new (BGP_MAX_PACKET_SIZE);
392
393 /* Make BGP update packet. */
394 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
395
396 /* Unfeasible Routes Length. */
397 stream_putw (s, 0);
398
399 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000400 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000401 stream_putw (s, 0);
402 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
403
404 /* Set Total Path Attribute Length. */
405 stream_putw_at (s, pos, total_attr_len);
406
407 /* NLRI set. */
408 if (p.family == AF_INET && safi == SAFI_UNICAST)
409 stream_put_prefix (s, &p);
410
411 /* Set size. */
412 bgp_packet_set_size (s);
413
paule83e2082005-05-19 02:12:25 +0000414 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000415 stream_free (s);
416
417 /* Dump packet if debug option is set. */
418#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000419 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000420#endif /* DEBUG */
421
422 /* Add packet to the peer. */
423 bgp_packet_add (peer, packet);
424
pauleb821182004-05-01 08:44:08 +0000425 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000426}
427
428void
429bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
430{
431 struct stream *s;
432 struct stream *packet;
433 struct prefix p;
434 unsigned long pos;
435 unsigned long cp;
436 bgp_size_t unfeasible_len;
437 bgp_size_t total_attr_len;
438 char buf[BUFSIZ];
439
Paul Jakma750e8142008-07-22 21:11:48 +0000440 if (DISABLE_BGP_ANNOUNCE)
441 return;
paul718e3742002-12-13 20:15:29 +0000442
443 if (afi == AFI_IP)
444 str2prefix ("0.0.0.0/0", &p);
445#ifdef HAVE_IPV6
446 else
447 str2prefix ("::/0", &p);
448#endif /* HAVE_IPV6 */
449
450 total_attr_len = 0;
451 pos = 0;
452
453 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000454 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000455 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
456 p.prefixlen);
457
458 s = stream_new (BGP_MAX_PACKET_SIZE);
459
460 /* Make BGP update packet. */
461 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
462
463 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000464 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000465 stream_putw (s, 0);
466
467 /* Withdrawn Routes. */
468 if (p.family == AF_INET && safi == SAFI_UNICAST)
469 {
470 stream_put_prefix (s, &p);
471
paul9985f832005-02-09 15:51:56 +0000472 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000473
474 /* Set unfeasible len. */
475 stream_putw_at (s, cp, unfeasible_len);
476
477 /* Set total path attribute length. */
478 stream_putw (s, 0);
479 }
480 else
481 {
paul9985f832005-02-09 15:51:56 +0000482 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000483 stream_putw (s, 0);
484 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
485
486 /* Set total path attribute length. */
487 stream_putw_at (s, pos, total_attr_len);
488 }
489
490 bgp_packet_set_size (s);
491
paule83e2082005-05-19 02:12:25 +0000492 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000493 stream_free (s);
494
495 /* Add packet to the peer. */
496 bgp_packet_add (peer, packet);
497
pauleb821182004-05-01 08:44:08 +0000498 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000499}
500
501/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000502static struct stream *
paul718e3742002-12-13 20:15:29 +0000503bgp_write_packet (struct peer *peer)
504{
505 afi_t afi;
506 safi_t safi;
507 struct stream *s = NULL;
508 struct bgp_advertise *adv;
509
510 s = stream_fifo_head (peer->obuf);
511 if (s)
512 return s;
513
514 for (afi = AFI_IP; afi < AFI_MAX; afi++)
515 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
516 {
517 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
518 if (adv)
519 {
520 s = bgp_withdraw_packet (peer, afi, safi);
521 if (s)
522 return s;
523 }
524 }
525
526 for (afi = AFI_IP; afi < AFI_MAX; afi++)
527 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
528 {
529 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
530 if (adv)
531 {
532 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000533 {
534 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
535 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
536 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
537 && safi != SAFI_MPLS_VPN)
538 {
539 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
540 PEER_STATUS_EOR_RECEIVED))
541 s = bgp_update_packet (peer, afi, safi);
542 }
543 else
544 s = bgp_update_packet (peer, afi, safi);
545 }
paul718e3742002-12-13 20:15:29 +0000546
547 if (s)
548 return s;
549 }
hasso93406d82005-02-02 14:40:33 +0000550
551 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
552 {
553 if (peer->afc_nego[afi][safi] && peer->synctime
554 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
555 && safi != SAFI_MPLS_VPN)
556 {
557 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
558 return bgp_update_packet_eor (peer, afi, safi);
559 }
560 }
paul718e3742002-12-13 20:15:29 +0000561 }
562
563 return NULL;
564}
565
566/* Is there partially written packet or updates we can send right
567 now. */
paul94f2b392005-06-28 12:44:16 +0000568static int
paul718e3742002-12-13 20:15:29 +0000569bgp_write_proceed (struct peer *peer)
570{
571 afi_t afi;
572 safi_t safi;
573 struct bgp_advertise *adv;
574
575 if (stream_fifo_head (peer->obuf))
576 return 1;
577
578 for (afi = AFI_IP; afi < AFI_MAX; afi++)
579 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
580 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
581 return 1;
582
583 for (afi = AFI_IP; afi < AFI_MAX; afi++)
584 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
585 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
586 if (adv->binfo->uptime < peer->synctime)
587 return 1;
588
589 return 0;
590}
591
592/* Write packet to the peer. */
593int
594bgp_write (struct thread *thread)
595{
596 struct peer *peer;
597 u_char type;
598 struct stream *s;
599 int num;
paulfd79ac92004-10-13 05:06:08 +0000600 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000601
602 /* Yes first of all get peer pointer. */
603 peer = THREAD_ARG (thread);
604 peer->t_write = NULL;
605
606 /* For non-blocking IO check. */
607 if (peer->status == Connect)
608 {
609 bgp_connect_check (peer);
610 return 0;
611 }
612
Stephen Hemmingereac57022010-08-05 10:26:25 -0700613 s = bgp_write_packet (peer);
614 if (!s)
615 return 0; /* nothing to send */
616
617 sockopt_cork (peer->fd, 1);
618
619 /* Nonblocking write until TCP output buffer is full. */
620 do
paul718e3742002-12-13 20:15:29 +0000621 {
622 int writenum;
paul718e3742002-12-13 20:15:29 +0000623
624 /* Number of bytes to be sent. */
625 writenum = stream_get_endp (s) - stream_get_getp (s);
626
627 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000628 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700629 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000630 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700631 /* write failed either retry needed or error */
632 if (ERRNO_IO_RETRY(errno))
633 break;
634
635 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000636 return 0;
637 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700638
paul718e3742002-12-13 20:15:29 +0000639 if (num != writenum)
640 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700641 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000642 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700643 break;
paul718e3742002-12-13 20:15:29 +0000644 }
645
646 /* Retrieve BGP packet type. */
647 stream_set_getp (s, BGP_MARKER_SIZE + 2);
648 type = stream_getc (s);
649
650 switch (type)
651 {
652 case BGP_MSG_OPEN:
653 peer->open_out++;
654 break;
655 case BGP_MSG_UPDATE:
656 peer->update_out++;
657 break;
658 case BGP_MSG_NOTIFY:
659 peer->notify_out++;
660 /* Double start timer. */
661 peer->v_start *= 2;
662
663 /* Overflow check. */
664 if (peer->v_start >= (60 * 2))
665 peer->v_start = (60 * 2);
666
Paul Jakmaca058a32006-09-14 02:58:49 +0000667 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000668 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000669 return 0;
paul718e3742002-12-13 20:15:29 +0000670 case BGP_MSG_KEEPALIVE:
671 peer->keepalive_out++;
672 break;
673 case BGP_MSG_ROUTE_REFRESH_NEW:
674 case BGP_MSG_ROUTE_REFRESH_OLD:
675 peer->refresh_out++;
676 break;
677 case BGP_MSG_CAPABILITY:
678 peer->dynamic_cap_out++;
679 break;
680 }
681
682 /* OK we send packet so delete it. */
683 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000684 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700685 while (++count < BGP_WRITE_PACKET_MAX &&
686 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000687
688 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000689 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700690 else
691 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000692
693 return 0;
694}
695
696/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000697static int
paul718e3742002-12-13 20:15:29 +0000698bgp_write_notify (struct peer *peer)
699{
Stephen Hemminger35398582010-08-05 10:26:23 -0700700 int ret, val;
paul718e3742002-12-13 20:15:29 +0000701 u_char type;
702 struct stream *s;
703
704 /* There should be at least one packet. */
705 s = stream_fifo_head (peer->obuf);
706 if (!s)
707 return 0;
708 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
709
Stephen Hemminger35398582010-08-05 10:26:23 -0700710 /* Put socket in blocking mode. */
711 val = fcntl (peer->fd, F_GETFL, 0);
712 fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);
713
pauleb821182004-05-01 08:44:08 +0000714 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000715 if (ret <= 0)
716 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000717 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000718 return 0;
719 }
720
721 /* Retrieve BGP packet type. */
722 stream_set_getp (s, BGP_MARKER_SIZE + 2);
723 type = stream_getc (s);
724
725 assert (type == BGP_MSG_NOTIFY);
726
727 /* Type should be notify. */
728 peer->notify_out++;
729
730 /* Double start timer. */
731 peer->v_start *= 2;
732
733 /* Overflow check. */
734 if (peer->v_start >= (60 * 2))
735 peer->v_start = (60 * 2);
736
Paul Jakmadcdf3992006-10-15 23:39:59 +0000737 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000738
739 return 0;
740}
741
742/* Make keepalive packet and send it to the peer. */
743void
744bgp_keepalive_send (struct peer *peer)
745{
746 struct stream *s;
747 int length;
748
749 s = stream_new (BGP_MAX_PACKET_SIZE);
750
751 /* Make keepalive packet. */
752 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
753
754 /* Set packet size. */
755 length = bgp_packet_set_size (s);
756
757 /* Dump packet if debug option is set. */
758 /* bgp_packet_dump (s); */
759
760 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000761 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000762 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000763 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000764 peer->host, BGP_MSG_KEEPALIVE, length);
765
766 /* Add packet to the peer. */
767 bgp_packet_add (peer, s);
768
pauleb821182004-05-01 08:44:08 +0000769 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000770}
771
772/* Make open packet and send it to the peer. */
773void
774bgp_open_send (struct peer *peer)
775{
776 struct stream *s;
777 int length;
778 u_int16_t send_holdtime;
779 as_t local_as;
780
781 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
782 send_holdtime = peer->holdtime;
783 else
784 send_holdtime = peer->bgp->default_holdtime;
785
786 /* local-as Change */
787 if (peer->change_local_as)
788 local_as = peer->change_local_as;
789 else
790 local_as = peer->local_as;
791
792 s = stream_new (BGP_MAX_PACKET_SIZE);
793
794 /* Make open packet. */
795 bgp_packet_set_marker (s, BGP_MSG_OPEN);
796
797 /* Set open packet values. */
798 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000799 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
800 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000801 stream_putw (s, send_holdtime); /* Hold Time */
802 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
803
804 /* Set capability code. */
805 bgp_open_capability (s, peer);
806
807 /* Set BGP packet length. */
808 length = bgp_packet_set_size (s);
809
810 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400811 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000812 peer->host, BGP_VERSION_4, local_as,
813 send_holdtime, inet_ntoa (peer->local_id));
814
815 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000816 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000817 peer->host, BGP_MSG_OPEN, length);
818
819 /* Dump packet if debug option is set. */
820 /* bgp_packet_dump (s); */
821
822 /* Add packet to the peer. */
823 bgp_packet_add (peer, s);
824
pauleb821182004-05-01 08:44:08 +0000825 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000826}
827
828/* Send BGP notify packet with data potion. */
829void
830bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
831 u_char *data, size_t datalen)
832{
833 struct stream *s;
834 int length;
835
836 /* Allocate new stream. */
837 s = stream_new (BGP_MAX_PACKET_SIZE);
838
839 /* Make nitify packet. */
840 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
841
842 /* Set notify packet values. */
843 stream_putc (s, code); /* BGP notify code */
844 stream_putc (s, sub_code); /* BGP notify sub_code */
845
846 /* If notify data is present. */
847 if (data)
848 stream_write (s, data, datalen);
849
850 /* Set BGP packet length. */
851 length = bgp_packet_set_size (s);
852
853 /* Add packet to the peer. */
854 stream_fifo_clean (peer->obuf);
855 bgp_packet_add (peer, s);
856
857 /* For debug */
858 {
859 struct bgp_notify bgp_notify;
860 int first = 0;
861 int i;
862 char c[4];
863
864 bgp_notify.code = code;
865 bgp_notify.subcode = sub_code;
866 bgp_notify.data = NULL;
867 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
868
869 if (bgp_notify.length)
870 {
871 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
872 for (i = 0; i < bgp_notify.length; i++)
873 if (first)
874 {
875 sprintf (c, " %02x", data[i]);
876 strcat (bgp_notify.data, c);
877 }
878 else
879 {
880 first = 1;
881 sprintf (c, "%02x", data[i]);
882 strcpy (bgp_notify.data, c);
883 }
884 }
885 bgp_notify_print (peer, &bgp_notify, "sending");
886 if (bgp_notify.data)
887 XFREE (MTYPE_TMP, bgp_notify.data);
888 }
889
890 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000891 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000892 peer->host, BGP_MSG_NOTIFY, length);
893
hassoe0701b72004-05-20 09:19:34 +0000894 /* peer reset cause */
895 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
896 {
897 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
898 peer->last_reset = PEER_DOWN_USER_RESET;
899 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
900 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
901 else
902 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
903 }
904
paul718e3742002-12-13 20:15:29 +0000905 /* Call imidiately. */
906 BGP_WRITE_OFF (peer->t_write);
907
908 bgp_write_notify (peer);
909}
910
911/* Send BGP notify packet. */
912void
913bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
914{
915 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
916}
917
paul718e3742002-12-13 20:15:29 +0000918/* Send route refresh message to the peer. */
919void
920bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
921 u_char orf_type, u_char when_to_refresh, int remove)
922{
923 struct stream *s;
924 struct stream *packet;
925 int length;
926 struct bgp_filter *filter;
927 int orf_refresh = 0;
928
Paul Jakma750e8142008-07-22 21:11:48 +0000929 if (DISABLE_BGP_ANNOUNCE)
930 return;
paul718e3742002-12-13 20:15:29 +0000931
932 filter = &peer->filter[afi][safi];
933
934 /* Adjust safi code. */
935 if (safi == SAFI_MPLS_VPN)
936 safi = BGP_SAFI_VPNV4;
937
938 s = stream_new (BGP_MAX_PACKET_SIZE);
939
940 /* Make BGP update packet. */
941 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
942 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
943 else
944 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
945
946 /* Encode Route Refresh message. */
947 stream_putw (s, afi);
948 stream_putc (s, 0);
949 stream_putc (s, safi);
950
951 if (orf_type == ORF_TYPE_PREFIX
952 || orf_type == ORF_TYPE_PREFIX_OLD)
953 if (remove || filter->plist[FILTER_IN].plist)
954 {
955 u_int16_t orf_len;
956 unsigned long orfp;
957
958 orf_refresh = 1;
959 stream_putc (s, when_to_refresh);
960 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000961 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000962 stream_putw (s, 0);
963
964 if (remove)
965 {
966 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
967 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
968 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000969 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000970 peer->host, orf_type,
971 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
972 afi, safi);
973 }
974 else
975 {
976 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
977 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
978 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
979 ORF_COMMON_PART_DENY);
980 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000981 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000982 peer->host, orf_type,
983 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
984 afi, safi);
985 }
986
987 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +0000988 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +0000989 stream_putw_at (s, orfp, orf_len);
990 }
991
992 /* Set packet size. */
993 length = bgp_packet_set_size (s);
994
995 if (BGP_DEBUG (normal, NORMAL))
996 {
997 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +0000998 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000999 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001000 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001001 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1002 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1003 }
1004
1005 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001006 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001007 stream_free (s);
1008
1009 /* Add packet to the peer. */
1010 bgp_packet_add (peer, packet);
1011
pauleb821182004-05-01 08:44:08 +00001012 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001013}
1014
1015/* Send capability message to the peer. */
1016void
1017bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1018 int capability_code, int action)
1019{
1020 struct stream *s;
1021 struct stream *packet;
1022 int length;
1023
1024 /* Adjust safi code. */
1025 if (safi == SAFI_MPLS_VPN)
1026 safi = BGP_SAFI_VPNV4;
1027
1028 s = stream_new (BGP_MAX_PACKET_SIZE);
1029
1030 /* Make BGP update packet. */
1031 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1032
1033 /* Encode MP_EXT capability. */
1034 if (capability_code == CAPABILITY_CODE_MP)
1035 {
1036 stream_putc (s, action);
1037 stream_putc (s, CAPABILITY_CODE_MP);
1038 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1039 stream_putw (s, afi);
1040 stream_putc (s, 0);
1041 stream_putc (s, safi);
1042
1043 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001044 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001045 peer->host, action == CAPABILITY_ACTION_SET ?
1046 "Advertising" : "Removing", afi, safi);
1047 }
1048
paul718e3742002-12-13 20:15:29 +00001049 /* Set packet size. */
1050 length = bgp_packet_set_size (s);
1051
1052 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001053 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001054 stream_free (s);
1055
1056 /* Add packet to the peer. */
1057 bgp_packet_add (peer, packet);
1058
1059 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001060 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001061 peer->host, BGP_MSG_CAPABILITY, length);
1062
pauleb821182004-05-01 08:44:08 +00001063 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001064}
1065
1066/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001067static int
pauleb821182004-05-01 08:44:08 +00001068bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001069{
pauleb821182004-05-01 08:44:08 +00001070 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001071 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001072 struct bgp *bgp;
1073
1074 bgp = bgp_get_default ();
1075 if (! bgp)
1076 return 0;
1077
1078 /* Upon receipt of an OPEN message, the local system must examine
1079 all of its connections that are in the OpenConfirm state. A BGP
1080 speaker may also examine connections in an OpenSent state if it
1081 knows the BGP Identifier of the peer by means outside of the
1082 protocol. If among these connections there is a connection to a
1083 remote BGP speaker whose BGP Identifier equals the one in the
1084 OPEN message, then the local system performs the following
1085 collision resolution procedure: */
1086
paul1eb8ef22005-04-07 07:30:20 +00001087 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001088 {
1089 /* Under OpenConfirm status, local peer structure already hold
1090 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001091
1092 if (peer != new
1093 && (peer->status == OpenConfirm || peer->status == OpenSent)
1094 && sockunion_same (&peer->su, &new->su))
1095 {
paul718e3742002-12-13 20:15:29 +00001096 /* 1. The BGP Identifier of the local system is compared to
1097 the BGP Identifier of the remote system (as specified in
1098 the OPEN message). */
1099
1100 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1101 {
1102 /* 2. If the value of the local BGP Identifier is less
1103 than the remote one, the local system closes BGP
1104 connection that already exists (the one that is
1105 already in the OpenConfirm state), and accepts BGP
1106 connection initiated by the remote system. */
1107
pauleb821182004-05-01 08:44:08 +00001108 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001109 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001110 return 1;
1111 }
1112 else
1113 {
1114 /* 3. Otherwise, the local system closes newly created
1115 BGP connection (the one associated with the newly
1116 received OPEN message), and continues to use the
1117 existing one (the one that is already in the
1118 OpenConfirm state). */
1119
pauleb821182004-05-01 08:44:08 +00001120 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001121 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1122 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001123 return -1;
1124 }
pauleb821182004-05-01 08:44:08 +00001125 }
1126 }
paul718e3742002-12-13 20:15:29 +00001127 return 0;
1128}
1129
paul94f2b392005-06-28 12:44:16 +00001130static int
paul718e3742002-12-13 20:15:29 +00001131bgp_open_receive (struct peer *peer, bgp_size_t size)
1132{
1133 int ret;
1134 u_char version;
1135 u_char optlen;
1136 u_int16_t holdtime;
1137 u_int16_t send_holdtime;
1138 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001139 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001140 struct peer *realpeer;
1141 struct in_addr remote_id;
1142 int capability;
paul5228ad22004-06-04 17:58:18 +00001143 u_int8_t notify_data_remote_as[2];
1144 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001145
1146 realpeer = NULL;
1147
1148 /* Parse open packet. */
1149 version = stream_getc (peer->ibuf);
1150 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1151 remote_as = stream_getw (peer->ibuf);
1152 holdtime = stream_getw (peer->ibuf);
1153 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1154 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1155
1156 /* Receive OPEN message log */
1157 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001158 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001159 " holdtime %d, id %s",
1160 peer->host, version, remote_as, holdtime,
1161 inet_ntoa (remote_id));
1162
1163 /* BEGIN to read the capability here, but dont do it yet */
1164 capability = 0;
1165 optlen = stream_getc (peer->ibuf);
1166
1167 if (optlen != 0)
1168 {
1169 /* We need the as4 capability value *right now* because
1170 * if it is there, we have not got the remote_as yet, and without
1171 * that we do not know which peer is connecting to us now.
1172 */
1173 as4 = peek_for_as4_capability (peer, optlen);
1174 }
1175
1176 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1177 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1178 {
1179 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1180 peer->host);
1181 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1182 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1183 return -1;
1184 }
1185
1186 if (remote_as == BGP_AS_TRANS)
1187 {
1188 /* Take the AS4 from the capability. We must have received the
1189 * capability now! Otherwise we have a asn16 peer who uses
1190 * BGP_AS_TRANS, for some unknown reason.
1191 */
1192 if (as4 == BGP_AS_TRANS)
1193 {
1194 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1195 peer->host);
1196 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1197 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1198 return -1;
1199 }
1200
1201 if (!as4 && BGP_DEBUG (as4, AS4))
1202 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1203 " Odd, but proceeding.", peer->host);
1204 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001205 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001206 "in 2-bytes, very odd peer.", peer->host, as4);
1207 if (as4)
1208 remote_as = as4;
1209 }
1210 else
1211 {
1212 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1213 /* If we have got the capability, peer->as4cap must match remote_as */
1214 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1215 && as4 != remote_as)
1216 {
1217 /* raise error, log this, close session */
1218 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1219 " mismatch with 16bit 'myasn' %u in open",
1220 peer->host, as4, remote_as);
1221 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1222 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1223 return -1;
1224 }
1225 }
1226
paul718e3742002-12-13 20:15:29 +00001227 /* Lookup peer from Open packet. */
1228 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1229 {
1230 int as = 0;
1231
1232 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1233
1234 if (! realpeer)
1235 {
1236 /* Peer's source IP address is check in bgp_accept(), so this
1237 must be AS number mismatch or remote-id configuration
1238 mismatch. */
1239 if (as)
1240 {
1241 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001242 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1243 peer->host, inet_ntoa (remote_id));
1244 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1245 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1246 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001247 }
1248 else
1249 {
1250 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001251 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001252 peer->host, remote_as, peer->as);
1253 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1254 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1255 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001256 }
1257 return -1;
1258 }
1259 }
1260
1261 /* When collision is detected and this peer is closed. Retrun
1262 immidiately. */
1263 ret = bgp_collision_detect (peer, remote_id);
1264 if (ret < 0)
1265 return ret;
1266
pauleb821182004-05-01 08:44:08 +00001267 /* Hack part. */
1268 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1269 {
hasso93406d82005-02-02 14:40:33 +00001270 if (realpeer->status == Established
1271 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1272 {
1273 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1274 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1275 }
1276 else if (ret == 0 && realpeer->status != Active
1277 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001278 && realpeer->status != OpenConfirm
1279 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001280 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001281 /* XXX: This is an awful problem..
1282 *
1283 * According to the RFC we should just let this connection (of the
1284 * accepted 'peer') continue on to Established if the other
1285 * connection (the 'realpeer' one) is in state Connect, and deal
1286 * with the more larval FSM as/when it gets far enough to receive
1287 * an Open. We don't do that though, we instead close the (more
1288 * developed) accepted connection.
1289 *
1290 * This means there's a race, which if hit, can loop:
1291 *
1292 * FSM for A FSM for B
1293 * realpeer accept-peer realpeer accept-peer
1294 *
1295 * Connect Connect
1296 * Active
1297 * OpenSent OpenSent
1298 * <arrive here,
1299 * Notify, delete>
1300 * Idle Active
1301 * OpenSent OpenSent
1302 * <arrive here,
1303 * Notify, delete>
1304 * Idle
1305 * <wait> <wait>
1306 * Connect Connect
1307 *
1308 *
1309 * If both sides are Quagga, they're almost certain to wait for
1310 * the same amount of time of course (which doesn't preclude other
1311 * implementations also waiting for same time). The race is
1312 * exacerbated by high-latency (in bgpd and/or the network).
1313 *
1314 * The reason we do this is because our FSM is tied to our peer
1315 * structure, which carries our configuration information, etc.
1316 * I.e. we can't let the accepted-peer FSM continue on as it is,
1317 * cause it's not associated with any actual peer configuration -
1318 * it's just a dummy.
1319 *
1320 * It's possible we could hack-fix this by just bgp_stop'ing the
1321 * realpeer and continueing on with the 'transfer FSM' below.
1322 * Ideally, we need to seperate FSMs from struct peer.
1323 *
1324 * Setting one side to passive avoids the race, as a workaround.
1325 */
pauleb821182004-05-01 08:44:08 +00001326 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001327 zlog_debug ("%s peer status is %s close connection",
1328 realpeer->host, LOOKUP (bgp_status_msg,
1329 realpeer->status));
1330 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1331 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1332
pauleb821182004-05-01 08:44:08 +00001333 return -1;
1334 }
1335
1336 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001337 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1338 peer->host,
1339 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001340
1341 bgp_stop (realpeer);
1342
1343 /* Transfer file descriptor. */
1344 realpeer->fd = peer->fd;
1345 peer->fd = -1;
1346
1347 /* Transfer input buffer. */
1348 stream_free (realpeer->ibuf);
1349 realpeer->ibuf = peer->ibuf;
1350 realpeer->packet_size = peer->packet_size;
1351 peer->ibuf = NULL;
1352
1353 /* Transfer status. */
1354 realpeer->status = peer->status;
1355 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001356
pauleb821182004-05-01 08:44:08 +00001357 /* peer pointer change. Open packet send to neighbor. */
1358 peer = realpeer;
1359 bgp_open_send (peer);
1360 if (peer->fd < 0)
1361 {
1362 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1363 peer->fd);
1364 return -1;
1365 }
1366 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1367 }
1368
paul718e3742002-12-13 20:15:29 +00001369 /* remote router-id check. */
1370 if (remote_id.s_addr == 0
1371 || ntohl (remote_id.s_addr) >= 0xe0000000
1372 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1373 {
1374 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001375 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001376 peer->host, inet_ntoa (remote_id));
1377 bgp_notify_send_with_data (peer,
1378 BGP_NOTIFY_OPEN_ERR,
1379 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1380 notify_data_remote_id, 4);
1381 return -1;
1382 }
1383
1384 /* Set remote router-id */
1385 peer->remote_id = remote_id;
1386
1387 /* Peer BGP version check. */
1388 if (version != BGP_VERSION_4)
1389 {
paul5228ad22004-06-04 17:58:18 +00001390 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001391 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001392 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001393 peer->host, version, BGP_VERSION_4);
1394 bgp_notify_send_with_data (peer,
1395 BGP_NOTIFY_OPEN_ERR,
1396 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001397 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001398 return -1;
1399 }
1400
1401 /* Check neighbor as number. */
1402 if (remote_as != peer->as)
1403 {
1404 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001405 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001406 peer->host, remote_as, peer->as);
1407 bgp_notify_send_with_data (peer,
1408 BGP_NOTIFY_OPEN_ERR,
1409 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1410 notify_data_remote_as, 2);
1411 return -1;
1412 }
1413
1414 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1415 calculate the value of the Hold Timer by using the smaller of its
1416 configured Hold Time and the Hold Time received in the OPEN message.
1417 The Hold Time MUST be either zero or at least three seconds. An
1418 implementation may reject connections on the basis of the Hold Time. */
1419
1420 if (holdtime < 3 && holdtime != 0)
1421 {
1422 bgp_notify_send (peer,
1423 BGP_NOTIFY_OPEN_ERR,
1424 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1425 return -1;
1426 }
1427
1428 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1429 would be one third of the Hold Time interval. KEEPALIVE messages
1430 MUST NOT be sent more frequently than one per second. An
1431 implementation MAY adjust the rate at which it sends KEEPALIVE
1432 messages as a function of the Hold Time interval. */
1433
1434 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1435 send_holdtime = peer->holdtime;
1436 else
1437 send_holdtime = peer->bgp->default_holdtime;
1438
1439 if (holdtime < send_holdtime)
1440 peer->v_holdtime = holdtime;
1441 else
1442 peer->v_holdtime = send_holdtime;
1443
1444 peer->v_keepalive = peer->v_holdtime / 3;
1445
1446 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001447 if (optlen != 0)
1448 {
1449 ret = bgp_open_option_parse (peer, optlen, &capability);
1450 if (ret < 0)
1451 return ret;
paul718e3742002-12-13 20:15:29 +00001452 }
1453 else
1454 {
1455 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001456 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001457 peer->host);
1458 }
1459
1460 /* Override capability. */
1461 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1462 {
1463 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1464 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1465 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1466 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1467 }
1468
1469 /* Get sockname. */
1470 bgp_getsockname (peer);
1471
1472 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1473
1474 peer->packet_size = 0;
1475 if (peer->ibuf)
1476 stream_reset (peer->ibuf);
1477
1478 return 0;
1479}
1480
1481/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001482static int
paul718e3742002-12-13 20:15:29 +00001483bgp_update_receive (struct peer *peer, bgp_size_t size)
1484{
1485 int ret;
1486 u_char *end;
1487 struct stream *s;
1488 struct attr attr;
1489 bgp_size_t attribute_len;
1490 bgp_size_t update_len;
1491 bgp_size_t withdraw_len;
1492 struct bgp_nlri update;
1493 struct bgp_nlri withdraw;
1494 struct bgp_nlri mp_update;
1495 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001496 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001497
1498 /* Status must be Established. */
1499 if (peer->status != Established)
1500 {
1501 zlog_err ("%s [FSM] Update packet received under status %s",
1502 peer->host, LOOKUP (bgp_status_msg, peer->status));
1503 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1504 return -1;
1505 }
1506
1507 /* Set initial values. */
1508 memset (&attr, 0, sizeof (struct attr));
1509 memset (&update, 0, sizeof (struct bgp_nlri));
1510 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1511 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1512 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1513
1514 s = peer->ibuf;
1515 end = stream_pnt (s) + size;
1516
1517 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1518 Length is too large (i.e., if Unfeasible Routes Length + Total
1519 Attribute Length + 23 exceeds the message Length), then the Error
1520 Subcode is set to Malformed Attribute List. */
1521 if (stream_pnt (s) + 2 > end)
1522 {
1523 zlog_err ("%s [Error] Update packet error"
1524 " (packet length is short for unfeasible length)",
1525 peer->host);
1526 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1527 BGP_NOTIFY_UPDATE_MAL_ATTR);
1528 return -1;
1529 }
1530
1531 /* Unfeasible Route Length. */
1532 withdraw_len = stream_getw (s);
1533
1534 /* Unfeasible Route Length check. */
1535 if (stream_pnt (s) + withdraw_len > end)
1536 {
1537 zlog_err ("%s [Error] Update packet error"
1538 " (packet unfeasible length overflow %d)",
1539 peer->host, withdraw_len);
1540 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1541 BGP_NOTIFY_UPDATE_MAL_ATTR);
1542 return -1;
1543 }
1544
1545 /* Unfeasible Route packet format check. */
1546 if (withdraw_len > 0)
1547 {
1548 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1549 if (ret < 0)
1550 return -1;
1551
1552 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001553 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001554
1555 withdraw.afi = AFI_IP;
1556 withdraw.safi = SAFI_UNICAST;
1557 withdraw.nlri = stream_pnt (s);
1558 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001559 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001560 }
1561
1562 /* Attribute total length check. */
1563 if (stream_pnt (s) + 2 > end)
1564 {
1565 zlog_warn ("%s [Error] Packet Error"
1566 " (update packet is short for attribute length)",
1567 peer->host);
1568 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1569 BGP_NOTIFY_UPDATE_MAL_ATTR);
1570 return -1;
1571 }
1572
1573 /* Fetch attribute total length. */
1574 attribute_len = stream_getw (s);
1575
1576 /* Attribute length check. */
1577 if (stream_pnt (s) + attribute_len > end)
1578 {
1579 zlog_warn ("%s [Error] Packet Error"
1580 " (update packet attribute length overflow %d)",
1581 peer->host, attribute_len);
1582 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1583 BGP_NOTIFY_UPDATE_MAL_ATTR);
1584 return -1;
1585 }
Paul Jakmab881c702010-11-23 16:35:42 +00001586
1587 /* Certain attribute parsing errors should not be considered bad enough
1588 * to reset the session for, most particularly any partial/optional
1589 * attributes that have 'tunneled' over speakers that don't understand
1590 * them. Instead we withdraw only the prefix concerned.
1591 *
1592 * Complicates the flow a little though..
1593 */
1594 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1595 /* This define morphs the update case into a withdraw when lower levels
1596 * have signalled an error condition where this is best.
1597 */
1598#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001599
1600 /* Parse attribute when it exists. */
1601 if (attribute_len)
1602 {
Paul Jakmab881c702010-11-23 16:35:42 +00001603 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
paul718e3742002-12-13 20:15:29 +00001604 &mp_update, &mp_withdraw);
Paul Jakmab881c702010-11-23 16:35:42 +00001605 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
paul718e3742002-12-13 20:15:29 +00001606 return -1;
1607 }
Paul Jakmab881c702010-11-23 16:35:42 +00001608
paul718e3742002-12-13 20:15:29 +00001609 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001610 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1611 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001612 {
paule01f9cb2004-07-09 17:48:53 +00001613 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001614 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1615 ? LOG_ERR : LOG_DEBUG;
1616
1617 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1618 zlog (peer->log, LOG_ERR,
1619 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1620 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001621
1622 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001623 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001624 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001625 }
Paul Jakmab881c702010-11-23 16:35:42 +00001626
paul718e3742002-12-13 20:15:29 +00001627 /* Network Layer Reachability Information. */
1628 update_len = end - stream_pnt (s);
1629
1630 if (update_len)
1631 {
1632 /* Check NLRI packet format and prefix length. */
1633 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1634 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001635 {
1636 bgp_attr_unintern_sub (&attr);
1637 if (attr.extra)
1638 bgp_attr_extra_free (&attr);
1639 return -1;
1640 }
paul718e3742002-12-13 20:15:29 +00001641
1642 /* Set NLRI portion to structure. */
1643 update.afi = AFI_IP;
1644 update.safi = SAFI_UNICAST;
1645 update.nlri = stream_pnt (s);
1646 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001647 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001648 }
1649
1650 /* NLRI is processed only when the peer is configured specific
1651 Address Family and Subsequent Address Family. */
1652 if (peer->afc[AFI_IP][SAFI_UNICAST])
1653 {
1654 if (withdraw.length)
1655 bgp_nlri_parse (peer, NULL, &withdraw);
1656
1657 if (update.length)
1658 {
1659 /* We check well-known attribute only for IPv4 unicast
1660 update. */
1661 ret = bgp_attr_check (peer, &attr);
1662 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001663 {
1664 bgp_attr_unintern_sub (&attr);
1665 if (attr.extra)
1666 bgp_attr_extra_free (&attr);
1667 return -1;
1668 }
paul718e3742002-12-13 20:15:29 +00001669
Paul Jakmab881c702010-11-23 16:35:42 +00001670 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
paul718e3742002-12-13 20:15:29 +00001671 }
paule01f9cb2004-07-09 17:48:53 +00001672
hassof4184462005-02-01 20:13:16 +00001673 if (mp_update.length
1674 && mp_update.afi == AFI_IP
1675 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001676 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
hassof4184462005-02-01 20:13:16 +00001677
1678 if (mp_withdraw.length
1679 && mp_withdraw.afi == AFI_IP
1680 && mp_withdraw.safi == SAFI_UNICAST)
1681 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1682
paule01f9cb2004-07-09 17:48:53 +00001683 if (! attribute_len && ! withdraw_len)
1684 {
1685 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001686 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1687 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001688
hasso93406d82005-02-02 14:40:33 +00001689 /* NSF delete stale route */
1690 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1691 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1692
1693 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001694 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001695 peer->host);
1696 }
paul718e3742002-12-13 20:15:29 +00001697 }
1698 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1699 {
1700 if (mp_update.length
1701 && mp_update.afi == AFI_IP
1702 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001703 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001704
1705 if (mp_withdraw.length
1706 && mp_withdraw.afi == AFI_IP
1707 && mp_withdraw.safi == SAFI_MULTICAST)
1708 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001709
hasso93406d82005-02-02 14:40:33 +00001710 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001711 && mp_withdraw.afi == AFI_IP
1712 && mp_withdraw.safi == SAFI_MULTICAST
1713 && mp_withdraw.length == 0)
1714 {
1715 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001716 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1717 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001718
hasso93406d82005-02-02 14:40:33 +00001719 /* NSF delete stale route */
1720 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1721 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1722
1723 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001724 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001725 peer->host);
1726 }
paul718e3742002-12-13 20:15:29 +00001727 }
1728 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1729 {
1730 if (mp_update.length
1731 && mp_update.afi == AFI_IP6
1732 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001733 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001734
1735 if (mp_withdraw.length
1736 && mp_withdraw.afi == AFI_IP6
1737 && mp_withdraw.safi == SAFI_UNICAST)
1738 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001739
hasso93406d82005-02-02 14:40:33 +00001740 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001741 && mp_withdraw.afi == AFI_IP6
1742 && mp_withdraw.safi == SAFI_UNICAST
1743 && mp_withdraw.length == 0)
1744 {
1745 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001746 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001747
hasso93406d82005-02-02 14:40:33 +00001748 /* NSF delete stale route */
1749 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1750 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1751
1752 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001753 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001754 peer->host);
1755 }
paul718e3742002-12-13 20:15:29 +00001756 }
1757 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1758 {
1759 if (mp_update.length
1760 && mp_update.afi == AFI_IP6
1761 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001762 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001763
1764 if (mp_withdraw.length
1765 && mp_withdraw.afi == AFI_IP6
1766 && mp_withdraw.safi == SAFI_MULTICAST)
1767 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001768
hasso93406d82005-02-02 14:40:33 +00001769 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001770 && mp_withdraw.afi == AFI_IP6
1771 && mp_withdraw.safi == SAFI_MULTICAST
1772 && mp_withdraw.length == 0)
1773 {
1774 /* End-of-RIB received */
1775
hasso93406d82005-02-02 14:40:33 +00001776 /* NSF delete stale route */
1777 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1778 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1779
paule01f9cb2004-07-09 17:48:53 +00001780 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001781 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001782 peer->host);
1783 }
paul718e3742002-12-13 20:15:29 +00001784 }
1785 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1786 {
1787 if (mp_update.length
1788 && mp_update.afi == AFI_IP
1789 && mp_update.safi == BGP_SAFI_VPNV4)
Paul Jakmab881c702010-11-23 16:35:42 +00001790 bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001791
1792 if (mp_withdraw.length
1793 && mp_withdraw.afi == AFI_IP
1794 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1795 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001796
hasso93406d82005-02-02 14:40:33 +00001797 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001798 && mp_withdraw.afi == AFI_IP
1799 && mp_withdraw.safi == BGP_SAFI_VPNV4
1800 && mp_withdraw.length == 0)
1801 {
1802 /* End-of-RIB received */
1803
1804 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001805 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001806 peer->host);
1807 }
paul718e3742002-12-13 20:15:29 +00001808 }
1809
1810 /* Everything is done. We unintern temporary structures which
1811 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001812 bgp_attr_unintern_sub (&attr);
Paul Jakmafb982c22007-05-04 20:15:47 +00001813 if (attr.extra)
Paul Jakmab881c702010-11-23 16:35:42 +00001814 bgp_attr_extra_free (&attr);
1815
paul718e3742002-12-13 20:15:29 +00001816 /* If peering is stopped due to some reason, do not generate BGP
1817 event. */
1818 if (peer->status != Established)
1819 return 0;
1820
1821 /* Increment packet counter. */
1822 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001823 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001824
1825 /* Generate BGP event. */
1826 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1827
1828 return 0;
1829}
1830
1831/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001832static void
paul718e3742002-12-13 20:15:29 +00001833bgp_notify_receive (struct peer *peer, bgp_size_t size)
1834{
1835 struct bgp_notify bgp_notify;
1836
1837 if (peer->notify.data)
1838 {
1839 XFREE (MTYPE_TMP, peer->notify.data);
1840 peer->notify.data = NULL;
1841 peer->notify.length = 0;
1842 }
1843
1844 bgp_notify.code = stream_getc (peer->ibuf);
1845 bgp_notify.subcode = stream_getc (peer->ibuf);
1846 bgp_notify.length = size - 2;
1847 bgp_notify.data = NULL;
1848
1849 /* Preserv notify code and sub code. */
1850 peer->notify.code = bgp_notify.code;
1851 peer->notify.subcode = bgp_notify.subcode;
1852 /* For further diagnostic record returned Data. */
1853 if (bgp_notify.length)
1854 {
1855 peer->notify.length = size - 2;
1856 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1857 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1858 }
1859
1860 /* For debug */
1861 {
1862 int i;
1863 int first = 0;
1864 char c[4];
1865
1866 if (bgp_notify.length)
1867 {
1868 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1869 for (i = 0; i < bgp_notify.length; i++)
1870 if (first)
1871 {
1872 sprintf (c, " %02x", stream_getc (peer->ibuf));
1873 strcat (bgp_notify.data, c);
1874 }
1875 else
1876 {
1877 first = 1;
1878 sprintf (c, "%02x", stream_getc (peer->ibuf));
1879 strcpy (bgp_notify.data, c);
1880 }
1881 }
1882
1883 bgp_notify_print(peer, &bgp_notify, "received");
1884 if (bgp_notify.data)
1885 XFREE (MTYPE_TMP, bgp_notify.data);
1886 }
1887
1888 /* peer count update */
1889 peer->notify_in++;
1890
hassoe0701b72004-05-20 09:19:34 +00001891 if (peer->status == Established)
1892 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1893
paul718e3742002-12-13 20:15:29 +00001894 /* We have to check for Notify with Unsupported Optional Parameter.
1895 in that case we fallback to open without the capability option.
1896 But this done in bgp_stop. We just mark it here to avoid changing
1897 the fsm tables. */
1898 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1899 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1900 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1901
paul718e3742002-12-13 20:15:29 +00001902 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1903}
1904
1905/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001906static void
paul718e3742002-12-13 20:15:29 +00001907bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1908{
1909 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001910 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001911
1912 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1913}
1914
1915/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001916static void
paul718e3742002-12-13 20:15:29 +00001917bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1918{
1919 afi_t afi;
1920 safi_t safi;
1921 u_char reserved;
1922 struct stream *s;
1923
1924 /* If peer does not have the capability, send notification. */
1925 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1926 {
1927 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1928 peer->host);
1929 bgp_notify_send (peer,
1930 BGP_NOTIFY_HEADER_ERR,
1931 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1932 return;
1933 }
1934
1935 /* Status must be Established. */
1936 if (peer->status != Established)
1937 {
1938 plog_err (peer->log,
1939 "%s [Error] Route refresh packet received under status %s",
1940 peer->host, LOOKUP (bgp_status_msg, peer->status));
1941 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1942 return;
1943 }
1944
1945 s = peer->ibuf;
1946
1947 /* Parse packet. */
1948 afi = stream_getw (s);
1949 reserved = stream_getc (s);
1950 safi = stream_getc (s);
1951
1952 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001953 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001954 peer->host, afi, safi);
1955
1956 /* Check AFI and SAFI. */
1957 if ((afi != AFI_IP && afi != AFI_IP6)
1958 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1959 && safi != BGP_SAFI_VPNV4))
1960 {
1961 if (BGP_DEBUG (normal, NORMAL))
1962 {
ajs6b514742004-12-08 21:03:23 +00001963 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001964 peer->host, afi, safi);
1965 }
1966 return;
1967 }
1968
1969 /* Adjust safi code. */
1970 if (safi == BGP_SAFI_VPNV4)
1971 safi = SAFI_MPLS_VPN;
1972
1973 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1974 {
1975 u_char *end;
1976 u_char when_to_refresh;
1977 u_char orf_type;
1978 u_int16_t orf_len;
1979
1980 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1981 {
1982 zlog_info ("%s ORF route refresh length error", peer->host);
1983 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1984 return;
1985 }
1986
1987 when_to_refresh = stream_getc (s);
1988 end = stream_pnt (s) + (size - 5);
1989
Paul Jakma370b64a2007-12-22 16:49:52 +00001990 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00001991 {
1992 orf_type = stream_getc (s);
1993 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00001994
1995 /* orf_len in bounds? */
1996 if ((stream_pnt (s) + orf_len) > end)
1997 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00001998 if (orf_type == ORF_TYPE_PREFIX
1999 || orf_type == ORF_TYPE_PREFIX_OLD)
2000 {
2001 u_char *p_pnt = stream_pnt (s);
2002 u_char *p_end = stream_pnt (s) + orf_len;
2003 struct orf_prefix orfp;
2004 u_char common = 0;
2005 u_int32_t seq;
2006 int psize;
2007 char name[BUFSIZ];
2008 char buf[BUFSIZ];
2009 int ret;
2010
2011 if (BGP_DEBUG (normal, NORMAL))
2012 {
ajs6b514742004-12-08 21:03:23 +00002013 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002014 peer->host, orf_type, orf_len);
2015 }
2016
Paul Jakma370b64a2007-12-22 16:49:52 +00002017 /* we're going to read at least 1 byte of common ORF header,
2018 * and 7 bytes of ORF Address-filter entry from the stream
2019 */
2020 if (orf_len < 7)
2021 break;
2022
paul718e3742002-12-13 20:15:29 +00002023 /* ORF prefix-list name */
2024 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2025
2026 while (p_pnt < p_end)
2027 {
Chris Halld64379e2010-05-14 16:38:39 +04002028 /* If the ORF entry is malformed, want to read as much of it
2029 * as possible without going beyond the bounds of the entry,
2030 * to maximise debug information.
2031 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002032 int ok;
paul718e3742002-12-13 20:15:29 +00002033 memset (&orfp, 0, sizeof (struct orf_prefix));
2034 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002035 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002036 if (common & ORF_COMMON_PART_REMOVE_ALL)
2037 {
2038 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002039 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00002040 prefix_bgp_orf_remove_all (name);
2041 break;
2042 }
Chris Halld64379e2010-05-14 16:38:39 +04002043 ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002044 if (!ok)
Chris Halld64379e2010-05-14 16:38:39 +04002045 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002046 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2047 p_pnt += sizeof (u_int32_t);
2048 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002049 }
2050 else
2051 p_pnt = p_end ;
2052
2053 if ((ok = (p_pnt < p_end)))
2054 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2055 if ((ok = (p_pnt < p_end)))
2056 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2057 if ((ok = (p_pnt < p_end)))
2058 orfp.p.prefixlen = *p_pnt++ ;
2059 orfp.p.family = afi2family (afi); /* afi checked already */
2060
2061 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2062 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2063 {
2064 ok = 0 ;
2065 psize = prefix_blen(&orfp.p) ;
2066 }
2067 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2068 {
2069 ok = 0 ;
2070 psize = p_end - p_pnt ;
2071 }
2072
2073 if (psize > 0)
2074 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002075 p_pnt += psize;
2076
2077 if (BGP_DEBUG (normal, NORMAL))
Chris Halld64379e2010-05-14 16:38:39 +04002078 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
paul718e3742002-12-13 20:15:29 +00002079 peer->host,
2080 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2081 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2082 orfp.seq,
2083 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
Chris Halld64379e2010-05-14 16:38:39 +04002084 orfp.p.prefixlen, orfp.ge, orfp.le,
2085 ok ? "" : " MALFORMED");
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002086
Chris Halld64379e2010-05-14 16:38:39 +04002087 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002088 ret = prefix_bgp_orf_set (name, afi, &orfp,
2089 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2090 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
paul718e3742002-12-13 20:15:29 +00002091
Chris Halld64379e2010-05-14 16:38:39 +04002092 if (!ok || (ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002093 {
2094 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002095 zlog_debug ("%s Received misformatted prefixlist ORF."
2096 " Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002097 prefix_bgp_orf_remove_all (name);
2098 break;
2099 }
2100 }
2101 peer->orf_plist[afi][safi] =
2102 prefix_list_lookup (AFI_ORF_PREFIX, name);
2103 }
paul9985f832005-02-09 15:51:56 +00002104 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002105 }
2106 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002107 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002108 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2109 if (when_to_refresh == REFRESH_DEFER)
2110 return;
2111 }
2112
2113 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2114 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2115 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2116
2117 /* Perform route refreshment to the peer */
2118 bgp_announce_route (peer, afi, safi);
2119}
2120
paul94f2b392005-06-28 12:44:16 +00002121static int
paul718e3742002-12-13 20:15:29 +00002122bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2123{
2124 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002125 struct capability_mp_data mpc;
2126 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002127 u_char action;
2128 struct bgp *bgp;
2129 afi_t afi;
2130 safi_t safi;
2131
2132 bgp = peer->bgp;
2133 end = pnt + length;
2134
2135 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002136 {
paul718e3742002-12-13 20:15:29 +00002137 /* We need at least action, capability code and capability length. */
2138 if (pnt + 3 > end)
2139 {
2140 zlog_info ("%s Capability length error", peer->host);
2141 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2142 return -1;
2143 }
paul718e3742002-12-13 20:15:29 +00002144 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002145 hdr = (struct capability_header *)(pnt + 1);
2146
paul718e3742002-12-13 20:15:29 +00002147 /* Action value check. */
2148 if (action != CAPABILITY_ACTION_SET
2149 && action != CAPABILITY_ACTION_UNSET)
2150 {
2151 zlog_info ("%s Capability Action Value error %d",
2152 peer->host, action);
2153 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2154 return -1;
2155 }
2156
2157 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002158 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002159 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002160
2161 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002162 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002163 {
2164 zlog_info ("%s Capability length error", peer->host);
2165 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2166 return -1;
2167 }
2168
Paul Jakma6d582722007-08-06 15:21:45 +00002169 /* Fetch structure to the byte stream. */
2170 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2171
paul718e3742002-12-13 20:15:29 +00002172 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002173 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002174 {
Paul Jakma6d582722007-08-06 15:21:45 +00002175 afi = ntohs (mpc.afi);
2176 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002177
2178 /* Ignore capability when override-capability is set. */
2179 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2180 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002181
2182 if (!bgp_afi_safi_valid_indices (afi, &safi))
2183 {
2184 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002185 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2186 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002187 continue;
2188 }
2189
paul718e3742002-12-13 20:15:29 +00002190 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002191 if (BGP_DEBUG (normal, NORMAL))
2192 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2193 peer->host,
2194 action == CAPABILITY_ACTION_SET
2195 ? "Advertising" : "Removing",
2196 ntohs(mpc.afi) , mpc.safi);
2197
2198 if (action == CAPABILITY_ACTION_SET)
2199 {
2200 peer->afc_recv[afi][safi] = 1;
2201 if (peer->afc[afi][safi])
2202 {
2203 peer->afc_nego[afi][safi] = 1;
2204 bgp_announce_route (peer, afi, safi);
2205 }
2206 }
2207 else
2208 {
2209 peer->afc_recv[afi][safi] = 0;
2210 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002211
Paul Jakma6d582722007-08-06 15:21:45 +00002212 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002213 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002214 else
2215 BGP_EVENT_ADD (peer, BGP_Stop);
2216 }
paul718e3742002-12-13 20:15:29 +00002217 }
paul718e3742002-12-13 20:15:29 +00002218 else
2219 {
2220 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002221 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002222 }
Paul Jakma6d582722007-08-06 15:21:45 +00002223 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002224 }
2225 return 0;
2226}
2227
Paul Jakma01b7ce22009-06-18 12:34:43 +01002228/* Dynamic Capability is received.
2229 *
2230 * This is exported for unit-test purposes
2231 */
Paul Jakma6d582722007-08-06 15:21:45 +00002232int
paul718e3742002-12-13 20:15:29 +00002233bgp_capability_receive (struct peer *peer, bgp_size_t size)
2234{
2235 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002236
2237 /* Fetch pointer. */
2238 pnt = stream_pnt (peer->ibuf);
2239
2240 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002241 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002242
2243 /* If peer does not have the capability, send notification. */
2244 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2245 {
2246 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2247 peer->host);
2248 bgp_notify_send (peer,
2249 BGP_NOTIFY_HEADER_ERR,
2250 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002251 return -1;
paul718e3742002-12-13 20:15:29 +00002252 }
2253
2254 /* Status must be Established. */
2255 if (peer->status != Established)
2256 {
2257 plog_err (peer->log,
2258 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2259 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002260 return -1;
paul718e3742002-12-13 20:15:29 +00002261 }
2262
2263 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002264 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002265}
2266
2267/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002268static int
paul718e3742002-12-13 20:15:29 +00002269bgp_read_packet (struct peer *peer)
2270{
2271 int nbytes;
2272 int readsize;
2273
paul9985f832005-02-09 15:51:56 +00002274 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002275
2276 /* If size is zero then return. */
2277 if (! readsize)
2278 return 0;
2279
2280 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002281 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002282
2283 /* If read byte is smaller than zero then error occured. */
2284 if (nbytes < 0)
2285 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002286 /* Transient error should retry */
2287 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002288 return -1;
2289
2290 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002291 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002292
2293 if (peer->status == Established)
2294 {
2295 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2296 {
2297 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2298 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2299 }
2300 else
2301 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2302 }
2303
paul718e3742002-12-13 20:15:29 +00002304 BGP_EVENT_ADD (peer, TCP_fatal_error);
2305 return -1;
2306 }
2307
2308 /* When read byte is zero : clear bgp peer and return */
2309 if (nbytes == 0)
2310 {
2311 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002312 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002313 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002314
2315 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002316 {
2317 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2318 {
2319 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2320 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2321 }
2322 else
2323 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2324 }
hassoe0701b72004-05-20 09:19:34 +00002325
paul718e3742002-12-13 20:15:29 +00002326 BGP_EVENT_ADD (peer, TCP_connection_closed);
2327 return -1;
2328 }
2329
2330 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002331 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002332 return -1;
2333
2334 return 0;
2335}
2336
2337/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002338static int
paul718e3742002-12-13 20:15:29 +00002339bgp_marker_all_one (struct stream *s, int length)
2340{
2341 int i;
2342
2343 for (i = 0; i < length; i++)
2344 if (s->data[i] != 0xff)
2345 return 0;
2346
2347 return 1;
2348}
2349
2350/* Starting point of packet process function. */
2351int
2352bgp_read (struct thread *thread)
2353{
2354 int ret;
2355 u_char type = 0;
2356 struct peer *peer;
2357 bgp_size_t size;
2358 char notify_data_length[2];
2359
2360 /* Yes first of all get peer pointer. */
2361 peer = THREAD_ARG (thread);
2362 peer->t_read = NULL;
2363
2364 /* For non-blocking IO check. */
2365 if (peer->status == Connect)
2366 {
2367 bgp_connect_check (peer);
2368 goto done;
2369 }
2370 else
2371 {
pauleb821182004-05-01 08:44:08 +00002372 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002373 {
pauleb821182004-05-01 08:44:08 +00002374 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002375 return -1;
2376 }
pauleb821182004-05-01 08:44:08 +00002377 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002378 }
2379
2380 /* Read packet header to determine type of the packet */
2381 if (peer->packet_size == 0)
2382 peer->packet_size = BGP_HEADER_SIZE;
2383
paul9985f832005-02-09 15:51:56 +00002384 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002385 {
2386 ret = bgp_read_packet (peer);
2387
2388 /* Header read error or partial read packet. */
2389 if (ret < 0)
2390 goto done;
2391
2392 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002393 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002394 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2395 size = stream_getw (peer->ibuf);
2396 type = stream_getc (peer->ibuf);
2397
2398 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002399 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002400 peer->host, type, size - BGP_HEADER_SIZE);
2401
2402 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002403 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002404 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2405 {
2406 bgp_notify_send (peer,
2407 BGP_NOTIFY_HEADER_ERR,
2408 BGP_NOTIFY_HEADER_NOT_SYNC);
2409 goto done;
2410 }
2411
2412 /* BGP type check. */
2413 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2414 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2415 && type != BGP_MSG_ROUTE_REFRESH_NEW
2416 && type != BGP_MSG_ROUTE_REFRESH_OLD
2417 && type != BGP_MSG_CAPABILITY)
2418 {
2419 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002420 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002421 "%s unknown message type 0x%02x",
2422 peer->host, type);
2423 bgp_notify_send_with_data (peer,
2424 BGP_NOTIFY_HEADER_ERR,
2425 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2426 &type, 1);
2427 goto done;
2428 }
2429 /* Mimimum packet length check. */
2430 if ((size < BGP_HEADER_SIZE)
2431 || (size > BGP_MAX_PACKET_SIZE)
2432 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2433 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2434 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2435 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2436 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2437 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2438 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2439 {
2440 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002441 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002442 "%s bad message length - %d for %s",
2443 peer->host, size,
2444 type == 128 ? "ROUTE-REFRESH" :
2445 bgp_type_str[(int) type]);
2446 bgp_notify_send_with_data (peer,
2447 BGP_NOTIFY_HEADER_ERR,
2448 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002449 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002450 goto done;
2451 }
2452
2453 /* Adjust size to message length. */
2454 peer->packet_size = size;
2455 }
2456
2457 ret = bgp_read_packet (peer);
2458 if (ret < 0)
2459 goto done;
2460
2461 /* Get size and type again. */
2462 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2463 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2464
2465 /* BGP packet dump function. */
2466 bgp_dump_packet (peer, type, peer->ibuf);
2467
2468 size = (peer->packet_size - BGP_HEADER_SIZE);
2469
2470 /* Read rest of the packet and call each sort of packet routine */
2471 switch (type)
2472 {
2473 case BGP_MSG_OPEN:
2474 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002475 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002476 break;
2477 case BGP_MSG_UPDATE:
2478 peer->readtime = time(NULL); /* Last read timer reset */
2479 bgp_update_receive (peer, size);
2480 break;
2481 case BGP_MSG_NOTIFY:
2482 bgp_notify_receive (peer, size);
2483 break;
2484 case BGP_MSG_KEEPALIVE:
2485 peer->readtime = time(NULL); /* Last read timer reset */
2486 bgp_keepalive_receive (peer, size);
2487 break;
2488 case BGP_MSG_ROUTE_REFRESH_NEW:
2489 case BGP_MSG_ROUTE_REFRESH_OLD:
2490 peer->refresh_in++;
2491 bgp_route_refresh_receive (peer, size);
2492 break;
2493 case BGP_MSG_CAPABILITY:
2494 peer->dynamic_cap_in++;
2495 bgp_capability_receive (peer, size);
2496 break;
2497 }
2498
2499 /* Clear input buffer. */
2500 peer->packet_size = 0;
2501 if (peer->ibuf)
2502 stream_reset (peer->ibuf);
2503
2504 done:
2505 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2506 {
2507 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002508 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002509 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002510 }
2511 return 0;
2512}