blob: b29bc1f036ef1aa36800ed44339e56bc9e8edc83 [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;
Paul Jakmafb982c22007-05-04 20:15:47 +0000180 if (binfo && binfo->extra)
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000182 tag = binfo->extra->tag;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000183 from = binfo->peer;
184 }
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000185
paul718e3742002-12-13 20:15:29 +0000186 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
187 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000188 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000189 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000190 total_attr_len = bgp_packet_attribute (NULL, peer, s,
191 adv->baa->attr,
192 &rn->p, afi, safi,
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000193 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000194 stream_putw_at (s, pos, total_attr_len);
195 }
196
197 if (afi == AFI_IP && safi == SAFI_UNICAST)
198 stream_put_prefix (s, &rn->p);
199
200 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000201 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000202 peer->host,
203 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
204 rn->p.prefixlen);
205
206 /* Synchnorize attribute. */
207 if (adj->attr)
208 bgp_attr_unintern (adj->attr);
209 else
210 peer->scount[afi][safi]++;
211
212 adj->attr = bgp_attr_intern (adv->baa->attr);
213
214 adv = bgp_advertise_clean (peer, adj, afi, safi);
215
216 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
217 break;
218 }
219
220 if (! stream_empty (s))
221 {
222 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000223 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000224 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000225 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000226 stream_reset (s);
227 return packet;
228 }
229 return NULL;
hasso93406d82005-02-02 14:40:33 +0000230}
paul718e3742002-12-13 20:15:29 +0000231
paul94f2b392005-06-28 12:44:16 +0000232static struct stream *
hasso93406d82005-02-02 14:40:33 +0000233bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
234{
235 struct stream *s;
236 struct stream *packet;
237
Paul Jakma750e8142008-07-22 21:11:48 +0000238 if (DISABLE_BGP_ANNOUNCE)
239 return NULL;
hasso93406d82005-02-02 14:40:33 +0000240
241 if (BGP_DEBUG (normal, NORMAL))
242 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
243
244 s = stream_new (BGP_MAX_PACKET_SIZE);
245
246 /* Make BGP update packet. */
247 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
248
249 /* Unfeasible Routes Length */
250 stream_putw (s, 0);
251
252 if (afi == AFI_IP && safi == SAFI_UNICAST)
253 {
254 /* Total Path Attribute Length */
255 stream_putw (s, 0);
256 }
257 else
258 {
259 /* Total Path Attribute Length */
260 stream_putw (s, 6);
261 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
262 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
263 stream_putc (s, 3);
264 stream_putw (s, afi);
265 stream_putc (s, safi);
266 }
267
268 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000269 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000270 bgp_packet_add (peer, packet);
271 stream_free (s);
272 return packet;
paul718e3742002-12-13 20:15:29 +0000273}
274
275/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000276static struct stream *
paul718e3742002-12-13 20:15:29 +0000277bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
278{
279 struct stream *s;
280 struct stream *packet;
281 struct bgp_adj_out *adj;
282 struct bgp_advertise *adv;
283 struct bgp_node *rn;
284 unsigned long pos;
285 bgp_size_t unfeasible_len;
286 bgp_size_t total_attr_len;
287 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000288
289 s = peer->work;
290 stream_reset (s);
291
292 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
293 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000294 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000295 adj = adv->adj;
296 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000297
298 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000299 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000300 break;
301
302 if (stream_empty (s))
303 {
304 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
305 stream_putw (s, 0);
306 }
307
308 if (afi == AFI_IP && safi == SAFI_UNICAST)
309 stream_put_prefix (s, &rn->p);
310 else
311 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000312 struct prefix_rd *prd = NULL;
313
314 if (rn->prn)
315 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000316 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000317 stream_putw (s, 0);
318 total_attr_len
319 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
320
321 /* Set total path attribute length. */
322 stream_putw_at (s, pos, total_attr_len);
323 }
324
325 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000326 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000327 peer->host,
328 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
329 rn->p.prefixlen);
330
331 peer->scount[afi][safi]--;
332
333 bgp_adj_out_remove (rn, adj, peer, afi, safi);
334 bgp_unlock_node (rn);
335
336 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
337 break;
338 }
339
340 if (! stream_empty (s))
341 {
342 if (afi == AFI_IP && safi == SAFI_UNICAST)
343 {
344 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000345 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000346 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
347 stream_putw (s, 0);
348 }
349 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000350 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000351 bgp_packet_add (peer, packet);
352 stream_reset (s);
353 return packet;
354 }
355
356 return NULL;
357}
358
359void
360bgp_default_update_send (struct peer *peer, struct attr *attr,
361 afi_t afi, safi_t safi, struct peer *from)
362{
363 struct stream *s;
364 struct stream *packet;
365 struct prefix p;
366 unsigned long pos;
367 bgp_size_t total_attr_len;
368 char attrstr[BUFSIZ];
369 char buf[BUFSIZ];
370
Paul Jakma750e8142008-07-22 21:11:48 +0000371 if (DISABLE_BGP_ANNOUNCE)
372 return;
paul718e3742002-12-13 20:15:29 +0000373
374 if (afi == AFI_IP)
375 str2prefix ("0.0.0.0/0", &p);
376#ifdef HAVE_IPV6
377 else
378 str2prefix ("::/0", &p);
379#endif /* HAVE_IPV6 */
380
381 /* Logging the attribute. */
382 if (BGP_DEBUG (update, UPDATE_OUT))
383 {
384 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000385 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000386 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
387 p.prefixlen, attrstr);
388 }
389
390 s = stream_new (BGP_MAX_PACKET_SIZE);
391
392 /* Make BGP update packet. */
393 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
394
395 /* Unfeasible Routes Length. */
396 stream_putw (s, 0);
397
398 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000399 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000400 stream_putw (s, 0);
401 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
402
403 /* Set Total Path Attribute Length. */
404 stream_putw_at (s, pos, total_attr_len);
405
406 /* NLRI set. */
407 if (p.family == AF_INET && safi == SAFI_UNICAST)
408 stream_put_prefix (s, &p);
409
410 /* Set size. */
411 bgp_packet_set_size (s);
412
paule83e2082005-05-19 02:12:25 +0000413 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000414 stream_free (s);
415
416 /* Dump packet if debug option is set. */
417#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000418 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000419#endif /* DEBUG */
420
421 /* Add packet to the peer. */
422 bgp_packet_add (peer, packet);
423
pauleb821182004-05-01 08:44:08 +0000424 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000425}
426
427void
428bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
429{
430 struct stream *s;
431 struct stream *packet;
432 struct prefix p;
433 unsigned long pos;
434 unsigned long cp;
435 bgp_size_t unfeasible_len;
436 bgp_size_t total_attr_len;
437 char buf[BUFSIZ];
438
Paul Jakma750e8142008-07-22 21:11:48 +0000439 if (DISABLE_BGP_ANNOUNCE)
440 return;
paul718e3742002-12-13 20:15:29 +0000441
442 if (afi == AFI_IP)
443 str2prefix ("0.0.0.0/0", &p);
444#ifdef HAVE_IPV6
445 else
446 str2prefix ("::/0", &p);
447#endif /* HAVE_IPV6 */
448
449 total_attr_len = 0;
450 pos = 0;
451
452 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000453 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000454 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
455 p.prefixlen);
456
457 s = stream_new (BGP_MAX_PACKET_SIZE);
458
459 /* Make BGP update packet. */
460 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
461
462 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000463 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000464 stream_putw (s, 0);
465
466 /* Withdrawn Routes. */
467 if (p.family == AF_INET && safi == SAFI_UNICAST)
468 {
469 stream_put_prefix (s, &p);
470
paul9985f832005-02-09 15:51:56 +0000471 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000472
473 /* Set unfeasible len. */
474 stream_putw_at (s, cp, unfeasible_len);
475
476 /* Set total path attribute length. */
477 stream_putw (s, 0);
478 }
479 else
480 {
paul9985f832005-02-09 15:51:56 +0000481 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000482 stream_putw (s, 0);
483 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
484
485 /* Set total path attribute length. */
486 stream_putw_at (s, pos, total_attr_len);
487 }
488
489 bgp_packet_set_size (s);
490
paule83e2082005-05-19 02:12:25 +0000491 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000492 stream_free (s);
493
494 /* Add packet to the peer. */
495 bgp_packet_add (peer, packet);
496
pauleb821182004-05-01 08:44:08 +0000497 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000498}
499
500/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000501static struct stream *
paul718e3742002-12-13 20:15:29 +0000502bgp_write_packet (struct peer *peer)
503{
504 afi_t afi;
505 safi_t safi;
506 struct stream *s = NULL;
507 struct bgp_advertise *adv;
508
509 s = stream_fifo_head (peer->obuf);
510 if (s)
511 return s;
512
513 for (afi = AFI_IP; afi < AFI_MAX; afi++)
514 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
515 {
516 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
517 if (adv)
518 {
519 s = bgp_withdraw_packet (peer, afi, safi);
520 if (s)
521 return s;
522 }
523 }
524
525 for (afi = AFI_IP; afi < AFI_MAX; afi++)
526 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
527 {
528 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
529 if (adv)
530 {
531 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000532 {
533 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
534 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
535 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
536 && safi != SAFI_MPLS_VPN)
537 {
538 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
539 PEER_STATUS_EOR_RECEIVED))
540 s = bgp_update_packet (peer, afi, safi);
541 }
542 else
543 s = bgp_update_packet (peer, afi, safi);
544 }
paul718e3742002-12-13 20:15:29 +0000545
546 if (s)
547 return s;
548 }
hasso93406d82005-02-02 14:40:33 +0000549
550 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
551 {
552 if (peer->afc_nego[afi][safi] && peer->synctime
553 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
554 && safi != SAFI_MPLS_VPN)
555 {
556 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
557 return bgp_update_packet_eor (peer, afi, safi);
558 }
559 }
paul718e3742002-12-13 20:15:29 +0000560 }
561
562 return NULL;
563}
564
565/* Is there partially written packet or updates we can send right
566 now. */
paul94f2b392005-06-28 12:44:16 +0000567static int
paul718e3742002-12-13 20:15:29 +0000568bgp_write_proceed (struct peer *peer)
569{
570 afi_t afi;
571 safi_t safi;
572 struct bgp_advertise *adv;
573
574 if (stream_fifo_head (peer->obuf))
575 return 1;
576
577 for (afi = AFI_IP; afi < AFI_MAX; afi++)
578 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
579 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
580 return 1;
581
582 for (afi = AFI_IP; afi < AFI_MAX; afi++)
583 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
584 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
585 if (adv->binfo->uptime < peer->synctime)
586 return 1;
587
588 return 0;
589}
590
591/* Write packet to the peer. */
592int
593bgp_write (struct thread *thread)
594{
595 struct peer *peer;
596 u_char type;
597 struct stream *s;
598 int num;
paulfd79ac92004-10-13 05:06:08 +0000599 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000600 int write_errno;
601
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;
paula24a7e12005-01-05 08:14:13 +0000622
623 /* XXX: FIXME, the socket should be NONBLOCK from the start
624 * status shouldnt need to be toggled on each write
625 */
626 val = fcntl (peer->fd, F_GETFL, 0);
627 fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
paul718e3742002-12-13 20:15:29 +0000628
629 /* Number of bytes to be sent. */
630 writenum = stream_get_endp (s) - stream_get_getp (s);
631
632 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000633 num = write (peer->fd, STREAM_PNT (s), writenum);
paul718e3742002-12-13 20:15:29 +0000634 write_errno = errno;
paula24a7e12005-01-05 08:14:13 +0000635 fcntl (peer->fd, F_SETFL, val);
paul718e3742002-12-13 20:15:29 +0000636 if (num <= 0)
637 {
638 /* Partial write. */
639 if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
640 break;
641
Paul Jakmadcdf3992006-10-15 23:39:59 +0000642 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000643 return 0;
644 }
645 if (num != writenum)
646 {
paul9985f832005-02-09 15:51:56 +0000647 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000648
649 if (write_errno == EAGAIN)
650 break;
651
652 continue;
653 }
654
655 /* Retrieve BGP packet type. */
656 stream_set_getp (s, BGP_MARKER_SIZE + 2);
657 type = stream_getc (s);
658
659 switch (type)
660 {
661 case BGP_MSG_OPEN:
662 peer->open_out++;
663 break;
664 case BGP_MSG_UPDATE:
665 peer->update_out++;
666 break;
667 case BGP_MSG_NOTIFY:
668 peer->notify_out++;
669 /* Double start timer. */
670 peer->v_start *= 2;
671
672 /* Overflow check. */
673 if (peer->v_start >= (60 * 2))
674 peer->v_start = (60 * 2);
675
Paul Jakmaca058a32006-09-14 02:58:49 +0000676 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000677 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000678 return 0;
paul718e3742002-12-13 20:15:29 +0000679 case BGP_MSG_KEEPALIVE:
680 peer->keepalive_out++;
681 break;
682 case BGP_MSG_ROUTE_REFRESH_NEW:
683 case BGP_MSG_ROUTE_REFRESH_OLD:
684 peer->refresh_out++;
685 break;
686 case BGP_MSG_CAPABILITY:
687 peer->dynamic_cap_out++;
688 break;
689 }
690
691 /* OK we send packet so delete it. */
692 bgp_packet_delete (peer);
693
694 if (++count >= BGP_WRITE_PACKET_MAX)
695 break;
696 }
697
698 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000699 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000700
701 return 0;
702}
703
704/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000705static int
paul718e3742002-12-13 20:15:29 +0000706bgp_write_notify (struct peer *peer)
707{
708 int ret;
709 u_char type;
710 struct stream *s;
711
712 /* There should be at least one packet. */
713 s = stream_fifo_head (peer->obuf);
714 if (!s)
715 return 0;
716 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
717
718 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000719 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000720 if (ret <= 0)
721 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000722 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000723 return 0;
724 }
725
726 /* Retrieve BGP packet type. */
727 stream_set_getp (s, BGP_MARKER_SIZE + 2);
728 type = stream_getc (s);
729
730 assert (type == BGP_MSG_NOTIFY);
731
732 /* Type should be notify. */
733 peer->notify_out++;
734
735 /* Double start timer. */
736 peer->v_start *= 2;
737
738 /* Overflow check. */
739 if (peer->v_start >= (60 * 2))
740 peer->v_start = (60 * 2);
741
Paul Jakmadcdf3992006-10-15 23:39:59 +0000742 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000743
744 return 0;
745}
746
747/* Make keepalive packet and send it to the peer. */
748void
749bgp_keepalive_send (struct peer *peer)
750{
751 struct stream *s;
752 int length;
753
754 s = stream_new (BGP_MAX_PACKET_SIZE);
755
756 /* Make keepalive packet. */
757 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
758
759 /* Set packet size. */
760 length = bgp_packet_set_size (s);
761
762 /* Dump packet if debug option is set. */
763 /* bgp_packet_dump (s); */
764
765 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000766 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000767 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000768 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000769 peer->host, BGP_MSG_KEEPALIVE, length);
770
771 /* Add packet to the peer. */
772 bgp_packet_add (peer, s);
773
pauleb821182004-05-01 08:44:08 +0000774 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000775}
776
777/* Make open packet and send it to the peer. */
778void
779bgp_open_send (struct peer *peer)
780{
781 struct stream *s;
782 int length;
783 u_int16_t send_holdtime;
784 as_t local_as;
785
786 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
787 send_holdtime = peer->holdtime;
788 else
789 send_holdtime = peer->bgp->default_holdtime;
790
791 /* local-as Change */
792 if (peer->change_local_as)
793 local_as = peer->change_local_as;
794 else
795 local_as = peer->local_as;
796
797 s = stream_new (BGP_MAX_PACKET_SIZE);
798
799 /* Make open packet. */
800 bgp_packet_set_marker (s, BGP_MSG_OPEN);
801
802 /* Set open packet values. */
803 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000804 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
805 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000806 stream_putw (s, send_holdtime); /* Hold Time */
807 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
808
809 /* Set capability code. */
810 bgp_open_capability (s, peer);
811
812 /* Set BGP packet length. */
813 length = bgp_packet_set_size (s);
814
815 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400816 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000817 peer->host, BGP_VERSION_4, local_as,
818 send_holdtime, inet_ntoa (peer->local_id));
819
820 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000821 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000822 peer->host, BGP_MSG_OPEN, length);
823
824 /* Dump packet if debug option is set. */
825 /* bgp_packet_dump (s); */
826
827 /* Add packet to the peer. */
828 bgp_packet_add (peer, s);
829
pauleb821182004-05-01 08:44:08 +0000830 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000831}
832
833/* Send BGP notify packet with data potion. */
834void
835bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
836 u_char *data, size_t datalen)
837{
838 struct stream *s;
839 int length;
840
841 /* Allocate new stream. */
842 s = stream_new (BGP_MAX_PACKET_SIZE);
843
844 /* Make nitify packet. */
845 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
846
847 /* Set notify packet values. */
848 stream_putc (s, code); /* BGP notify code */
849 stream_putc (s, sub_code); /* BGP notify sub_code */
850
851 /* If notify data is present. */
852 if (data)
853 stream_write (s, data, datalen);
854
855 /* Set BGP packet length. */
856 length = bgp_packet_set_size (s);
857
858 /* Add packet to the peer. */
859 stream_fifo_clean (peer->obuf);
860 bgp_packet_add (peer, s);
861
862 /* For debug */
863 {
864 struct bgp_notify bgp_notify;
865 int first = 0;
866 int i;
867 char c[4];
868
869 bgp_notify.code = code;
870 bgp_notify.subcode = sub_code;
871 bgp_notify.data = NULL;
872 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
873
874 if (bgp_notify.length)
875 {
876 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
877 for (i = 0; i < bgp_notify.length; i++)
878 if (first)
879 {
880 sprintf (c, " %02x", data[i]);
881 strcat (bgp_notify.data, c);
882 }
883 else
884 {
885 first = 1;
886 sprintf (c, "%02x", data[i]);
887 strcpy (bgp_notify.data, c);
888 }
889 }
890 bgp_notify_print (peer, &bgp_notify, "sending");
891 if (bgp_notify.data)
892 XFREE (MTYPE_TMP, bgp_notify.data);
893 }
894
895 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000896 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000897 peer->host, BGP_MSG_NOTIFY, length);
898
hassoe0701b72004-05-20 09:19:34 +0000899 /* peer reset cause */
900 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
901 {
902 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
903 peer->last_reset = PEER_DOWN_USER_RESET;
904 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
905 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
906 else
907 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
908 }
909
paul718e3742002-12-13 20:15:29 +0000910 /* Call imidiately. */
911 BGP_WRITE_OFF (peer->t_write);
912
913 bgp_write_notify (peer);
914}
915
916/* Send BGP notify packet. */
917void
918bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
919{
920 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
921}
922
paul718e3742002-12-13 20:15:29 +0000923/* Send route refresh message to the peer. */
924void
925bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
926 u_char orf_type, u_char when_to_refresh, int remove)
927{
928 struct stream *s;
929 struct stream *packet;
930 int length;
931 struct bgp_filter *filter;
932 int orf_refresh = 0;
933
Paul Jakma750e8142008-07-22 21:11:48 +0000934 if (DISABLE_BGP_ANNOUNCE)
935 return;
paul718e3742002-12-13 20:15:29 +0000936
937 filter = &peer->filter[afi][safi];
938
939 /* Adjust safi code. */
940 if (safi == SAFI_MPLS_VPN)
941 safi = BGP_SAFI_VPNV4;
942
943 s = stream_new (BGP_MAX_PACKET_SIZE);
944
945 /* Make BGP update packet. */
946 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
947 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
948 else
949 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
950
951 /* Encode Route Refresh message. */
952 stream_putw (s, afi);
953 stream_putc (s, 0);
954 stream_putc (s, safi);
955
956 if (orf_type == ORF_TYPE_PREFIX
957 || orf_type == ORF_TYPE_PREFIX_OLD)
958 if (remove || filter->plist[FILTER_IN].plist)
959 {
960 u_int16_t orf_len;
961 unsigned long orfp;
962
963 orf_refresh = 1;
964 stream_putc (s, when_to_refresh);
965 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000966 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000967 stream_putw (s, 0);
968
969 if (remove)
970 {
971 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
972 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
973 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000974 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000975 peer->host, orf_type,
976 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
977 afi, safi);
978 }
979 else
980 {
981 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
982 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
983 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
984 ORF_COMMON_PART_DENY);
985 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000986 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000987 peer->host, orf_type,
988 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
989 afi, safi);
990 }
991
992 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +0000993 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +0000994 stream_putw_at (s, orfp, orf_len);
995 }
996
997 /* Set packet size. */
998 length = bgp_packet_set_size (s);
999
1000 if (BGP_DEBUG (normal, NORMAL))
1001 {
1002 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001003 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001004 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001005 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001006 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1007 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1008 }
1009
1010 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001011 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001012 stream_free (s);
1013
1014 /* Add packet to the peer. */
1015 bgp_packet_add (peer, packet);
1016
pauleb821182004-05-01 08:44:08 +00001017 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001018}
1019
1020/* Send capability message to the peer. */
1021void
1022bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1023 int capability_code, int action)
1024{
1025 struct stream *s;
1026 struct stream *packet;
1027 int length;
1028
1029 /* Adjust safi code. */
1030 if (safi == SAFI_MPLS_VPN)
1031 safi = BGP_SAFI_VPNV4;
1032
1033 s = stream_new (BGP_MAX_PACKET_SIZE);
1034
1035 /* Make BGP update packet. */
1036 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1037
1038 /* Encode MP_EXT capability. */
1039 if (capability_code == CAPABILITY_CODE_MP)
1040 {
1041 stream_putc (s, action);
1042 stream_putc (s, CAPABILITY_CODE_MP);
1043 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1044 stream_putw (s, afi);
1045 stream_putc (s, 0);
1046 stream_putc (s, safi);
1047
1048 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001049 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001050 peer->host, action == CAPABILITY_ACTION_SET ?
1051 "Advertising" : "Removing", afi, safi);
1052 }
1053
paul718e3742002-12-13 20:15:29 +00001054 /* Set packet size. */
1055 length = bgp_packet_set_size (s);
1056
1057 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001058 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001059 stream_free (s);
1060
1061 /* Add packet to the peer. */
1062 bgp_packet_add (peer, packet);
1063
1064 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001065 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001066 peer->host, BGP_MSG_CAPABILITY, length);
1067
pauleb821182004-05-01 08:44:08 +00001068 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001069}
1070
1071/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001072static int
pauleb821182004-05-01 08:44:08 +00001073bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001074{
pauleb821182004-05-01 08:44:08 +00001075 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001076 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001077 struct bgp *bgp;
1078
1079 bgp = bgp_get_default ();
1080 if (! bgp)
1081 return 0;
1082
1083 /* Upon receipt of an OPEN message, the local system must examine
1084 all of its connections that are in the OpenConfirm state. A BGP
1085 speaker may also examine connections in an OpenSent state if it
1086 knows the BGP Identifier of the peer by means outside of the
1087 protocol. If among these connections there is a connection to a
1088 remote BGP speaker whose BGP Identifier equals the one in the
1089 OPEN message, then the local system performs the following
1090 collision resolution procedure: */
1091
paul1eb8ef22005-04-07 07:30:20 +00001092 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001093 {
1094 /* Under OpenConfirm status, local peer structure already hold
1095 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001096
1097 if (peer != new
1098 && (peer->status == OpenConfirm || peer->status == OpenSent)
1099 && sockunion_same (&peer->su, &new->su))
1100 {
paul718e3742002-12-13 20:15:29 +00001101 /* 1. The BGP Identifier of the local system is compared to
1102 the BGP Identifier of the remote system (as specified in
1103 the OPEN message). */
1104
1105 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1106 {
1107 /* 2. If the value of the local BGP Identifier is less
1108 than the remote one, the local system closes BGP
1109 connection that already exists (the one that is
1110 already in the OpenConfirm state), and accepts BGP
1111 connection initiated by the remote system. */
1112
pauleb821182004-05-01 08:44:08 +00001113 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001114 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001115 return 1;
1116 }
1117 else
1118 {
1119 /* 3. Otherwise, the local system closes newly created
1120 BGP connection (the one associated with the newly
1121 received OPEN message), and continues to use the
1122 existing one (the one that is already in the
1123 OpenConfirm state). */
1124
pauleb821182004-05-01 08:44:08 +00001125 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001126 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1127 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001128 return -1;
1129 }
pauleb821182004-05-01 08:44:08 +00001130 }
1131 }
paul718e3742002-12-13 20:15:29 +00001132 return 0;
1133}
1134
paul94f2b392005-06-28 12:44:16 +00001135static int
paul718e3742002-12-13 20:15:29 +00001136bgp_open_receive (struct peer *peer, bgp_size_t size)
1137{
1138 int ret;
1139 u_char version;
1140 u_char optlen;
1141 u_int16_t holdtime;
1142 u_int16_t send_holdtime;
1143 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001144 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001145 struct peer *realpeer;
1146 struct in_addr remote_id;
1147 int capability;
paul5228ad22004-06-04 17:58:18 +00001148 u_int8_t notify_data_remote_as[2];
1149 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001150
1151 realpeer = NULL;
1152
1153 /* Parse open packet. */
1154 version = stream_getc (peer->ibuf);
1155 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1156 remote_as = stream_getw (peer->ibuf);
1157 holdtime = stream_getw (peer->ibuf);
1158 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1159 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1160
1161 /* Receive OPEN message log */
1162 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001163 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001164 " holdtime %d, id %s",
1165 peer->host, version, remote_as, holdtime,
1166 inet_ntoa (remote_id));
1167
1168 /* BEGIN to read the capability here, but dont do it yet */
1169 capability = 0;
1170 optlen = stream_getc (peer->ibuf);
1171
1172 if (optlen != 0)
1173 {
1174 /* We need the as4 capability value *right now* because
1175 * if it is there, we have not got the remote_as yet, and without
1176 * that we do not know which peer is connecting to us now.
1177 */
1178 as4 = peek_for_as4_capability (peer, optlen);
1179 }
1180
1181 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1182 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1183 {
1184 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1185 peer->host);
1186 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1187 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1188 return -1;
1189 }
1190
1191 if (remote_as == BGP_AS_TRANS)
1192 {
1193 /* Take the AS4 from the capability. We must have received the
1194 * capability now! Otherwise we have a asn16 peer who uses
1195 * BGP_AS_TRANS, for some unknown reason.
1196 */
1197 if (as4 == BGP_AS_TRANS)
1198 {
1199 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1200 peer->host);
1201 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1202 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1203 return -1;
1204 }
1205
1206 if (!as4 && BGP_DEBUG (as4, AS4))
1207 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1208 " Odd, but proceeding.", peer->host);
1209 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001210 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001211 "in 2-bytes, very odd peer.", peer->host, as4);
1212 if (as4)
1213 remote_as = as4;
1214 }
1215 else
1216 {
1217 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1218 /* If we have got the capability, peer->as4cap must match remote_as */
1219 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1220 && as4 != remote_as)
1221 {
1222 /* raise error, log this, close session */
1223 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1224 " mismatch with 16bit 'myasn' %u in open",
1225 peer->host, as4, remote_as);
1226 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1227 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1228 return -1;
1229 }
1230 }
1231
paul718e3742002-12-13 20:15:29 +00001232 /* Lookup peer from Open packet. */
1233 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1234 {
1235 int as = 0;
1236
1237 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1238
1239 if (! realpeer)
1240 {
1241 /* Peer's source IP address is check in bgp_accept(), so this
1242 must be AS number mismatch or remote-id configuration
1243 mismatch. */
1244 if (as)
1245 {
1246 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001247 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1248 peer->host, inet_ntoa (remote_id));
1249 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1250 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1251 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001252 }
1253 else
1254 {
1255 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001256 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001257 peer->host, remote_as, peer->as);
1258 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1259 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1260 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001261 }
1262 return -1;
1263 }
1264 }
1265
1266 /* When collision is detected and this peer is closed. Retrun
1267 immidiately. */
1268 ret = bgp_collision_detect (peer, remote_id);
1269 if (ret < 0)
1270 return ret;
1271
pauleb821182004-05-01 08:44:08 +00001272 /* Hack part. */
1273 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1274 {
hasso93406d82005-02-02 14:40:33 +00001275 if (realpeer->status == Established
1276 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1277 {
1278 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1279 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1280 }
1281 else if (ret == 0 && realpeer->status != Active
1282 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001283 && realpeer->status != OpenConfirm
1284 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001285 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001286 /* XXX: This is an awful problem..
1287 *
1288 * According to the RFC we should just let this connection (of the
1289 * accepted 'peer') continue on to Established if the other
1290 * connection (the 'realpeer' one) is in state Connect, and deal
1291 * with the more larval FSM as/when it gets far enough to receive
1292 * an Open. We don't do that though, we instead close the (more
1293 * developed) accepted connection.
1294 *
1295 * This means there's a race, which if hit, can loop:
1296 *
1297 * FSM for A FSM for B
1298 * realpeer accept-peer realpeer accept-peer
1299 *
1300 * Connect Connect
1301 * Active
1302 * OpenSent OpenSent
1303 * <arrive here,
1304 * Notify, delete>
1305 * Idle Active
1306 * OpenSent OpenSent
1307 * <arrive here,
1308 * Notify, delete>
1309 * Idle
1310 * <wait> <wait>
1311 * Connect Connect
1312 *
1313 *
1314 * If both sides are Quagga, they're almost certain to wait for
1315 * the same amount of time of course (which doesn't preclude other
1316 * implementations also waiting for same time). The race is
1317 * exacerbated by high-latency (in bgpd and/or the network).
1318 *
1319 * The reason we do this is because our FSM is tied to our peer
1320 * structure, which carries our configuration information, etc.
1321 * I.e. we can't let the accepted-peer FSM continue on as it is,
1322 * cause it's not associated with any actual peer configuration -
1323 * it's just a dummy.
1324 *
1325 * It's possible we could hack-fix this by just bgp_stop'ing the
1326 * realpeer and continueing on with the 'transfer FSM' below.
1327 * Ideally, we need to seperate FSMs from struct peer.
1328 *
1329 * Setting one side to passive avoids the race, as a workaround.
1330 */
pauleb821182004-05-01 08:44:08 +00001331 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001332 zlog_debug ("%s peer status is %s close connection",
1333 realpeer->host, LOOKUP (bgp_status_msg,
1334 realpeer->status));
1335 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1336 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1337
pauleb821182004-05-01 08:44:08 +00001338 return -1;
1339 }
1340
1341 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001342 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1343 peer->host,
1344 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001345
1346 bgp_stop (realpeer);
1347
1348 /* Transfer file descriptor. */
1349 realpeer->fd = peer->fd;
1350 peer->fd = -1;
1351
1352 /* Transfer input buffer. */
1353 stream_free (realpeer->ibuf);
1354 realpeer->ibuf = peer->ibuf;
1355 realpeer->packet_size = peer->packet_size;
1356 peer->ibuf = NULL;
1357
1358 /* Transfer status. */
1359 realpeer->status = peer->status;
1360 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001361
pauleb821182004-05-01 08:44:08 +00001362 /* peer pointer change. Open packet send to neighbor. */
1363 peer = realpeer;
1364 bgp_open_send (peer);
1365 if (peer->fd < 0)
1366 {
1367 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1368 peer->fd);
1369 return -1;
1370 }
1371 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1372 }
1373
paul718e3742002-12-13 20:15:29 +00001374 /* remote router-id check. */
1375 if (remote_id.s_addr == 0
1376 || ntohl (remote_id.s_addr) >= 0xe0000000
1377 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1378 {
1379 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001380 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001381 peer->host, inet_ntoa (remote_id));
1382 bgp_notify_send_with_data (peer,
1383 BGP_NOTIFY_OPEN_ERR,
1384 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1385 notify_data_remote_id, 4);
1386 return -1;
1387 }
1388
1389 /* Set remote router-id */
1390 peer->remote_id = remote_id;
1391
1392 /* Peer BGP version check. */
1393 if (version != BGP_VERSION_4)
1394 {
paul5228ad22004-06-04 17:58:18 +00001395 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001396 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001397 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001398 peer->host, version, BGP_VERSION_4);
1399 bgp_notify_send_with_data (peer,
1400 BGP_NOTIFY_OPEN_ERR,
1401 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001402 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001403 return -1;
1404 }
1405
1406 /* Check neighbor as number. */
1407 if (remote_as != peer->as)
1408 {
1409 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001410 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001411 peer->host, remote_as, peer->as);
1412 bgp_notify_send_with_data (peer,
1413 BGP_NOTIFY_OPEN_ERR,
1414 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1415 notify_data_remote_as, 2);
1416 return -1;
1417 }
1418
1419 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1420 calculate the value of the Hold Timer by using the smaller of its
1421 configured Hold Time and the Hold Time received in the OPEN message.
1422 The Hold Time MUST be either zero or at least three seconds. An
1423 implementation may reject connections on the basis of the Hold Time. */
1424
1425 if (holdtime < 3 && holdtime != 0)
1426 {
1427 bgp_notify_send (peer,
1428 BGP_NOTIFY_OPEN_ERR,
1429 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1430 return -1;
1431 }
1432
1433 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1434 would be one third of the Hold Time interval. KEEPALIVE messages
1435 MUST NOT be sent more frequently than one per second. An
1436 implementation MAY adjust the rate at which it sends KEEPALIVE
1437 messages as a function of the Hold Time interval. */
1438
1439 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1440 send_holdtime = peer->holdtime;
1441 else
1442 send_holdtime = peer->bgp->default_holdtime;
1443
1444 if (holdtime < send_holdtime)
1445 peer->v_holdtime = holdtime;
1446 else
1447 peer->v_holdtime = send_holdtime;
1448
1449 peer->v_keepalive = peer->v_holdtime / 3;
1450
1451 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001452 if (optlen != 0)
1453 {
1454 ret = bgp_open_option_parse (peer, optlen, &capability);
1455 if (ret < 0)
1456 return ret;
paul718e3742002-12-13 20:15:29 +00001457 }
1458 else
1459 {
1460 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001461 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001462 peer->host);
1463 }
1464
1465 /* Override capability. */
1466 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1467 {
1468 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1469 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1470 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1471 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1472 }
1473
1474 /* Get sockname. */
1475 bgp_getsockname (peer);
1476
1477 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1478
1479 peer->packet_size = 0;
1480 if (peer->ibuf)
1481 stream_reset (peer->ibuf);
1482
1483 return 0;
1484}
1485
1486/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001487static int
paul718e3742002-12-13 20:15:29 +00001488bgp_update_receive (struct peer *peer, bgp_size_t size)
1489{
1490 int ret;
1491 u_char *end;
1492 struct stream *s;
1493 struct attr attr;
1494 bgp_size_t attribute_len;
1495 bgp_size_t update_len;
1496 bgp_size_t withdraw_len;
1497 struct bgp_nlri update;
1498 struct bgp_nlri withdraw;
1499 struct bgp_nlri mp_update;
1500 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001501 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001502
1503 /* Status must be Established. */
1504 if (peer->status != Established)
1505 {
1506 zlog_err ("%s [FSM] Update packet received under status %s",
1507 peer->host, LOOKUP (bgp_status_msg, peer->status));
1508 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1509 return -1;
1510 }
1511
1512 /* Set initial values. */
1513 memset (&attr, 0, sizeof (struct attr));
1514 memset (&update, 0, sizeof (struct bgp_nlri));
1515 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1516 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1517 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1518
1519 s = peer->ibuf;
1520 end = stream_pnt (s) + size;
1521
1522 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1523 Length is too large (i.e., if Unfeasible Routes Length + Total
1524 Attribute Length + 23 exceeds the message Length), then the Error
1525 Subcode is set to Malformed Attribute List. */
1526 if (stream_pnt (s) + 2 > end)
1527 {
1528 zlog_err ("%s [Error] Update packet error"
1529 " (packet length is short for unfeasible length)",
1530 peer->host);
1531 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1532 BGP_NOTIFY_UPDATE_MAL_ATTR);
1533 return -1;
1534 }
1535
1536 /* Unfeasible Route Length. */
1537 withdraw_len = stream_getw (s);
1538
1539 /* Unfeasible Route Length check. */
1540 if (stream_pnt (s) + withdraw_len > end)
1541 {
1542 zlog_err ("%s [Error] Update packet error"
1543 " (packet unfeasible length overflow %d)",
1544 peer->host, withdraw_len);
1545 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1546 BGP_NOTIFY_UPDATE_MAL_ATTR);
1547 return -1;
1548 }
1549
1550 /* Unfeasible Route packet format check. */
1551 if (withdraw_len > 0)
1552 {
1553 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1554 if (ret < 0)
1555 return -1;
1556
1557 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001558 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001559
1560 withdraw.afi = AFI_IP;
1561 withdraw.safi = SAFI_UNICAST;
1562 withdraw.nlri = stream_pnt (s);
1563 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001564 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001565 }
1566
1567 /* Attribute total length check. */
1568 if (stream_pnt (s) + 2 > end)
1569 {
1570 zlog_warn ("%s [Error] Packet Error"
1571 " (update packet is short for attribute length)",
1572 peer->host);
1573 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1574 BGP_NOTIFY_UPDATE_MAL_ATTR);
1575 return -1;
1576 }
1577
1578 /* Fetch attribute total length. */
1579 attribute_len = stream_getw (s);
1580
1581 /* Attribute length check. */
1582 if (stream_pnt (s) + attribute_len > end)
1583 {
1584 zlog_warn ("%s [Error] Packet Error"
1585 " (update packet attribute length overflow %d)",
1586 peer->host, attribute_len);
1587 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1588 BGP_NOTIFY_UPDATE_MAL_ATTR);
1589 return -1;
1590 }
1591
1592 /* Parse attribute when it exists. */
1593 if (attribute_len)
1594 {
1595 ret = bgp_attr_parse (peer, &attr, attribute_len,
1596 &mp_update, &mp_withdraw);
1597 if (ret < 0)
1598 return -1;
1599 }
1600
1601 /* Logging the attribute. */
1602 if (BGP_DEBUG (update, UPDATE_IN))
1603 {
paule01f9cb2004-07-09 17:48:53 +00001604 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1605
1606 if (ret)
ajs6b514742004-12-08 21:03:23 +00001607 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001608 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001609 }
1610
1611 /* Network Layer Reachability Information. */
1612 update_len = end - stream_pnt (s);
1613
1614 if (update_len)
1615 {
1616 /* Check NLRI packet format and prefix length. */
1617 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1618 if (ret < 0)
1619 return -1;
1620
1621 /* Set NLRI portion to structure. */
1622 update.afi = AFI_IP;
1623 update.safi = SAFI_UNICAST;
1624 update.nlri = stream_pnt (s);
1625 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001626 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001627 }
1628
1629 /* NLRI is processed only when the peer is configured specific
1630 Address Family and Subsequent Address Family. */
1631 if (peer->afc[AFI_IP][SAFI_UNICAST])
1632 {
1633 if (withdraw.length)
1634 bgp_nlri_parse (peer, NULL, &withdraw);
1635
1636 if (update.length)
1637 {
1638 /* We check well-known attribute only for IPv4 unicast
1639 update. */
1640 ret = bgp_attr_check (peer, &attr);
1641 if (ret < 0)
1642 return -1;
1643
1644 bgp_nlri_parse (peer, &attr, &update);
1645 }
paule01f9cb2004-07-09 17:48:53 +00001646
hassof4184462005-02-01 20:13:16 +00001647 if (mp_update.length
1648 && mp_update.afi == AFI_IP
1649 && mp_update.safi == SAFI_UNICAST)
1650 bgp_nlri_parse (peer, &attr, &mp_update);
1651
1652 if (mp_withdraw.length
1653 && mp_withdraw.afi == AFI_IP
1654 && mp_withdraw.safi == SAFI_UNICAST)
1655 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1656
paule01f9cb2004-07-09 17:48:53 +00001657 if (! attribute_len && ! withdraw_len)
1658 {
1659 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001660 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1661 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001662
hasso93406d82005-02-02 14:40:33 +00001663 /* NSF delete stale route */
1664 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1665 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1666
1667 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001668 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001669 peer->host);
1670 }
paul718e3742002-12-13 20:15:29 +00001671 }
1672 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1673 {
1674 if (mp_update.length
1675 && mp_update.afi == AFI_IP
1676 && mp_update.safi == SAFI_MULTICAST)
1677 bgp_nlri_parse (peer, &attr, &mp_update);
1678
1679 if (mp_withdraw.length
1680 && mp_withdraw.afi == AFI_IP
1681 && mp_withdraw.safi == SAFI_MULTICAST)
1682 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001683
hasso93406d82005-02-02 14:40:33 +00001684 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001685 && mp_withdraw.afi == AFI_IP
1686 && mp_withdraw.safi == SAFI_MULTICAST
1687 && mp_withdraw.length == 0)
1688 {
1689 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001690 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1691 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001692
hasso93406d82005-02-02 14:40:33 +00001693 /* NSF delete stale route */
1694 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1695 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1696
1697 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001698 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001699 peer->host);
1700 }
paul718e3742002-12-13 20:15:29 +00001701 }
1702 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1703 {
1704 if (mp_update.length
1705 && mp_update.afi == AFI_IP6
1706 && mp_update.safi == SAFI_UNICAST)
1707 bgp_nlri_parse (peer, &attr, &mp_update);
1708
1709 if (mp_withdraw.length
1710 && mp_withdraw.afi == AFI_IP6
1711 && mp_withdraw.safi == SAFI_UNICAST)
1712 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001713
hasso93406d82005-02-02 14:40:33 +00001714 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001715 && mp_withdraw.afi == AFI_IP6
1716 && mp_withdraw.safi == SAFI_UNICAST
1717 && mp_withdraw.length == 0)
1718 {
1719 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001720 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001721
hasso93406d82005-02-02 14:40:33 +00001722 /* NSF delete stale route */
1723 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1724 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1725
1726 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001727 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001728 peer->host);
1729 }
paul718e3742002-12-13 20:15:29 +00001730 }
1731 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1732 {
1733 if (mp_update.length
1734 && mp_update.afi == AFI_IP6
1735 && mp_update.safi == SAFI_MULTICAST)
1736 bgp_nlri_parse (peer, &attr, &mp_update);
1737
1738 if (mp_withdraw.length
1739 && mp_withdraw.afi == AFI_IP6
1740 && mp_withdraw.safi == SAFI_MULTICAST)
1741 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001742
hasso93406d82005-02-02 14:40:33 +00001743 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001744 && mp_withdraw.afi == AFI_IP6
1745 && mp_withdraw.safi == SAFI_MULTICAST
1746 && mp_withdraw.length == 0)
1747 {
1748 /* End-of-RIB received */
1749
hasso93406d82005-02-02 14:40:33 +00001750 /* NSF delete stale route */
1751 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1752 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1753
paule01f9cb2004-07-09 17:48:53 +00001754 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001755 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001756 peer->host);
1757 }
paul718e3742002-12-13 20:15:29 +00001758 }
1759 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1760 {
1761 if (mp_update.length
1762 && mp_update.afi == AFI_IP
1763 && mp_update.safi == BGP_SAFI_VPNV4)
1764 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1765
1766 if (mp_withdraw.length
1767 && mp_withdraw.afi == AFI_IP
1768 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1769 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001770
hasso93406d82005-02-02 14:40:33 +00001771 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001772 && mp_withdraw.afi == AFI_IP
1773 && mp_withdraw.safi == BGP_SAFI_VPNV4
1774 && mp_withdraw.length == 0)
1775 {
1776 /* End-of-RIB received */
1777
1778 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001779 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001780 peer->host);
1781 }
paul718e3742002-12-13 20:15:29 +00001782 }
1783
1784 /* Everything is done. We unintern temporary structures which
1785 interned in bgp_attr_parse(). */
1786 if (attr.aspath)
1787 aspath_unintern (attr.aspath);
1788 if (attr.community)
1789 community_unintern (attr.community);
Paul Jakmafb982c22007-05-04 20:15:47 +00001790 if (attr.extra)
1791 {
1792 if (attr.extra->ecommunity)
1793 ecommunity_unintern (attr.extra->ecommunity);
1794 if (attr.extra->cluster)
1795 cluster_unintern (attr.extra->cluster);
1796 if (attr.extra->transit)
1797 transit_unintern (attr.extra->transit);
1798 bgp_attr_extra_free (&attr);
1799 }
paul718e3742002-12-13 20:15:29 +00001800
1801 /* If peering is stopped due to some reason, do not generate BGP
1802 event. */
1803 if (peer->status != Established)
1804 return 0;
1805
1806 /* Increment packet counter. */
1807 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001808 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001809
1810 /* Generate BGP event. */
1811 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1812
1813 return 0;
1814}
1815
1816/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001817static void
paul718e3742002-12-13 20:15:29 +00001818bgp_notify_receive (struct peer *peer, bgp_size_t size)
1819{
1820 struct bgp_notify bgp_notify;
1821
1822 if (peer->notify.data)
1823 {
1824 XFREE (MTYPE_TMP, peer->notify.data);
1825 peer->notify.data = NULL;
1826 peer->notify.length = 0;
1827 }
1828
1829 bgp_notify.code = stream_getc (peer->ibuf);
1830 bgp_notify.subcode = stream_getc (peer->ibuf);
1831 bgp_notify.length = size - 2;
1832 bgp_notify.data = NULL;
1833
1834 /* Preserv notify code and sub code. */
1835 peer->notify.code = bgp_notify.code;
1836 peer->notify.subcode = bgp_notify.subcode;
1837 /* For further diagnostic record returned Data. */
1838 if (bgp_notify.length)
1839 {
1840 peer->notify.length = size - 2;
1841 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1842 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1843 }
1844
1845 /* For debug */
1846 {
1847 int i;
1848 int first = 0;
1849 char c[4];
1850
1851 if (bgp_notify.length)
1852 {
1853 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1854 for (i = 0; i < bgp_notify.length; i++)
1855 if (first)
1856 {
1857 sprintf (c, " %02x", stream_getc (peer->ibuf));
1858 strcat (bgp_notify.data, c);
1859 }
1860 else
1861 {
1862 first = 1;
1863 sprintf (c, "%02x", stream_getc (peer->ibuf));
1864 strcpy (bgp_notify.data, c);
1865 }
1866 }
1867
1868 bgp_notify_print(peer, &bgp_notify, "received");
1869 if (bgp_notify.data)
1870 XFREE (MTYPE_TMP, bgp_notify.data);
1871 }
1872
1873 /* peer count update */
1874 peer->notify_in++;
1875
hassoe0701b72004-05-20 09:19:34 +00001876 if (peer->status == Established)
1877 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1878
paul718e3742002-12-13 20:15:29 +00001879 /* We have to check for Notify with Unsupported Optional Parameter.
1880 in that case we fallback to open without the capability option.
1881 But this done in bgp_stop. We just mark it here to avoid changing
1882 the fsm tables. */
1883 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1884 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1885 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1886
1887 /* Also apply to Unsupported Capability until remote router support
1888 capability. */
1889 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1890 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
1891 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1892
1893 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1894}
1895
1896/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001897static void
paul718e3742002-12-13 20:15:29 +00001898bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1899{
1900 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001901 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001902
1903 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1904}
1905
1906/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001907static void
paul718e3742002-12-13 20:15:29 +00001908bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1909{
1910 afi_t afi;
1911 safi_t safi;
1912 u_char reserved;
1913 struct stream *s;
1914
1915 /* If peer does not have the capability, send notification. */
1916 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1917 {
1918 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1919 peer->host);
1920 bgp_notify_send (peer,
1921 BGP_NOTIFY_HEADER_ERR,
1922 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1923 return;
1924 }
1925
1926 /* Status must be Established. */
1927 if (peer->status != Established)
1928 {
1929 plog_err (peer->log,
1930 "%s [Error] Route refresh packet received under status %s",
1931 peer->host, LOOKUP (bgp_status_msg, peer->status));
1932 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1933 return;
1934 }
1935
1936 s = peer->ibuf;
1937
1938 /* Parse packet. */
1939 afi = stream_getw (s);
1940 reserved = stream_getc (s);
1941 safi = stream_getc (s);
1942
1943 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001944 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001945 peer->host, afi, safi);
1946
1947 /* Check AFI and SAFI. */
1948 if ((afi != AFI_IP && afi != AFI_IP6)
1949 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1950 && safi != BGP_SAFI_VPNV4))
1951 {
1952 if (BGP_DEBUG (normal, NORMAL))
1953 {
ajs6b514742004-12-08 21:03:23 +00001954 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001955 peer->host, afi, safi);
1956 }
1957 return;
1958 }
1959
1960 /* Adjust safi code. */
1961 if (safi == BGP_SAFI_VPNV4)
1962 safi = SAFI_MPLS_VPN;
1963
1964 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1965 {
1966 u_char *end;
1967 u_char when_to_refresh;
1968 u_char orf_type;
1969 u_int16_t orf_len;
1970
1971 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1972 {
1973 zlog_info ("%s ORF route refresh length error", peer->host);
1974 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1975 return;
1976 }
1977
1978 when_to_refresh = stream_getc (s);
1979 end = stream_pnt (s) + (size - 5);
1980
Paul Jakma370b64a2007-12-22 16:49:52 +00001981 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00001982 {
1983 orf_type = stream_getc (s);
1984 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00001985
1986 /* orf_len in bounds? */
1987 if ((stream_pnt (s) + orf_len) > end)
1988 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00001989 if (orf_type == ORF_TYPE_PREFIX
1990 || orf_type == ORF_TYPE_PREFIX_OLD)
1991 {
1992 u_char *p_pnt = stream_pnt (s);
1993 u_char *p_end = stream_pnt (s) + orf_len;
1994 struct orf_prefix orfp;
1995 u_char common = 0;
1996 u_int32_t seq;
1997 int psize;
1998 char name[BUFSIZ];
1999 char buf[BUFSIZ];
2000 int ret;
2001
2002 if (BGP_DEBUG (normal, NORMAL))
2003 {
ajs6b514742004-12-08 21:03:23 +00002004 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002005 peer->host, orf_type, orf_len);
2006 }
2007
Paul Jakma370b64a2007-12-22 16:49:52 +00002008 /* we're going to read at least 1 byte of common ORF header,
2009 * and 7 bytes of ORF Address-filter entry from the stream
2010 */
2011 if (orf_len < 7)
2012 break;
2013
paul718e3742002-12-13 20:15:29 +00002014 /* ORF prefix-list name */
2015 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2016
2017 while (p_pnt < p_end)
2018 {
2019 memset (&orfp, 0, sizeof (struct orf_prefix));
2020 common = *p_pnt++;
2021 if (common & ORF_COMMON_PART_REMOVE_ALL)
2022 {
2023 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002024 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00002025 prefix_bgp_orf_remove_all (name);
2026 break;
2027 }
2028 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2029 p_pnt += sizeof (u_int32_t);
2030 orfp.seq = ntohl (seq);
2031 orfp.ge = *p_pnt++;
2032 orfp.le = *p_pnt++;
2033 orfp.p.prefixlen = *p_pnt++;
2034 orfp.p.family = afi2family (afi);
2035 psize = PSIZE (orfp.p.prefixlen);
2036 memcpy (&orfp.p.u.prefix, p_pnt, psize);
2037 p_pnt += psize;
2038
2039 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002040 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
paul718e3742002-12-13 20:15:29 +00002041 peer->host,
2042 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2043 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2044 orfp.seq,
2045 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
2046 orfp.p.prefixlen, orfp.ge, orfp.le);
2047
2048 ret = prefix_bgp_orf_set (name, afi, &orfp,
2049 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2050 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
2051
2052 if (ret != CMD_SUCCESS)
2053 {
2054 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002055 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002056 prefix_bgp_orf_remove_all (name);
2057 break;
2058 }
2059 }
2060 peer->orf_plist[afi][safi] =
2061 prefix_list_lookup (AFI_ORF_PREFIX, name);
2062 }
paul9985f832005-02-09 15:51:56 +00002063 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002064 }
2065 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002066 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002067 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2068 if (when_to_refresh == REFRESH_DEFER)
2069 return;
2070 }
2071
2072 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2073 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2074 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2075
2076 /* Perform route refreshment to the peer */
2077 bgp_announce_route (peer, afi, safi);
2078}
2079
paul94f2b392005-06-28 12:44:16 +00002080static int
paul718e3742002-12-13 20:15:29 +00002081bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2082{
2083 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002084 struct capability_mp_data mpc;
2085 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002086 u_char action;
2087 struct bgp *bgp;
2088 afi_t afi;
2089 safi_t safi;
2090
2091 bgp = peer->bgp;
2092 end = pnt + length;
2093
2094 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002095 {
paul718e3742002-12-13 20:15:29 +00002096 /* We need at least action, capability code and capability length. */
2097 if (pnt + 3 > end)
2098 {
2099 zlog_info ("%s Capability length error", peer->host);
2100 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2101 return -1;
2102 }
paul718e3742002-12-13 20:15:29 +00002103 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002104 hdr = (struct capability_header *)(pnt + 1);
2105
paul718e3742002-12-13 20:15:29 +00002106 /* Action value check. */
2107 if (action != CAPABILITY_ACTION_SET
2108 && action != CAPABILITY_ACTION_UNSET)
2109 {
2110 zlog_info ("%s Capability Action Value error %d",
2111 peer->host, action);
2112 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2113 return -1;
2114 }
2115
2116 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002117 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002118 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002119
2120 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002121 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002122 {
2123 zlog_info ("%s Capability length error", peer->host);
2124 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2125 return -1;
2126 }
2127
Paul Jakma6d582722007-08-06 15:21:45 +00002128 /* Fetch structure to the byte stream. */
2129 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2130
paul718e3742002-12-13 20:15:29 +00002131 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002132 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002133 {
Paul Jakma6d582722007-08-06 15:21:45 +00002134 afi = ntohs (mpc.afi);
2135 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002136
2137 /* Ignore capability when override-capability is set. */
2138 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2139 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002140
2141 if (!bgp_afi_safi_valid_indices (afi, &safi))
2142 {
2143 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002144 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2145 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002146 continue;
2147 }
2148
paul718e3742002-12-13 20:15:29 +00002149 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002150 if (BGP_DEBUG (normal, NORMAL))
2151 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2152 peer->host,
2153 action == CAPABILITY_ACTION_SET
2154 ? "Advertising" : "Removing",
2155 ntohs(mpc.afi) , mpc.safi);
2156
2157 if (action == CAPABILITY_ACTION_SET)
2158 {
2159 peer->afc_recv[afi][safi] = 1;
2160 if (peer->afc[afi][safi])
2161 {
2162 peer->afc_nego[afi][safi] = 1;
2163 bgp_announce_route (peer, afi, safi);
2164 }
2165 }
2166 else
2167 {
2168 peer->afc_recv[afi][safi] = 0;
2169 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002170
Paul Jakma6d582722007-08-06 15:21:45 +00002171 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002172 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002173 else
2174 BGP_EVENT_ADD (peer, BGP_Stop);
2175 }
paul718e3742002-12-13 20:15:29 +00002176 }
paul718e3742002-12-13 20:15:29 +00002177 else
2178 {
2179 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002180 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002181 }
Paul Jakma6d582722007-08-06 15:21:45 +00002182 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002183 }
2184 return 0;
2185}
2186
Paul Jakma01b7ce22009-06-18 12:34:43 +01002187/* Dynamic Capability is received.
2188 *
2189 * This is exported for unit-test purposes
2190 */
Paul Jakma6d582722007-08-06 15:21:45 +00002191int
paul718e3742002-12-13 20:15:29 +00002192bgp_capability_receive (struct peer *peer, bgp_size_t size)
2193{
2194 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002195
2196 /* Fetch pointer. */
2197 pnt = stream_pnt (peer->ibuf);
2198
2199 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002200 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002201
2202 /* If peer does not have the capability, send notification. */
2203 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2204 {
2205 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2206 peer->host);
2207 bgp_notify_send (peer,
2208 BGP_NOTIFY_HEADER_ERR,
2209 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002210 return -1;
paul718e3742002-12-13 20:15:29 +00002211 }
2212
2213 /* Status must be Established. */
2214 if (peer->status != Established)
2215 {
2216 plog_err (peer->log,
2217 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2218 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002219 return -1;
paul718e3742002-12-13 20:15:29 +00002220 }
2221
2222 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002223 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002224}
2225
2226/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002227static int
paul718e3742002-12-13 20:15:29 +00002228bgp_read_packet (struct peer *peer)
2229{
2230 int nbytes;
2231 int readsize;
2232
paul9985f832005-02-09 15:51:56 +00002233 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002234
2235 /* If size is zero then return. */
2236 if (! readsize)
2237 return 0;
2238
2239 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002240 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002241
2242 /* If read byte is smaller than zero then error occured. */
2243 if (nbytes < 0)
2244 {
2245 if (errno == EAGAIN)
2246 return -1;
2247
2248 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002249 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002250
2251 if (peer->status == Established)
2252 {
2253 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2254 {
2255 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2256 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2257 }
2258 else
2259 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2260 }
2261
paul718e3742002-12-13 20:15:29 +00002262 BGP_EVENT_ADD (peer, TCP_fatal_error);
2263 return -1;
2264 }
2265
2266 /* When read byte is zero : clear bgp peer and return */
2267 if (nbytes == 0)
2268 {
2269 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002270 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002271 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002272
2273 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002274 {
2275 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2276 {
2277 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2278 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2279 }
2280 else
2281 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2282 }
hassoe0701b72004-05-20 09:19:34 +00002283
paul718e3742002-12-13 20:15:29 +00002284 BGP_EVENT_ADD (peer, TCP_connection_closed);
2285 return -1;
2286 }
2287
2288 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002289 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002290 return -1;
2291
2292 return 0;
2293}
2294
2295/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002296static int
paul718e3742002-12-13 20:15:29 +00002297bgp_marker_all_one (struct stream *s, int length)
2298{
2299 int i;
2300
2301 for (i = 0; i < length; i++)
2302 if (s->data[i] != 0xff)
2303 return 0;
2304
2305 return 1;
2306}
2307
2308/* Starting point of packet process function. */
2309int
2310bgp_read (struct thread *thread)
2311{
2312 int ret;
2313 u_char type = 0;
2314 struct peer *peer;
2315 bgp_size_t size;
2316 char notify_data_length[2];
2317
2318 /* Yes first of all get peer pointer. */
2319 peer = THREAD_ARG (thread);
2320 peer->t_read = NULL;
2321
2322 /* For non-blocking IO check. */
2323 if (peer->status == Connect)
2324 {
2325 bgp_connect_check (peer);
2326 goto done;
2327 }
2328 else
2329 {
pauleb821182004-05-01 08:44:08 +00002330 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002331 {
pauleb821182004-05-01 08:44:08 +00002332 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002333 return -1;
2334 }
pauleb821182004-05-01 08:44:08 +00002335 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002336 }
2337
2338 /* Read packet header to determine type of the packet */
2339 if (peer->packet_size == 0)
2340 peer->packet_size = BGP_HEADER_SIZE;
2341
paul9985f832005-02-09 15:51:56 +00002342 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002343 {
2344 ret = bgp_read_packet (peer);
2345
2346 /* Header read error or partial read packet. */
2347 if (ret < 0)
2348 goto done;
2349
2350 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002351 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002352 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2353 size = stream_getw (peer->ibuf);
2354 type = stream_getc (peer->ibuf);
2355
2356 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002357 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002358 peer->host, type, size - BGP_HEADER_SIZE);
2359
2360 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002361 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002362 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2363 {
2364 bgp_notify_send (peer,
2365 BGP_NOTIFY_HEADER_ERR,
2366 BGP_NOTIFY_HEADER_NOT_SYNC);
2367 goto done;
2368 }
2369
2370 /* BGP type check. */
2371 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2372 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2373 && type != BGP_MSG_ROUTE_REFRESH_NEW
2374 && type != BGP_MSG_ROUTE_REFRESH_OLD
2375 && type != BGP_MSG_CAPABILITY)
2376 {
2377 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002378 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002379 "%s unknown message type 0x%02x",
2380 peer->host, type);
2381 bgp_notify_send_with_data (peer,
2382 BGP_NOTIFY_HEADER_ERR,
2383 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2384 &type, 1);
2385 goto done;
2386 }
2387 /* Mimimum packet length check. */
2388 if ((size < BGP_HEADER_SIZE)
2389 || (size > BGP_MAX_PACKET_SIZE)
2390 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2391 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2392 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2393 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2394 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2395 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2396 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2397 {
2398 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002399 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002400 "%s bad message length - %d for %s",
2401 peer->host, size,
2402 type == 128 ? "ROUTE-REFRESH" :
2403 bgp_type_str[(int) type]);
2404 bgp_notify_send_with_data (peer,
2405 BGP_NOTIFY_HEADER_ERR,
2406 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002407 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002408 goto done;
2409 }
2410
2411 /* Adjust size to message length. */
2412 peer->packet_size = size;
2413 }
2414
2415 ret = bgp_read_packet (peer);
2416 if (ret < 0)
2417 goto done;
2418
2419 /* Get size and type again. */
2420 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2421 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2422
2423 /* BGP packet dump function. */
2424 bgp_dump_packet (peer, type, peer->ibuf);
2425
2426 size = (peer->packet_size - BGP_HEADER_SIZE);
2427
2428 /* Read rest of the packet and call each sort of packet routine */
2429 switch (type)
2430 {
2431 case BGP_MSG_OPEN:
2432 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002433 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002434 break;
2435 case BGP_MSG_UPDATE:
2436 peer->readtime = time(NULL); /* Last read timer reset */
2437 bgp_update_receive (peer, size);
2438 break;
2439 case BGP_MSG_NOTIFY:
2440 bgp_notify_receive (peer, size);
2441 break;
2442 case BGP_MSG_KEEPALIVE:
2443 peer->readtime = time(NULL); /* Last read timer reset */
2444 bgp_keepalive_receive (peer, size);
2445 break;
2446 case BGP_MSG_ROUTE_REFRESH_NEW:
2447 case BGP_MSG_ROUTE_REFRESH_OLD:
2448 peer->refresh_in++;
2449 bgp_route_refresh_receive (peer, size);
2450 break;
2451 case BGP_MSG_CAPABILITY:
2452 peer->dynamic_cap_in++;
2453 bgp_capability_receive (peer, size);
2454 break;
2455 }
2456
2457 /* Clear input buffer. */
2458 peer->packet_size = 0;
2459 if (peer->ibuf)
2460 stream_reset (peer->ibuf);
2461
2462 done:
2463 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2464 {
2465 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002466 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002467 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002468 }
2469 return 0;
2470}