blob: 390b556356d4b2ac158194d7d040f120bf1488d6 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
31#include "linklist.h"
32#include "plist.h"
33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_table.h"
36#include "bgpd/bgp_dump.h"
37#include "bgpd/bgp_attr.h"
38#include "bgpd/bgp_debug.h"
39#include "bgpd/bgp_fsm.h"
40#include "bgpd/bgp_route.h"
41#include "bgpd/bgp_packet.h"
42#include "bgpd/bgp_open.h"
43#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_community.h"
45#include "bgpd/bgp_ecommunity.h"
46#include "bgpd/bgp_network.h"
47#include "bgpd/bgp_mplsvpn.h"
48#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000049#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000050
51int stream_put_prefix (struct stream *, struct prefix *);
52
53/* Set up BGP packet marker and packet type. */
54static int
55bgp_packet_set_marker (struct stream *s, u_char type)
56{
57 int i;
58
59 /* Fill in marker. */
60 for (i = 0; i < BGP_MARKER_SIZE; i++)
61 stream_putc (s, 0xff);
62
63 /* Dummy total length. This field is should be filled in later on. */
64 stream_putw (s, 0);
65
66 /* BGP packet type. */
67 stream_putc (s, type);
68
69 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000070 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000071}
72
73/* Set BGP packet header size entry. If size is zero then use current
74 stream size. */
75static int
76bgp_packet_set_size (struct stream *s)
77{
78 int cp;
79
80 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000081 cp = stream_get_endp (s);
82 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000083
84 return cp;
85}
86
87/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000088static void
paul718e3742002-12-13 20:15:29 +000089bgp_packet_add (struct peer *peer, struct stream *s)
90{
91 /* Add packet to the end of list. */
92 stream_fifo_push (peer->obuf, s);
93}
94
95/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000096static void
paul718e3742002-12-13 20:15:29 +000097bgp_packet_delete (struct peer *peer)
98{
99 stream_free (stream_fifo_pop (peer->obuf));
100}
101
paul718e3742002-12-13 20:15:29 +0000102/* Check file descriptor whether connect is established. */
103static void
104bgp_connect_check (struct peer *peer)
105{
106 int status;
paul5228ad22004-06-04 17:58:18 +0000107 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000108 int ret;
109
110 /* Anyway I have to reset read and write thread. */
111 BGP_READ_OFF (peer->t_read);
112 BGP_WRITE_OFF (peer->t_write);
113
114 /* Check file descriptor. */
115 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000116 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000117
118 /* If getsockopt is fail, this is fatal error. */
119 if (ret < 0)
120 {
121 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
122 BGP_EVENT_ADD (peer, TCP_fatal_error);
123 return;
124 }
125
126 /* When status is 0 then TCP connection is established. */
127 if (status == 0)
128 {
129 BGP_EVENT_ADD (peer, TCP_connection_open);
130 }
131 else
132 {
133 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000134 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000135 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000136 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
137 }
138}
139
140/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000141static struct stream *
paul718e3742002-12-13 20:15:29 +0000142bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
143{
144 struct stream *s;
145 struct bgp_adj_out *adj;
146 struct bgp_advertise *adv;
147 struct stream *packet;
148 struct bgp_node *rn = NULL;
149 struct bgp_info *binfo = NULL;
150 bgp_size_t total_attr_len = 0;
151 unsigned long pos;
152 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000153
154 s = peer->work;
155 stream_reset (s);
156
157 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
158
159 while (adv)
160 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000161 assert (adv->rn);
162 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000163 adj = adv->adj;
164 if (adv->binfo)
165 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000166
167 /* When remaining space can't include NLRI and it's length. */
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000168 if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
paul718e3742002-12-13 20:15:29 +0000169 break;
170
171 /* If packet is empty, set attribute. */
172 if (stream_empty (s))
173 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000174 struct prefix_rd *prd = NULL;
175 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000176 struct peer *from = NULL;
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000177
178 if (rn->prn)
179 prd = (struct prefix_rd *) &rn->prn->p;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400180 if (binfo)
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000182 from = binfo->peer;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400183 if (binfo->extra)
184 tag = binfo->extra->tag;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000185 }
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000186
paul718e3742002-12-13 20:15:29 +0000187 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
188 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000189 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000190 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000191 total_attr_len = bgp_packet_attribute (NULL, peer, s,
192 adv->baa->attr,
193 &rn->p, afi, safi,
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000194 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000195 stream_putw_at (s, pos, total_attr_len);
196 }
197
198 if (afi == AFI_IP && safi == SAFI_UNICAST)
199 stream_put_prefix (s, &rn->p);
200
201 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000202 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000203 peer->host,
204 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
205 rn->p.prefixlen);
206
207 /* Synchnorize attribute. */
208 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000209 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000210 else
211 peer->scount[afi][safi]++;
212
213 adj->attr = bgp_attr_intern (adv->baa->attr);
214
215 adv = bgp_advertise_clean (peer, adj, afi, safi);
216
217 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
218 break;
219 }
220
221 if (! stream_empty (s))
222 {
223 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000224 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000225 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000226 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000227 stream_reset (s);
228 return packet;
229 }
230 return NULL;
hasso93406d82005-02-02 14:40:33 +0000231}
paul718e3742002-12-13 20:15:29 +0000232
paul94f2b392005-06-28 12:44:16 +0000233static struct stream *
hasso93406d82005-02-02 14:40:33 +0000234bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
235{
236 struct stream *s;
237 struct stream *packet;
238
Paul Jakma750e8142008-07-22 21:11:48 +0000239 if (DISABLE_BGP_ANNOUNCE)
240 return NULL;
hasso93406d82005-02-02 14:40:33 +0000241
242 if (BGP_DEBUG (normal, NORMAL))
243 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
244
245 s = stream_new (BGP_MAX_PACKET_SIZE);
246
247 /* Make BGP update packet. */
248 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
249
250 /* Unfeasible Routes Length */
251 stream_putw (s, 0);
252
253 if (afi == AFI_IP && safi == SAFI_UNICAST)
254 {
255 /* Total Path Attribute Length */
256 stream_putw (s, 0);
257 }
258 else
259 {
260 /* Total Path Attribute Length */
261 stream_putw (s, 6);
262 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
263 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
264 stream_putc (s, 3);
265 stream_putw (s, afi);
266 stream_putc (s, safi);
267 }
268
269 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000270 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000271 bgp_packet_add (peer, packet);
272 stream_free (s);
273 return packet;
paul718e3742002-12-13 20:15:29 +0000274}
275
276/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000277static struct stream *
paul718e3742002-12-13 20:15:29 +0000278bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
279{
280 struct stream *s;
281 struct stream *packet;
282 struct bgp_adj_out *adj;
283 struct bgp_advertise *adv;
284 struct bgp_node *rn;
285 unsigned long pos;
286 bgp_size_t unfeasible_len;
287 bgp_size_t total_attr_len;
288 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000289
290 s = peer->work;
291 stream_reset (s);
292
293 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
294 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000295 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000296 adj = adv->adj;
297 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000298
299 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000300 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000301 break;
302
303 if (stream_empty (s))
304 {
305 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
306 stream_putw (s, 0);
307 }
308
309 if (afi == AFI_IP && safi == SAFI_UNICAST)
310 stream_put_prefix (s, &rn->p);
311 else
312 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000313 struct prefix_rd *prd = NULL;
314
315 if (rn->prn)
316 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000317 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000318 stream_putw (s, 0);
319 total_attr_len
320 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
321
322 /* Set total path attribute length. */
323 stream_putw_at (s, pos, total_attr_len);
324 }
325
326 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000327 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000328 peer->host,
329 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
330 rn->p.prefixlen);
331
332 peer->scount[afi][safi]--;
333
334 bgp_adj_out_remove (rn, adj, peer, afi, safi);
335 bgp_unlock_node (rn);
336
337 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
338 break;
339 }
340
341 if (! stream_empty (s))
342 {
343 if (afi == AFI_IP && safi == SAFI_UNICAST)
344 {
345 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000346 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000347 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
348 stream_putw (s, 0);
349 }
350 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000351 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000352 bgp_packet_add (peer, packet);
353 stream_reset (s);
354 return packet;
355 }
356
357 return NULL;
358}
359
360void
361bgp_default_update_send (struct peer *peer, struct attr *attr,
362 afi_t afi, safi_t safi, struct peer *from)
363{
364 struct stream *s;
365 struct stream *packet;
366 struct prefix p;
367 unsigned long pos;
368 bgp_size_t total_attr_len;
369 char attrstr[BUFSIZ];
370 char buf[BUFSIZ];
371
Paul Jakma750e8142008-07-22 21:11:48 +0000372 if (DISABLE_BGP_ANNOUNCE)
373 return;
paul718e3742002-12-13 20:15:29 +0000374
375 if (afi == AFI_IP)
376 str2prefix ("0.0.0.0/0", &p);
377#ifdef HAVE_IPV6
378 else
379 str2prefix ("::/0", &p);
380#endif /* HAVE_IPV6 */
381
382 /* Logging the attribute. */
383 if (BGP_DEBUG (update, UPDATE_OUT))
384 {
385 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000386 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000387 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
388 p.prefixlen, attrstr);
389 }
390
391 s = stream_new (BGP_MAX_PACKET_SIZE);
392
393 /* Make BGP update packet. */
394 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
395
396 /* Unfeasible Routes Length. */
397 stream_putw (s, 0);
398
399 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000400 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000401 stream_putw (s, 0);
402 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
403
404 /* Set Total Path Attribute Length. */
405 stream_putw_at (s, pos, total_attr_len);
406
407 /* NLRI set. */
408 if (p.family == AF_INET && safi == SAFI_UNICAST)
409 stream_put_prefix (s, &p);
410
411 /* Set size. */
412 bgp_packet_set_size (s);
413
paule83e2082005-05-19 02:12:25 +0000414 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000415 stream_free (s);
416
417 /* Dump packet if debug option is set. */
418#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000419 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000420#endif /* DEBUG */
421
422 /* Add packet to the peer. */
423 bgp_packet_add (peer, packet);
424
pauleb821182004-05-01 08:44:08 +0000425 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000426}
427
428void
429bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
430{
431 struct stream *s;
432 struct stream *packet;
433 struct prefix p;
434 unsigned long pos;
435 unsigned long cp;
436 bgp_size_t unfeasible_len;
437 bgp_size_t total_attr_len;
438 char buf[BUFSIZ];
439
Paul Jakma750e8142008-07-22 21:11:48 +0000440 if (DISABLE_BGP_ANNOUNCE)
441 return;
paul718e3742002-12-13 20:15:29 +0000442
443 if (afi == AFI_IP)
444 str2prefix ("0.0.0.0/0", &p);
445#ifdef HAVE_IPV6
446 else
447 str2prefix ("::/0", &p);
448#endif /* HAVE_IPV6 */
449
450 total_attr_len = 0;
451 pos = 0;
452
453 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000454 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000455 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
456 p.prefixlen);
457
458 s = stream_new (BGP_MAX_PACKET_SIZE);
459
460 /* Make BGP update packet. */
461 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
462
463 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000464 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000465 stream_putw (s, 0);
466
467 /* Withdrawn Routes. */
468 if (p.family == AF_INET && safi == SAFI_UNICAST)
469 {
470 stream_put_prefix (s, &p);
471
paul9985f832005-02-09 15:51:56 +0000472 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000473
474 /* Set unfeasible len. */
475 stream_putw_at (s, cp, unfeasible_len);
476
477 /* Set total path attribute length. */
478 stream_putw (s, 0);
479 }
480 else
481 {
paul9985f832005-02-09 15:51:56 +0000482 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000483 stream_putw (s, 0);
484 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
485
486 /* Set total path attribute length. */
487 stream_putw_at (s, pos, total_attr_len);
488 }
489
490 bgp_packet_set_size (s);
491
paule83e2082005-05-19 02:12:25 +0000492 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000493 stream_free (s);
494
495 /* Add packet to the peer. */
496 bgp_packet_add (peer, packet);
497
pauleb821182004-05-01 08:44:08 +0000498 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000499}
500
501/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000502static struct stream *
paul718e3742002-12-13 20:15:29 +0000503bgp_write_packet (struct peer *peer)
504{
505 afi_t afi;
506 safi_t safi;
507 struct stream *s = NULL;
508 struct bgp_advertise *adv;
509
510 s = stream_fifo_head (peer->obuf);
511 if (s)
512 return s;
513
514 for (afi = AFI_IP; afi < AFI_MAX; afi++)
515 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
516 {
517 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
518 if (adv)
519 {
520 s = bgp_withdraw_packet (peer, afi, safi);
521 if (s)
522 return s;
523 }
524 }
525
526 for (afi = AFI_IP; afi < AFI_MAX; afi++)
527 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
528 {
529 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
530 if (adv)
531 {
532 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000533 {
534 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
535 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
536 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
537 && safi != SAFI_MPLS_VPN)
538 {
539 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
540 PEER_STATUS_EOR_RECEIVED))
541 s = bgp_update_packet (peer, afi, safi);
542 }
543 else
544 s = bgp_update_packet (peer, afi, safi);
545 }
paul718e3742002-12-13 20:15:29 +0000546
547 if (s)
548 return s;
549 }
hasso93406d82005-02-02 14:40:33 +0000550
551 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
552 {
553 if (peer->afc_nego[afi][safi] && peer->synctime
554 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
555 && safi != SAFI_MPLS_VPN)
556 {
557 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
558 return bgp_update_packet_eor (peer, afi, safi);
559 }
560 }
paul718e3742002-12-13 20:15:29 +0000561 }
562
563 return NULL;
564}
565
566/* Is there partially written packet or updates we can send right
567 now. */
paul94f2b392005-06-28 12:44:16 +0000568static int
paul718e3742002-12-13 20:15:29 +0000569bgp_write_proceed (struct peer *peer)
570{
571 afi_t afi;
572 safi_t safi;
573 struct bgp_advertise *adv;
574
575 if (stream_fifo_head (peer->obuf))
576 return 1;
577
578 for (afi = AFI_IP; afi < AFI_MAX; afi++)
579 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
580 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
581 return 1;
582
583 for (afi = AFI_IP; afi < AFI_MAX; afi++)
584 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
585 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
586 if (adv->binfo->uptime < peer->synctime)
587 return 1;
588
589 return 0;
590}
591
592/* Write packet to the peer. */
593int
594bgp_write (struct thread *thread)
595{
596 struct peer *peer;
597 u_char type;
598 struct stream *s;
599 int num;
paulfd79ac92004-10-13 05:06:08 +0000600 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000601
602 /* Yes first of all get peer pointer. */
603 peer = THREAD_ARG (thread);
604 peer->t_write = NULL;
605
606 /* For non-blocking IO check. */
607 if (peer->status == Connect)
608 {
609 bgp_connect_check (peer);
610 return 0;
611 }
612
Stephen Hemmingereac57022010-08-05 10:26:25 -0700613 s = bgp_write_packet (peer);
614 if (!s)
615 return 0; /* nothing to send */
616
617 sockopt_cork (peer->fd, 1);
618
619 /* Nonblocking write until TCP output buffer is full. */
620 do
paul718e3742002-12-13 20:15:29 +0000621 {
622 int writenum;
paul718e3742002-12-13 20:15:29 +0000623
624 /* Number of bytes to be sent. */
625 writenum = stream_get_endp (s) - stream_get_getp (s);
626
627 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000628 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700629 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000630 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700631 /* write failed either retry needed or error */
632 if (ERRNO_IO_RETRY(errno))
633 break;
634
635 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000636 return 0;
637 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700638
paul718e3742002-12-13 20:15:29 +0000639 if (num != writenum)
640 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700641 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000642 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700643 break;
paul718e3742002-12-13 20:15:29 +0000644 }
645
646 /* Retrieve BGP packet type. */
647 stream_set_getp (s, BGP_MARKER_SIZE + 2);
648 type = stream_getc (s);
649
650 switch (type)
651 {
652 case BGP_MSG_OPEN:
653 peer->open_out++;
654 break;
655 case BGP_MSG_UPDATE:
656 peer->update_out++;
657 break;
658 case BGP_MSG_NOTIFY:
659 peer->notify_out++;
660 /* Double start timer. */
661 peer->v_start *= 2;
662
663 /* Overflow check. */
664 if (peer->v_start >= (60 * 2))
665 peer->v_start = (60 * 2);
666
Paul Jakmaca058a32006-09-14 02:58:49 +0000667 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000668 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000669 return 0;
paul718e3742002-12-13 20:15:29 +0000670 case BGP_MSG_KEEPALIVE:
671 peer->keepalive_out++;
672 break;
673 case BGP_MSG_ROUTE_REFRESH_NEW:
674 case BGP_MSG_ROUTE_REFRESH_OLD:
675 peer->refresh_out++;
676 break;
677 case BGP_MSG_CAPABILITY:
678 peer->dynamic_cap_out++;
679 break;
680 }
681
682 /* OK we send packet so delete it. */
683 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000684 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700685 while (++count < BGP_WRITE_PACKET_MAX &&
686 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000687
688 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000689 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700690 else
691 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000692
693 return 0;
694}
695
696/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000697static int
paul718e3742002-12-13 20:15:29 +0000698bgp_write_notify (struct peer *peer)
699{
Stephen Hemminger35398582010-08-05 10:26:23 -0700700 int ret, val;
paul718e3742002-12-13 20:15:29 +0000701 u_char type;
702 struct stream *s;
703
704 /* There should be at least one packet. */
705 s = stream_fifo_head (peer->obuf);
706 if (!s)
707 return 0;
708 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
709
Stephen Hemminger35398582010-08-05 10:26:23 -0700710 /* Put socket in blocking mode. */
711 val = fcntl (peer->fd, F_GETFL, 0);
712 fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);
713
pauleb821182004-05-01 08:44:08 +0000714 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000715 if (ret <= 0)
716 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000717 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000718 return 0;
719 }
720
721 /* Retrieve BGP packet type. */
722 stream_set_getp (s, BGP_MARKER_SIZE + 2);
723 type = stream_getc (s);
724
725 assert (type == BGP_MSG_NOTIFY);
726
727 /* Type should be notify. */
728 peer->notify_out++;
729
730 /* Double start timer. */
731 peer->v_start *= 2;
732
733 /* Overflow check. */
734 if (peer->v_start >= (60 * 2))
735 peer->v_start = (60 * 2);
736
Paul Jakmadcdf3992006-10-15 23:39:59 +0000737 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000738
739 return 0;
740}
741
742/* Make keepalive packet and send it to the peer. */
743void
744bgp_keepalive_send (struct peer *peer)
745{
746 struct stream *s;
747 int length;
748
749 s = stream_new (BGP_MAX_PACKET_SIZE);
750
751 /* Make keepalive packet. */
752 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
753
754 /* Set packet size. */
755 length = bgp_packet_set_size (s);
756
757 /* Dump packet if debug option is set. */
758 /* bgp_packet_dump (s); */
759
760 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000761 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000762 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000763 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000764 peer->host, BGP_MSG_KEEPALIVE, length);
765
766 /* Add packet to the peer. */
767 bgp_packet_add (peer, s);
768
pauleb821182004-05-01 08:44:08 +0000769 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000770}
771
772/* Make open packet and send it to the peer. */
773void
774bgp_open_send (struct peer *peer)
775{
776 struct stream *s;
777 int length;
778 u_int16_t send_holdtime;
779 as_t local_as;
780
781 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
782 send_holdtime = peer->holdtime;
783 else
784 send_holdtime = peer->bgp->default_holdtime;
785
786 /* local-as Change */
787 if (peer->change_local_as)
788 local_as = peer->change_local_as;
789 else
790 local_as = peer->local_as;
791
792 s = stream_new (BGP_MAX_PACKET_SIZE);
793
794 /* Make open packet. */
795 bgp_packet_set_marker (s, BGP_MSG_OPEN);
796
797 /* Set open packet values. */
798 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000799 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
800 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000801 stream_putw (s, send_holdtime); /* Hold Time */
802 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
803
804 /* Set capability code. */
805 bgp_open_capability (s, peer);
806
807 /* Set BGP packet length. */
808 length = bgp_packet_set_size (s);
809
810 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400811 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000812 peer->host, BGP_VERSION_4, local_as,
813 send_holdtime, inet_ntoa (peer->local_id));
814
815 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000816 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000817 peer->host, BGP_MSG_OPEN, length);
818
819 /* Dump packet if debug option is set. */
820 /* bgp_packet_dump (s); */
821
822 /* Add packet to the peer. */
823 bgp_packet_add (peer, s);
824
pauleb821182004-05-01 08:44:08 +0000825 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000826}
827
828/* Send BGP notify packet with data potion. */
829void
830bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
831 u_char *data, size_t datalen)
832{
833 struct stream *s;
834 int length;
835
836 /* Allocate new stream. */
837 s = stream_new (BGP_MAX_PACKET_SIZE);
838
839 /* Make nitify packet. */
840 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
841
842 /* Set notify packet values. */
843 stream_putc (s, code); /* BGP notify code */
844 stream_putc (s, sub_code); /* BGP notify sub_code */
845
846 /* If notify data is present. */
847 if (data)
848 stream_write (s, data, datalen);
849
850 /* Set BGP packet length. */
851 length = bgp_packet_set_size (s);
852
853 /* Add packet to the peer. */
854 stream_fifo_clean (peer->obuf);
855 bgp_packet_add (peer, s);
856
857 /* For debug */
858 {
859 struct bgp_notify bgp_notify;
860 int first = 0;
861 int i;
862 char c[4];
863
864 bgp_notify.code = code;
865 bgp_notify.subcode = sub_code;
866 bgp_notify.data = NULL;
867 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
868
869 if (bgp_notify.length)
870 {
871 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
872 for (i = 0; i < bgp_notify.length; i++)
873 if (first)
874 {
875 sprintf (c, " %02x", data[i]);
876 strcat (bgp_notify.data, c);
877 }
878 else
879 {
880 first = 1;
881 sprintf (c, "%02x", data[i]);
882 strcpy (bgp_notify.data, c);
883 }
884 }
885 bgp_notify_print (peer, &bgp_notify, "sending");
886 if (bgp_notify.data)
887 XFREE (MTYPE_TMP, bgp_notify.data);
888 }
889
890 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000891 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000892 peer->host, BGP_MSG_NOTIFY, length);
893
hassoe0701b72004-05-20 09:19:34 +0000894 /* peer reset cause */
895 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
896 {
897 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +0400898 {
899 peer->last_reset = PEER_DOWN_USER_RESET;
900 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
901 }
hassoe0701b72004-05-20 09:19:34 +0000902 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +0400903 {
904 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
905 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
906 }
hassoe0701b72004-05-20 09:19:34 +0000907 else
heasley1212dc12011-09-12 13:27:52 +0400908 {
909 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
910 zlog_info ("Notification sent to neighbor %s: type %u/%u",
911 peer->host, code, sub_code);
912 }
hassoe0701b72004-05-20 09:19:34 +0000913 }
heasley1212dc12011-09-12 13:27:52 +0400914 else
915 zlog_info ("Notification sent to neighbor %s: configuration change",
916 peer->host);
hassoe0701b72004-05-20 09:19:34 +0000917
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +0400918 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +0000919 BGP_WRITE_OFF (peer->t_write);
920
921 bgp_write_notify (peer);
922}
923
924/* Send BGP notify packet. */
925void
926bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
927{
928 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
929}
930
paul718e3742002-12-13 20:15:29 +0000931/* Send route refresh message to the peer. */
932void
933bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
934 u_char orf_type, u_char when_to_refresh, int remove)
935{
936 struct stream *s;
937 struct stream *packet;
938 int length;
939 struct bgp_filter *filter;
940 int orf_refresh = 0;
941
Paul Jakma750e8142008-07-22 21:11:48 +0000942 if (DISABLE_BGP_ANNOUNCE)
943 return;
paul718e3742002-12-13 20:15:29 +0000944
945 filter = &peer->filter[afi][safi];
946
947 /* Adjust safi code. */
948 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400949 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +0000950
951 s = stream_new (BGP_MAX_PACKET_SIZE);
952
953 /* Make BGP update packet. */
954 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
955 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
956 else
957 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
958
959 /* Encode Route Refresh message. */
960 stream_putw (s, afi);
961 stream_putc (s, 0);
962 stream_putc (s, safi);
963
964 if (orf_type == ORF_TYPE_PREFIX
965 || orf_type == ORF_TYPE_PREFIX_OLD)
966 if (remove || filter->plist[FILTER_IN].plist)
967 {
968 u_int16_t orf_len;
969 unsigned long orfp;
970
971 orf_refresh = 1;
972 stream_putc (s, when_to_refresh);
973 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000974 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000975 stream_putw (s, 0);
976
977 if (remove)
978 {
979 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
980 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
981 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000982 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000983 peer->host, orf_type,
984 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
985 afi, safi);
986 }
987 else
988 {
989 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
990 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
991 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
992 ORF_COMMON_PART_DENY);
993 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000994 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000995 peer->host, orf_type,
996 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
997 afi, safi);
998 }
999
1000 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001001 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001002 stream_putw_at (s, orfp, orf_len);
1003 }
1004
1005 /* Set packet size. */
1006 length = bgp_packet_set_size (s);
1007
1008 if (BGP_DEBUG (normal, NORMAL))
1009 {
1010 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001011 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001012 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001013 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001014 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1015 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1016 }
1017
1018 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001019 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001020 stream_free (s);
1021
1022 /* Add packet to the peer. */
1023 bgp_packet_add (peer, packet);
1024
pauleb821182004-05-01 08:44:08 +00001025 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001026}
1027
1028/* Send capability message to the peer. */
1029void
1030bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1031 int capability_code, int action)
1032{
1033 struct stream *s;
1034 struct stream *packet;
1035 int length;
1036
1037 /* Adjust safi code. */
1038 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001039 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001040
1041 s = stream_new (BGP_MAX_PACKET_SIZE);
1042
1043 /* Make BGP update packet. */
1044 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1045
1046 /* Encode MP_EXT capability. */
1047 if (capability_code == CAPABILITY_CODE_MP)
1048 {
1049 stream_putc (s, action);
1050 stream_putc (s, CAPABILITY_CODE_MP);
1051 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1052 stream_putw (s, afi);
1053 stream_putc (s, 0);
1054 stream_putc (s, safi);
1055
1056 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001057 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001058 peer->host, action == CAPABILITY_ACTION_SET ?
1059 "Advertising" : "Removing", afi, safi);
1060 }
1061
paul718e3742002-12-13 20:15:29 +00001062 /* Set packet size. */
1063 length = bgp_packet_set_size (s);
1064
1065 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001066 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001067 stream_free (s);
1068
1069 /* Add packet to the peer. */
1070 bgp_packet_add (peer, packet);
1071
1072 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001073 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001074 peer->host, BGP_MSG_CAPABILITY, length);
1075
pauleb821182004-05-01 08:44:08 +00001076 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001077}
1078
1079/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001080static int
pauleb821182004-05-01 08:44:08 +00001081bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001082{
pauleb821182004-05-01 08:44:08 +00001083 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001084 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001085 struct bgp *bgp;
1086
1087 bgp = bgp_get_default ();
1088 if (! bgp)
1089 return 0;
1090
1091 /* Upon receipt of an OPEN message, the local system must examine
1092 all of its connections that are in the OpenConfirm state. A BGP
1093 speaker may also examine connections in an OpenSent state if it
1094 knows the BGP Identifier of the peer by means outside of the
1095 protocol. If among these connections there is a connection to a
1096 remote BGP speaker whose BGP Identifier equals the one in the
1097 OPEN message, then the local system performs the following
1098 collision resolution procedure: */
1099
paul1eb8ef22005-04-07 07:30:20 +00001100 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001101 {
1102 /* Under OpenConfirm status, local peer structure already hold
1103 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001104
1105 if (peer != new
1106 && (peer->status == OpenConfirm || peer->status == OpenSent)
1107 && sockunion_same (&peer->su, &new->su))
1108 {
paul718e3742002-12-13 20:15:29 +00001109 /* 1. The BGP Identifier of the local system is compared to
1110 the BGP Identifier of the remote system (as specified in
1111 the OPEN message). */
1112
1113 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1114 {
1115 /* 2. If the value of the local BGP Identifier is less
1116 than the remote one, the local system closes BGP
1117 connection that already exists (the one that is
1118 already in the OpenConfirm state), and accepts BGP
1119 connection initiated by the remote system. */
1120
pauleb821182004-05-01 08:44:08 +00001121 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001122 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001123 return 1;
1124 }
1125 else
1126 {
1127 /* 3. Otherwise, the local system closes newly created
1128 BGP connection (the one associated with the newly
1129 received OPEN message), and continues to use the
1130 existing one (the one that is already in the
1131 OpenConfirm state). */
1132
pauleb821182004-05-01 08:44:08 +00001133 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001134 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1135 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001136 return -1;
1137 }
pauleb821182004-05-01 08:44:08 +00001138 }
1139 }
paul718e3742002-12-13 20:15:29 +00001140 return 0;
1141}
1142
paul94f2b392005-06-28 12:44:16 +00001143static int
paul718e3742002-12-13 20:15:29 +00001144bgp_open_receive (struct peer *peer, bgp_size_t size)
1145{
1146 int ret;
1147 u_char version;
1148 u_char optlen;
1149 u_int16_t holdtime;
1150 u_int16_t send_holdtime;
1151 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001152 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001153 struct peer *realpeer;
1154 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001155 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001156 u_int8_t notify_data_remote_as[2];
1157 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001158
1159 realpeer = NULL;
1160
1161 /* Parse open packet. */
1162 version = stream_getc (peer->ibuf);
1163 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1164 remote_as = stream_getw (peer->ibuf);
1165 holdtime = stream_getw (peer->ibuf);
1166 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1167 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1168
1169 /* Receive OPEN message log */
1170 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001171 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001172 " holdtime %d, id %s",
1173 peer->host, version, remote_as, holdtime,
1174 inet_ntoa (remote_id));
1175
1176 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001177 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001178 optlen = stream_getc (peer->ibuf);
1179
1180 if (optlen != 0)
1181 {
1182 /* We need the as4 capability value *right now* because
1183 * if it is there, we have not got the remote_as yet, and without
1184 * that we do not know which peer is connecting to us now.
1185 */
1186 as4 = peek_for_as4_capability (peer, optlen);
1187 }
1188
1189 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1190 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1191 {
1192 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1193 peer->host);
1194 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1195 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1196 return -1;
1197 }
1198
1199 if (remote_as == BGP_AS_TRANS)
1200 {
1201 /* Take the AS4 from the capability. We must have received the
1202 * capability now! Otherwise we have a asn16 peer who uses
1203 * BGP_AS_TRANS, for some unknown reason.
1204 */
1205 if (as4 == BGP_AS_TRANS)
1206 {
1207 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1208 peer->host);
1209 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1210 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1211 return -1;
1212 }
1213
1214 if (!as4 && BGP_DEBUG (as4, AS4))
1215 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1216 " Odd, but proceeding.", peer->host);
1217 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001218 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001219 "in 2-bytes, very odd peer.", peer->host, as4);
1220 if (as4)
1221 remote_as = as4;
1222 }
1223 else
1224 {
1225 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1226 /* If we have got the capability, peer->as4cap must match remote_as */
1227 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1228 && as4 != remote_as)
1229 {
1230 /* raise error, log this, close session */
1231 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1232 " mismatch with 16bit 'myasn' %u in open",
1233 peer->host, as4, remote_as);
1234 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1235 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1236 return -1;
1237 }
1238 }
1239
paul718e3742002-12-13 20:15:29 +00001240 /* Lookup peer from Open packet. */
1241 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1242 {
1243 int as = 0;
1244
1245 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1246
1247 if (! realpeer)
1248 {
1249 /* Peer's source IP address is check in bgp_accept(), so this
1250 must be AS number mismatch or remote-id configuration
1251 mismatch. */
1252 if (as)
1253 {
1254 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001255 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1256 peer->host, inet_ntoa (remote_id));
1257 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1258 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1259 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001260 }
1261 else
1262 {
1263 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001264 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001265 peer->host, remote_as, peer->as);
1266 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1267 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1268 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001269 }
1270 return -1;
1271 }
1272 }
1273
1274 /* When collision is detected and this peer is closed. Retrun
1275 immidiately. */
1276 ret = bgp_collision_detect (peer, remote_id);
1277 if (ret < 0)
1278 return ret;
1279
pauleb821182004-05-01 08:44:08 +00001280 /* Hack part. */
1281 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1282 {
hasso93406d82005-02-02 14:40:33 +00001283 if (realpeer->status == Established
1284 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1285 {
1286 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1287 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1288 }
1289 else if (ret == 0 && realpeer->status != Active
1290 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001291 && realpeer->status != OpenConfirm
1292 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001293 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001294 /* XXX: This is an awful problem..
1295 *
1296 * According to the RFC we should just let this connection (of the
1297 * accepted 'peer') continue on to Established if the other
1298 * connection (the 'realpeer' one) is in state Connect, and deal
1299 * with the more larval FSM as/when it gets far enough to receive
1300 * an Open. We don't do that though, we instead close the (more
1301 * developed) accepted connection.
1302 *
1303 * This means there's a race, which if hit, can loop:
1304 *
1305 * FSM for A FSM for B
1306 * realpeer accept-peer realpeer accept-peer
1307 *
1308 * Connect Connect
1309 * Active
1310 * OpenSent OpenSent
1311 * <arrive here,
1312 * Notify, delete>
1313 * Idle Active
1314 * OpenSent OpenSent
1315 * <arrive here,
1316 * Notify, delete>
1317 * Idle
1318 * <wait> <wait>
1319 * Connect Connect
1320 *
1321 *
1322 * If both sides are Quagga, they're almost certain to wait for
1323 * the same amount of time of course (which doesn't preclude other
1324 * implementations also waiting for same time). The race is
1325 * exacerbated by high-latency (in bgpd and/or the network).
1326 *
1327 * The reason we do this is because our FSM is tied to our peer
1328 * structure, which carries our configuration information, etc.
1329 * I.e. we can't let the accepted-peer FSM continue on as it is,
1330 * cause it's not associated with any actual peer configuration -
1331 * it's just a dummy.
1332 *
1333 * It's possible we could hack-fix this by just bgp_stop'ing the
1334 * realpeer and continueing on with the 'transfer FSM' below.
1335 * Ideally, we need to seperate FSMs from struct peer.
1336 *
1337 * Setting one side to passive avoids the race, as a workaround.
1338 */
pauleb821182004-05-01 08:44:08 +00001339 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001340 zlog_debug ("%s peer status is %s close connection",
1341 realpeer->host, LOOKUP (bgp_status_msg,
1342 realpeer->status));
1343 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1344 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1345
pauleb821182004-05-01 08:44:08 +00001346 return -1;
1347 }
1348
1349 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001350 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1351 peer->host,
1352 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001353
1354 bgp_stop (realpeer);
1355
1356 /* Transfer file descriptor. */
1357 realpeer->fd = peer->fd;
1358 peer->fd = -1;
1359
1360 /* Transfer input buffer. */
1361 stream_free (realpeer->ibuf);
1362 realpeer->ibuf = peer->ibuf;
1363 realpeer->packet_size = peer->packet_size;
1364 peer->ibuf = NULL;
1365
1366 /* Transfer status. */
1367 realpeer->status = peer->status;
1368 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001369
pauleb821182004-05-01 08:44:08 +00001370 /* peer pointer change. Open packet send to neighbor. */
1371 peer = realpeer;
1372 bgp_open_send (peer);
1373 if (peer->fd < 0)
1374 {
1375 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1376 peer->fd);
1377 return -1;
1378 }
1379 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1380 }
1381
paul718e3742002-12-13 20:15:29 +00001382 /* remote router-id check. */
1383 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001384 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001385 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1386 {
1387 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001388 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001389 peer->host, inet_ntoa (remote_id));
1390 bgp_notify_send_with_data (peer,
1391 BGP_NOTIFY_OPEN_ERR,
1392 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1393 notify_data_remote_id, 4);
1394 return -1;
1395 }
1396
1397 /* Set remote router-id */
1398 peer->remote_id = remote_id;
1399
1400 /* Peer BGP version check. */
1401 if (version != BGP_VERSION_4)
1402 {
paul5228ad22004-06-04 17:58:18 +00001403 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001404 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001405 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001406 peer->host, version, BGP_VERSION_4);
1407 bgp_notify_send_with_data (peer,
1408 BGP_NOTIFY_OPEN_ERR,
1409 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001410 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001411 return -1;
1412 }
1413
1414 /* Check neighbor as number. */
1415 if (remote_as != peer->as)
1416 {
1417 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001418 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001419 peer->host, remote_as, peer->as);
1420 bgp_notify_send_with_data (peer,
1421 BGP_NOTIFY_OPEN_ERR,
1422 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1423 notify_data_remote_as, 2);
1424 return -1;
1425 }
1426
1427 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1428 calculate the value of the Hold Timer by using the smaller of its
1429 configured Hold Time and the Hold Time received in the OPEN message.
1430 The Hold Time MUST be either zero or at least three seconds. An
1431 implementation may reject connections on the basis of the Hold Time. */
1432
1433 if (holdtime < 3 && holdtime != 0)
1434 {
1435 bgp_notify_send (peer,
1436 BGP_NOTIFY_OPEN_ERR,
1437 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1438 return -1;
1439 }
1440
1441 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1442 would be one third of the Hold Time interval. KEEPALIVE messages
1443 MUST NOT be sent more frequently than one per second. An
1444 implementation MAY adjust the rate at which it sends KEEPALIVE
1445 messages as a function of the Hold Time interval. */
1446
1447 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1448 send_holdtime = peer->holdtime;
1449 else
1450 send_holdtime = peer->bgp->default_holdtime;
1451
1452 if (holdtime < send_holdtime)
1453 peer->v_holdtime = holdtime;
1454 else
1455 peer->v_holdtime = send_holdtime;
1456
1457 peer->v_keepalive = peer->v_holdtime / 3;
1458
1459 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001460 if (optlen != 0)
1461 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001462 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001463 {
1464 bgp_notify_send (peer,
1465 BGP_NOTIFY_OPEN_ERR,
1466 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1467 return ret;
1468 }
paul718e3742002-12-13 20:15:29 +00001469 }
1470 else
1471 {
1472 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001473 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001474 peer->host);
1475 }
1476
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001477 /*
1478 * Assume that the peer supports the locally configured set of
1479 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1480 * capabilities, or if 'override-capability' is configured.
1481 */
1482 if (! mp_capability ||
1483 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001484 {
1485 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1486 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1487 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1488 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1489 }
1490
1491 /* Get sockname. */
1492 bgp_getsockname (peer);
1493
1494 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1495
1496 peer->packet_size = 0;
1497 if (peer->ibuf)
1498 stream_reset (peer->ibuf);
1499
1500 return 0;
1501}
1502
1503/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001504static int
paul718e3742002-12-13 20:15:29 +00001505bgp_update_receive (struct peer *peer, bgp_size_t size)
1506{
1507 int ret;
1508 u_char *end;
1509 struct stream *s;
1510 struct attr attr;
1511 bgp_size_t attribute_len;
1512 bgp_size_t update_len;
1513 bgp_size_t withdraw_len;
1514 struct bgp_nlri update;
1515 struct bgp_nlri withdraw;
1516 struct bgp_nlri mp_update;
1517 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001518 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001519
1520 /* Status must be Established. */
1521 if (peer->status != Established)
1522 {
1523 zlog_err ("%s [FSM] Update packet received under status %s",
1524 peer->host, LOOKUP (bgp_status_msg, peer->status));
1525 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1526 return -1;
1527 }
1528
1529 /* Set initial values. */
1530 memset (&attr, 0, sizeof (struct attr));
1531 memset (&update, 0, sizeof (struct bgp_nlri));
1532 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1533 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1534 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1535
1536 s = peer->ibuf;
1537 end = stream_pnt (s) + size;
1538
1539 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1540 Length is too large (i.e., if Unfeasible Routes Length + Total
1541 Attribute Length + 23 exceeds the message Length), then the Error
1542 Subcode is set to Malformed Attribute List. */
1543 if (stream_pnt (s) + 2 > end)
1544 {
1545 zlog_err ("%s [Error] Update packet error"
1546 " (packet length is short for unfeasible length)",
1547 peer->host);
1548 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1549 BGP_NOTIFY_UPDATE_MAL_ATTR);
1550 return -1;
1551 }
1552
1553 /* Unfeasible Route Length. */
1554 withdraw_len = stream_getw (s);
1555
1556 /* Unfeasible Route Length check. */
1557 if (stream_pnt (s) + withdraw_len > end)
1558 {
1559 zlog_err ("%s [Error] Update packet error"
1560 " (packet unfeasible length overflow %d)",
1561 peer->host, withdraw_len);
1562 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1563 BGP_NOTIFY_UPDATE_MAL_ATTR);
1564 return -1;
1565 }
1566
1567 /* Unfeasible Route packet format check. */
1568 if (withdraw_len > 0)
1569 {
1570 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1571 if (ret < 0)
1572 return -1;
1573
1574 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001575 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001576
1577 withdraw.afi = AFI_IP;
1578 withdraw.safi = SAFI_UNICAST;
1579 withdraw.nlri = stream_pnt (s);
1580 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001581 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001582 }
1583
1584 /* Attribute total length check. */
1585 if (stream_pnt (s) + 2 > end)
1586 {
1587 zlog_warn ("%s [Error] Packet Error"
1588 " (update packet is short for attribute length)",
1589 peer->host);
1590 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1591 BGP_NOTIFY_UPDATE_MAL_ATTR);
1592 return -1;
1593 }
1594
1595 /* Fetch attribute total length. */
1596 attribute_len = stream_getw (s);
1597
1598 /* Attribute length check. */
1599 if (stream_pnt (s) + attribute_len > end)
1600 {
1601 zlog_warn ("%s [Error] Packet Error"
1602 " (update packet attribute length overflow %d)",
1603 peer->host, attribute_len);
1604 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1605 BGP_NOTIFY_UPDATE_MAL_ATTR);
1606 return -1;
1607 }
Paul Jakmab881c702010-11-23 16:35:42 +00001608
1609 /* Certain attribute parsing errors should not be considered bad enough
1610 * to reset the session for, most particularly any partial/optional
1611 * attributes that have 'tunneled' over speakers that don't understand
1612 * them. Instead we withdraw only the prefix concerned.
1613 *
1614 * Complicates the flow a little though..
1615 */
1616 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1617 /* This define morphs the update case into a withdraw when lower levels
1618 * have signalled an error condition where this is best.
1619 */
1620#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001621
1622 /* Parse attribute when it exists. */
1623 if (attribute_len)
1624 {
Paul Jakmab881c702010-11-23 16:35:42 +00001625 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
paul718e3742002-12-13 20:15:29 +00001626 &mp_update, &mp_withdraw);
Paul Jakmab881c702010-11-23 16:35:42 +00001627 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
paul718e3742002-12-13 20:15:29 +00001628 return -1;
1629 }
Paul Jakmab881c702010-11-23 16:35:42 +00001630
paul718e3742002-12-13 20:15:29 +00001631 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001632 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1633 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001634 {
paule01f9cb2004-07-09 17:48:53 +00001635 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001636 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1637 ? LOG_ERR : LOG_DEBUG;
1638
1639 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1640 zlog (peer->log, LOG_ERR,
1641 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1642 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001643
1644 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001645 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001646 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001647 }
Paul Jakmab881c702010-11-23 16:35:42 +00001648
paul718e3742002-12-13 20:15:29 +00001649 /* Network Layer Reachability Information. */
1650 update_len = end - stream_pnt (s);
1651
1652 if (update_len)
1653 {
1654 /* Check NLRI packet format and prefix length. */
1655 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1656 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001657 {
1658 bgp_attr_unintern_sub (&attr);
1659 if (attr.extra)
1660 bgp_attr_extra_free (&attr);
1661 return -1;
1662 }
paul718e3742002-12-13 20:15:29 +00001663
1664 /* Set NLRI portion to structure. */
1665 update.afi = AFI_IP;
1666 update.safi = SAFI_UNICAST;
1667 update.nlri = stream_pnt (s);
1668 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001669 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001670 }
1671
1672 /* NLRI is processed only when the peer is configured specific
1673 Address Family and Subsequent Address Family. */
1674 if (peer->afc[AFI_IP][SAFI_UNICAST])
1675 {
1676 if (withdraw.length)
1677 bgp_nlri_parse (peer, NULL, &withdraw);
1678
1679 if (update.length)
1680 {
1681 /* We check well-known attribute only for IPv4 unicast
1682 update. */
1683 ret = bgp_attr_check (peer, &attr);
1684 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001685 {
1686 bgp_attr_unintern_sub (&attr);
1687 if (attr.extra)
1688 bgp_attr_extra_free (&attr);
1689 return -1;
1690 }
paul718e3742002-12-13 20:15:29 +00001691
Paul Jakmab881c702010-11-23 16:35:42 +00001692 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
paul718e3742002-12-13 20:15:29 +00001693 }
paule01f9cb2004-07-09 17:48:53 +00001694
hassof4184462005-02-01 20:13:16 +00001695 if (mp_update.length
1696 && mp_update.afi == AFI_IP
1697 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001698 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
hassof4184462005-02-01 20:13:16 +00001699
1700 if (mp_withdraw.length
1701 && mp_withdraw.afi == AFI_IP
1702 && mp_withdraw.safi == SAFI_UNICAST)
1703 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1704
paule01f9cb2004-07-09 17:48:53 +00001705 if (! attribute_len && ! withdraw_len)
1706 {
1707 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001708 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1709 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001710
hasso93406d82005-02-02 14:40:33 +00001711 /* NSF delete stale route */
1712 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1713 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1714
1715 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001716 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001717 peer->host);
1718 }
paul718e3742002-12-13 20:15:29 +00001719 }
1720 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1721 {
1722 if (mp_update.length
1723 && mp_update.afi == AFI_IP
1724 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001725 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001726
1727 if (mp_withdraw.length
1728 && mp_withdraw.afi == AFI_IP
1729 && mp_withdraw.safi == SAFI_MULTICAST)
1730 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001731
hasso93406d82005-02-02 14:40:33 +00001732 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001733 && mp_withdraw.afi == AFI_IP
1734 && mp_withdraw.safi == SAFI_MULTICAST
1735 && mp_withdraw.length == 0)
1736 {
1737 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001738 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1739 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001740
hasso93406d82005-02-02 14:40:33 +00001741 /* NSF delete stale route */
1742 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1743 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1744
1745 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001746 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 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_IP6][SAFI_UNICAST])
1751 {
1752 if (mp_update.length
1753 && mp_update.afi == AFI_IP6
1754 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001755 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001756
1757 if (mp_withdraw.length
1758 && mp_withdraw.afi == AFI_IP6
1759 && mp_withdraw.safi == SAFI_UNICAST)
1760 bgp_nlri_parse (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_IP6
1764 && mp_withdraw.safi == SAFI_UNICAST
1765 && mp_withdraw.length == 0)
1766 {
1767 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001768 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001769
hasso93406d82005-02-02 14:40:33 +00001770 /* NSF delete stale route */
1771 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1772 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1773
1774 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001775 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001776 peer->host);
1777 }
paul718e3742002-12-13 20:15:29 +00001778 }
1779 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1780 {
1781 if (mp_update.length
1782 && mp_update.afi == AFI_IP6
1783 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001784 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001785
1786 if (mp_withdraw.length
1787 && mp_withdraw.afi == AFI_IP6
1788 && mp_withdraw.safi == SAFI_MULTICAST)
1789 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001790
hasso93406d82005-02-02 14:40:33 +00001791 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001792 && mp_withdraw.afi == AFI_IP6
1793 && mp_withdraw.safi == SAFI_MULTICAST
1794 && mp_withdraw.length == 0)
1795 {
1796 /* End-of-RIB received */
1797
hasso93406d82005-02-02 14:40:33 +00001798 /* NSF delete stale route */
1799 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1800 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1801
paule01f9cb2004-07-09 17:48:53 +00001802 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001803 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001804 peer->host);
1805 }
paul718e3742002-12-13 20:15:29 +00001806 }
1807 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1808 {
1809 if (mp_update.length
1810 && mp_update.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001811 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
Paul Jakmab881c702010-11-23 16:35:42 +00001812 bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001813
1814 if (mp_withdraw.length
1815 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001816 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00001817 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001818
hasso93406d82005-02-02 14:40:33 +00001819 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001820 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001821 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
paule01f9cb2004-07-09 17:48:53 +00001822 && mp_withdraw.length == 0)
1823 {
1824 /* End-of-RIB received */
1825
1826 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001827 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001828 peer->host);
1829 }
paul718e3742002-12-13 20:15:29 +00001830 }
1831
1832 /* Everything is done. We unintern temporary structures which
1833 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001834 bgp_attr_unintern_sub (&attr);
Paul Jakmafb982c22007-05-04 20:15:47 +00001835 if (attr.extra)
Paul Jakmab881c702010-11-23 16:35:42 +00001836 bgp_attr_extra_free (&attr);
1837
paul718e3742002-12-13 20:15:29 +00001838 /* If peering is stopped due to some reason, do not generate BGP
1839 event. */
1840 if (peer->status != Established)
1841 return 0;
1842
1843 /* Increment packet counter. */
1844 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001845 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001846
1847 /* Generate BGP event. */
1848 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1849
1850 return 0;
1851}
1852
1853/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001854static void
paul718e3742002-12-13 20:15:29 +00001855bgp_notify_receive (struct peer *peer, bgp_size_t size)
1856{
1857 struct bgp_notify bgp_notify;
1858
1859 if (peer->notify.data)
1860 {
1861 XFREE (MTYPE_TMP, peer->notify.data);
1862 peer->notify.data = NULL;
1863 peer->notify.length = 0;
1864 }
1865
1866 bgp_notify.code = stream_getc (peer->ibuf);
1867 bgp_notify.subcode = stream_getc (peer->ibuf);
1868 bgp_notify.length = size - 2;
1869 bgp_notify.data = NULL;
1870
1871 /* Preserv notify code and sub code. */
1872 peer->notify.code = bgp_notify.code;
1873 peer->notify.subcode = bgp_notify.subcode;
1874 /* For further diagnostic record returned Data. */
1875 if (bgp_notify.length)
1876 {
1877 peer->notify.length = size - 2;
1878 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1879 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1880 }
1881
1882 /* For debug */
1883 {
1884 int i;
1885 int first = 0;
1886 char c[4];
1887
1888 if (bgp_notify.length)
1889 {
1890 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1891 for (i = 0; i < bgp_notify.length; i++)
1892 if (first)
1893 {
1894 sprintf (c, " %02x", stream_getc (peer->ibuf));
1895 strcat (bgp_notify.data, c);
1896 }
1897 else
1898 {
1899 first = 1;
1900 sprintf (c, "%02x", stream_getc (peer->ibuf));
1901 strcpy (bgp_notify.data, c);
1902 }
1903 }
1904
1905 bgp_notify_print(peer, &bgp_notify, "received");
1906 if (bgp_notify.data)
1907 XFREE (MTYPE_TMP, bgp_notify.data);
1908 }
1909
1910 /* peer count update */
1911 peer->notify_in++;
1912
hassoe0701b72004-05-20 09:19:34 +00001913 if (peer->status == Established)
1914 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1915
paul718e3742002-12-13 20:15:29 +00001916 /* We have to check for Notify with Unsupported Optional Parameter.
1917 in that case we fallback to open without the capability option.
1918 But this done in bgp_stop. We just mark it here to avoid changing
1919 the fsm tables. */
1920 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1921 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1922 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1923
paul718e3742002-12-13 20:15:29 +00001924 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1925}
1926
1927/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001928static void
paul718e3742002-12-13 20:15:29 +00001929bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1930{
1931 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001932 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001933
1934 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1935}
1936
1937/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001938static void
paul718e3742002-12-13 20:15:29 +00001939bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1940{
1941 afi_t afi;
1942 safi_t safi;
1943 u_char reserved;
1944 struct stream *s;
1945
1946 /* If peer does not have the capability, send notification. */
1947 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1948 {
1949 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1950 peer->host);
1951 bgp_notify_send (peer,
1952 BGP_NOTIFY_HEADER_ERR,
1953 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1954 return;
1955 }
1956
1957 /* Status must be Established. */
1958 if (peer->status != Established)
1959 {
1960 plog_err (peer->log,
1961 "%s [Error] Route refresh packet received under status %s",
1962 peer->host, LOOKUP (bgp_status_msg, peer->status));
1963 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1964 return;
1965 }
1966
1967 s = peer->ibuf;
1968
1969 /* Parse packet. */
1970 afi = stream_getw (s);
1971 reserved = stream_getc (s);
1972 safi = stream_getc (s);
1973
1974 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001975 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001976 peer->host, afi, safi);
1977
1978 /* Check AFI and SAFI. */
1979 if ((afi != AFI_IP && afi != AFI_IP6)
1980 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001981 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00001982 {
1983 if (BGP_DEBUG (normal, NORMAL))
1984 {
ajs6b514742004-12-08 21:03:23 +00001985 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001986 peer->host, afi, safi);
1987 }
1988 return;
1989 }
1990
1991 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001992 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00001993 safi = SAFI_MPLS_VPN;
1994
1995 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1996 {
1997 u_char *end;
1998 u_char when_to_refresh;
1999 u_char orf_type;
2000 u_int16_t orf_len;
2001
2002 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2003 {
2004 zlog_info ("%s ORF route refresh length error", peer->host);
2005 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2006 return;
2007 }
2008
2009 when_to_refresh = stream_getc (s);
2010 end = stream_pnt (s) + (size - 5);
2011
Paul Jakma370b64a2007-12-22 16:49:52 +00002012 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002013 {
2014 orf_type = stream_getc (s);
2015 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002016
2017 /* orf_len in bounds? */
2018 if ((stream_pnt (s) + orf_len) > end)
2019 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002020 if (orf_type == ORF_TYPE_PREFIX
2021 || orf_type == ORF_TYPE_PREFIX_OLD)
2022 {
2023 u_char *p_pnt = stream_pnt (s);
2024 u_char *p_end = stream_pnt (s) + orf_len;
2025 struct orf_prefix orfp;
2026 u_char common = 0;
2027 u_int32_t seq;
2028 int psize;
2029 char name[BUFSIZ];
2030 char buf[BUFSIZ];
2031 int ret;
2032
2033 if (BGP_DEBUG (normal, NORMAL))
2034 {
ajs6b514742004-12-08 21:03:23 +00002035 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002036 peer->host, orf_type, orf_len);
2037 }
2038
Paul Jakma370b64a2007-12-22 16:49:52 +00002039 /* we're going to read at least 1 byte of common ORF header,
2040 * and 7 bytes of ORF Address-filter entry from the stream
2041 */
2042 if (orf_len < 7)
2043 break;
2044
paul718e3742002-12-13 20:15:29 +00002045 /* ORF prefix-list name */
2046 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2047
2048 while (p_pnt < p_end)
2049 {
Chris Halld64379e2010-05-14 16:38:39 +04002050 /* If the ORF entry is malformed, want to read as much of it
2051 * as possible without going beyond the bounds of the entry,
2052 * to maximise debug information.
2053 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002054 int ok;
paul718e3742002-12-13 20:15:29 +00002055 memset (&orfp, 0, sizeof (struct orf_prefix));
2056 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002057 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002058 if (common & ORF_COMMON_PART_REMOVE_ALL)
2059 {
2060 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002061 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00002062 prefix_bgp_orf_remove_all (name);
2063 break;
2064 }
Chris Halld64379e2010-05-14 16:38:39 +04002065 ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002066 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002067 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002068 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2069 p_pnt += sizeof (u_int32_t);
2070 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002071 }
2072 else
2073 p_pnt = p_end ;
2074
2075 if ((ok = (p_pnt < p_end)))
2076 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2077 if ((ok = (p_pnt < p_end)))
2078 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2079 if ((ok = (p_pnt < p_end)))
2080 orfp.p.prefixlen = *p_pnt++ ;
2081 orfp.p.family = afi2family (afi); /* afi checked already */
2082
2083 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2084 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2085 {
2086 ok = 0 ;
2087 psize = prefix_blen(&orfp.p) ;
2088 }
2089 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2090 {
2091 ok = 0 ;
2092 psize = p_end - p_pnt ;
2093 }
2094
2095 if (psize > 0)
2096 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002097 p_pnt += psize;
2098
2099 if (BGP_DEBUG (normal, NORMAL))
Chris Halld64379e2010-05-14 16:38:39 +04002100 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
paul718e3742002-12-13 20:15:29 +00002101 peer->host,
2102 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2103 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2104 orfp.seq,
2105 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
Chris Halld64379e2010-05-14 16:38:39 +04002106 orfp.p.prefixlen, orfp.ge, orfp.le,
2107 ok ? "" : " MALFORMED");
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002108
Chris Halld64379e2010-05-14 16:38:39 +04002109 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002110 ret = prefix_bgp_orf_set (name, afi, &orfp,
2111 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2112 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
paul718e3742002-12-13 20:15:29 +00002113
Chris Halld64379e2010-05-14 16:38:39 +04002114 if (!ok || (ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002115 {
2116 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002117 zlog_debug ("%s Received misformatted prefixlist ORF."
2118 " Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002119 prefix_bgp_orf_remove_all (name);
2120 break;
2121 }
2122 }
2123 peer->orf_plist[afi][safi] =
2124 prefix_list_lookup (AFI_ORF_PREFIX, name);
2125 }
paul9985f832005-02-09 15:51:56 +00002126 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002127 }
2128 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002129 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002130 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2131 if (when_to_refresh == REFRESH_DEFER)
2132 return;
2133 }
2134
2135 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2136 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2137 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2138
2139 /* Perform route refreshment to the peer */
2140 bgp_announce_route (peer, afi, safi);
2141}
2142
paul94f2b392005-06-28 12:44:16 +00002143static int
paul718e3742002-12-13 20:15:29 +00002144bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2145{
2146 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002147 struct capability_mp_data mpc;
2148 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002149 u_char action;
2150 struct bgp *bgp;
2151 afi_t afi;
2152 safi_t safi;
2153
2154 bgp = peer->bgp;
2155 end = pnt + length;
2156
2157 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002158 {
paul718e3742002-12-13 20:15:29 +00002159 /* We need at least action, capability code and capability length. */
2160 if (pnt + 3 > end)
2161 {
2162 zlog_info ("%s Capability length error", peer->host);
2163 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2164 return -1;
2165 }
paul718e3742002-12-13 20:15:29 +00002166 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002167 hdr = (struct capability_header *)(pnt + 1);
2168
paul718e3742002-12-13 20:15:29 +00002169 /* Action value check. */
2170 if (action != CAPABILITY_ACTION_SET
2171 && action != CAPABILITY_ACTION_UNSET)
2172 {
2173 zlog_info ("%s Capability Action Value error %d",
2174 peer->host, action);
2175 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2176 return -1;
2177 }
2178
2179 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002180 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002181 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002182
2183 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002184 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002185 {
2186 zlog_info ("%s Capability length error", peer->host);
2187 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2188 return -1;
2189 }
2190
Paul Jakma6d582722007-08-06 15:21:45 +00002191 /* Fetch structure to the byte stream. */
2192 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2193
paul718e3742002-12-13 20:15:29 +00002194 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002195 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002196 {
Paul Jakma6d582722007-08-06 15:21:45 +00002197 afi = ntohs (mpc.afi);
2198 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002199
2200 /* Ignore capability when override-capability is set. */
2201 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2202 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002203
2204 if (!bgp_afi_safi_valid_indices (afi, &safi))
2205 {
2206 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002207 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2208 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002209 continue;
2210 }
2211
paul718e3742002-12-13 20:15:29 +00002212 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002213 if (BGP_DEBUG (normal, NORMAL))
2214 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2215 peer->host,
2216 action == CAPABILITY_ACTION_SET
2217 ? "Advertising" : "Removing",
2218 ntohs(mpc.afi) , mpc.safi);
2219
2220 if (action == CAPABILITY_ACTION_SET)
2221 {
2222 peer->afc_recv[afi][safi] = 1;
2223 if (peer->afc[afi][safi])
2224 {
2225 peer->afc_nego[afi][safi] = 1;
2226 bgp_announce_route (peer, afi, safi);
2227 }
2228 }
2229 else
2230 {
2231 peer->afc_recv[afi][safi] = 0;
2232 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002233
Paul Jakma6d582722007-08-06 15:21:45 +00002234 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002235 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002236 else
2237 BGP_EVENT_ADD (peer, BGP_Stop);
2238 }
paul718e3742002-12-13 20:15:29 +00002239 }
paul718e3742002-12-13 20:15:29 +00002240 else
2241 {
2242 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002243 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002244 }
Paul Jakma6d582722007-08-06 15:21:45 +00002245 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002246 }
2247 return 0;
2248}
2249
Paul Jakma01b7ce22009-06-18 12:34:43 +01002250/* Dynamic Capability is received.
2251 *
2252 * This is exported for unit-test purposes
2253 */
Paul Jakma6d582722007-08-06 15:21:45 +00002254int
paul718e3742002-12-13 20:15:29 +00002255bgp_capability_receive (struct peer *peer, bgp_size_t size)
2256{
2257 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002258
2259 /* Fetch pointer. */
2260 pnt = stream_pnt (peer->ibuf);
2261
2262 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002263 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002264
2265 /* If peer does not have the capability, send notification. */
2266 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2267 {
2268 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2269 peer->host);
2270 bgp_notify_send (peer,
2271 BGP_NOTIFY_HEADER_ERR,
2272 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002273 return -1;
paul718e3742002-12-13 20:15:29 +00002274 }
2275
2276 /* Status must be Established. */
2277 if (peer->status != Established)
2278 {
2279 plog_err (peer->log,
2280 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2281 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002282 return -1;
paul718e3742002-12-13 20:15:29 +00002283 }
2284
2285 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002286 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002287}
2288
2289/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002290static int
paul718e3742002-12-13 20:15:29 +00002291bgp_read_packet (struct peer *peer)
2292{
2293 int nbytes;
2294 int readsize;
2295
paul9985f832005-02-09 15:51:56 +00002296 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002297
2298 /* If size is zero then return. */
2299 if (! readsize)
2300 return 0;
2301
2302 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002303 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002304
2305 /* If read byte is smaller than zero then error occured. */
2306 if (nbytes < 0)
2307 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002308 /* Transient error should retry */
2309 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002310 return -1;
2311
2312 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002313 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002314
2315 if (peer->status == Established)
2316 {
2317 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2318 {
2319 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2320 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2321 }
2322 else
2323 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2324 }
2325
paul718e3742002-12-13 20:15:29 +00002326 BGP_EVENT_ADD (peer, TCP_fatal_error);
2327 return -1;
2328 }
2329
2330 /* When read byte is zero : clear bgp peer and return */
2331 if (nbytes == 0)
2332 {
2333 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002334 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002335 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002336
2337 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002338 {
2339 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2340 {
2341 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2342 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2343 }
2344 else
2345 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2346 }
hassoe0701b72004-05-20 09:19:34 +00002347
paul718e3742002-12-13 20:15:29 +00002348 BGP_EVENT_ADD (peer, TCP_connection_closed);
2349 return -1;
2350 }
2351
2352 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002353 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002354 return -1;
2355
2356 return 0;
2357}
2358
2359/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002360static int
paul718e3742002-12-13 20:15:29 +00002361bgp_marker_all_one (struct stream *s, int length)
2362{
2363 int i;
2364
2365 for (i = 0; i < length; i++)
2366 if (s->data[i] != 0xff)
2367 return 0;
2368
2369 return 1;
2370}
2371
2372/* Starting point of packet process function. */
2373int
2374bgp_read (struct thread *thread)
2375{
2376 int ret;
2377 u_char type = 0;
2378 struct peer *peer;
2379 bgp_size_t size;
2380 char notify_data_length[2];
2381
2382 /* Yes first of all get peer pointer. */
2383 peer = THREAD_ARG (thread);
2384 peer->t_read = NULL;
2385
2386 /* For non-blocking IO check. */
2387 if (peer->status == Connect)
2388 {
2389 bgp_connect_check (peer);
2390 goto done;
2391 }
2392 else
2393 {
pauleb821182004-05-01 08:44:08 +00002394 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002395 {
pauleb821182004-05-01 08:44:08 +00002396 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002397 return -1;
2398 }
pauleb821182004-05-01 08:44:08 +00002399 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002400 }
2401
2402 /* Read packet header to determine type of the packet */
2403 if (peer->packet_size == 0)
2404 peer->packet_size = BGP_HEADER_SIZE;
2405
paul9985f832005-02-09 15:51:56 +00002406 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002407 {
2408 ret = bgp_read_packet (peer);
2409
2410 /* Header read error or partial read packet. */
2411 if (ret < 0)
2412 goto done;
2413
2414 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002415 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002416 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2417 size = stream_getw (peer->ibuf);
2418 type = stream_getc (peer->ibuf);
2419
2420 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002421 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002422 peer->host, type, size - BGP_HEADER_SIZE);
2423
2424 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002425 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002426 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2427 {
2428 bgp_notify_send (peer,
2429 BGP_NOTIFY_HEADER_ERR,
2430 BGP_NOTIFY_HEADER_NOT_SYNC);
2431 goto done;
2432 }
2433
2434 /* BGP type check. */
2435 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2436 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2437 && type != BGP_MSG_ROUTE_REFRESH_NEW
2438 && type != BGP_MSG_ROUTE_REFRESH_OLD
2439 && type != BGP_MSG_CAPABILITY)
2440 {
2441 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002442 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002443 "%s unknown message type 0x%02x",
2444 peer->host, type);
2445 bgp_notify_send_with_data (peer,
2446 BGP_NOTIFY_HEADER_ERR,
2447 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2448 &type, 1);
2449 goto done;
2450 }
2451 /* Mimimum packet length check. */
2452 if ((size < BGP_HEADER_SIZE)
2453 || (size > BGP_MAX_PACKET_SIZE)
2454 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2455 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2456 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2457 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2458 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2459 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2460 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2461 {
2462 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002463 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002464 "%s bad message length - %d for %s",
2465 peer->host, size,
2466 type == 128 ? "ROUTE-REFRESH" :
2467 bgp_type_str[(int) type]);
2468 bgp_notify_send_with_data (peer,
2469 BGP_NOTIFY_HEADER_ERR,
2470 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002471 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002472 goto done;
2473 }
2474
2475 /* Adjust size to message length. */
2476 peer->packet_size = size;
2477 }
2478
2479 ret = bgp_read_packet (peer);
2480 if (ret < 0)
2481 goto done;
2482
2483 /* Get size and type again. */
2484 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2485 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2486
2487 /* BGP packet dump function. */
2488 bgp_dump_packet (peer, type, peer->ibuf);
2489
2490 size = (peer->packet_size - BGP_HEADER_SIZE);
2491
2492 /* Read rest of the packet and call each sort of packet routine */
2493 switch (type)
2494 {
2495 case BGP_MSG_OPEN:
2496 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002497 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002498 break;
2499 case BGP_MSG_UPDATE:
2500 peer->readtime = time(NULL); /* Last read timer reset */
2501 bgp_update_receive (peer, size);
2502 break;
2503 case BGP_MSG_NOTIFY:
2504 bgp_notify_receive (peer, size);
2505 break;
2506 case BGP_MSG_KEEPALIVE:
2507 peer->readtime = time(NULL); /* Last read timer reset */
2508 bgp_keepalive_receive (peer, size);
2509 break;
2510 case BGP_MSG_ROUTE_REFRESH_NEW:
2511 case BGP_MSG_ROUTE_REFRESH_OLD:
2512 peer->refresh_in++;
2513 bgp_route_refresh_receive (peer, size);
2514 break;
2515 case BGP_MSG_CAPABILITY:
2516 peer->dynamic_cap_in++;
2517 bgp_capability_receive (peer, size);
2518 break;
2519 }
2520
2521 /* Clear input buffer. */
2522 peer->packet_size = 0;
2523 if (peer->ibuf)
2524 stream_reset (peer->ibuf);
2525
2526 done:
2527 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2528 {
2529 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002530 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002531 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002532 }
2533 return 0;
2534}