blob: 5620e0c4f58c8c6c8ffaf9cd3f9b5307897e6918 [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
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
613 /* Nonblocking write until TCP output buffer is full. */
614 while (1)
615 {
616 int writenum;
paula24a7e12005-01-05 08:14:13 +0000617 int val;
paul718e3742002-12-13 20:15:29 +0000618
619 s = bgp_write_packet (peer);
620 if (! s)
621 return 0;
622
623 /* Number of bytes to be sent. */
624 writenum = stream_get_endp (s) - stream_get_getp (s);
625
626 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000627 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700628 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000629 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700630 /* need to try again */
631 if (!ERRNO_IO_RETRY(errno))
632 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000633 return 0;
634 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700635
paul718e3742002-12-13 20:15:29 +0000636 if (num != writenum)
637 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700638 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000639 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000640 continue;
641 }
642
643 /* Retrieve BGP packet type. */
644 stream_set_getp (s, BGP_MARKER_SIZE + 2);
645 type = stream_getc (s);
646
647 switch (type)
648 {
649 case BGP_MSG_OPEN:
650 peer->open_out++;
651 break;
652 case BGP_MSG_UPDATE:
653 peer->update_out++;
654 break;
655 case BGP_MSG_NOTIFY:
656 peer->notify_out++;
657 /* Double start timer. */
658 peer->v_start *= 2;
659
660 /* Overflow check. */
661 if (peer->v_start >= (60 * 2))
662 peer->v_start = (60 * 2);
663
Paul Jakmaca058a32006-09-14 02:58:49 +0000664 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000665 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000666 return 0;
paul718e3742002-12-13 20:15:29 +0000667 case BGP_MSG_KEEPALIVE:
668 peer->keepalive_out++;
669 break;
670 case BGP_MSG_ROUTE_REFRESH_NEW:
671 case BGP_MSG_ROUTE_REFRESH_OLD:
672 peer->refresh_out++;
673 break;
674 case BGP_MSG_CAPABILITY:
675 peer->dynamic_cap_out++;
676 break;
677 }
678
679 /* OK we send packet so delete it. */
680 bgp_packet_delete (peer);
681
682 if (++count >= BGP_WRITE_PACKET_MAX)
683 break;
684 }
685
686 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000687 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000688
689 return 0;
690}
691
692/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000693static int
paul718e3742002-12-13 20:15:29 +0000694bgp_write_notify (struct peer *peer)
695{
Stephen Hemminger35398582010-08-05 10:26:23 -0700696 int ret, val;
paul718e3742002-12-13 20:15:29 +0000697 u_char type;
698 struct stream *s;
699
700 /* There should be at least one packet. */
701 s = stream_fifo_head (peer->obuf);
702 if (!s)
703 return 0;
704 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
705
Stephen Hemminger35398582010-08-05 10:26:23 -0700706 /* Put socket in blocking mode. */
707 val = fcntl (peer->fd, F_GETFL, 0);
708 fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);
709
pauleb821182004-05-01 08:44:08 +0000710 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000711 if (ret <= 0)
712 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000713 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000714 return 0;
715 }
716
717 /* Retrieve BGP packet type. */
718 stream_set_getp (s, BGP_MARKER_SIZE + 2);
719 type = stream_getc (s);
720
721 assert (type == BGP_MSG_NOTIFY);
722
723 /* Type should be notify. */
724 peer->notify_out++;
725
726 /* Double start timer. */
727 peer->v_start *= 2;
728
729 /* Overflow check. */
730 if (peer->v_start >= (60 * 2))
731 peer->v_start = (60 * 2);
732
Paul Jakmadcdf3992006-10-15 23:39:59 +0000733 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000734
735 return 0;
736}
737
738/* Make keepalive packet and send it to the peer. */
739void
740bgp_keepalive_send (struct peer *peer)
741{
742 struct stream *s;
743 int length;
744
745 s = stream_new (BGP_MAX_PACKET_SIZE);
746
747 /* Make keepalive packet. */
748 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
749
750 /* Set packet size. */
751 length = bgp_packet_set_size (s);
752
753 /* Dump packet if debug option is set. */
754 /* bgp_packet_dump (s); */
755
756 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000757 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000758 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000759 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000760 peer->host, BGP_MSG_KEEPALIVE, length);
761
762 /* Add packet to the peer. */
763 bgp_packet_add (peer, s);
764
pauleb821182004-05-01 08:44:08 +0000765 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000766}
767
768/* Make open packet and send it to the peer. */
769void
770bgp_open_send (struct peer *peer)
771{
772 struct stream *s;
773 int length;
774 u_int16_t send_holdtime;
775 as_t local_as;
776
777 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
778 send_holdtime = peer->holdtime;
779 else
780 send_holdtime = peer->bgp->default_holdtime;
781
782 /* local-as Change */
783 if (peer->change_local_as)
784 local_as = peer->change_local_as;
785 else
786 local_as = peer->local_as;
787
788 s = stream_new (BGP_MAX_PACKET_SIZE);
789
790 /* Make open packet. */
791 bgp_packet_set_marker (s, BGP_MSG_OPEN);
792
793 /* Set open packet values. */
794 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000795 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
796 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000797 stream_putw (s, send_holdtime); /* Hold Time */
798 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
799
800 /* Set capability code. */
801 bgp_open_capability (s, peer);
802
803 /* Set BGP packet length. */
804 length = bgp_packet_set_size (s);
805
806 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400807 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000808 peer->host, BGP_VERSION_4, local_as,
809 send_holdtime, inet_ntoa (peer->local_id));
810
811 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000812 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000813 peer->host, BGP_MSG_OPEN, length);
814
815 /* Dump packet if debug option is set. */
816 /* bgp_packet_dump (s); */
817
818 /* Add packet to the peer. */
819 bgp_packet_add (peer, s);
820
pauleb821182004-05-01 08:44:08 +0000821 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000822}
823
824/* Send BGP notify packet with data potion. */
825void
826bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
827 u_char *data, size_t datalen)
828{
829 struct stream *s;
830 int length;
831
832 /* Allocate new stream. */
833 s = stream_new (BGP_MAX_PACKET_SIZE);
834
835 /* Make nitify packet. */
836 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
837
838 /* Set notify packet values. */
839 stream_putc (s, code); /* BGP notify code */
840 stream_putc (s, sub_code); /* BGP notify sub_code */
841
842 /* If notify data is present. */
843 if (data)
844 stream_write (s, data, datalen);
845
846 /* Set BGP packet length. */
847 length = bgp_packet_set_size (s);
848
849 /* Add packet to the peer. */
850 stream_fifo_clean (peer->obuf);
851 bgp_packet_add (peer, s);
852
853 /* For debug */
854 {
855 struct bgp_notify bgp_notify;
856 int first = 0;
857 int i;
858 char c[4];
859
860 bgp_notify.code = code;
861 bgp_notify.subcode = sub_code;
862 bgp_notify.data = NULL;
863 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
864
865 if (bgp_notify.length)
866 {
867 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
868 for (i = 0; i < bgp_notify.length; i++)
869 if (first)
870 {
871 sprintf (c, " %02x", data[i]);
872 strcat (bgp_notify.data, c);
873 }
874 else
875 {
876 first = 1;
877 sprintf (c, "%02x", data[i]);
878 strcpy (bgp_notify.data, c);
879 }
880 }
881 bgp_notify_print (peer, &bgp_notify, "sending");
882 if (bgp_notify.data)
883 XFREE (MTYPE_TMP, bgp_notify.data);
884 }
885
886 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000887 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000888 peer->host, BGP_MSG_NOTIFY, length);
889
hassoe0701b72004-05-20 09:19:34 +0000890 /* peer reset cause */
891 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
892 {
893 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
894 peer->last_reset = PEER_DOWN_USER_RESET;
895 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
896 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
897 else
898 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
899 }
900
paul718e3742002-12-13 20:15:29 +0000901 /* Call imidiately. */
902 BGP_WRITE_OFF (peer->t_write);
903
904 bgp_write_notify (peer);
905}
906
907/* Send BGP notify packet. */
908void
909bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
910{
911 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
912}
913
paul718e3742002-12-13 20:15:29 +0000914/* Send route refresh message to the peer. */
915void
916bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
917 u_char orf_type, u_char when_to_refresh, int remove)
918{
919 struct stream *s;
920 struct stream *packet;
921 int length;
922 struct bgp_filter *filter;
923 int orf_refresh = 0;
924
Paul Jakma750e8142008-07-22 21:11:48 +0000925 if (DISABLE_BGP_ANNOUNCE)
926 return;
paul718e3742002-12-13 20:15:29 +0000927
928 filter = &peer->filter[afi][safi];
929
930 /* Adjust safi code. */
931 if (safi == SAFI_MPLS_VPN)
932 safi = BGP_SAFI_VPNV4;
933
934 s = stream_new (BGP_MAX_PACKET_SIZE);
935
936 /* Make BGP update packet. */
937 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
938 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
939 else
940 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
941
942 /* Encode Route Refresh message. */
943 stream_putw (s, afi);
944 stream_putc (s, 0);
945 stream_putc (s, safi);
946
947 if (orf_type == ORF_TYPE_PREFIX
948 || orf_type == ORF_TYPE_PREFIX_OLD)
949 if (remove || filter->plist[FILTER_IN].plist)
950 {
951 u_int16_t orf_len;
952 unsigned long orfp;
953
954 orf_refresh = 1;
955 stream_putc (s, when_to_refresh);
956 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000957 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000958 stream_putw (s, 0);
959
960 if (remove)
961 {
962 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
963 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
964 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000965 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000966 peer->host, orf_type,
967 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
968 afi, safi);
969 }
970 else
971 {
972 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
973 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
974 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
975 ORF_COMMON_PART_DENY);
976 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000977 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000978 peer->host, orf_type,
979 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
980 afi, safi);
981 }
982
983 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +0000984 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +0000985 stream_putw_at (s, orfp, orf_len);
986 }
987
988 /* Set packet size. */
989 length = bgp_packet_set_size (s);
990
991 if (BGP_DEBUG (normal, NORMAL))
992 {
993 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +0000994 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000995 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +0000996 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000997 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
998 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
999 }
1000
1001 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001002 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001003 stream_free (s);
1004
1005 /* Add packet to the peer. */
1006 bgp_packet_add (peer, packet);
1007
pauleb821182004-05-01 08:44:08 +00001008 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001009}
1010
1011/* Send capability message to the peer. */
1012void
1013bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1014 int capability_code, int action)
1015{
1016 struct stream *s;
1017 struct stream *packet;
1018 int length;
1019
1020 /* Adjust safi code. */
1021 if (safi == SAFI_MPLS_VPN)
1022 safi = BGP_SAFI_VPNV4;
1023
1024 s = stream_new (BGP_MAX_PACKET_SIZE);
1025
1026 /* Make BGP update packet. */
1027 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1028
1029 /* Encode MP_EXT capability. */
1030 if (capability_code == CAPABILITY_CODE_MP)
1031 {
1032 stream_putc (s, action);
1033 stream_putc (s, CAPABILITY_CODE_MP);
1034 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1035 stream_putw (s, afi);
1036 stream_putc (s, 0);
1037 stream_putc (s, safi);
1038
1039 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001040 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001041 peer->host, action == CAPABILITY_ACTION_SET ?
1042 "Advertising" : "Removing", afi, safi);
1043 }
1044
paul718e3742002-12-13 20:15:29 +00001045 /* Set packet size. */
1046 length = bgp_packet_set_size (s);
1047
1048 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001049 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001050 stream_free (s);
1051
1052 /* Add packet to the peer. */
1053 bgp_packet_add (peer, packet);
1054
1055 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001056 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001057 peer->host, BGP_MSG_CAPABILITY, length);
1058
pauleb821182004-05-01 08:44:08 +00001059 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001060}
1061
1062/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001063static int
pauleb821182004-05-01 08:44:08 +00001064bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001065{
pauleb821182004-05-01 08:44:08 +00001066 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001067 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001068 struct bgp *bgp;
1069
1070 bgp = bgp_get_default ();
1071 if (! bgp)
1072 return 0;
1073
1074 /* Upon receipt of an OPEN message, the local system must examine
1075 all of its connections that are in the OpenConfirm state. A BGP
1076 speaker may also examine connections in an OpenSent state if it
1077 knows the BGP Identifier of the peer by means outside of the
1078 protocol. If among these connections there is a connection to a
1079 remote BGP speaker whose BGP Identifier equals the one in the
1080 OPEN message, then the local system performs the following
1081 collision resolution procedure: */
1082
paul1eb8ef22005-04-07 07:30:20 +00001083 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001084 {
1085 /* Under OpenConfirm status, local peer structure already hold
1086 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001087
1088 if (peer != new
1089 && (peer->status == OpenConfirm || peer->status == OpenSent)
1090 && sockunion_same (&peer->su, &new->su))
1091 {
paul718e3742002-12-13 20:15:29 +00001092 /* 1. The BGP Identifier of the local system is compared to
1093 the BGP Identifier of the remote system (as specified in
1094 the OPEN message). */
1095
1096 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1097 {
1098 /* 2. If the value of the local BGP Identifier is less
1099 than the remote one, the local system closes BGP
1100 connection that already exists (the one that is
1101 already in the OpenConfirm state), and accepts BGP
1102 connection initiated by the remote system. */
1103
pauleb821182004-05-01 08:44:08 +00001104 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001105 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001106 return 1;
1107 }
1108 else
1109 {
1110 /* 3. Otherwise, the local system closes newly created
1111 BGP connection (the one associated with the newly
1112 received OPEN message), and continues to use the
1113 existing one (the one that is already in the
1114 OpenConfirm state). */
1115
pauleb821182004-05-01 08:44:08 +00001116 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001117 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1118 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001119 return -1;
1120 }
pauleb821182004-05-01 08:44:08 +00001121 }
1122 }
paul718e3742002-12-13 20:15:29 +00001123 return 0;
1124}
1125
paul94f2b392005-06-28 12:44:16 +00001126static int
paul718e3742002-12-13 20:15:29 +00001127bgp_open_receive (struct peer *peer, bgp_size_t size)
1128{
1129 int ret;
1130 u_char version;
1131 u_char optlen;
1132 u_int16_t holdtime;
1133 u_int16_t send_holdtime;
1134 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001135 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001136 struct peer *realpeer;
1137 struct in_addr remote_id;
1138 int capability;
paul5228ad22004-06-04 17:58:18 +00001139 u_int8_t notify_data_remote_as[2];
1140 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001141
1142 realpeer = NULL;
1143
1144 /* Parse open packet. */
1145 version = stream_getc (peer->ibuf);
1146 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1147 remote_as = stream_getw (peer->ibuf);
1148 holdtime = stream_getw (peer->ibuf);
1149 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1150 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1151
1152 /* Receive OPEN message log */
1153 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001154 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001155 " holdtime %d, id %s",
1156 peer->host, version, remote_as, holdtime,
1157 inet_ntoa (remote_id));
1158
1159 /* BEGIN to read the capability here, but dont do it yet */
1160 capability = 0;
1161 optlen = stream_getc (peer->ibuf);
1162
1163 if (optlen != 0)
1164 {
1165 /* We need the as4 capability value *right now* because
1166 * if it is there, we have not got the remote_as yet, and without
1167 * that we do not know which peer is connecting to us now.
1168 */
1169 as4 = peek_for_as4_capability (peer, optlen);
1170 }
1171
1172 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1173 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1174 {
1175 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1176 peer->host);
1177 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1178 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1179 return -1;
1180 }
1181
1182 if (remote_as == BGP_AS_TRANS)
1183 {
1184 /* Take the AS4 from the capability. We must have received the
1185 * capability now! Otherwise we have a asn16 peer who uses
1186 * BGP_AS_TRANS, for some unknown reason.
1187 */
1188 if (as4 == BGP_AS_TRANS)
1189 {
1190 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1191 peer->host);
1192 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1193 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1194 return -1;
1195 }
1196
1197 if (!as4 && BGP_DEBUG (as4, AS4))
1198 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1199 " Odd, but proceeding.", peer->host);
1200 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001201 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001202 "in 2-bytes, very odd peer.", peer->host, as4);
1203 if (as4)
1204 remote_as = as4;
1205 }
1206 else
1207 {
1208 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1209 /* If we have got the capability, peer->as4cap must match remote_as */
1210 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1211 && as4 != remote_as)
1212 {
1213 /* raise error, log this, close session */
1214 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1215 " mismatch with 16bit 'myasn' %u in open",
1216 peer->host, as4, remote_as);
1217 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1218 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1219 return -1;
1220 }
1221 }
1222
paul718e3742002-12-13 20:15:29 +00001223 /* Lookup peer from Open packet. */
1224 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1225 {
1226 int as = 0;
1227
1228 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1229
1230 if (! realpeer)
1231 {
1232 /* Peer's source IP address is check in bgp_accept(), so this
1233 must be AS number mismatch or remote-id configuration
1234 mismatch. */
1235 if (as)
1236 {
1237 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001238 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1239 peer->host, inet_ntoa (remote_id));
1240 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1241 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1242 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001243 }
1244 else
1245 {
1246 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001247 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001248 peer->host, remote_as, peer->as);
1249 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1250 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1251 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001252 }
1253 return -1;
1254 }
1255 }
1256
1257 /* When collision is detected and this peer is closed. Retrun
1258 immidiately. */
1259 ret = bgp_collision_detect (peer, remote_id);
1260 if (ret < 0)
1261 return ret;
1262
pauleb821182004-05-01 08:44:08 +00001263 /* Hack part. */
1264 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1265 {
hasso93406d82005-02-02 14:40:33 +00001266 if (realpeer->status == Established
1267 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1268 {
1269 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1270 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1271 }
1272 else if (ret == 0 && realpeer->status != Active
1273 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001274 && realpeer->status != OpenConfirm
1275 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001276 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001277 /* XXX: This is an awful problem..
1278 *
1279 * According to the RFC we should just let this connection (of the
1280 * accepted 'peer') continue on to Established if the other
1281 * connection (the 'realpeer' one) is in state Connect, and deal
1282 * with the more larval FSM as/when it gets far enough to receive
1283 * an Open. We don't do that though, we instead close the (more
1284 * developed) accepted connection.
1285 *
1286 * This means there's a race, which if hit, can loop:
1287 *
1288 * FSM for A FSM for B
1289 * realpeer accept-peer realpeer accept-peer
1290 *
1291 * Connect Connect
1292 * Active
1293 * OpenSent OpenSent
1294 * <arrive here,
1295 * Notify, delete>
1296 * Idle Active
1297 * OpenSent OpenSent
1298 * <arrive here,
1299 * Notify, delete>
1300 * Idle
1301 * <wait> <wait>
1302 * Connect Connect
1303 *
1304 *
1305 * If both sides are Quagga, they're almost certain to wait for
1306 * the same amount of time of course (which doesn't preclude other
1307 * implementations also waiting for same time). The race is
1308 * exacerbated by high-latency (in bgpd and/or the network).
1309 *
1310 * The reason we do this is because our FSM is tied to our peer
1311 * structure, which carries our configuration information, etc.
1312 * I.e. we can't let the accepted-peer FSM continue on as it is,
1313 * cause it's not associated with any actual peer configuration -
1314 * it's just a dummy.
1315 *
1316 * It's possible we could hack-fix this by just bgp_stop'ing the
1317 * realpeer and continueing on with the 'transfer FSM' below.
1318 * Ideally, we need to seperate FSMs from struct peer.
1319 *
1320 * Setting one side to passive avoids the race, as a workaround.
1321 */
pauleb821182004-05-01 08:44:08 +00001322 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001323 zlog_debug ("%s peer status is %s close connection",
1324 realpeer->host, LOOKUP (bgp_status_msg,
1325 realpeer->status));
1326 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1327 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1328
pauleb821182004-05-01 08:44:08 +00001329 return -1;
1330 }
1331
1332 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001333 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1334 peer->host,
1335 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001336
1337 bgp_stop (realpeer);
1338
1339 /* Transfer file descriptor. */
1340 realpeer->fd = peer->fd;
1341 peer->fd = -1;
1342
1343 /* Transfer input buffer. */
1344 stream_free (realpeer->ibuf);
1345 realpeer->ibuf = peer->ibuf;
1346 realpeer->packet_size = peer->packet_size;
1347 peer->ibuf = NULL;
1348
1349 /* Transfer status. */
1350 realpeer->status = peer->status;
1351 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001352
pauleb821182004-05-01 08:44:08 +00001353 /* peer pointer change. Open packet send to neighbor. */
1354 peer = realpeer;
1355 bgp_open_send (peer);
1356 if (peer->fd < 0)
1357 {
1358 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1359 peer->fd);
1360 return -1;
1361 }
1362 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1363 }
1364
paul718e3742002-12-13 20:15:29 +00001365 /* remote router-id check. */
1366 if (remote_id.s_addr == 0
1367 || ntohl (remote_id.s_addr) >= 0xe0000000
1368 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1369 {
1370 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001371 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001372 peer->host, inet_ntoa (remote_id));
1373 bgp_notify_send_with_data (peer,
1374 BGP_NOTIFY_OPEN_ERR,
1375 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1376 notify_data_remote_id, 4);
1377 return -1;
1378 }
1379
1380 /* Set remote router-id */
1381 peer->remote_id = remote_id;
1382
1383 /* Peer BGP version check. */
1384 if (version != BGP_VERSION_4)
1385 {
paul5228ad22004-06-04 17:58:18 +00001386 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001387 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001388 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001389 peer->host, version, BGP_VERSION_4);
1390 bgp_notify_send_with_data (peer,
1391 BGP_NOTIFY_OPEN_ERR,
1392 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001393 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001394 return -1;
1395 }
1396
1397 /* Check neighbor as number. */
1398 if (remote_as != peer->as)
1399 {
1400 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001401 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001402 peer->host, remote_as, peer->as);
1403 bgp_notify_send_with_data (peer,
1404 BGP_NOTIFY_OPEN_ERR,
1405 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1406 notify_data_remote_as, 2);
1407 return -1;
1408 }
1409
1410 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1411 calculate the value of the Hold Timer by using the smaller of its
1412 configured Hold Time and the Hold Time received in the OPEN message.
1413 The Hold Time MUST be either zero or at least three seconds. An
1414 implementation may reject connections on the basis of the Hold Time. */
1415
1416 if (holdtime < 3 && holdtime != 0)
1417 {
1418 bgp_notify_send (peer,
1419 BGP_NOTIFY_OPEN_ERR,
1420 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1421 return -1;
1422 }
1423
1424 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1425 would be one third of the Hold Time interval. KEEPALIVE messages
1426 MUST NOT be sent more frequently than one per second. An
1427 implementation MAY adjust the rate at which it sends KEEPALIVE
1428 messages as a function of the Hold Time interval. */
1429
1430 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1431 send_holdtime = peer->holdtime;
1432 else
1433 send_holdtime = peer->bgp->default_holdtime;
1434
1435 if (holdtime < send_holdtime)
1436 peer->v_holdtime = holdtime;
1437 else
1438 peer->v_holdtime = send_holdtime;
1439
1440 peer->v_keepalive = peer->v_holdtime / 3;
1441
1442 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001443 if (optlen != 0)
1444 {
1445 ret = bgp_open_option_parse (peer, optlen, &capability);
1446 if (ret < 0)
1447 return ret;
paul718e3742002-12-13 20:15:29 +00001448 }
1449 else
1450 {
1451 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001452 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001453 peer->host);
1454 }
1455
1456 /* Override capability. */
1457 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1458 {
1459 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1460 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1461 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1462 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1463 }
1464
1465 /* Get sockname. */
1466 bgp_getsockname (peer);
1467
1468 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1469
1470 peer->packet_size = 0;
1471 if (peer->ibuf)
1472 stream_reset (peer->ibuf);
1473
1474 return 0;
1475}
1476
1477/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001478static int
paul718e3742002-12-13 20:15:29 +00001479bgp_update_receive (struct peer *peer, bgp_size_t size)
1480{
1481 int ret;
1482 u_char *end;
1483 struct stream *s;
1484 struct attr attr;
1485 bgp_size_t attribute_len;
1486 bgp_size_t update_len;
1487 bgp_size_t withdraw_len;
1488 struct bgp_nlri update;
1489 struct bgp_nlri withdraw;
1490 struct bgp_nlri mp_update;
1491 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001492 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001493
1494 /* Status must be Established. */
1495 if (peer->status != Established)
1496 {
1497 zlog_err ("%s [FSM] Update packet received under status %s",
1498 peer->host, LOOKUP (bgp_status_msg, peer->status));
1499 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1500 return -1;
1501 }
1502
1503 /* Set initial values. */
1504 memset (&attr, 0, sizeof (struct attr));
1505 memset (&update, 0, sizeof (struct bgp_nlri));
1506 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1507 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1508 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1509
1510 s = peer->ibuf;
1511 end = stream_pnt (s) + size;
1512
1513 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1514 Length is too large (i.e., if Unfeasible Routes Length + Total
1515 Attribute Length + 23 exceeds the message Length), then the Error
1516 Subcode is set to Malformed Attribute List. */
1517 if (stream_pnt (s) + 2 > end)
1518 {
1519 zlog_err ("%s [Error] Update packet error"
1520 " (packet length is short for unfeasible length)",
1521 peer->host);
1522 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1523 BGP_NOTIFY_UPDATE_MAL_ATTR);
1524 return -1;
1525 }
1526
1527 /* Unfeasible Route Length. */
1528 withdraw_len = stream_getw (s);
1529
1530 /* Unfeasible Route Length check. */
1531 if (stream_pnt (s) + withdraw_len > end)
1532 {
1533 zlog_err ("%s [Error] Update packet error"
1534 " (packet unfeasible length overflow %d)",
1535 peer->host, withdraw_len);
1536 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1537 BGP_NOTIFY_UPDATE_MAL_ATTR);
1538 return -1;
1539 }
1540
1541 /* Unfeasible Route packet format check. */
1542 if (withdraw_len > 0)
1543 {
1544 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1545 if (ret < 0)
1546 return -1;
1547
1548 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001549 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001550
1551 withdraw.afi = AFI_IP;
1552 withdraw.safi = SAFI_UNICAST;
1553 withdraw.nlri = stream_pnt (s);
1554 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001555 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001556 }
1557
1558 /* Attribute total length check. */
1559 if (stream_pnt (s) + 2 > end)
1560 {
1561 zlog_warn ("%s [Error] Packet Error"
1562 " (update packet is short for attribute length)",
1563 peer->host);
1564 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1565 BGP_NOTIFY_UPDATE_MAL_ATTR);
1566 return -1;
1567 }
1568
1569 /* Fetch attribute total length. */
1570 attribute_len = stream_getw (s);
1571
1572 /* Attribute length check. */
1573 if (stream_pnt (s) + attribute_len > end)
1574 {
1575 zlog_warn ("%s [Error] Packet Error"
1576 " (update packet attribute length overflow %d)",
1577 peer->host, attribute_len);
1578 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1579 BGP_NOTIFY_UPDATE_MAL_ATTR);
1580 return -1;
1581 }
1582
1583 /* Parse attribute when it exists. */
1584 if (attribute_len)
1585 {
1586 ret = bgp_attr_parse (peer, &attr, attribute_len,
1587 &mp_update, &mp_withdraw);
1588 if (ret < 0)
1589 return -1;
1590 }
1591
1592 /* Logging the attribute. */
1593 if (BGP_DEBUG (update, UPDATE_IN))
1594 {
paule01f9cb2004-07-09 17:48:53 +00001595 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1596
1597 if (ret)
ajs6b514742004-12-08 21:03:23 +00001598 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001599 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001600 }
1601
1602 /* Network Layer Reachability Information. */
1603 update_len = end - stream_pnt (s);
1604
1605 if (update_len)
1606 {
1607 /* Check NLRI packet format and prefix length. */
1608 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1609 if (ret < 0)
1610 return -1;
1611
1612 /* Set NLRI portion to structure. */
1613 update.afi = AFI_IP;
1614 update.safi = SAFI_UNICAST;
1615 update.nlri = stream_pnt (s);
1616 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001617 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001618 }
1619
1620 /* NLRI is processed only when the peer is configured specific
1621 Address Family and Subsequent Address Family. */
1622 if (peer->afc[AFI_IP][SAFI_UNICAST])
1623 {
1624 if (withdraw.length)
1625 bgp_nlri_parse (peer, NULL, &withdraw);
1626
1627 if (update.length)
1628 {
1629 /* We check well-known attribute only for IPv4 unicast
1630 update. */
1631 ret = bgp_attr_check (peer, &attr);
1632 if (ret < 0)
1633 return -1;
1634
1635 bgp_nlri_parse (peer, &attr, &update);
1636 }
paule01f9cb2004-07-09 17:48:53 +00001637
hassof4184462005-02-01 20:13:16 +00001638 if (mp_update.length
1639 && mp_update.afi == AFI_IP
1640 && mp_update.safi == SAFI_UNICAST)
1641 bgp_nlri_parse (peer, &attr, &mp_update);
1642
1643 if (mp_withdraw.length
1644 && mp_withdraw.afi == AFI_IP
1645 && mp_withdraw.safi == SAFI_UNICAST)
1646 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1647
paule01f9cb2004-07-09 17:48:53 +00001648 if (! attribute_len && ! withdraw_len)
1649 {
1650 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001651 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1652 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001653
hasso93406d82005-02-02 14:40:33 +00001654 /* NSF delete stale route */
1655 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1656 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1657
1658 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001659 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001660 peer->host);
1661 }
paul718e3742002-12-13 20:15:29 +00001662 }
1663 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1664 {
1665 if (mp_update.length
1666 && mp_update.afi == AFI_IP
1667 && mp_update.safi == SAFI_MULTICAST)
1668 bgp_nlri_parse (peer, &attr, &mp_update);
1669
1670 if (mp_withdraw.length
1671 && mp_withdraw.afi == AFI_IP
1672 && mp_withdraw.safi == SAFI_MULTICAST)
1673 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001674
hasso93406d82005-02-02 14:40:33 +00001675 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001676 && mp_withdraw.afi == AFI_IP
1677 && mp_withdraw.safi == SAFI_MULTICAST
1678 && mp_withdraw.length == 0)
1679 {
1680 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001681 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1682 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001683
hasso93406d82005-02-02 14:40:33 +00001684 /* NSF delete stale route */
1685 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1686 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1687
1688 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001689 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001690 peer->host);
1691 }
paul718e3742002-12-13 20:15:29 +00001692 }
1693 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1694 {
1695 if (mp_update.length
1696 && mp_update.afi == AFI_IP6
1697 && mp_update.safi == SAFI_UNICAST)
1698 bgp_nlri_parse (peer, &attr, &mp_update);
1699
1700 if (mp_withdraw.length
1701 && mp_withdraw.afi == AFI_IP6
1702 && mp_withdraw.safi == SAFI_UNICAST)
1703 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001704
hasso93406d82005-02-02 14:40:33 +00001705 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001706 && mp_withdraw.afi == AFI_IP6
1707 && mp_withdraw.safi == SAFI_UNICAST
1708 && mp_withdraw.length == 0)
1709 {
1710 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001711 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001712
hasso93406d82005-02-02 14:40:33 +00001713 /* NSF delete stale route */
1714 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1715 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1716
1717 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001718 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001719 peer->host);
1720 }
paul718e3742002-12-13 20:15:29 +00001721 }
1722 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1723 {
1724 if (mp_update.length
1725 && mp_update.afi == AFI_IP6
1726 && mp_update.safi == SAFI_MULTICAST)
1727 bgp_nlri_parse (peer, &attr, &mp_update);
1728
1729 if (mp_withdraw.length
1730 && mp_withdraw.afi == AFI_IP6
1731 && mp_withdraw.safi == SAFI_MULTICAST)
1732 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001733
hasso93406d82005-02-02 14:40:33 +00001734 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001735 && mp_withdraw.afi == AFI_IP6
1736 && mp_withdraw.safi == SAFI_MULTICAST
1737 && mp_withdraw.length == 0)
1738 {
1739 /* End-of-RIB received */
1740
hasso93406d82005-02-02 14:40:33 +00001741 /* NSF delete stale route */
1742 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1743 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1744
paule01f9cb2004-07-09 17:48:53 +00001745 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001746 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001747 peer->host);
1748 }
paul718e3742002-12-13 20:15:29 +00001749 }
1750 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1751 {
1752 if (mp_update.length
1753 && mp_update.afi == AFI_IP
1754 && mp_update.safi == BGP_SAFI_VPNV4)
1755 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1756
1757 if (mp_withdraw.length
1758 && mp_withdraw.afi == AFI_IP
1759 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1760 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001761
hasso93406d82005-02-02 14:40:33 +00001762 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001763 && mp_withdraw.afi == AFI_IP
1764 && mp_withdraw.safi == BGP_SAFI_VPNV4
1765 && mp_withdraw.length == 0)
1766 {
1767 /* End-of-RIB received */
1768
1769 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001770 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001771 peer->host);
1772 }
paul718e3742002-12-13 20:15:29 +00001773 }
1774
1775 /* Everything is done. We unintern temporary structures which
1776 interned in bgp_attr_parse(). */
1777 if (attr.aspath)
1778 aspath_unintern (attr.aspath);
1779 if (attr.community)
1780 community_unintern (attr.community);
Paul Jakmafb982c22007-05-04 20:15:47 +00001781 if (attr.extra)
1782 {
1783 if (attr.extra->ecommunity)
1784 ecommunity_unintern (attr.extra->ecommunity);
1785 if (attr.extra->cluster)
1786 cluster_unintern (attr.extra->cluster);
1787 if (attr.extra->transit)
1788 transit_unintern (attr.extra->transit);
1789 bgp_attr_extra_free (&attr);
1790 }
paul718e3742002-12-13 20:15:29 +00001791
1792 /* If peering is stopped due to some reason, do not generate BGP
1793 event. */
1794 if (peer->status != Established)
1795 return 0;
1796
1797 /* Increment packet counter. */
1798 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001799 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001800
1801 /* Generate BGP event. */
1802 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1803
1804 return 0;
1805}
1806
1807/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001808static void
paul718e3742002-12-13 20:15:29 +00001809bgp_notify_receive (struct peer *peer, bgp_size_t size)
1810{
1811 struct bgp_notify bgp_notify;
1812
1813 if (peer->notify.data)
1814 {
1815 XFREE (MTYPE_TMP, peer->notify.data);
1816 peer->notify.data = NULL;
1817 peer->notify.length = 0;
1818 }
1819
1820 bgp_notify.code = stream_getc (peer->ibuf);
1821 bgp_notify.subcode = stream_getc (peer->ibuf);
1822 bgp_notify.length = size - 2;
1823 bgp_notify.data = NULL;
1824
1825 /* Preserv notify code and sub code. */
1826 peer->notify.code = bgp_notify.code;
1827 peer->notify.subcode = bgp_notify.subcode;
1828 /* For further diagnostic record returned Data. */
1829 if (bgp_notify.length)
1830 {
1831 peer->notify.length = size - 2;
1832 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1833 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1834 }
1835
1836 /* For debug */
1837 {
1838 int i;
1839 int first = 0;
1840 char c[4];
1841
1842 if (bgp_notify.length)
1843 {
1844 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1845 for (i = 0; i < bgp_notify.length; i++)
1846 if (first)
1847 {
1848 sprintf (c, " %02x", stream_getc (peer->ibuf));
1849 strcat (bgp_notify.data, c);
1850 }
1851 else
1852 {
1853 first = 1;
1854 sprintf (c, "%02x", stream_getc (peer->ibuf));
1855 strcpy (bgp_notify.data, c);
1856 }
1857 }
1858
1859 bgp_notify_print(peer, &bgp_notify, "received");
1860 if (bgp_notify.data)
1861 XFREE (MTYPE_TMP, bgp_notify.data);
1862 }
1863
1864 /* peer count update */
1865 peer->notify_in++;
1866
hassoe0701b72004-05-20 09:19:34 +00001867 if (peer->status == Established)
1868 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1869
paul718e3742002-12-13 20:15:29 +00001870 /* We have to check for Notify with Unsupported Optional Parameter.
1871 in that case we fallback to open without the capability option.
1872 But this done in bgp_stop. We just mark it here to avoid changing
1873 the fsm tables. */
1874 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1875 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1876 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1877
paul718e3742002-12-13 20:15:29 +00001878 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1879}
1880
1881/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001882static void
paul718e3742002-12-13 20:15:29 +00001883bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1884{
1885 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001886 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001887
1888 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1889}
1890
1891/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001892static void
paul718e3742002-12-13 20:15:29 +00001893bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1894{
1895 afi_t afi;
1896 safi_t safi;
1897 u_char reserved;
1898 struct stream *s;
1899
1900 /* If peer does not have the capability, send notification. */
1901 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1902 {
1903 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1904 peer->host);
1905 bgp_notify_send (peer,
1906 BGP_NOTIFY_HEADER_ERR,
1907 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1908 return;
1909 }
1910
1911 /* Status must be Established. */
1912 if (peer->status != Established)
1913 {
1914 plog_err (peer->log,
1915 "%s [Error] Route refresh packet received under status %s",
1916 peer->host, LOOKUP (bgp_status_msg, peer->status));
1917 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1918 return;
1919 }
1920
1921 s = peer->ibuf;
1922
1923 /* Parse packet. */
1924 afi = stream_getw (s);
1925 reserved = stream_getc (s);
1926 safi = stream_getc (s);
1927
1928 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001929 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001930 peer->host, afi, safi);
1931
1932 /* Check AFI and SAFI. */
1933 if ((afi != AFI_IP && afi != AFI_IP6)
1934 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1935 && safi != BGP_SAFI_VPNV4))
1936 {
1937 if (BGP_DEBUG (normal, NORMAL))
1938 {
ajs6b514742004-12-08 21:03:23 +00001939 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001940 peer->host, afi, safi);
1941 }
1942 return;
1943 }
1944
1945 /* Adjust safi code. */
1946 if (safi == BGP_SAFI_VPNV4)
1947 safi = SAFI_MPLS_VPN;
1948
1949 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1950 {
1951 u_char *end;
1952 u_char when_to_refresh;
1953 u_char orf_type;
1954 u_int16_t orf_len;
1955
1956 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1957 {
1958 zlog_info ("%s ORF route refresh length error", peer->host);
1959 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1960 return;
1961 }
1962
1963 when_to_refresh = stream_getc (s);
1964 end = stream_pnt (s) + (size - 5);
1965
Paul Jakma370b64a2007-12-22 16:49:52 +00001966 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00001967 {
1968 orf_type = stream_getc (s);
1969 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00001970
1971 /* orf_len in bounds? */
1972 if ((stream_pnt (s) + orf_len) > end)
1973 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00001974 if (orf_type == ORF_TYPE_PREFIX
1975 || orf_type == ORF_TYPE_PREFIX_OLD)
1976 {
1977 u_char *p_pnt = stream_pnt (s);
1978 u_char *p_end = stream_pnt (s) + orf_len;
1979 struct orf_prefix orfp;
1980 u_char common = 0;
1981 u_int32_t seq;
1982 int psize;
1983 char name[BUFSIZ];
1984 char buf[BUFSIZ];
1985 int ret;
1986
1987 if (BGP_DEBUG (normal, NORMAL))
1988 {
ajs6b514742004-12-08 21:03:23 +00001989 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00001990 peer->host, orf_type, orf_len);
1991 }
1992
Paul Jakma370b64a2007-12-22 16:49:52 +00001993 /* we're going to read at least 1 byte of common ORF header,
1994 * and 7 bytes of ORF Address-filter entry from the stream
1995 */
1996 if (orf_len < 7)
1997 break;
1998
paul718e3742002-12-13 20:15:29 +00001999 /* ORF prefix-list name */
2000 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2001
2002 while (p_pnt < p_end)
2003 {
Chris Halld64379e2010-05-14 16:38:39 +04002004 /* If the ORF entry is malformed, want to read as much of it
2005 * as possible without going beyond the bounds of the entry,
2006 * to maximise debug information.
2007 */
2008 int ok ;
paul718e3742002-12-13 20:15:29 +00002009 memset (&orfp, 0, sizeof (struct orf_prefix));
2010 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002011 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002012 if (common & ORF_COMMON_PART_REMOVE_ALL)
2013 {
2014 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002015 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00002016 prefix_bgp_orf_remove_all (name);
2017 break;
2018 }
Chris Halld64379e2010-05-14 16:38:39 +04002019 ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
2020 if (ok)
2021 {
paul718e3742002-12-13 20:15:29 +00002022 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2023 p_pnt += sizeof (u_int32_t);
2024 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002025 }
2026 else
2027 p_pnt = p_end ;
2028
2029 if ((ok = (p_pnt < p_end)))
2030 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2031 if ((ok = (p_pnt < p_end)))
2032 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2033 if ((ok = (p_pnt < p_end)))
2034 orfp.p.prefixlen = *p_pnt++ ;
2035 orfp.p.family = afi2family (afi); /* afi checked already */
2036
2037 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2038 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2039 {
2040 ok = 0 ;
2041 psize = prefix_blen(&orfp.p) ;
2042 }
2043 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2044 {
2045 ok = 0 ;
2046 psize = p_end - p_pnt ;
2047 }
2048
2049 if (psize > 0)
2050 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002051 p_pnt += psize;
2052
2053 if (BGP_DEBUG (normal, NORMAL))
Chris Halld64379e2010-05-14 16:38:39 +04002054 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
paul718e3742002-12-13 20:15:29 +00002055 peer->host,
2056 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2057 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2058 orfp.seq,
2059 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
Chris Halld64379e2010-05-14 16:38:39 +04002060 orfp.p.prefixlen, orfp.ge, orfp.le,
2061 ok ? "" : " MALFORMED");
paul718e3742002-12-13 20:15:29 +00002062
Chris Halld64379e2010-05-14 16:38:39 +04002063 if (ok)
paul718e3742002-12-13 20:15:29 +00002064 ret = prefix_bgp_orf_set (name, afi, &orfp,
2065 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2066 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
2067
Chris Halld64379e2010-05-14 16:38:39 +04002068 if (!ok || (ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002069 {
2070 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002071 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002072 prefix_bgp_orf_remove_all (name);
2073 break;
2074 }
2075 }
2076 peer->orf_plist[afi][safi] =
2077 prefix_list_lookup (AFI_ORF_PREFIX, name);
2078 }
paul9985f832005-02-09 15:51:56 +00002079 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002080 }
2081 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002082 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002083 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2084 if (when_to_refresh == REFRESH_DEFER)
2085 return;
2086 }
2087
2088 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2089 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2090 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2091
2092 /* Perform route refreshment to the peer */
2093 bgp_announce_route (peer, afi, safi);
2094}
2095
paul94f2b392005-06-28 12:44:16 +00002096static int
paul718e3742002-12-13 20:15:29 +00002097bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2098{
2099 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002100 struct capability_mp_data mpc;
2101 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002102 u_char action;
2103 struct bgp *bgp;
2104 afi_t afi;
2105 safi_t safi;
2106
2107 bgp = peer->bgp;
2108 end = pnt + length;
2109
2110 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002111 {
paul718e3742002-12-13 20:15:29 +00002112 /* We need at least action, capability code and capability length. */
2113 if (pnt + 3 > end)
2114 {
2115 zlog_info ("%s Capability length error", peer->host);
2116 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2117 return -1;
2118 }
paul718e3742002-12-13 20:15:29 +00002119 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002120 hdr = (struct capability_header *)(pnt + 1);
2121
paul718e3742002-12-13 20:15:29 +00002122 /* Action value check. */
2123 if (action != CAPABILITY_ACTION_SET
2124 && action != CAPABILITY_ACTION_UNSET)
2125 {
2126 zlog_info ("%s Capability Action Value error %d",
2127 peer->host, action);
2128 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2129 return -1;
2130 }
2131
2132 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002133 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002134 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002135
2136 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002137 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002138 {
2139 zlog_info ("%s Capability length error", peer->host);
2140 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2141 return -1;
2142 }
2143
Paul Jakma6d582722007-08-06 15:21:45 +00002144 /* Fetch structure to the byte stream. */
2145 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2146
paul718e3742002-12-13 20:15:29 +00002147 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002148 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002149 {
Paul Jakma6d582722007-08-06 15:21:45 +00002150 afi = ntohs (mpc.afi);
2151 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002152
2153 /* Ignore capability when override-capability is set. */
2154 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2155 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002156
2157 if (!bgp_afi_safi_valid_indices (afi, &safi))
2158 {
2159 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002160 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2161 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002162 continue;
2163 }
2164
paul718e3742002-12-13 20:15:29 +00002165 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002166 if (BGP_DEBUG (normal, NORMAL))
2167 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2168 peer->host,
2169 action == CAPABILITY_ACTION_SET
2170 ? "Advertising" : "Removing",
2171 ntohs(mpc.afi) , mpc.safi);
2172
2173 if (action == CAPABILITY_ACTION_SET)
2174 {
2175 peer->afc_recv[afi][safi] = 1;
2176 if (peer->afc[afi][safi])
2177 {
2178 peer->afc_nego[afi][safi] = 1;
2179 bgp_announce_route (peer, afi, safi);
2180 }
2181 }
2182 else
2183 {
2184 peer->afc_recv[afi][safi] = 0;
2185 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002186
Paul Jakma6d582722007-08-06 15:21:45 +00002187 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002188 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002189 else
2190 BGP_EVENT_ADD (peer, BGP_Stop);
2191 }
paul718e3742002-12-13 20:15:29 +00002192 }
paul718e3742002-12-13 20:15:29 +00002193 else
2194 {
2195 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002196 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002197 }
Paul Jakma6d582722007-08-06 15:21:45 +00002198 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002199 }
2200 return 0;
2201}
2202
Paul Jakma01b7ce22009-06-18 12:34:43 +01002203/* Dynamic Capability is received.
2204 *
2205 * This is exported for unit-test purposes
2206 */
Paul Jakma6d582722007-08-06 15:21:45 +00002207int
paul718e3742002-12-13 20:15:29 +00002208bgp_capability_receive (struct peer *peer, bgp_size_t size)
2209{
2210 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002211
2212 /* Fetch pointer. */
2213 pnt = stream_pnt (peer->ibuf);
2214
2215 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002216 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002217
2218 /* If peer does not have the capability, send notification. */
2219 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2220 {
2221 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2222 peer->host);
2223 bgp_notify_send (peer,
2224 BGP_NOTIFY_HEADER_ERR,
2225 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002226 return -1;
paul718e3742002-12-13 20:15:29 +00002227 }
2228
2229 /* Status must be Established. */
2230 if (peer->status != Established)
2231 {
2232 plog_err (peer->log,
2233 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2234 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002235 return -1;
paul718e3742002-12-13 20:15:29 +00002236 }
2237
2238 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002239 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002240}
2241
2242/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002243static int
paul718e3742002-12-13 20:15:29 +00002244bgp_read_packet (struct peer *peer)
2245{
2246 int nbytes;
2247 int readsize;
2248
paul9985f832005-02-09 15:51:56 +00002249 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002250
2251 /* If size is zero then return. */
2252 if (! readsize)
2253 return 0;
2254
2255 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002256 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002257
2258 /* If read byte is smaller than zero then error occured. */
2259 if (nbytes < 0)
2260 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002261 /* Transient error should retry */
2262 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002263 return -1;
2264
2265 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002266 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002267
2268 if (peer->status == Established)
2269 {
2270 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2271 {
2272 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2273 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2274 }
2275 else
2276 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2277 }
2278
paul718e3742002-12-13 20:15:29 +00002279 BGP_EVENT_ADD (peer, TCP_fatal_error);
2280 return -1;
2281 }
2282
2283 /* When read byte is zero : clear bgp peer and return */
2284 if (nbytes == 0)
2285 {
2286 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002287 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002288 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002289
2290 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002291 {
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 }
hassoe0701b72004-05-20 09:19:34 +00002300
paul718e3742002-12-13 20:15:29 +00002301 BGP_EVENT_ADD (peer, TCP_connection_closed);
2302 return -1;
2303 }
2304
2305 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002306 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002307 return -1;
2308
2309 return 0;
2310}
2311
2312/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002313static int
paul718e3742002-12-13 20:15:29 +00002314bgp_marker_all_one (struct stream *s, int length)
2315{
2316 int i;
2317
2318 for (i = 0; i < length; i++)
2319 if (s->data[i] != 0xff)
2320 return 0;
2321
2322 return 1;
2323}
2324
2325/* Starting point of packet process function. */
2326int
2327bgp_read (struct thread *thread)
2328{
2329 int ret;
2330 u_char type = 0;
2331 struct peer *peer;
2332 bgp_size_t size;
2333 char notify_data_length[2];
2334
2335 /* Yes first of all get peer pointer. */
2336 peer = THREAD_ARG (thread);
2337 peer->t_read = NULL;
2338
2339 /* For non-blocking IO check. */
2340 if (peer->status == Connect)
2341 {
2342 bgp_connect_check (peer);
2343 goto done;
2344 }
2345 else
2346 {
pauleb821182004-05-01 08:44:08 +00002347 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002348 {
pauleb821182004-05-01 08:44:08 +00002349 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002350 return -1;
2351 }
pauleb821182004-05-01 08:44:08 +00002352 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002353 }
2354
2355 /* Read packet header to determine type of the packet */
2356 if (peer->packet_size == 0)
2357 peer->packet_size = BGP_HEADER_SIZE;
2358
paul9985f832005-02-09 15:51:56 +00002359 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002360 {
2361 ret = bgp_read_packet (peer);
2362
2363 /* Header read error or partial read packet. */
2364 if (ret < 0)
2365 goto done;
2366
2367 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002368 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002369 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2370 size = stream_getw (peer->ibuf);
2371 type = stream_getc (peer->ibuf);
2372
2373 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002374 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002375 peer->host, type, size - BGP_HEADER_SIZE);
2376
2377 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002378 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002379 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2380 {
2381 bgp_notify_send (peer,
2382 BGP_NOTIFY_HEADER_ERR,
2383 BGP_NOTIFY_HEADER_NOT_SYNC);
2384 goto done;
2385 }
2386
2387 /* BGP type check. */
2388 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2389 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2390 && type != BGP_MSG_ROUTE_REFRESH_NEW
2391 && type != BGP_MSG_ROUTE_REFRESH_OLD
2392 && type != BGP_MSG_CAPABILITY)
2393 {
2394 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002395 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002396 "%s unknown message type 0x%02x",
2397 peer->host, type);
2398 bgp_notify_send_with_data (peer,
2399 BGP_NOTIFY_HEADER_ERR,
2400 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2401 &type, 1);
2402 goto done;
2403 }
2404 /* Mimimum packet length check. */
2405 if ((size < BGP_HEADER_SIZE)
2406 || (size > BGP_MAX_PACKET_SIZE)
2407 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2408 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2409 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2410 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2411 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2412 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2413 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2414 {
2415 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002416 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002417 "%s bad message length - %d for %s",
2418 peer->host, size,
2419 type == 128 ? "ROUTE-REFRESH" :
2420 bgp_type_str[(int) type]);
2421 bgp_notify_send_with_data (peer,
2422 BGP_NOTIFY_HEADER_ERR,
2423 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002424 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002425 goto done;
2426 }
2427
2428 /* Adjust size to message length. */
2429 peer->packet_size = size;
2430 }
2431
2432 ret = bgp_read_packet (peer);
2433 if (ret < 0)
2434 goto done;
2435
2436 /* Get size and type again. */
2437 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2438 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2439
2440 /* BGP packet dump function. */
2441 bgp_dump_packet (peer, type, peer->ibuf);
2442
2443 size = (peer->packet_size - BGP_HEADER_SIZE);
2444
2445 /* Read rest of the packet and call each sort of packet routine */
2446 switch (type)
2447 {
2448 case BGP_MSG_OPEN:
2449 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002450 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002451 break;
2452 case BGP_MSG_UPDATE:
2453 peer->readtime = time(NULL); /* Last read timer reset */
2454 bgp_update_receive (peer, size);
2455 break;
2456 case BGP_MSG_NOTIFY:
2457 bgp_notify_receive (peer, size);
2458 break;
2459 case BGP_MSG_KEEPALIVE:
2460 peer->readtime = time(NULL); /* Last read timer reset */
2461 bgp_keepalive_receive (peer, size);
2462 break;
2463 case BGP_MSG_ROUTE_REFRESH_NEW:
2464 case BGP_MSG_ROUTE_REFRESH_OLD:
2465 peer->refresh_in++;
2466 bgp_route_refresh_receive (peer, size);
2467 break;
2468 case BGP_MSG_CAPABILITY:
2469 peer->dynamic_cap_in++;
2470 bgp_capability_receive (peer, size);
2471 break;
2472 }
2473
2474 /* Clear input buffer. */
2475 peer->packet_size = 0;
2476 if (peer->ibuf)
2477 stream_reset (peer->ibuf);
2478
2479 done:
2480 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2481 {
2482 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002483 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002484 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002485 }
2486 return 0;
2487}