blob: 5f150600df685e78b8a39046e006fa1628468ac9 [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)
209 bgp_attr_unintern (adj->attr);
210 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 int write_errno;
602
603 /* Yes first of all get peer pointer. */
604 peer = THREAD_ARG (thread);
605 peer->t_write = NULL;
606
607 /* For non-blocking IO check. */
608 if (peer->status == Connect)
609 {
610 bgp_connect_check (peer);
611 return 0;
612 }
613
614 /* Nonblocking write until TCP output buffer is full. */
615 while (1)
616 {
617 int writenum;
paula24a7e12005-01-05 08:14:13 +0000618 int val;
paul718e3742002-12-13 20:15:29 +0000619
620 s = bgp_write_packet (peer);
621 if (! s)
622 return 0;
paula24a7e12005-01-05 08:14:13 +0000623
624 /* XXX: FIXME, the socket should be NONBLOCK from the start
625 * status shouldnt need to be toggled on each write
626 */
627 val = fcntl (peer->fd, F_GETFL, 0);
628 fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
paul718e3742002-12-13 20:15:29 +0000629
630 /* Number of bytes to be sent. */
631 writenum = stream_get_endp (s) - stream_get_getp (s);
632
633 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000634 num = write (peer->fd, STREAM_PNT (s), writenum);
paul718e3742002-12-13 20:15:29 +0000635 write_errno = errno;
paula24a7e12005-01-05 08:14:13 +0000636 fcntl (peer->fd, F_SETFL, val);
paul718e3742002-12-13 20:15:29 +0000637 if (num <= 0)
638 {
639 /* Partial write. */
640 if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
641 break;
642
Paul Jakmadcdf3992006-10-15 23:39:59 +0000643 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000644 return 0;
645 }
646 if (num != writenum)
647 {
paul9985f832005-02-09 15:51:56 +0000648 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000649
650 if (write_errno == EAGAIN)
651 break;
652
653 continue;
654 }
655
656 /* Retrieve BGP packet type. */
657 stream_set_getp (s, BGP_MARKER_SIZE + 2);
658 type = stream_getc (s);
659
660 switch (type)
661 {
662 case BGP_MSG_OPEN:
663 peer->open_out++;
664 break;
665 case BGP_MSG_UPDATE:
666 peer->update_out++;
667 break;
668 case BGP_MSG_NOTIFY:
669 peer->notify_out++;
670 /* Double start timer. */
671 peer->v_start *= 2;
672
673 /* Overflow check. */
674 if (peer->v_start >= (60 * 2))
675 peer->v_start = (60 * 2);
676
Paul Jakmaca058a32006-09-14 02:58:49 +0000677 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000678 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000679 return 0;
paul718e3742002-12-13 20:15:29 +0000680 case BGP_MSG_KEEPALIVE:
681 peer->keepalive_out++;
682 break;
683 case BGP_MSG_ROUTE_REFRESH_NEW:
684 case BGP_MSG_ROUTE_REFRESH_OLD:
685 peer->refresh_out++;
686 break;
687 case BGP_MSG_CAPABILITY:
688 peer->dynamic_cap_out++;
689 break;
690 }
691
692 /* OK we send packet so delete it. */
693 bgp_packet_delete (peer);
694
695 if (++count >= BGP_WRITE_PACKET_MAX)
696 break;
697 }
698
699 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000700 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000701
702 return 0;
703}
704
705/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000706static int
paul718e3742002-12-13 20:15:29 +0000707bgp_write_notify (struct peer *peer)
708{
709 int ret;
710 u_char type;
711 struct stream *s;
712
713 /* There should be at least one packet. */
714 s = stream_fifo_head (peer->obuf);
715 if (!s)
716 return 0;
717 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
718
719 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000720 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000721 if (ret <= 0)
722 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000723 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000724 return 0;
725 }
726
727 /* Retrieve BGP packet type. */
728 stream_set_getp (s, BGP_MARKER_SIZE + 2);
729 type = stream_getc (s);
730
731 assert (type == BGP_MSG_NOTIFY);
732
733 /* Type should be notify. */
734 peer->notify_out++;
735
736 /* Double start timer. */
737 peer->v_start *= 2;
738
739 /* Overflow check. */
740 if (peer->v_start >= (60 * 2))
741 peer->v_start = (60 * 2);
742
Paul Jakmadcdf3992006-10-15 23:39:59 +0000743 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000744
745 return 0;
746}
747
748/* Make keepalive packet and send it to the peer. */
749void
750bgp_keepalive_send (struct peer *peer)
751{
752 struct stream *s;
753 int length;
754
755 s = stream_new (BGP_MAX_PACKET_SIZE);
756
757 /* Make keepalive packet. */
758 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
759
760 /* Set packet size. */
761 length = bgp_packet_set_size (s);
762
763 /* Dump packet if debug option is set. */
764 /* bgp_packet_dump (s); */
765
766 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000767 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000768 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000769 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000770 peer->host, BGP_MSG_KEEPALIVE, length);
771
772 /* Add packet to the peer. */
773 bgp_packet_add (peer, s);
774
pauleb821182004-05-01 08:44:08 +0000775 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000776}
777
778/* Make open packet and send it to the peer. */
779void
780bgp_open_send (struct peer *peer)
781{
782 struct stream *s;
783 int length;
784 u_int16_t send_holdtime;
785 as_t local_as;
786
787 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
788 send_holdtime = peer->holdtime;
789 else
790 send_holdtime = peer->bgp->default_holdtime;
791
792 /* local-as Change */
793 if (peer->change_local_as)
794 local_as = peer->change_local_as;
795 else
796 local_as = peer->local_as;
797
798 s = stream_new (BGP_MAX_PACKET_SIZE);
799
800 /* Make open packet. */
801 bgp_packet_set_marker (s, BGP_MSG_OPEN);
802
803 /* Set open packet values. */
804 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000805 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
806 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000807 stream_putw (s, send_holdtime); /* Hold Time */
808 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
809
810 /* Set capability code. */
811 bgp_open_capability (s, peer);
812
813 /* Set BGP packet length. */
814 length = bgp_packet_set_size (s);
815
816 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400817 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000818 peer->host, BGP_VERSION_4, local_as,
819 send_holdtime, inet_ntoa (peer->local_id));
820
821 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000822 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000823 peer->host, BGP_MSG_OPEN, length);
824
825 /* Dump packet if debug option is set. */
826 /* bgp_packet_dump (s); */
827
828 /* Add packet to the peer. */
829 bgp_packet_add (peer, s);
830
pauleb821182004-05-01 08:44:08 +0000831 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000832}
833
834/* Send BGP notify packet with data potion. */
835void
836bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
837 u_char *data, size_t datalen)
838{
839 struct stream *s;
840 int length;
841
842 /* Allocate new stream. */
843 s = stream_new (BGP_MAX_PACKET_SIZE);
844
845 /* Make nitify packet. */
846 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
847
848 /* Set notify packet values. */
849 stream_putc (s, code); /* BGP notify code */
850 stream_putc (s, sub_code); /* BGP notify sub_code */
851
852 /* If notify data is present. */
853 if (data)
854 stream_write (s, data, datalen);
855
856 /* Set BGP packet length. */
857 length = bgp_packet_set_size (s);
858
859 /* Add packet to the peer. */
860 stream_fifo_clean (peer->obuf);
861 bgp_packet_add (peer, s);
862
863 /* For debug */
864 {
865 struct bgp_notify bgp_notify;
866 int first = 0;
867 int i;
868 char c[4];
869
870 bgp_notify.code = code;
871 bgp_notify.subcode = sub_code;
872 bgp_notify.data = NULL;
873 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
874
875 if (bgp_notify.length)
876 {
877 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
878 for (i = 0; i < bgp_notify.length; i++)
879 if (first)
880 {
881 sprintf (c, " %02x", data[i]);
882 strcat (bgp_notify.data, c);
883 }
884 else
885 {
886 first = 1;
887 sprintf (c, "%02x", data[i]);
888 strcpy (bgp_notify.data, c);
889 }
890 }
891 bgp_notify_print (peer, &bgp_notify, "sending");
892 if (bgp_notify.data)
893 XFREE (MTYPE_TMP, bgp_notify.data);
894 }
895
896 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000897 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000898 peer->host, BGP_MSG_NOTIFY, length);
899
hassoe0701b72004-05-20 09:19:34 +0000900 /* peer reset cause */
901 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
902 {
903 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley2e35e962011-09-12 13:27:52 +0400904 {
905 peer->last_reset = PEER_DOWN_USER_RESET;
906 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
907 }
hassoe0701b72004-05-20 09:19:34 +0000908 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley2e35e962011-09-12 13:27:52 +0400909 {
910 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
911 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
912 }
hassoe0701b72004-05-20 09:19:34 +0000913 else
heasley2e35e962011-09-12 13:27:52 +0400914 {
915 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
916 zlog_info ("Notification sent to neighbor %s: type %u/%u",
917 peer->host, code, sub_code);
918 }
hassoe0701b72004-05-20 09:19:34 +0000919 }
heasley2e35e962011-09-12 13:27:52 +0400920 else
921 zlog_info ("Notification sent to neighbor %s: configuration change",
922 peer->host);
hassoe0701b72004-05-20 09:19:34 +0000923
Denis Ovsienko71008de2011-09-10 16:53:30 +0400924 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +0000925 BGP_WRITE_OFF (peer->t_write);
926
927 bgp_write_notify (peer);
928}
929
930/* Send BGP notify packet. */
931void
932bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
933{
934 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
935}
936
paul718e3742002-12-13 20:15:29 +0000937/* Send route refresh message to the peer. */
938void
939bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
940 u_char orf_type, u_char when_to_refresh, int remove)
941{
942 struct stream *s;
943 struct stream *packet;
944 int length;
945 struct bgp_filter *filter;
946 int orf_refresh = 0;
947
Paul Jakma750e8142008-07-22 21:11:48 +0000948 if (DISABLE_BGP_ANNOUNCE)
949 return;
paul718e3742002-12-13 20:15:29 +0000950
951 filter = &peer->filter[afi][safi];
952
953 /* Adjust safi code. */
954 if (safi == SAFI_MPLS_VPN)
Denis Ovsienkoe81537d2011-07-14 12:36:19 +0400955 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +0000956
957 s = stream_new (BGP_MAX_PACKET_SIZE);
958
959 /* Make BGP update packet. */
960 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
961 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
962 else
963 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
964
965 /* Encode Route Refresh message. */
966 stream_putw (s, afi);
967 stream_putc (s, 0);
968 stream_putc (s, safi);
969
970 if (orf_type == ORF_TYPE_PREFIX
971 || orf_type == ORF_TYPE_PREFIX_OLD)
972 if (remove || filter->plist[FILTER_IN].plist)
973 {
974 u_int16_t orf_len;
975 unsigned long orfp;
976
977 orf_refresh = 1;
978 stream_putc (s, when_to_refresh);
979 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000980 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000981 stream_putw (s, 0);
982
983 if (remove)
984 {
985 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
986 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
987 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000988 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000989 peer->host, orf_type,
990 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
991 afi, safi);
992 }
993 else
994 {
995 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
996 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
997 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
998 ORF_COMMON_PART_DENY);
999 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001000 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001001 peer->host, orf_type,
1002 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1003 afi, safi);
1004 }
1005
1006 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001007 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001008 stream_putw_at (s, orfp, orf_len);
1009 }
1010
1011 /* Set packet size. */
1012 length = bgp_packet_set_size (s);
1013
1014 if (BGP_DEBUG (normal, NORMAL))
1015 {
1016 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001017 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001018 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001019 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001020 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1021 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1022 }
1023
1024 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001025 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001026 stream_free (s);
1027
1028 /* Add packet to the peer. */
1029 bgp_packet_add (peer, packet);
1030
pauleb821182004-05-01 08:44:08 +00001031 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001032}
1033
1034/* Send capability message to the peer. */
1035void
1036bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1037 int capability_code, int action)
1038{
1039 struct stream *s;
1040 struct stream *packet;
1041 int length;
1042
1043 /* Adjust safi code. */
1044 if (safi == SAFI_MPLS_VPN)
Denis Ovsienkoe81537d2011-07-14 12:36:19 +04001045 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001046
1047 s = stream_new (BGP_MAX_PACKET_SIZE);
1048
1049 /* Make BGP update packet. */
1050 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1051
1052 /* Encode MP_EXT capability. */
1053 if (capability_code == CAPABILITY_CODE_MP)
1054 {
1055 stream_putc (s, action);
1056 stream_putc (s, CAPABILITY_CODE_MP);
1057 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1058 stream_putw (s, afi);
1059 stream_putc (s, 0);
1060 stream_putc (s, safi);
1061
1062 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001063 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001064 peer->host, action == CAPABILITY_ACTION_SET ?
1065 "Advertising" : "Removing", afi, safi);
1066 }
1067
paul718e3742002-12-13 20:15:29 +00001068 /* Set packet size. */
1069 length = bgp_packet_set_size (s);
1070
1071 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001072 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001073 stream_free (s);
1074
1075 /* Add packet to the peer. */
1076 bgp_packet_add (peer, packet);
1077
1078 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001079 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001080 peer->host, BGP_MSG_CAPABILITY, length);
1081
pauleb821182004-05-01 08:44:08 +00001082 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001083}
1084
1085/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001086static int
pauleb821182004-05-01 08:44:08 +00001087bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001088{
pauleb821182004-05-01 08:44:08 +00001089 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001090 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001091 struct bgp *bgp;
1092
1093 bgp = bgp_get_default ();
1094 if (! bgp)
1095 return 0;
1096
1097 /* Upon receipt of an OPEN message, the local system must examine
1098 all of its connections that are in the OpenConfirm state. A BGP
1099 speaker may also examine connections in an OpenSent state if it
1100 knows the BGP Identifier of the peer by means outside of the
1101 protocol. If among these connections there is a connection to a
1102 remote BGP speaker whose BGP Identifier equals the one in the
1103 OPEN message, then the local system performs the following
1104 collision resolution procedure: */
1105
paul1eb8ef22005-04-07 07:30:20 +00001106 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001107 {
1108 /* Under OpenConfirm status, local peer structure already hold
1109 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001110
1111 if (peer != new
1112 && (peer->status == OpenConfirm || peer->status == OpenSent)
1113 && sockunion_same (&peer->su, &new->su))
1114 {
paul718e3742002-12-13 20:15:29 +00001115 /* 1. The BGP Identifier of the local system is compared to
1116 the BGP Identifier of the remote system (as specified in
1117 the OPEN message). */
1118
1119 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1120 {
1121 /* 2. If the value of the local BGP Identifier is less
1122 than the remote one, the local system closes BGP
1123 connection that already exists (the one that is
1124 already in the OpenConfirm state), and accepts BGP
1125 connection initiated by the remote system. */
1126
pauleb821182004-05-01 08:44:08 +00001127 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001128 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001129 return 1;
1130 }
1131 else
1132 {
1133 /* 3. Otherwise, the local system closes newly created
1134 BGP connection (the one associated with the newly
1135 received OPEN message), and continues to use the
1136 existing one (the one that is already in the
1137 OpenConfirm state). */
1138
pauleb821182004-05-01 08:44:08 +00001139 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001140 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1141 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001142 return -1;
1143 }
pauleb821182004-05-01 08:44:08 +00001144 }
1145 }
paul718e3742002-12-13 20:15:29 +00001146 return 0;
1147}
1148
paul94f2b392005-06-28 12:44:16 +00001149static int
paul718e3742002-12-13 20:15:29 +00001150bgp_open_receive (struct peer *peer, bgp_size_t size)
1151{
1152 int ret;
1153 u_char version;
1154 u_char optlen;
1155 u_int16_t holdtime;
1156 u_int16_t send_holdtime;
1157 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001158 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001159 struct peer *realpeer;
1160 struct in_addr remote_id;
1161 int capability;
paul5228ad22004-06-04 17:58:18 +00001162 u_int8_t notify_data_remote_as[2];
1163 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001164
1165 realpeer = NULL;
1166
1167 /* Parse open packet. */
1168 version = stream_getc (peer->ibuf);
1169 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1170 remote_as = stream_getw (peer->ibuf);
1171 holdtime = stream_getw (peer->ibuf);
1172 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1173 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1174
1175 /* Receive OPEN message log */
1176 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001177 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001178 " holdtime %d, id %s",
1179 peer->host, version, remote_as, holdtime,
1180 inet_ntoa (remote_id));
1181
1182 /* BEGIN to read the capability here, but dont do it yet */
1183 capability = 0;
1184 optlen = stream_getc (peer->ibuf);
1185
1186 if (optlen != 0)
1187 {
1188 /* We need the as4 capability value *right now* because
1189 * if it is there, we have not got the remote_as yet, and without
1190 * that we do not know which peer is connecting to us now.
1191 */
1192 as4 = peek_for_as4_capability (peer, optlen);
1193 }
1194
1195 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1196 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1197 {
1198 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1199 peer->host);
1200 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1201 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1202 return -1;
1203 }
1204
1205 if (remote_as == BGP_AS_TRANS)
1206 {
1207 /* Take the AS4 from the capability. We must have received the
1208 * capability now! Otherwise we have a asn16 peer who uses
1209 * BGP_AS_TRANS, for some unknown reason.
1210 */
1211 if (as4 == BGP_AS_TRANS)
1212 {
1213 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1214 peer->host);
1215 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1216 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1217 return -1;
1218 }
1219
1220 if (!as4 && BGP_DEBUG (as4, AS4))
1221 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1222 " Odd, but proceeding.", peer->host);
1223 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001224 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001225 "in 2-bytes, very odd peer.", peer->host, as4);
1226 if (as4)
1227 remote_as = as4;
1228 }
1229 else
1230 {
1231 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1232 /* If we have got the capability, peer->as4cap must match remote_as */
1233 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1234 && as4 != remote_as)
1235 {
1236 /* raise error, log this, close session */
1237 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1238 " mismatch with 16bit 'myasn' %u in open",
1239 peer->host, as4, remote_as);
1240 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1241 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1242 return -1;
1243 }
1244 }
1245
paul718e3742002-12-13 20:15:29 +00001246 /* Lookup peer from Open packet. */
1247 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1248 {
1249 int as = 0;
1250
1251 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1252
1253 if (! realpeer)
1254 {
1255 /* Peer's source IP address is check in bgp_accept(), so this
1256 must be AS number mismatch or remote-id configuration
1257 mismatch. */
1258 if (as)
1259 {
1260 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001261 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1262 peer->host, inet_ntoa (remote_id));
1263 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1264 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1265 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001266 }
1267 else
1268 {
1269 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001270 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001271 peer->host, remote_as, peer->as);
1272 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1273 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1274 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001275 }
1276 return -1;
1277 }
1278 }
1279
1280 /* When collision is detected and this peer is closed. Retrun
1281 immidiately. */
1282 ret = bgp_collision_detect (peer, remote_id);
1283 if (ret < 0)
1284 return ret;
1285
pauleb821182004-05-01 08:44:08 +00001286 /* Hack part. */
1287 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1288 {
hasso93406d82005-02-02 14:40:33 +00001289 if (realpeer->status == Established
1290 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1291 {
1292 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1293 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1294 }
1295 else if (ret == 0 && realpeer->status != Active
1296 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001297 && realpeer->status != OpenConfirm
1298 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001299 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001300 /* XXX: This is an awful problem..
1301 *
1302 * According to the RFC we should just let this connection (of the
1303 * accepted 'peer') continue on to Established if the other
1304 * connection (the 'realpeer' one) is in state Connect, and deal
1305 * with the more larval FSM as/when it gets far enough to receive
1306 * an Open. We don't do that though, we instead close the (more
1307 * developed) accepted connection.
1308 *
1309 * This means there's a race, which if hit, can loop:
1310 *
1311 * FSM for A FSM for B
1312 * realpeer accept-peer realpeer accept-peer
1313 *
1314 * Connect Connect
1315 * Active
1316 * OpenSent OpenSent
1317 * <arrive here,
1318 * Notify, delete>
1319 * Idle Active
1320 * OpenSent OpenSent
1321 * <arrive here,
1322 * Notify, delete>
1323 * Idle
1324 * <wait> <wait>
1325 * Connect Connect
1326 *
1327 *
1328 * If both sides are Quagga, they're almost certain to wait for
1329 * the same amount of time of course (which doesn't preclude other
1330 * implementations also waiting for same time). The race is
1331 * exacerbated by high-latency (in bgpd and/or the network).
1332 *
1333 * The reason we do this is because our FSM is tied to our peer
1334 * structure, which carries our configuration information, etc.
1335 * I.e. we can't let the accepted-peer FSM continue on as it is,
1336 * cause it's not associated with any actual peer configuration -
1337 * it's just a dummy.
1338 *
1339 * It's possible we could hack-fix this by just bgp_stop'ing the
1340 * realpeer and continueing on with the 'transfer FSM' below.
1341 * Ideally, we need to seperate FSMs from struct peer.
1342 *
1343 * Setting one side to passive avoids the race, as a workaround.
1344 */
pauleb821182004-05-01 08:44:08 +00001345 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001346 zlog_debug ("%s peer status is %s close connection",
1347 realpeer->host, LOOKUP (bgp_status_msg,
1348 realpeer->status));
1349 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1350 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1351
pauleb821182004-05-01 08:44:08 +00001352 return -1;
1353 }
1354
1355 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001356 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1357 peer->host,
1358 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001359
1360 bgp_stop (realpeer);
1361
1362 /* Transfer file descriptor. */
1363 realpeer->fd = peer->fd;
1364 peer->fd = -1;
1365
1366 /* Transfer input buffer. */
1367 stream_free (realpeer->ibuf);
1368 realpeer->ibuf = peer->ibuf;
1369 realpeer->packet_size = peer->packet_size;
1370 peer->ibuf = NULL;
1371
1372 /* Transfer status. */
1373 realpeer->status = peer->status;
1374 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001375
pauleb821182004-05-01 08:44:08 +00001376 /* peer pointer change. Open packet send to neighbor. */
1377 peer = realpeer;
1378 bgp_open_send (peer);
1379 if (peer->fd < 0)
1380 {
1381 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1382 peer->fd);
1383 return -1;
1384 }
1385 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1386 }
1387
paul718e3742002-12-13 20:15:29 +00001388 /* remote router-id check. */
1389 if (remote_id.s_addr == 0
1390 || ntohl (remote_id.s_addr) >= 0xe0000000
1391 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1392 {
1393 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001394 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001395 peer->host, inet_ntoa (remote_id));
1396 bgp_notify_send_with_data (peer,
1397 BGP_NOTIFY_OPEN_ERR,
1398 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1399 notify_data_remote_id, 4);
1400 return -1;
1401 }
1402
1403 /* Set remote router-id */
1404 peer->remote_id = remote_id;
1405
1406 /* Peer BGP version check. */
1407 if (version != BGP_VERSION_4)
1408 {
paul5228ad22004-06-04 17:58:18 +00001409 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001410 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001411 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001412 peer->host, version, BGP_VERSION_4);
1413 bgp_notify_send_with_data (peer,
1414 BGP_NOTIFY_OPEN_ERR,
1415 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001416 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001417 return -1;
1418 }
1419
1420 /* Check neighbor as number. */
1421 if (remote_as != peer->as)
1422 {
1423 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001424 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001425 peer->host, remote_as, peer->as);
1426 bgp_notify_send_with_data (peer,
1427 BGP_NOTIFY_OPEN_ERR,
1428 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1429 notify_data_remote_as, 2);
1430 return -1;
1431 }
1432
1433 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1434 calculate the value of the Hold Timer by using the smaller of its
1435 configured Hold Time and the Hold Time received in the OPEN message.
1436 The Hold Time MUST be either zero or at least three seconds. An
1437 implementation may reject connections on the basis of the Hold Time. */
1438
1439 if (holdtime < 3 && holdtime != 0)
1440 {
1441 bgp_notify_send (peer,
1442 BGP_NOTIFY_OPEN_ERR,
1443 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1444 return -1;
1445 }
1446
1447 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1448 would be one third of the Hold Time interval. KEEPALIVE messages
1449 MUST NOT be sent more frequently than one per second. An
1450 implementation MAY adjust the rate at which it sends KEEPALIVE
1451 messages as a function of the Hold Time interval. */
1452
1453 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1454 send_holdtime = peer->holdtime;
1455 else
1456 send_holdtime = peer->bgp->default_holdtime;
1457
1458 if (holdtime < send_holdtime)
1459 peer->v_holdtime = holdtime;
1460 else
1461 peer->v_holdtime = send_holdtime;
1462
1463 peer->v_keepalive = peer->v_holdtime / 3;
1464
1465 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001466 if (optlen != 0)
1467 {
1468 ret = bgp_open_option_parse (peer, optlen, &capability);
1469 if (ret < 0)
1470 return ret;
paul718e3742002-12-13 20:15:29 +00001471 }
1472 else
1473 {
1474 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001475 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001476 peer->host);
1477 }
1478
1479 /* Override capability. */
1480 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1481 {
1482 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1483 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1484 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1485 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1486 }
1487
1488 /* Get sockname. */
1489 bgp_getsockname (peer);
1490
1491 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1492
1493 peer->packet_size = 0;
1494 if (peer->ibuf)
1495 stream_reset (peer->ibuf);
1496
1497 return 0;
1498}
1499
1500/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001501static int
paul718e3742002-12-13 20:15:29 +00001502bgp_update_receive (struct peer *peer, bgp_size_t size)
1503{
1504 int ret;
1505 u_char *end;
1506 struct stream *s;
1507 struct attr attr;
1508 bgp_size_t attribute_len;
1509 bgp_size_t update_len;
1510 bgp_size_t withdraw_len;
1511 struct bgp_nlri update;
1512 struct bgp_nlri withdraw;
1513 struct bgp_nlri mp_update;
1514 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001515 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001516
1517 /* Status must be Established. */
1518 if (peer->status != Established)
1519 {
1520 zlog_err ("%s [FSM] Update packet received under status %s",
1521 peer->host, LOOKUP (bgp_status_msg, peer->status));
1522 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1523 return -1;
1524 }
1525
1526 /* Set initial values. */
1527 memset (&attr, 0, sizeof (struct attr));
1528 memset (&update, 0, sizeof (struct bgp_nlri));
1529 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1530 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1531 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1532
1533 s = peer->ibuf;
1534 end = stream_pnt (s) + size;
1535
1536 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1537 Length is too large (i.e., if Unfeasible Routes Length + Total
1538 Attribute Length + 23 exceeds the message Length), then the Error
1539 Subcode is set to Malformed Attribute List. */
1540 if (stream_pnt (s) + 2 > end)
1541 {
1542 zlog_err ("%s [Error] Update packet error"
1543 " (packet length is short for unfeasible length)",
1544 peer->host);
1545 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1546 BGP_NOTIFY_UPDATE_MAL_ATTR);
1547 return -1;
1548 }
1549
1550 /* Unfeasible Route Length. */
1551 withdraw_len = stream_getw (s);
1552
1553 /* Unfeasible Route Length check. */
1554 if (stream_pnt (s) + withdraw_len > end)
1555 {
1556 zlog_err ("%s [Error] Update packet error"
1557 " (packet unfeasible length overflow %d)",
1558 peer->host, withdraw_len);
1559 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1560 BGP_NOTIFY_UPDATE_MAL_ATTR);
1561 return -1;
1562 }
1563
1564 /* Unfeasible Route packet format check. */
1565 if (withdraw_len > 0)
1566 {
1567 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1568 if (ret < 0)
1569 return -1;
1570
1571 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001572 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001573
1574 withdraw.afi = AFI_IP;
1575 withdraw.safi = SAFI_UNICAST;
1576 withdraw.nlri = stream_pnt (s);
1577 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001578 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001579 }
1580
1581 /* Attribute total length check. */
1582 if (stream_pnt (s) + 2 > end)
1583 {
1584 zlog_warn ("%s [Error] Packet Error"
1585 " (update packet is short for attribute length)",
1586 peer->host);
1587 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1588 BGP_NOTIFY_UPDATE_MAL_ATTR);
1589 return -1;
1590 }
1591
1592 /* Fetch attribute total length. */
1593 attribute_len = stream_getw (s);
1594
1595 /* Attribute length check. */
1596 if (stream_pnt (s) + attribute_len > end)
1597 {
1598 zlog_warn ("%s [Error] Packet Error"
1599 " (update packet attribute length overflow %d)",
1600 peer->host, attribute_len);
1601 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1602 BGP_NOTIFY_UPDATE_MAL_ATTR);
1603 return -1;
1604 }
1605
1606 /* Parse attribute when it exists. */
1607 if (attribute_len)
1608 {
1609 ret = bgp_attr_parse (peer, &attr, attribute_len,
1610 &mp_update, &mp_withdraw);
1611 if (ret < 0)
1612 return -1;
1613 }
1614
1615 /* Logging the attribute. */
1616 if (BGP_DEBUG (update, UPDATE_IN))
1617 {
paule01f9cb2004-07-09 17:48:53 +00001618 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1619
1620 if (ret)
ajs6b514742004-12-08 21:03:23 +00001621 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001622 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001623 }
1624
1625 /* Network Layer Reachability Information. */
1626 update_len = end - stream_pnt (s);
1627
1628 if (update_len)
1629 {
1630 /* Check NLRI packet format and prefix length. */
1631 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1632 if (ret < 0)
1633 return -1;
1634
1635 /* Set NLRI portion to structure. */
1636 update.afi = AFI_IP;
1637 update.safi = SAFI_UNICAST;
1638 update.nlri = stream_pnt (s);
1639 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001640 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001641 }
1642
1643 /* NLRI is processed only when the peer is configured specific
1644 Address Family and Subsequent Address Family. */
1645 if (peer->afc[AFI_IP][SAFI_UNICAST])
1646 {
1647 if (withdraw.length)
1648 bgp_nlri_parse (peer, NULL, &withdraw);
1649
1650 if (update.length)
1651 {
1652 /* We check well-known attribute only for IPv4 unicast
1653 update. */
1654 ret = bgp_attr_check (peer, &attr);
1655 if (ret < 0)
1656 return -1;
1657
1658 bgp_nlri_parse (peer, &attr, &update);
1659 }
paule01f9cb2004-07-09 17:48:53 +00001660
hassof4184462005-02-01 20:13:16 +00001661 if (mp_update.length
1662 && mp_update.afi == AFI_IP
1663 && mp_update.safi == SAFI_UNICAST)
1664 bgp_nlri_parse (peer, &attr, &mp_update);
1665
1666 if (mp_withdraw.length
1667 && mp_withdraw.afi == AFI_IP
1668 && mp_withdraw.safi == SAFI_UNICAST)
1669 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1670
paule01f9cb2004-07-09 17:48:53 +00001671 if (! attribute_len && ! withdraw_len)
1672 {
1673 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001674 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1675 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001676
hasso93406d82005-02-02 14:40:33 +00001677 /* NSF delete stale route */
1678 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1679 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1680
1681 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001682 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001683 peer->host);
1684 }
paul718e3742002-12-13 20:15:29 +00001685 }
1686 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1687 {
1688 if (mp_update.length
1689 && mp_update.afi == AFI_IP
1690 && mp_update.safi == SAFI_MULTICAST)
1691 bgp_nlri_parse (peer, &attr, &mp_update);
1692
1693 if (mp_withdraw.length
1694 && mp_withdraw.afi == AFI_IP
1695 && mp_withdraw.safi == SAFI_MULTICAST)
1696 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001697
hasso93406d82005-02-02 14:40:33 +00001698 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001699 && mp_withdraw.afi == AFI_IP
1700 && mp_withdraw.safi == SAFI_MULTICAST
1701 && mp_withdraw.length == 0)
1702 {
1703 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001704 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1705 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001706
hasso93406d82005-02-02 14:40:33 +00001707 /* NSF delete stale route */
1708 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1709 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1710
1711 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001712 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001713 peer->host);
1714 }
paul718e3742002-12-13 20:15:29 +00001715 }
1716 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1717 {
1718 if (mp_update.length
1719 && mp_update.afi == AFI_IP6
1720 && mp_update.safi == SAFI_UNICAST)
1721 bgp_nlri_parse (peer, &attr, &mp_update);
1722
1723 if (mp_withdraw.length
1724 && mp_withdraw.afi == AFI_IP6
1725 && mp_withdraw.safi == SAFI_UNICAST)
1726 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001727
hasso93406d82005-02-02 14:40:33 +00001728 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001729 && mp_withdraw.afi == AFI_IP6
1730 && mp_withdraw.safi == SAFI_UNICAST
1731 && mp_withdraw.length == 0)
1732 {
1733 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001734 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001735
hasso93406d82005-02-02 14:40:33 +00001736 /* NSF delete stale route */
1737 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1738 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1739
1740 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001741 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001742 peer->host);
1743 }
paul718e3742002-12-13 20:15:29 +00001744 }
1745 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1746 {
1747 if (mp_update.length
1748 && mp_update.afi == AFI_IP6
1749 && mp_update.safi == SAFI_MULTICAST)
1750 bgp_nlri_parse (peer, &attr, &mp_update);
1751
1752 if (mp_withdraw.length
1753 && mp_withdraw.afi == AFI_IP6
1754 && mp_withdraw.safi == SAFI_MULTICAST)
1755 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001756
hasso93406d82005-02-02 14:40:33 +00001757 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001758 && mp_withdraw.afi == AFI_IP6
1759 && mp_withdraw.safi == SAFI_MULTICAST
1760 && mp_withdraw.length == 0)
1761 {
1762 /* End-of-RIB received */
1763
hasso93406d82005-02-02 14:40:33 +00001764 /* NSF delete stale route */
1765 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1766 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1767
paule01f9cb2004-07-09 17:48:53 +00001768 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001769 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001770 peer->host);
1771 }
paul718e3742002-12-13 20:15:29 +00001772 }
1773 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1774 {
1775 if (mp_update.length
1776 && mp_update.afi == AFI_IP
Denis Ovsienkoe81537d2011-07-14 12:36:19 +04001777 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00001778 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1779
1780 if (mp_withdraw.length
1781 && mp_withdraw.afi == AFI_IP
Denis Ovsienkoe81537d2011-07-14 12:36:19 +04001782 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00001783 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001784
hasso93406d82005-02-02 14:40:33 +00001785 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001786 && mp_withdraw.afi == AFI_IP
Denis Ovsienkoe81537d2011-07-14 12:36:19 +04001787 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
paule01f9cb2004-07-09 17:48:53 +00001788 && mp_withdraw.length == 0)
1789 {
1790 /* End-of-RIB received */
1791
1792 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001793 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001794 peer->host);
1795 }
paul718e3742002-12-13 20:15:29 +00001796 }
1797
1798 /* Everything is done. We unintern temporary structures which
1799 interned in bgp_attr_parse(). */
1800 if (attr.aspath)
1801 aspath_unintern (attr.aspath);
1802 if (attr.community)
1803 community_unintern (attr.community);
Paul Jakmafb982c22007-05-04 20:15:47 +00001804 if (attr.extra)
1805 {
1806 if (attr.extra->ecommunity)
1807 ecommunity_unintern (attr.extra->ecommunity);
1808 if (attr.extra->cluster)
1809 cluster_unintern (attr.extra->cluster);
1810 if (attr.extra->transit)
1811 transit_unintern (attr.extra->transit);
1812 bgp_attr_extra_free (&attr);
1813 }
paul718e3742002-12-13 20:15:29 +00001814
1815 /* If peering is stopped due to some reason, do not generate BGP
1816 event. */
1817 if (peer->status != Established)
1818 return 0;
1819
1820 /* Increment packet counter. */
1821 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001822 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001823
1824 /* Generate BGP event. */
1825 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1826
1827 return 0;
1828}
1829
1830/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001831static void
paul718e3742002-12-13 20:15:29 +00001832bgp_notify_receive (struct peer *peer, bgp_size_t size)
1833{
1834 struct bgp_notify bgp_notify;
1835
1836 if (peer->notify.data)
1837 {
1838 XFREE (MTYPE_TMP, peer->notify.data);
1839 peer->notify.data = NULL;
1840 peer->notify.length = 0;
1841 }
1842
1843 bgp_notify.code = stream_getc (peer->ibuf);
1844 bgp_notify.subcode = stream_getc (peer->ibuf);
1845 bgp_notify.length = size - 2;
1846 bgp_notify.data = NULL;
1847
1848 /* Preserv notify code and sub code. */
1849 peer->notify.code = bgp_notify.code;
1850 peer->notify.subcode = bgp_notify.subcode;
1851 /* For further diagnostic record returned Data. */
1852 if (bgp_notify.length)
1853 {
1854 peer->notify.length = size - 2;
1855 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1856 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1857 }
1858
1859 /* For debug */
1860 {
1861 int i;
1862 int first = 0;
1863 char c[4];
1864
1865 if (bgp_notify.length)
1866 {
1867 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1868 for (i = 0; i < bgp_notify.length; i++)
1869 if (first)
1870 {
1871 sprintf (c, " %02x", stream_getc (peer->ibuf));
1872 strcat (bgp_notify.data, c);
1873 }
1874 else
1875 {
1876 first = 1;
1877 sprintf (c, "%02x", stream_getc (peer->ibuf));
1878 strcpy (bgp_notify.data, c);
1879 }
1880 }
1881
1882 bgp_notify_print(peer, &bgp_notify, "received");
1883 if (bgp_notify.data)
1884 XFREE (MTYPE_TMP, bgp_notify.data);
1885 }
1886
1887 /* peer count update */
1888 peer->notify_in++;
1889
hassoe0701b72004-05-20 09:19:34 +00001890 if (peer->status == Established)
1891 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1892
paul718e3742002-12-13 20:15:29 +00001893 /* We have to check for Notify with Unsupported Optional Parameter.
1894 in that case we fallback to open without the capability option.
1895 But this done in bgp_stop. We just mark it here to avoid changing
1896 the fsm tables. */
1897 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1898 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1899 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1900
paul718e3742002-12-13 20:15:29 +00001901 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1902}
1903
1904/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001905static void
paul718e3742002-12-13 20:15:29 +00001906bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1907{
1908 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001909 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001910
1911 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1912}
1913
1914/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001915static void
paul718e3742002-12-13 20:15:29 +00001916bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1917{
1918 afi_t afi;
1919 safi_t safi;
1920 u_char reserved;
1921 struct stream *s;
1922
1923 /* If peer does not have the capability, send notification. */
1924 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1925 {
1926 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1927 peer->host);
1928 bgp_notify_send (peer,
1929 BGP_NOTIFY_HEADER_ERR,
1930 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1931 return;
1932 }
1933
1934 /* Status must be Established. */
1935 if (peer->status != Established)
1936 {
1937 plog_err (peer->log,
1938 "%s [Error] Route refresh packet received under status %s",
1939 peer->host, LOOKUP (bgp_status_msg, peer->status));
1940 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1941 return;
1942 }
1943
1944 s = peer->ibuf;
1945
1946 /* Parse packet. */
1947 afi = stream_getw (s);
1948 reserved = stream_getc (s);
1949 safi = stream_getc (s);
1950
1951 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001952 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001953 peer->host, afi, safi);
1954
1955 /* Check AFI and SAFI. */
1956 if ((afi != AFI_IP && afi != AFI_IP6)
1957 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienkoe81537d2011-07-14 12:36:19 +04001958 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00001959 {
1960 if (BGP_DEBUG (normal, NORMAL))
1961 {
ajs6b514742004-12-08 21:03:23 +00001962 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001963 peer->host, afi, safi);
1964 }
1965 return;
1966 }
1967
1968 /* Adjust safi code. */
Denis Ovsienkoe81537d2011-07-14 12:36:19 +04001969 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00001970 safi = SAFI_MPLS_VPN;
1971
1972 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1973 {
1974 u_char *end;
1975 u_char when_to_refresh;
1976 u_char orf_type;
1977 u_int16_t orf_len;
1978
1979 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1980 {
1981 zlog_info ("%s ORF route refresh length error", peer->host);
1982 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1983 return;
1984 }
1985
1986 when_to_refresh = stream_getc (s);
1987 end = stream_pnt (s) + (size - 5);
1988
Paul Jakma370b64a2007-12-22 16:49:52 +00001989 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00001990 {
1991 orf_type = stream_getc (s);
1992 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00001993
1994 /* orf_len in bounds? */
1995 if ((stream_pnt (s) + orf_len) > end)
1996 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00001997 if (orf_type == ORF_TYPE_PREFIX
1998 || orf_type == ORF_TYPE_PREFIX_OLD)
1999 {
2000 u_char *p_pnt = stream_pnt (s);
2001 u_char *p_end = stream_pnt (s) + orf_len;
2002 struct orf_prefix orfp;
2003 u_char common = 0;
2004 u_int32_t seq;
2005 int psize;
2006 char name[BUFSIZ];
2007 char buf[BUFSIZ];
2008 int ret;
2009
2010 if (BGP_DEBUG (normal, NORMAL))
2011 {
ajs6b514742004-12-08 21:03:23 +00002012 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002013 peer->host, orf_type, orf_len);
2014 }
2015
Paul Jakma370b64a2007-12-22 16:49:52 +00002016 /* we're going to read at least 1 byte of common ORF header,
2017 * and 7 bytes of ORF Address-filter entry from the stream
2018 */
2019 if (orf_len < 7)
2020 break;
2021
paul718e3742002-12-13 20:15:29 +00002022 /* ORF prefix-list name */
2023 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2024
2025 while (p_pnt < p_end)
2026 {
Chris Halld64379e2010-05-14 16:38:39 +04002027 /* If the ORF entry is malformed, want to read as much of it
2028 * as possible without going beyond the bounds of the entry,
2029 * to maximise debug information.
2030 */
2031 int ok ;
paul718e3742002-12-13 20:15:29 +00002032 memset (&orfp, 0, sizeof (struct orf_prefix));
2033 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002034 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002035 if (common & ORF_COMMON_PART_REMOVE_ALL)
2036 {
2037 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002038 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00002039 prefix_bgp_orf_remove_all (name);
2040 break;
2041 }
Chris Halld64379e2010-05-14 16:38:39 +04002042 ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
2043 if (ok)
2044 {
paul718e3742002-12-13 20:15:29 +00002045 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2046 p_pnt += sizeof (u_int32_t);
2047 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002048 }
2049 else
2050 p_pnt = p_end ;
2051
2052 if ((ok = (p_pnt < p_end)))
2053 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2054 if ((ok = (p_pnt < p_end)))
2055 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2056 if ((ok = (p_pnt < p_end)))
2057 orfp.p.prefixlen = *p_pnt++ ;
2058 orfp.p.family = afi2family (afi); /* afi checked already */
2059
2060 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2061 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2062 {
2063 ok = 0 ;
2064 psize = prefix_blen(&orfp.p) ;
2065 }
2066 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2067 {
2068 ok = 0 ;
2069 psize = p_end - p_pnt ;
2070 }
2071
2072 if (psize > 0)
2073 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002074 p_pnt += psize;
2075
2076 if (BGP_DEBUG (normal, NORMAL))
Chris Halld64379e2010-05-14 16:38:39 +04002077 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
paul718e3742002-12-13 20:15:29 +00002078 peer->host,
2079 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2080 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2081 orfp.seq,
2082 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
Chris Halld64379e2010-05-14 16:38:39 +04002083 orfp.p.prefixlen, orfp.ge, orfp.le,
2084 ok ? "" : " MALFORMED");
paul718e3742002-12-13 20:15:29 +00002085
Chris Halld64379e2010-05-14 16:38:39 +04002086 if (ok)
paul718e3742002-12-13 20:15:29 +00002087 ret = prefix_bgp_orf_set (name, afi, &orfp,
2088 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2089 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
2090
Chris Halld64379e2010-05-14 16:38:39 +04002091 if (!ok || (ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002092 {
2093 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002094 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002095 prefix_bgp_orf_remove_all (name);
2096 break;
2097 }
2098 }
2099 peer->orf_plist[afi][safi] =
2100 prefix_list_lookup (AFI_ORF_PREFIX, name);
2101 }
paul9985f832005-02-09 15:51:56 +00002102 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002103 }
2104 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002105 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002106 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2107 if (when_to_refresh == REFRESH_DEFER)
2108 return;
2109 }
2110
2111 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2112 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2113 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2114
2115 /* Perform route refreshment to the peer */
2116 bgp_announce_route (peer, afi, safi);
2117}
2118
paul94f2b392005-06-28 12:44:16 +00002119static int
paul718e3742002-12-13 20:15:29 +00002120bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2121{
2122 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002123 struct capability_mp_data mpc;
2124 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002125 u_char action;
2126 struct bgp *bgp;
2127 afi_t afi;
2128 safi_t safi;
2129
2130 bgp = peer->bgp;
2131 end = pnt + length;
2132
2133 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002134 {
paul718e3742002-12-13 20:15:29 +00002135 /* We need at least action, capability code and capability length. */
2136 if (pnt + 3 > end)
2137 {
2138 zlog_info ("%s Capability length error", peer->host);
2139 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2140 return -1;
2141 }
paul718e3742002-12-13 20:15:29 +00002142 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002143 hdr = (struct capability_header *)(pnt + 1);
2144
paul718e3742002-12-13 20:15:29 +00002145 /* Action value check. */
2146 if (action != CAPABILITY_ACTION_SET
2147 && action != CAPABILITY_ACTION_UNSET)
2148 {
2149 zlog_info ("%s Capability Action Value error %d",
2150 peer->host, action);
2151 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2152 return -1;
2153 }
2154
2155 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002156 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002157 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002158
2159 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002160 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002161 {
2162 zlog_info ("%s Capability length error", peer->host);
2163 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2164 return -1;
2165 }
2166
Paul Jakma6d582722007-08-06 15:21:45 +00002167 /* Fetch structure to the byte stream. */
2168 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2169
paul718e3742002-12-13 20:15:29 +00002170 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002171 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002172 {
Paul Jakma6d582722007-08-06 15:21:45 +00002173 afi = ntohs (mpc.afi);
2174 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002175
2176 /* Ignore capability when override-capability is set. */
2177 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2178 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002179
2180 if (!bgp_afi_safi_valid_indices (afi, &safi))
2181 {
2182 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002183 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2184 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002185 continue;
2186 }
2187
paul718e3742002-12-13 20:15:29 +00002188 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002189 if (BGP_DEBUG (normal, NORMAL))
2190 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2191 peer->host,
2192 action == CAPABILITY_ACTION_SET
2193 ? "Advertising" : "Removing",
2194 ntohs(mpc.afi) , mpc.safi);
2195
2196 if (action == CAPABILITY_ACTION_SET)
2197 {
2198 peer->afc_recv[afi][safi] = 1;
2199 if (peer->afc[afi][safi])
2200 {
2201 peer->afc_nego[afi][safi] = 1;
2202 bgp_announce_route (peer, afi, safi);
2203 }
2204 }
2205 else
2206 {
2207 peer->afc_recv[afi][safi] = 0;
2208 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002209
Paul Jakma6d582722007-08-06 15:21:45 +00002210 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002211 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002212 else
2213 BGP_EVENT_ADD (peer, BGP_Stop);
2214 }
paul718e3742002-12-13 20:15:29 +00002215 }
paul718e3742002-12-13 20:15:29 +00002216 else
2217 {
2218 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002219 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002220 }
Paul Jakma6d582722007-08-06 15:21:45 +00002221 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002222 }
2223 return 0;
2224}
2225
Paul Jakma01b7ce22009-06-18 12:34:43 +01002226/* Dynamic Capability is received.
2227 *
2228 * This is exported for unit-test purposes
2229 */
Paul Jakma6d582722007-08-06 15:21:45 +00002230int
paul718e3742002-12-13 20:15:29 +00002231bgp_capability_receive (struct peer *peer, bgp_size_t size)
2232{
2233 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002234
2235 /* Fetch pointer. */
2236 pnt = stream_pnt (peer->ibuf);
2237
2238 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002239 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002240
2241 /* If peer does not have the capability, send notification. */
2242 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2243 {
2244 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2245 peer->host);
2246 bgp_notify_send (peer,
2247 BGP_NOTIFY_HEADER_ERR,
2248 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002249 return -1;
paul718e3742002-12-13 20:15:29 +00002250 }
2251
2252 /* Status must be Established. */
2253 if (peer->status != Established)
2254 {
2255 plog_err (peer->log,
2256 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2257 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002258 return -1;
paul718e3742002-12-13 20:15:29 +00002259 }
2260
2261 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002262 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002263}
2264
2265/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002266static int
paul718e3742002-12-13 20:15:29 +00002267bgp_read_packet (struct peer *peer)
2268{
2269 int nbytes;
2270 int readsize;
2271
paul9985f832005-02-09 15:51:56 +00002272 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002273
2274 /* If size is zero then return. */
2275 if (! readsize)
2276 return 0;
2277
2278 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002279 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002280
2281 /* If read byte is smaller than zero then error occured. */
2282 if (nbytes < 0)
2283 {
2284 if (errno == EAGAIN)
2285 return -1;
2286
2287 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002288 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002289
2290 if (peer->status == Established)
2291 {
2292 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2293 {
2294 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2295 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2296 }
2297 else
2298 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2299 }
2300
paul718e3742002-12-13 20:15:29 +00002301 BGP_EVENT_ADD (peer, TCP_fatal_error);
2302 return -1;
2303 }
2304
2305 /* When read byte is zero : clear bgp peer and return */
2306 if (nbytes == 0)
2307 {
2308 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002309 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002310 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002311
2312 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002313 {
2314 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2315 {
2316 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2317 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2318 }
2319 else
2320 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2321 }
hassoe0701b72004-05-20 09:19:34 +00002322
paul718e3742002-12-13 20:15:29 +00002323 BGP_EVENT_ADD (peer, TCP_connection_closed);
2324 return -1;
2325 }
2326
2327 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002328 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002329 return -1;
2330
2331 return 0;
2332}
2333
2334/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002335static int
paul718e3742002-12-13 20:15:29 +00002336bgp_marker_all_one (struct stream *s, int length)
2337{
2338 int i;
2339
2340 for (i = 0; i < length; i++)
2341 if (s->data[i] != 0xff)
2342 return 0;
2343
2344 return 1;
2345}
2346
2347/* Starting point of packet process function. */
2348int
2349bgp_read (struct thread *thread)
2350{
2351 int ret;
2352 u_char type = 0;
2353 struct peer *peer;
2354 bgp_size_t size;
2355 char notify_data_length[2];
2356
2357 /* Yes first of all get peer pointer. */
2358 peer = THREAD_ARG (thread);
2359 peer->t_read = NULL;
2360
2361 /* For non-blocking IO check. */
2362 if (peer->status == Connect)
2363 {
2364 bgp_connect_check (peer);
2365 goto done;
2366 }
2367 else
2368 {
pauleb821182004-05-01 08:44:08 +00002369 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002370 {
pauleb821182004-05-01 08:44:08 +00002371 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002372 return -1;
2373 }
pauleb821182004-05-01 08:44:08 +00002374 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002375 }
2376
2377 /* Read packet header to determine type of the packet */
2378 if (peer->packet_size == 0)
2379 peer->packet_size = BGP_HEADER_SIZE;
2380
paul9985f832005-02-09 15:51:56 +00002381 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002382 {
2383 ret = bgp_read_packet (peer);
2384
2385 /* Header read error or partial read packet. */
2386 if (ret < 0)
2387 goto done;
2388
2389 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002390 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002391 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2392 size = stream_getw (peer->ibuf);
2393 type = stream_getc (peer->ibuf);
2394
2395 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002396 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002397 peer->host, type, size - BGP_HEADER_SIZE);
2398
2399 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002400 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002401 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2402 {
2403 bgp_notify_send (peer,
2404 BGP_NOTIFY_HEADER_ERR,
2405 BGP_NOTIFY_HEADER_NOT_SYNC);
2406 goto done;
2407 }
2408
2409 /* BGP type check. */
2410 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2411 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2412 && type != BGP_MSG_ROUTE_REFRESH_NEW
2413 && type != BGP_MSG_ROUTE_REFRESH_OLD
2414 && type != BGP_MSG_CAPABILITY)
2415 {
2416 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002417 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002418 "%s unknown message type 0x%02x",
2419 peer->host, type);
2420 bgp_notify_send_with_data (peer,
2421 BGP_NOTIFY_HEADER_ERR,
2422 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2423 &type, 1);
2424 goto done;
2425 }
2426 /* Mimimum packet length check. */
2427 if ((size < BGP_HEADER_SIZE)
2428 || (size > BGP_MAX_PACKET_SIZE)
2429 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2430 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2431 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2432 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2433 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2434 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2435 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2436 {
2437 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002438 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002439 "%s bad message length - %d for %s",
2440 peer->host, size,
2441 type == 128 ? "ROUTE-REFRESH" :
2442 bgp_type_str[(int) type]);
2443 bgp_notify_send_with_data (peer,
2444 BGP_NOTIFY_HEADER_ERR,
2445 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002446 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002447 goto done;
2448 }
2449
2450 /* Adjust size to message length. */
2451 peer->packet_size = size;
2452 }
2453
2454 ret = bgp_read_packet (peer);
2455 if (ret < 0)
2456 goto done;
2457
2458 /* Get size and type again. */
2459 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2460 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2461
2462 /* BGP packet dump function. */
2463 bgp_dump_packet (peer, type, peer->ibuf);
2464
2465 size = (peer->packet_size - BGP_HEADER_SIZE);
2466
2467 /* Read rest of the packet and call each sort of packet routine */
2468 switch (type)
2469 {
2470 case BGP_MSG_OPEN:
2471 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002472 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002473 break;
2474 case BGP_MSG_UPDATE:
2475 peer->readtime = time(NULL); /* Last read timer reset */
2476 bgp_update_receive (peer, size);
2477 break;
2478 case BGP_MSG_NOTIFY:
2479 bgp_notify_receive (peer, size);
2480 break;
2481 case BGP_MSG_KEEPALIVE:
2482 peer->readtime = time(NULL); /* Last read timer reset */
2483 bgp_keepalive_receive (peer, size);
2484 break;
2485 case BGP_MSG_ROUTE_REFRESH_NEW:
2486 case BGP_MSG_ROUTE_REFRESH_OLD:
2487 peer->refresh_in++;
2488 bgp_route_refresh_receive (peer, size);
2489 break;
2490 case BGP_MSG_CAPABILITY:
2491 peer->dynamic_cap_in++;
2492 bgp_capability_receive (peer, size);
2493 break;
2494 }
2495
2496 /* Clear input buffer. */
2497 peer->packet_size = 0;
2498 if (peer->ibuf)
2499 stream_reset (peer->ibuf);
2500
2501 done:
2502 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2503 {
2504 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002505 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002506 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002507 }
2508 return 0;
2509}