blob: 2d62c8dacc8c562350502c0879a77eb07f6bf778 [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;
paul718e3742002-12-13 20:15:29 +0000152
153 s = peer->work;
154 stream_reset (s);
155
156 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
157
158 while (adv)
159 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000160 assert (adv->rn);
161 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000162 adj = adv->adj;
163 if (adv->binfo)
164 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000165
166 /* When remaining space can't include NLRI and it's length. */
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000167 if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
paul718e3742002-12-13 20:15:29 +0000168 break;
169
170 /* If packet is empty, set attribute. */
171 if (stream_empty (s))
172 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000173 struct prefix_rd *prd = NULL;
174 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000175 struct peer *from = NULL;
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000176
177 if (rn->prn)
178 prd = (struct prefix_rd *) &rn->prn->p;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400179 if (binfo)
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000180 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 from = binfo->peer;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400182 if (binfo->extra)
183 tag = binfo->extra->tag;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000184 }
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))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000201 {
202 char buf[INET6_BUFSIZ];
203
204 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
205 peer->host,
206 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
207 rn->p.prefixlen);
208 }
paul718e3742002-12-13 20:15:29 +0000209
210 /* Synchnorize attribute. */
211 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000212 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000213 else
214 peer->scount[afi][safi]++;
215
216 adj->attr = bgp_attr_intern (adv->baa->attr);
217
218 adv = bgp_advertise_clean (peer, adj, afi, safi);
219
220 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
221 break;
222 }
223
224 if (! stream_empty (s))
225 {
226 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000227 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000228 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000229 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000230 stream_reset (s);
231 return packet;
232 }
233 return NULL;
hasso93406d82005-02-02 14:40:33 +0000234}
paul718e3742002-12-13 20:15:29 +0000235
paul94f2b392005-06-28 12:44:16 +0000236static struct stream *
hasso93406d82005-02-02 14:40:33 +0000237bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
238{
239 struct stream *s;
240 struct stream *packet;
241
Paul Jakma750e8142008-07-22 21:11:48 +0000242 if (DISABLE_BGP_ANNOUNCE)
243 return NULL;
hasso93406d82005-02-02 14:40:33 +0000244
245 if (BGP_DEBUG (normal, NORMAL))
246 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
247
248 s = stream_new (BGP_MAX_PACKET_SIZE);
249
250 /* Make BGP update packet. */
251 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
252
253 /* Unfeasible Routes Length */
254 stream_putw (s, 0);
255
256 if (afi == AFI_IP && safi == SAFI_UNICAST)
257 {
258 /* Total Path Attribute Length */
259 stream_putw (s, 0);
260 }
261 else
262 {
263 /* Total Path Attribute Length */
264 stream_putw (s, 6);
265 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
266 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
267 stream_putc (s, 3);
268 stream_putw (s, afi);
269 stream_putc (s, safi);
270 }
271
272 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000273 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000274 bgp_packet_add (peer, packet);
275 stream_free (s);
276 return packet;
paul718e3742002-12-13 20:15:29 +0000277}
278
279/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000280static struct stream *
paul718e3742002-12-13 20:15:29 +0000281bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
282{
283 struct stream *s;
284 struct stream *packet;
285 struct bgp_adj_out *adj;
286 struct bgp_advertise *adv;
287 struct bgp_node *rn;
288 unsigned long pos;
289 bgp_size_t unfeasible_len;
290 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000291
292 s = peer->work;
293 stream_reset (s);
294
295 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
296 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000297 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000298 adj = adv->adj;
299 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000300
301 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000302 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000303 break;
304
305 if (stream_empty (s))
306 {
307 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
308 stream_putw (s, 0);
309 }
310
311 if (afi == AFI_IP && safi == SAFI_UNICAST)
312 stream_put_prefix (s, &rn->p);
313 else
314 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000315 struct prefix_rd *prd = NULL;
316
317 if (rn->prn)
318 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000319 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000320 stream_putw (s, 0);
321 total_attr_len
322 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
323
324 /* Set total path attribute length. */
325 stream_putw_at (s, pos, total_attr_len);
326 }
327
328 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000329 {
330 char buf[INET6_BUFSIZ];
331
332 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
333 peer->host,
334 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
335 rn->p.prefixlen);
336 }
paul718e3742002-12-13 20:15:29 +0000337
338 peer->scount[afi][safi]--;
339
340 bgp_adj_out_remove (rn, adj, peer, afi, safi);
341 bgp_unlock_node (rn);
342
343 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
344 break;
345 }
346
347 if (! stream_empty (s))
348 {
349 if (afi == AFI_IP && safi == SAFI_UNICAST)
350 {
351 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000352 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000353 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
354 stream_putw (s, 0);
355 }
356 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000357 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000358 bgp_packet_add (peer, packet);
359 stream_reset (s);
360 return packet;
361 }
362
363 return NULL;
364}
365
366void
367bgp_default_update_send (struct peer *peer, struct attr *attr,
368 afi_t afi, safi_t safi, struct peer *from)
369{
370 struct stream *s;
371 struct stream *packet;
372 struct prefix p;
373 unsigned long pos;
374 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000375
Paul Jakma750e8142008-07-22 21:11:48 +0000376 if (DISABLE_BGP_ANNOUNCE)
377 return;
paul718e3742002-12-13 20:15:29 +0000378
379 if (afi == AFI_IP)
380 str2prefix ("0.0.0.0/0", &p);
381#ifdef HAVE_IPV6
382 else
383 str2prefix ("::/0", &p);
384#endif /* HAVE_IPV6 */
385
386 /* Logging the attribute. */
387 if (BGP_DEBUG (update, UPDATE_OUT))
388 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000389 char attrstr[BUFSIZ];
390 char buf[INET6_BUFSIZ];
391 attrstr[0] = '\0';
392
paul718e3742002-12-13 20:15:29 +0000393 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000394 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000395 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
paul718e3742002-12-13 20:15:29 +0000396 p.prefixlen, attrstr);
397 }
398
399 s = stream_new (BGP_MAX_PACKET_SIZE);
400
401 /* Make BGP update packet. */
402 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
403
404 /* Unfeasible Routes Length. */
405 stream_putw (s, 0);
406
407 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000408 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000409 stream_putw (s, 0);
410 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
411
412 /* Set Total Path Attribute Length. */
413 stream_putw_at (s, pos, total_attr_len);
414
415 /* NLRI set. */
416 if (p.family == AF_INET && safi == SAFI_UNICAST)
417 stream_put_prefix (s, &p);
418
419 /* Set size. */
420 bgp_packet_set_size (s);
421
paule83e2082005-05-19 02:12:25 +0000422 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000423 stream_free (s);
424
425 /* Dump packet if debug option is set. */
426#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000427 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000428#endif /* DEBUG */
429
430 /* Add packet to the peer. */
431 bgp_packet_add (peer, packet);
432
pauleb821182004-05-01 08:44:08 +0000433 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000434}
435
436void
437bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
438{
439 struct stream *s;
440 struct stream *packet;
441 struct prefix p;
442 unsigned long pos;
443 unsigned long cp;
444 bgp_size_t unfeasible_len;
445 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000446
Paul Jakma750e8142008-07-22 21:11:48 +0000447 if (DISABLE_BGP_ANNOUNCE)
448 return;
paul718e3742002-12-13 20:15:29 +0000449
450 if (afi == AFI_IP)
451 str2prefix ("0.0.0.0/0", &p);
452#ifdef HAVE_IPV6
453 else
454 str2prefix ("::/0", &p);
455#endif /* HAVE_IPV6 */
456
457 total_attr_len = 0;
458 pos = 0;
459
460 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000461 {
462 char buf[INET6_BUFSIZ];
463
464 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
465 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
466 p.prefixlen);
467 }
paul718e3742002-12-13 20:15:29 +0000468
469 s = stream_new (BGP_MAX_PACKET_SIZE);
470
471 /* Make BGP update packet. */
472 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
473
474 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000475 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000476 stream_putw (s, 0);
477
478 /* Withdrawn Routes. */
479 if (p.family == AF_INET && safi == SAFI_UNICAST)
480 {
481 stream_put_prefix (s, &p);
482
paul9985f832005-02-09 15:51:56 +0000483 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000484
485 /* Set unfeasible len. */
486 stream_putw_at (s, cp, unfeasible_len);
487
488 /* Set total path attribute length. */
489 stream_putw (s, 0);
490 }
491 else
492 {
paul9985f832005-02-09 15:51:56 +0000493 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000494 stream_putw (s, 0);
495 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
496
497 /* Set total path attribute length. */
498 stream_putw_at (s, pos, total_attr_len);
499 }
500
501 bgp_packet_set_size (s);
502
paule83e2082005-05-19 02:12:25 +0000503 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000504 stream_free (s);
505
506 /* Add packet to the peer. */
507 bgp_packet_add (peer, packet);
508
pauleb821182004-05-01 08:44:08 +0000509 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000510}
511
512/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000513static struct stream *
paul718e3742002-12-13 20:15:29 +0000514bgp_write_packet (struct peer *peer)
515{
516 afi_t afi;
517 safi_t safi;
518 struct stream *s = NULL;
519 struct bgp_advertise *adv;
520
521 s = stream_fifo_head (peer->obuf);
522 if (s)
523 return s;
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]->withdraw);
529 if (adv)
530 {
531 s = bgp_withdraw_packet (peer, afi, safi);
532 if (s)
533 return s;
534 }
535 }
536
537 for (afi = AFI_IP; afi < AFI_MAX; afi++)
538 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
539 {
540 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
541 if (adv)
542 {
543 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000544 {
545 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
546 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
547 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
548 && safi != SAFI_MPLS_VPN)
549 {
550 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
551 PEER_STATUS_EOR_RECEIVED))
552 s = bgp_update_packet (peer, afi, safi);
553 }
554 else
555 s = bgp_update_packet (peer, afi, safi);
556 }
paul718e3742002-12-13 20:15:29 +0000557
558 if (s)
559 return s;
560 }
hasso93406d82005-02-02 14:40:33 +0000561
562 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
563 {
564 if (peer->afc_nego[afi][safi] && peer->synctime
565 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
566 && safi != SAFI_MPLS_VPN)
567 {
568 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
569 return bgp_update_packet_eor (peer, afi, safi);
570 }
571 }
paul718e3742002-12-13 20:15:29 +0000572 }
573
574 return NULL;
575}
576
577/* Is there partially written packet or updates we can send right
578 now. */
paul94f2b392005-06-28 12:44:16 +0000579static int
paul718e3742002-12-13 20:15:29 +0000580bgp_write_proceed (struct peer *peer)
581{
582 afi_t afi;
583 safi_t safi;
584 struct bgp_advertise *adv;
585
586 if (stream_fifo_head (peer->obuf))
587 return 1;
588
589 for (afi = AFI_IP; afi < AFI_MAX; afi++)
590 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
591 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
592 return 1;
593
594 for (afi = AFI_IP; afi < AFI_MAX; afi++)
595 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
596 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
597 if (adv->binfo->uptime < peer->synctime)
598 return 1;
599
600 return 0;
601}
602
603/* Write packet to the peer. */
604int
605bgp_write (struct thread *thread)
606{
607 struct peer *peer;
608 u_char type;
609 struct stream *s;
610 int num;
paulfd79ac92004-10-13 05:06:08 +0000611 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000612
613 /* Yes first of all get peer pointer. */
614 peer = THREAD_ARG (thread);
615 peer->t_write = NULL;
616
617 /* For non-blocking IO check. */
618 if (peer->status == Connect)
619 {
620 bgp_connect_check (peer);
621 return 0;
622 }
623
Stephen Hemmingereac57022010-08-05 10:26:25 -0700624 s = bgp_write_packet (peer);
625 if (!s)
626 return 0; /* nothing to send */
627
628 sockopt_cork (peer->fd, 1);
629
630 /* Nonblocking write until TCP output buffer is full. */
631 do
paul718e3742002-12-13 20:15:29 +0000632 {
633 int writenum;
paul718e3742002-12-13 20:15:29 +0000634
635 /* Number of bytes to be sent. */
636 writenum = stream_get_endp (s) - stream_get_getp (s);
637
638 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000639 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700640 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000641 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700642 /* write failed either retry needed or error */
643 if (ERRNO_IO_RETRY(errno))
644 break;
645
646 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000647 return 0;
648 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700649
paul718e3742002-12-13 20:15:29 +0000650 if (num != writenum)
651 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700652 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000653 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700654 break;
paul718e3742002-12-13 20:15:29 +0000655 }
656
657 /* Retrieve BGP packet type. */
658 stream_set_getp (s, BGP_MARKER_SIZE + 2);
659 type = stream_getc (s);
660
661 switch (type)
662 {
663 case BGP_MSG_OPEN:
664 peer->open_out++;
665 break;
666 case BGP_MSG_UPDATE:
667 peer->update_out++;
668 break;
669 case BGP_MSG_NOTIFY:
670 peer->notify_out++;
671 /* Double start timer. */
672 peer->v_start *= 2;
673
674 /* Overflow check. */
675 if (peer->v_start >= (60 * 2))
676 peer->v_start = (60 * 2);
677
Paul Jakmaca058a32006-09-14 02:58:49 +0000678 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000679 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000680 return 0;
paul718e3742002-12-13 20:15:29 +0000681 case BGP_MSG_KEEPALIVE:
682 peer->keepalive_out++;
683 break;
684 case BGP_MSG_ROUTE_REFRESH_NEW:
685 case BGP_MSG_ROUTE_REFRESH_OLD:
686 peer->refresh_out++;
687 break;
688 case BGP_MSG_CAPABILITY:
689 peer->dynamic_cap_out++;
690 break;
691 }
692
693 /* OK we send packet so delete it. */
694 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000695 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700696 while (++count < BGP_WRITE_PACKET_MAX &&
697 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000698
699 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000700 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700701 else
702 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000703
704 return 0;
705}
706
707/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000708static int
paul718e3742002-12-13 20:15:29 +0000709bgp_write_notify (struct peer *peer)
710{
Stephen Hemminger35398582010-08-05 10:26:23 -0700711 int ret, val;
paul718e3742002-12-13 20:15:29 +0000712 u_char type;
713 struct stream *s;
714
715 /* There should be at least one packet. */
716 s = stream_fifo_head (peer->obuf);
717 if (!s)
718 return 0;
719 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
720
Stephen Hemminger35398582010-08-05 10:26:23 -0700721 /* Put socket in blocking mode. */
722 val = fcntl (peer->fd, F_GETFL, 0);
723 fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);
724
pauleb821182004-05-01 08:44:08 +0000725 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000726 if (ret <= 0)
727 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000728 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000729 return 0;
730 }
731
732 /* Retrieve BGP packet type. */
733 stream_set_getp (s, BGP_MARKER_SIZE + 2);
734 type = stream_getc (s);
735
736 assert (type == BGP_MSG_NOTIFY);
737
738 /* Type should be notify. */
739 peer->notify_out++;
740
741 /* Double start timer. */
742 peer->v_start *= 2;
743
744 /* Overflow check. */
745 if (peer->v_start >= (60 * 2))
746 peer->v_start = (60 * 2);
747
Paul Jakmadcdf3992006-10-15 23:39:59 +0000748 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000749
750 return 0;
751}
752
753/* Make keepalive packet and send it to the peer. */
754void
755bgp_keepalive_send (struct peer *peer)
756{
757 struct stream *s;
758 int length;
759
760 s = stream_new (BGP_MAX_PACKET_SIZE);
761
762 /* Make keepalive packet. */
763 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
764
765 /* Set packet size. */
766 length = bgp_packet_set_size (s);
767
768 /* Dump packet if debug option is set. */
769 /* bgp_packet_dump (s); */
770
771 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000772 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000773 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000774 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000775 peer->host, BGP_MSG_KEEPALIVE, length);
776
777 /* Add packet to the peer. */
778 bgp_packet_add (peer, s);
779
pauleb821182004-05-01 08:44:08 +0000780 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000781}
782
783/* Make open packet and send it to the peer. */
784void
785bgp_open_send (struct peer *peer)
786{
787 struct stream *s;
788 int length;
789 u_int16_t send_holdtime;
790 as_t local_as;
791
792 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
793 send_holdtime = peer->holdtime;
794 else
795 send_holdtime = peer->bgp->default_holdtime;
796
797 /* local-as Change */
798 if (peer->change_local_as)
799 local_as = peer->change_local_as;
800 else
801 local_as = peer->local_as;
802
803 s = stream_new (BGP_MAX_PACKET_SIZE);
804
805 /* Make open packet. */
806 bgp_packet_set_marker (s, BGP_MSG_OPEN);
807
808 /* Set open packet values. */
809 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000810 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
811 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000812 stream_putw (s, send_holdtime); /* Hold Time */
813 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
814
815 /* Set capability code. */
816 bgp_open_capability (s, peer);
817
818 /* Set BGP packet length. */
819 length = bgp_packet_set_size (s);
820
821 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400822 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000823 peer->host, BGP_VERSION_4, local_as,
824 send_holdtime, inet_ntoa (peer->local_id));
825
826 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000827 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000828 peer->host, BGP_MSG_OPEN, length);
829
830 /* Dump packet if debug option is set. */
831 /* bgp_packet_dump (s); */
832
833 /* Add packet to the peer. */
834 bgp_packet_add (peer, s);
835
pauleb821182004-05-01 08:44:08 +0000836 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000837}
838
839/* Send BGP notify packet with data potion. */
840void
841bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
842 u_char *data, size_t datalen)
843{
844 struct stream *s;
845 int length;
846
847 /* Allocate new stream. */
848 s = stream_new (BGP_MAX_PACKET_SIZE);
849
850 /* Make nitify packet. */
851 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
852
853 /* Set notify packet values. */
854 stream_putc (s, code); /* BGP notify code */
855 stream_putc (s, sub_code); /* BGP notify sub_code */
856
857 /* If notify data is present. */
858 if (data)
859 stream_write (s, data, datalen);
860
861 /* Set BGP packet length. */
862 length = bgp_packet_set_size (s);
863
864 /* Add packet to the peer. */
865 stream_fifo_clean (peer->obuf);
866 bgp_packet_add (peer, s);
867
868 /* For debug */
869 {
870 struct bgp_notify bgp_notify;
871 int first = 0;
872 int i;
873 char c[4];
874
875 bgp_notify.code = code;
876 bgp_notify.subcode = sub_code;
877 bgp_notify.data = NULL;
878 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
879
880 if (bgp_notify.length)
881 {
882 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
883 for (i = 0; i < bgp_notify.length; i++)
884 if (first)
885 {
886 sprintf (c, " %02x", data[i]);
887 strcat (bgp_notify.data, c);
888 }
889 else
890 {
891 first = 1;
892 sprintf (c, "%02x", data[i]);
893 strcpy (bgp_notify.data, c);
894 }
895 }
896 bgp_notify_print (peer, &bgp_notify, "sending");
897 if (bgp_notify.data)
898 XFREE (MTYPE_TMP, bgp_notify.data);
899 }
900
901 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000902 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000903 peer->host, BGP_MSG_NOTIFY, length);
904
hassoe0701b72004-05-20 09:19:34 +0000905 /* peer reset cause */
906 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
907 {
908 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +0400909 {
910 peer->last_reset = PEER_DOWN_USER_RESET;
911 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
912 }
hassoe0701b72004-05-20 09:19:34 +0000913 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +0400914 {
915 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
916 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
917 }
hassoe0701b72004-05-20 09:19:34 +0000918 else
heasley1212dc12011-09-12 13:27:52 +0400919 {
920 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
921 zlog_info ("Notification sent to neighbor %s: type %u/%u",
922 peer->host, code, sub_code);
923 }
hassoe0701b72004-05-20 09:19:34 +0000924 }
heasley1212dc12011-09-12 13:27:52 +0400925 else
926 zlog_info ("Notification sent to neighbor %s: configuration change",
927 peer->host);
hassoe0701b72004-05-20 09:19:34 +0000928
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +0400929 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +0000930 BGP_WRITE_OFF (peer->t_write);
931
932 bgp_write_notify (peer);
933}
934
935/* Send BGP notify packet. */
936void
937bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
938{
939 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
940}
941
paul718e3742002-12-13 20:15:29 +0000942/* Send route refresh message to the peer. */
943void
944bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
945 u_char orf_type, u_char when_to_refresh, int remove)
946{
947 struct stream *s;
948 struct stream *packet;
949 int length;
950 struct bgp_filter *filter;
951 int orf_refresh = 0;
952
Paul Jakma750e8142008-07-22 21:11:48 +0000953 if (DISABLE_BGP_ANNOUNCE)
954 return;
paul718e3742002-12-13 20:15:29 +0000955
956 filter = &peer->filter[afi][safi];
957
958 /* Adjust safi code. */
959 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400960 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +0000961
962 s = stream_new (BGP_MAX_PACKET_SIZE);
963
964 /* Make BGP update packet. */
965 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
966 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
967 else
968 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
969
970 /* Encode Route Refresh message. */
971 stream_putw (s, afi);
972 stream_putc (s, 0);
973 stream_putc (s, safi);
974
975 if (orf_type == ORF_TYPE_PREFIX
976 || orf_type == ORF_TYPE_PREFIX_OLD)
977 if (remove || filter->plist[FILTER_IN].plist)
978 {
979 u_int16_t orf_len;
980 unsigned long orfp;
981
982 orf_refresh = 1;
983 stream_putc (s, when_to_refresh);
984 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000985 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000986 stream_putw (s, 0);
987
988 if (remove)
989 {
990 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
991 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
992 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000993 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000994 peer->host, orf_type,
995 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
996 afi, safi);
997 }
998 else
999 {
1000 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1001 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1002 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1003 ORF_COMMON_PART_DENY);
1004 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001005 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001006 peer->host, orf_type,
1007 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1008 afi, safi);
1009 }
1010
1011 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001012 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001013 stream_putw_at (s, orfp, orf_len);
1014 }
1015
1016 /* Set packet size. */
1017 length = bgp_packet_set_size (s);
1018
1019 if (BGP_DEBUG (normal, NORMAL))
1020 {
1021 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001022 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001023 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001024 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001025 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1026 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1027 }
1028
1029 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001030 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001031 stream_free (s);
1032
1033 /* Add packet to the peer. */
1034 bgp_packet_add (peer, packet);
1035
pauleb821182004-05-01 08:44:08 +00001036 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001037}
1038
1039/* Send capability message to the peer. */
1040void
1041bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1042 int capability_code, int action)
1043{
1044 struct stream *s;
1045 struct stream *packet;
1046 int length;
1047
1048 /* Adjust safi code. */
1049 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001050 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001051
1052 s = stream_new (BGP_MAX_PACKET_SIZE);
1053
1054 /* Make BGP update packet. */
1055 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1056
1057 /* Encode MP_EXT capability. */
1058 if (capability_code == CAPABILITY_CODE_MP)
1059 {
1060 stream_putc (s, action);
1061 stream_putc (s, CAPABILITY_CODE_MP);
1062 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1063 stream_putw (s, afi);
1064 stream_putc (s, 0);
1065 stream_putc (s, safi);
1066
1067 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001068 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001069 peer->host, action == CAPABILITY_ACTION_SET ?
1070 "Advertising" : "Removing", afi, safi);
1071 }
1072
paul718e3742002-12-13 20:15:29 +00001073 /* Set packet size. */
1074 length = bgp_packet_set_size (s);
1075
1076 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001077 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001078 stream_free (s);
1079
1080 /* Add packet to the peer. */
1081 bgp_packet_add (peer, packet);
1082
1083 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001084 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001085 peer->host, BGP_MSG_CAPABILITY, length);
1086
pauleb821182004-05-01 08:44:08 +00001087 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001088}
1089
1090/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001091static int
pauleb821182004-05-01 08:44:08 +00001092bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001093{
pauleb821182004-05-01 08:44:08 +00001094 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001095 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001096 struct bgp *bgp;
1097
1098 bgp = bgp_get_default ();
1099 if (! bgp)
1100 return 0;
1101
1102 /* Upon receipt of an OPEN message, the local system must examine
1103 all of its connections that are in the OpenConfirm state. A BGP
1104 speaker may also examine connections in an OpenSent state if it
1105 knows the BGP Identifier of the peer by means outside of the
1106 protocol. If among these connections there is a connection to a
1107 remote BGP speaker whose BGP Identifier equals the one in the
1108 OPEN message, then the local system performs the following
1109 collision resolution procedure: */
1110
paul1eb8ef22005-04-07 07:30:20 +00001111 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001112 {
1113 /* Under OpenConfirm status, local peer structure already hold
1114 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001115
1116 if (peer != new
1117 && (peer->status == OpenConfirm || peer->status == OpenSent)
1118 && sockunion_same (&peer->su, &new->su))
1119 {
paul718e3742002-12-13 20:15:29 +00001120 /* 1. The BGP Identifier of the local system is compared to
1121 the BGP Identifier of the remote system (as specified in
1122 the OPEN message). */
1123
1124 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1125 {
1126 /* 2. If the value of the local BGP Identifier is less
1127 than the remote one, the local system closes BGP
1128 connection that already exists (the one that is
1129 already in the OpenConfirm state), and accepts BGP
1130 connection initiated by the remote system. */
1131
pauleb821182004-05-01 08:44:08 +00001132 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001133 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001134 return 1;
1135 }
1136 else
1137 {
1138 /* 3. Otherwise, the local system closes newly created
1139 BGP connection (the one associated with the newly
1140 received OPEN message), and continues to use the
1141 existing one (the one that is already in the
1142 OpenConfirm state). */
1143
pauleb821182004-05-01 08:44:08 +00001144 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001145 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1146 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001147 return -1;
1148 }
pauleb821182004-05-01 08:44:08 +00001149 }
1150 }
paul718e3742002-12-13 20:15:29 +00001151 return 0;
1152}
1153
paul94f2b392005-06-28 12:44:16 +00001154static int
paul718e3742002-12-13 20:15:29 +00001155bgp_open_receive (struct peer *peer, bgp_size_t size)
1156{
1157 int ret;
1158 u_char version;
1159 u_char optlen;
1160 u_int16_t holdtime;
1161 u_int16_t send_holdtime;
1162 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001163 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001164 struct peer *realpeer;
1165 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001166 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001167 u_int8_t notify_data_remote_as[2];
1168 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001169
1170 realpeer = NULL;
1171
1172 /* Parse open packet. */
1173 version = stream_getc (peer->ibuf);
1174 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1175 remote_as = stream_getw (peer->ibuf);
1176 holdtime = stream_getw (peer->ibuf);
1177 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1178 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1179
1180 /* Receive OPEN message log */
1181 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001182 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001183 " holdtime %d, id %s",
1184 peer->host, version, remote_as, holdtime,
1185 inet_ntoa (remote_id));
1186
1187 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001188 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001189 optlen = stream_getc (peer->ibuf);
1190
1191 if (optlen != 0)
1192 {
1193 /* We need the as4 capability value *right now* because
1194 * if it is there, we have not got the remote_as yet, and without
1195 * that we do not know which peer is connecting to us now.
1196 */
1197 as4 = peek_for_as4_capability (peer, optlen);
1198 }
1199
1200 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1201 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1202 {
1203 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1204 peer->host);
1205 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1206 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1207 return -1;
1208 }
1209
1210 if (remote_as == BGP_AS_TRANS)
1211 {
1212 /* Take the AS4 from the capability. We must have received the
1213 * capability now! Otherwise we have a asn16 peer who uses
1214 * BGP_AS_TRANS, for some unknown reason.
1215 */
1216 if (as4 == BGP_AS_TRANS)
1217 {
1218 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1219 peer->host);
1220 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1221 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1222 return -1;
1223 }
1224
1225 if (!as4 && BGP_DEBUG (as4, AS4))
1226 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1227 " Odd, but proceeding.", peer->host);
1228 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001229 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001230 "in 2-bytes, very odd peer.", peer->host, as4);
1231 if (as4)
1232 remote_as = as4;
1233 }
1234 else
1235 {
1236 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1237 /* If we have got the capability, peer->as4cap must match remote_as */
1238 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1239 && as4 != remote_as)
1240 {
1241 /* raise error, log this, close session */
1242 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1243 " mismatch with 16bit 'myasn' %u in open",
1244 peer->host, as4, remote_as);
1245 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1246 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1247 return -1;
1248 }
1249 }
1250
paul718e3742002-12-13 20:15:29 +00001251 /* Lookup peer from Open packet. */
1252 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1253 {
1254 int as = 0;
1255
1256 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1257
1258 if (! realpeer)
1259 {
1260 /* Peer's source IP address is check in bgp_accept(), so this
1261 must be AS number mismatch or remote-id configuration
1262 mismatch. */
1263 if (as)
1264 {
1265 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001266 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1267 peer->host, inet_ntoa (remote_id));
1268 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1269 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1270 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001271 }
1272 else
1273 {
1274 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001275 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001276 peer->host, remote_as, peer->as);
1277 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1278 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1279 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001280 }
1281 return -1;
1282 }
1283 }
1284
1285 /* When collision is detected and this peer is closed. Retrun
1286 immidiately. */
1287 ret = bgp_collision_detect (peer, remote_id);
1288 if (ret < 0)
1289 return ret;
1290
pauleb821182004-05-01 08:44:08 +00001291 /* Hack part. */
1292 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1293 {
hasso93406d82005-02-02 14:40:33 +00001294 if (realpeer->status == Established
1295 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1296 {
1297 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1298 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1299 }
1300 else if (ret == 0 && realpeer->status != Active
1301 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001302 && realpeer->status != OpenConfirm
1303 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001304 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001305 /* XXX: This is an awful problem..
1306 *
1307 * According to the RFC we should just let this connection (of the
1308 * accepted 'peer') continue on to Established if the other
1309 * connection (the 'realpeer' one) is in state Connect, and deal
1310 * with the more larval FSM as/when it gets far enough to receive
1311 * an Open. We don't do that though, we instead close the (more
1312 * developed) accepted connection.
1313 *
1314 * This means there's a race, which if hit, can loop:
1315 *
1316 * FSM for A FSM for B
1317 * realpeer accept-peer realpeer accept-peer
1318 *
1319 * Connect Connect
1320 * Active
1321 * OpenSent OpenSent
1322 * <arrive here,
1323 * Notify, delete>
1324 * Idle Active
1325 * OpenSent OpenSent
1326 * <arrive here,
1327 * Notify, delete>
1328 * Idle
1329 * <wait> <wait>
1330 * Connect Connect
1331 *
1332 *
1333 * If both sides are Quagga, they're almost certain to wait for
1334 * the same amount of time of course (which doesn't preclude other
1335 * implementations also waiting for same time). The race is
1336 * exacerbated by high-latency (in bgpd and/or the network).
1337 *
1338 * The reason we do this is because our FSM is tied to our peer
1339 * structure, which carries our configuration information, etc.
1340 * I.e. we can't let the accepted-peer FSM continue on as it is,
1341 * cause it's not associated with any actual peer configuration -
1342 * it's just a dummy.
1343 *
1344 * It's possible we could hack-fix this by just bgp_stop'ing the
1345 * realpeer and continueing on with the 'transfer FSM' below.
1346 * Ideally, we need to seperate FSMs from struct peer.
1347 *
1348 * Setting one side to passive avoids the race, as a workaround.
1349 */
pauleb821182004-05-01 08:44:08 +00001350 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001351 zlog_debug ("%s peer status is %s close connection",
1352 realpeer->host, LOOKUP (bgp_status_msg,
1353 realpeer->status));
1354 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1355 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1356
pauleb821182004-05-01 08:44:08 +00001357 return -1;
1358 }
1359
1360 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001361 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1362 peer->host,
1363 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001364
1365 bgp_stop (realpeer);
1366
1367 /* Transfer file descriptor. */
1368 realpeer->fd = peer->fd;
1369 peer->fd = -1;
1370
1371 /* Transfer input buffer. */
1372 stream_free (realpeer->ibuf);
1373 realpeer->ibuf = peer->ibuf;
1374 realpeer->packet_size = peer->packet_size;
1375 peer->ibuf = NULL;
1376
1377 /* Transfer status. */
1378 realpeer->status = peer->status;
1379 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001380
pauleb821182004-05-01 08:44:08 +00001381 /* peer pointer change. Open packet send to neighbor. */
1382 peer = realpeer;
1383 bgp_open_send (peer);
1384 if (peer->fd < 0)
1385 {
1386 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1387 peer->fd);
1388 return -1;
1389 }
1390 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1391 }
1392
paul718e3742002-12-13 20:15:29 +00001393 /* remote router-id check. */
1394 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001395 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001396 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1397 {
1398 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001399 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001400 peer->host, inet_ntoa (remote_id));
1401 bgp_notify_send_with_data (peer,
1402 BGP_NOTIFY_OPEN_ERR,
1403 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1404 notify_data_remote_id, 4);
1405 return -1;
1406 }
1407
1408 /* Set remote router-id */
1409 peer->remote_id = remote_id;
1410
1411 /* Peer BGP version check. */
1412 if (version != BGP_VERSION_4)
1413 {
paul5228ad22004-06-04 17:58:18 +00001414 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001415 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001416 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001417 peer->host, version, BGP_VERSION_4);
1418 bgp_notify_send_with_data (peer,
1419 BGP_NOTIFY_OPEN_ERR,
1420 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001421 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001422 return -1;
1423 }
1424
1425 /* Check neighbor as number. */
1426 if (remote_as != peer->as)
1427 {
1428 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001429 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001430 peer->host, remote_as, peer->as);
1431 bgp_notify_send_with_data (peer,
1432 BGP_NOTIFY_OPEN_ERR,
1433 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1434 notify_data_remote_as, 2);
1435 return -1;
1436 }
1437
1438 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1439 calculate the value of the Hold Timer by using the smaller of its
1440 configured Hold Time and the Hold Time received in the OPEN message.
1441 The Hold Time MUST be either zero or at least three seconds. An
1442 implementation may reject connections on the basis of the Hold Time. */
1443
1444 if (holdtime < 3 && holdtime != 0)
1445 {
1446 bgp_notify_send (peer,
1447 BGP_NOTIFY_OPEN_ERR,
1448 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1449 return -1;
1450 }
1451
1452 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1453 would be one third of the Hold Time interval. KEEPALIVE messages
1454 MUST NOT be sent more frequently than one per second. An
1455 implementation MAY adjust the rate at which it sends KEEPALIVE
1456 messages as a function of the Hold Time interval. */
1457
1458 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1459 send_holdtime = peer->holdtime;
1460 else
1461 send_holdtime = peer->bgp->default_holdtime;
1462
1463 if (holdtime < send_holdtime)
1464 peer->v_holdtime = holdtime;
1465 else
1466 peer->v_holdtime = send_holdtime;
1467
1468 peer->v_keepalive = peer->v_holdtime / 3;
1469
1470 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001471 if (optlen != 0)
1472 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001473 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001474 {
1475 bgp_notify_send (peer,
1476 BGP_NOTIFY_OPEN_ERR,
1477 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1478 return ret;
1479 }
paul718e3742002-12-13 20:15:29 +00001480 }
1481 else
1482 {
1483 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001484 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001485 peer->host);
1486 }
1487
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001488 /*
1489 * Assume that the peer supports the locally configured set of
1490 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1491 * capabilities, or if 'override-capability' is configured.
1492 */
1493 if (! mp_capability ||
1494 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001495 {
1496 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1497 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1498 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1499 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1500 }
1501
1502 /* Get sockname. */
1503 bgp_getsockname (peer);
1504
1505 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1506
1507 peer->packet_size = 0;
1508 if (peer->ibuf)
1509 stream_reset (peer->ibuf);
1510
1511 return 0;
1512}
1513
1514/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001515static int
paul718e3742002-12-13 20:15:29 +00001516bgp_update_receive (struct peer *peer, bgp_size_t size)
1517{
1518 int ret;
1519 u_char *end;
1520 struct stream *s;
1521 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001522 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001523 bgp_size_t attribute_len;
1524 bgp_size_t update_len;
1525 bgp_size_t withdraw_len;
1526 struct bgp_nlri update;
1527 struct bgp_nlri withdraw;
1528 struct bgp_nlri mp_update;
1529 struct bgp_nlri mp_withdraw;
paul718e3742002-12-13 20:15:29 +00001530
1531 /* Status must be Established. */
1532 if (peer->status != Established)
1533 {
1534 zlog_err ("%s [FSM] Update packet received under status %s",
1535 peer->host, LOOKUP (bgp_status_msg, peer->status));
1536 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1537 return -1;
1538 }
1539
1540 /* Set initial values. */
1541 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001542 memset (&extra, 0, sizeof (struct attr_extra));
paul718e3742002-12-13 20:15:29 +00001543 memset (&update, 0, sizeof (struct bgp_nlri));
1544 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1545 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1546 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001547 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001548
1549 s = peer->ibuf;
1550 end = stream_pnt (s) + size;
1551
1552 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1553 Length is too large (i.e., if Unfeasible Routes Length + Total
1554 Attribute Length + 23 exceeds the message Length), then the Error
1555 Subcode is set to Malformed Attribute List. */
1556 if (stream_pnt (s) + 2 > end)
1557 {
1558 zlog_err ("%s [Error] Update packet error"
1559 " (packet length is short for unfeasible length)",
1560 peer->host);
1561 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1562 BGP_NOTIFY_UPDATE_MAL_ATTR);
1563 return -1;
1564 }
1565
1566 /* Unfeasible Route Length. */
1567 withdraw_len = stream_getw (s);
1568
1569 /* Unfeasible Route Length check. */
1570 if (stream_pnt (s) + withdraw_len > end)
1571 {
1572 zlog_err ("%s [Error] Update packet error"
1573 " (packet unfeasible length overflow %d)",
1574 peer->host, withdraw_len);
1575 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1576 BGP_NOTIFY_UPDATE_MAL_ATTR);
1577 return -1;
1578 }
1579
1580 /* Unfeasible Route packet format check. */
1581 if (withdraw_len > 0)
1582 {
1583 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1584 if (ret < 0)
1585 return -1;
1586
1587 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001588 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001589
1590 withdraw.afi = AFI_IP;
1591 withdraw.safi = SAFI_UNICAST;
1592 withdraw.nlri = stream_pnt (s);
1593 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001594 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001595 }
1596
1597 /* Attribute total length check. */
1598 if (stream_pnt (s) + 2 > end)
1599 {
1600 zlog_warn ("%s [Error] Packet Error"
1601 " (update packet is short for attribute length)",
1602 peer->host);
1603 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1604 BGP_NOTIFY_UPDATE_MAL_ATTR);
1605 return -1;
1606 }
1607
1608 /* Fetch attribute total length. */
1609 attribute_len = stream_getw (s);
1610
1611 /* Attribute length check. */
1612 if (stream_pnt (s) + attribute_len > end)
1613 {
1614 zlog_warn ("%s [Error] Packet Error"
1615 " (update packet attribute length overflow %d)",
1616 peer->host, attribute_len);
1617 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1618 BGP_NOTIFY_UPDATE_MAL_ATTR);
1619 return -1;
1620 }
Paul Jakmab881c702010-11-23 16:35:42 +00001621
1622 /* Certain attribute parsing errors should not be considered bad enough
1623 * to reset the session for, most particularly any partial/optional
1624 * attributes that have 'tunneled' over speakers that don't understand
1625 * them. Instead we withdraw only the prefix concerned.
1626 *
1627 * Complicates the flow a little though..
1628 */
1629 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1630 /* This define morphs the update case into a withdraw when lower levels
1631 * have signalled an error condition where this is best.
1632 */
1633#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001634
1635 /* Parse attribute when it exists. */
1636 if (attribute_len)
1637 {
Paul Jakmab881c702010-11-23 16:35:42 +00001638 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
paul718e3742002-12-13 20:15:29 +00001639 &mp_update, &mp_withdraw);
Paul Jakmab881c702010-11-23 16:35:42 +00001640 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
paul718e3742002-12-13 20:15:29 +00001641 return -1;
1642 }
Paul Jakmab881c702010-11-23 16:35:42 +00001643
paul718e3742002-12-13 20:15:29 +00001644 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001645 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1646 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001647 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001648 char attrstr[BUFSIZ];
1649 attrstr[0] = '\0';
1650
paule01f9cb2004-07-09 17:48:53 +00001651 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001652 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1653 ? LOG_ERR : LOG_DEBUG;
1654
1655 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1656 zlog (peer->log, LOG_ERR,
1657 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1658 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001659
1660 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001661 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001662 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001663 }
Paul Jakmab881c702010-11-23 16:35:42 +00001664
paul718e3742002-12-13 20:15:29 +00001665 /* Network Layer Reachability Information. */
1666 update_len = end - stream_pnt (s);
1667
1668 if (update_len)
1669 {
1670 /* Check NLRI packet format and prefix length. */
1671 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1672 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001673 {
1674 bgp_attr_unintern_sub (&attr);
Paul Jakmab881c702010-11-23 16:35:42 +00001675 return -1;
1676 }
paul718e3742002-12-13 20:15:29 +00001677
1678 /* Set NLRI portion to structure. */
1679 update.afi = AFI_IP;
1680 update.safi = SAFI_UNICAST;
1681 update.nlri = stream_pnt (s);
1682 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001683 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001684 }
1685
1686 /* NLRI is processed only when the peer is configured specific
1687 Address Family and Subsequent Address Family. */
1688 if (peer->afc[AFI_IP][SAFI_UNICAST])
1689 {
1690 if (withdraw.length)
1691 bgp_nlri_parse (peer, NULL, &withdraw);
1692
1693 if (update.length)
1694 {
1695 /* We check well-known attribute only for IPv4 unicast
1696 update. */
1697 ret = bgp_attr_check (peer, &attr);
1698 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001699 {
1700 bgp_attr_unintern_sub (&attr);
Paul Jakmab881c702010-11-23 16:35:42 +00001701 return -1;
1702 }
paul718e3742002-12-13 20:15:29 +00001703
Paul Jakmab881c702010-11-23 16:35:42 +00001704 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
paul718e3742002-12-13 20:15:29 +00001705 }
paule01f9cb2004-07-09 17:48:53 +00001706
hassof4184462005-02-01 20:13:16 +00001707 if (mp_update.length
1708 && mp_update.afi == AFI_IP
1709 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001710 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
hassof4184462005-02-01 20:13:16 +00001711
1712 if (mp_withdraw.length
1713 && mp_withdraw.afi == AFI_IP
1714 && mp_withdraw.safi == SAFI_UNICAST)
1715 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1716
paule01f9cb2004-07-09 17:48:53 +00001717 if (! attribute_len && ! withdraw_len)
1718 {
1719 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001720 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1721 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001722
hasso93406d82005-02-02 14:40:33 +00001723 /* NSF delete stale route */
1724 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1725 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1726
1727 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001728 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001729 peer->host);
1730 }
paul718e3742002-12-13 20:15:29 +00001731 }
1732 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1733 {
1734 if (mp_update.length
1735 && mp_update.afi == AFI_IP
1736 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001737 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001738
1739 if (mp_withdraw.length
1740 && mp_withdraw.afi == AFI_IP
1741 && mp_withdraw.safi == SAFI_MULTICAST)
1742 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001743
hasso93406d82005-02-02 14:40:33 +00001744 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001745 && mp_withdraw.afi == AFI_IP
1746 && mp_withdraw.safi == SAFI_MULTICAST
1747 && mp_withdraw.length == 0)
1748 {
1749 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001750 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1751 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001752
hasso93406d82005-02-02 14:40:33 +00001753 /* NSF delete stale route */
1754 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1755 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1756
1757 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001758 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001759 peer->host);
1760 }
paul718e3742002-12-13 20:15:29 +00001761 }
1762 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1763 {
1764 if (mp_update.length
1765 && mp_update.afi == AFI_IP6
1766 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001767 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001768
1769 if (mp_withdraw.length
1770 && mp_withdraw.afi == AFI_IP6
1771 && mp_withdraw.safi == SAFI_UNICAST)
1772 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001773
hasso93406d82005-02-02 14:40:33 +00001774 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001775 && mp_withdraw.afi == AFI_IP6
1776 && mp_withdraw.safi == SAFI_UNICAST
1777 && mp_withdraw.length == 0)
1778 {
1779 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001780 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001781
hasso93406d82005-02-02 14:40:33 +00001782 /* NSF delete stale route */
1783 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1784 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1785
1786 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001787 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001788 peer->host);
1789 }
paul718e3742002-12-13 20:15:29 +00001790 }
1791 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1792 {
1793 if (mp_update.length
1794 && mp_update.afi == AFI_IP6
1795 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001796 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001797
1798 if (mp_withdraw.length
1799 && mp_withdraw.afi == AFI_IP6
1800 && mp_withdraw.safi == SAFI_MULTICAST)
1801 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001802
hasso93406d82005-02-02 14:40:33 +00001803 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001804 && mp_withdraw.afi == AFI_IP6
1805 && mp_withdraw.safi == SAFI_MULTICAST
1806 && mp_withdraw.length == 0)
1807 {
1808 /* End-of-RIB received */
1809
hasso93406d82005-02-02 14:40:33 +00001810 /* NSF delete stale route */
1811 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1812 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1813
paule01f9cb2004-07-09 17:48:53 +00001814 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001815 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001816 peer->host);
1817 }
paul718e3742002-12-13 20:15:29 +00001818 }
1819 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1820 {
1821 if (mp_update.length
1822 && mp_update.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001823 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
Paul Jakmab881c702010-11-23 16:35:42 +00001824 bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001825
1826 if (mp_withdraw.length
1827 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001828 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00001829 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001830
hasso93406d82005-02-02 14:40:33 +00001831 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001832 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001833 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
paule01f9cb2004-07-09 17:48:53 +00001834 && mp_withdraw.length == 0)
1835 {
1836 /* End-of-RIB received */
1837
1838 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001839 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001840 peer->host);
1841 }
paul718e3742002-12-13 20:15:29 +00001842 }
1843
1844 /* Everything is done. We unintern temporary structures which
1845 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001846 bgp_attr_unintern_sub (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001847
paul718e3742002-12-13 20:15:29 +00001848 /* If peering is stopped due to some reason, do not generate BGP
1849 event. */
1850 if (peer->status != Established)
1851 return 0;
1852
1853 /* Increment packet counter. */
1854 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001855 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001856
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001857 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001858 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001859 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001860
1861 return 0;
1862}
1863
1864/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001865static void
paul718e3742002-12-13 20:15:29 +00001866bgp_notify_receive (struct peer *peer, bgp_size_t size)
1867{
1868 struct bgp_notify bgp_notify;
1869
1870 if (peer->notify.data)
1871 {
1872 XFREE (MTYPE_TMP, peer->notify.data);
1873 peer->notify.data = NULL;
1874 peer->notify.length = 0;
1875 }
1876
1877 bgp_notify.code = stream_getc (peer->ibuf);
1878 bgp_notify.subcode = stream_getc (peer->ibuf);
1879 bgp_notify.length = size - 2;
1880 bgp_notify.data = NULL;
1881
1882 /* Preserv notify code and sub code. */
1883 peer->notify.code = bgp_notify.code;
1884 peer->notify.subcode = bgp_notify.subcode;
1885 /* For further diagnostic record returned Data. */
1886 if (bgp_notify.length)
1887 {
1888 peer->notify.length = size - 2;
1889 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1890 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1891 }
1892
1893 /* For debug */
1894 {
1895 int i;
1896 int first = 0;
1897 char c[4];
1898
1899 if (bgp_notify.length)
1900 {
1901 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1902 for (i = 0; i < bgp_notify.length; i++)
1903 if (first)
1904 {
1905 sprintf (c, " %02x", stream_getc (peer->ibuf));
1906 strcat (bgp_notify.data, c);
1907 }
1908 else
1909 {
1910 first = 1;
1911 sprintf (c, "%02x", stream_getc (peer->ibuf));
1912 strcpy (bgp_notify.data, c);
1913 }
1914 }
1915
1916 bgp_notify_print(peer, &bgp_notify, "received");
1917 if (bgp_notify.data)
1918 XFREE (MTYPE_TMP, bgp_notify.data);
1919 }
1920
1921 /* peer count update */
1922 peer->notify_in++;
1923
hassoe0701b72004-05-20 09:19:34 +00001924 if (peer->status == Established)
1925 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1926
paul718e3742002-12-13 20:15:29 +00001927 /* We have to check for Notify with Unsupported Optional Parameter.
1928 in that case we fallback to open without the capability option.
1929 But this done in bgp_stop. We just mark it here to avoid changing
1930 the fsm tables. */
1931 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1932 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1933 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1934
paul718e3742002-12-13 20:15:29 +00001935 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1936}
1937
1938/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001939static void
paul718e3742002-12-13 20:15:29 +00001940bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1941{
1942 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001943 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001944
1945 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1946}
1947
1948/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001949static void
paul718e3742002-12-13 20:15:29 +00001950bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1951{
1952 afi_t afi;
1953 safi_t safi;
1954 u_char reserved;
1955 struct stream *s;
1956
1957 /* If peer does not have the capability, send notification. */
1958 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1959 {
1960 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1961 peer->host);
1962 bgp_notify_send (peer,
1963 BGP_NOTIFY_HEADER_ERR,
1964 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1965 return;
1966 }
1967
1968 /* Status must be Established. */
1969 if (peer->status != Established)
1970 {
1971 plog_err (peer->log,
1972 "%s [Error] Route refresh packet received under status %s",
1973 peer->host, LOOKUP (bgp_status_msg, peer->status));
1974 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1975 return;
1976 }
1977
1978 s = peer->ibuf;
1979
1980 /* Parse packet. */
1981 afi = stream_getw (s);
1982 reserved = stream_getc (s);
1983 safi = stream_getc (s);
1984
1985 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001986 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001987 peer->host, afi, safi);
1988
1989 /* Check AFI and SAFI. */
1990 if ((afi != AFI_IP && afi != AFI_IP6)
1991 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001992 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00001993 {
1994 if (BGP_DEBUG (normal, NORMAL))
1995 {
ajs6b514742004-12-08 21:03:23 +00001996 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001997 peer->host, afi, safi);
1998 }
1999 return;
2000 }
2001
2002 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002003 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002004 safi = SAFI_MPLS_VPN;
2005
2006 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2007 {
2008 u_char *end;
2009 u_char when_to_refresh;
2010 u_char orf_type;
2011 u_int16_t orf_len;
2012
2013 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2014 {
2015 zlog_info ("%s ORF route refresh length error", peer->host);
2016 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2017 return;
2018 }
2019
2020 when_to_refresh = stream_getc (s);
2021 end = stream_pnt (s) + (size - 5);
2022
Paul Jakma370b64a2007-12-22 16:49:52 +00002023 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002024 {
2025 orf_type = stream_getc (s);
2026 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002027
2028 /* orf_len in bounds? */
2029 if ((stream_pnt (s) + orf_len) > end)
2030 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002031 if (orf_type == ORF_TYPE_PREFIX
2032 || orf_type == ORF_TYPE_PREFIX_OLD)
2033 {
2034 u_char *p_pnt = stream_pnt (s);
2035 u_char *p_end = stream_pnt (s) + orf_len;
2036 struct orf_prefix orfp;
2037 u_char common = 0;
2038 u_int32_t seq;
2039 int psize;
2040 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002041 int ret;
2042
2043 if (BGP_DEBUG (normal, NORMAL))
2044 {
ajs6b514742004-12-08 21:03:23 +00002045 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002046 peer->host, orf_type, orf_len);
2047 }
2048
Paul Jakma370b64a2007-12-22 16:49:52 +00002049 /* we're going to read at least 1 byte of common ORF header,
2050 * and 7 bytes of ORF Address-filter entry from the stream
2051 */
2052 if (orf_len < 7)
2053 break;
2054
paul718e3742002-12-13 20:15:29 +00002055 /* ORF prefix-list name */
2056 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2057
2058 while (p_pnt < p_end)
2059 {
Chris Halld64379e2010-05-14 16:38:39 +04002060 /* If the ORF entry is malformed, want to read as much of it
2061 * as possible without going beyond the bounds of the entry,
2062 * to maximise debug information.
2063 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002064 int ok;
paul718e3742002-12-13 20:15:29 +00002065 memset (&orfp, 0, sizeof (struct orf_prefix));
2066 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002067 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002068 if (common & ORF_COMMON_PART_REMOVE_ALL)
2069 {
2070 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002071 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00002072 prefix_bgp_orf_remove_all (name);
2073 break;
2074 }
Chris Halld64379e2010-05-14 16:38:39 +04002075 ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002076 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002077 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002078 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2079 p_pnt += sizeof (u_int32_t);
2080 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002081 }
2082 else
2083 p_pnt = p_end ;
2084
2085 if ((ok = (p_pnt < p_end)))
2086 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2087 if ((ok = (p_pnt < p_end)))
2088 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2089 if ((ok = (p_pnt < p_end)))
2090 orfp.p.prefixlen = *p_pnt++ ;
2091 orfp.p.family = afi2family (afi); /* afi checked already */
2092
2093 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2094 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2095 {
2096 ok = 0 ;
2097 psize = prefix_blen(&orfp.p) ;
2098 }
2099 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2100 {
2101 ok = 0 ;
2102 psize = p_end - p_pnt ;
2103 }
2104
2105 if (psize > 0)
2106 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002107 p_pnt += psize;
2108
2109 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002110 {
2111 char buf[INET6_BUFSIZ];
2112
2113 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2114 peer->host,
2115 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2116 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2117 orfp.seq,
2118 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2119 orfp.p.prefixlen, orfp.ge, orfp.le,
2120 ok ? "" : " MALFORMED");
2121 }
2122
Chris Halld64379e2010-05-14 16:38:39 +04002123 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002124 ret = prefix_bgp_orf_set (name, afi, &orfp,
2125 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2126 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
paul718e3742002-12-13 20:15:29 +00002127
Chris Halld64379e2010-05-14 16:38:39 +04002128 if (!ok || (ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002129 {
2130 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002131 zlog_debug ("%s Received misformatted prefixlist ORF."
2132 " Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002133 prefix_bgp_orf_remove_all (name);
2134 break;
2135 }
2136 }
2137 peer->orf_plist[afi][safi] =
2138 prefix_list_lookup (AFI_ORF_PREFIX, name);
2139 }
paul9985f832005-02-09 15:51:56 +00002140 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002141 }
2142 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002143 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002144 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2145 if (when_to_refresh == REFRESH_DEFER)
2146 return;
2147 }
2148
2149 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2150 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2151 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2152
2153 /* Perform route refreshment to the peer */
2154 bgp_announce_route (peer, afi, safi);
2155}
2156
paul94f2b392005-06-28 12:44:16 +00002157static int
paul718e3742002-12-13 20:15:29 +00002158bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2159{
2160 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002161 struct capability_mp_data mpc;
2162 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002163 u_char action;
2164 struct bgp *bgp;
2165 afi_t afi;
2166 safi_t safi;
2167
2168 bgp = peer->bgp;
2169 end = pnt + length;
2170
2171 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002172 {
paul718e3742002-12-13 20:15:29 +00002173 /* We need at least action, capability code and capability length. */
2174 if (pnt + 3 > end)
2175 {
2176 zlog_info ("%s Capability length error", peer->host);
2177 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2178 return -1;
2179 }
paul718e3742002-12-13 20:15:29 +00002180 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002181 hdr = (struct capability_header *)(pnt + 1);
2182
paul718e3742002-12-13 20:15:29 +00002183 /* Action value check. */
2184 if (action != CAPABILITY_ACTION_SET
2185 && action != CAPABILITY_ACTION_UNSET)
2186 {
2187 zlog_info ("%s Capability Action Value error %d",
2188 peer->host, action);
2189 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2190 return -1;
2191 }
2192
2193 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002194 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002195 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002196
2197 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002198 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002199 {
2200 zlog_info ("%s Capability length error", peer->host);
2201 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2202 return -1;
2203 }
2204
Paul Jakma6d582722007-08-06 15:21:45 +00002205 /* Fetch structure to the byte stream. */
2206 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2207
paul718e3742002-12-13 20:15:29 +00002208 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002209 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002210 {
Paul Jakma6d582722007-08-06 15:21:45 +00002211 afi = ntohs (mpc.afi);
2212 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002213
2214 /* Ignore capability when override-capability is set. */
2215 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2216 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002217
2218 if (!bgp_afi_safi_valid_indices (afi, &safi))
2219 {
2220 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002221 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2222 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002223 continue;
2224 }
2225
paul718e3742002-12-13 20:15:29 +00002226 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002227 if (BGP_DEBUG (normal, NORMAL))
2228 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2229 peer->host,
2230 action == CAPABILITY_ACTION_SET
2231 ? "Advertising" : "Removing",
2232 ntohs(mpc.afi) , mpc.safi);
2233
2234 if (action == CAPABILITY_ACTION_SET)
2235 {
2236 peer->afc_recv[afi][safi] = 1;
2237 if (peer->afc[afi][safi])
2238 {
2239 peer->afc_nego[afi][safi] = 1;
2240 bgp_announce_route (peer, afi, safi);
2241 }
2242 }
2243 else
2244 {
2245 peer->afc_recv[afi][safi] = 0;
2246 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002247
Paul Jakma6d582722007-08-06 15:21:45 +00002248 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002249 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002250 else
2251 BGP_EVENT_ADD (peer, BGP_Stop);
2252 }
paul718e3742002-12-13 20:15:29 +00002253 }
paul718e3742002-12-13 20:15:29 +00002254 else
2255 {
2256 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002257 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002258 }
Paul Jakma6d582722007-08-06 15:21:45 +00002259 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002260 }
2261 return 0;
2262}
2263
Paul Jakma01b7ce22009-06-18 12:34:43 +01002264/* Dynamic Capability is received.
2265 *
2266 * This is exported for unit-test purposes
2267 */
Paul Jakma6d582722007-08-06 15:21:45 +00002268int
paul718e3742002-12-13 20:15:29 +00002269bgp_capability_receive (struct peer *peer, bgp_size_t size)
2270{
2271 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002272
2273 /* Fetch pointer. */
2274 pnt = stream_pnt (peer->ibuf);
2275
2276 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002277 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002278
2279 /* If peer does not have the capability, send notification. */
2280 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2281 {
2282 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2283 peer->host);
2284 bgp_notify_send (peer,
2285 BGP_NOTIFY_HEADER_ERR,
2286 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002287 return -1;
paul718e3742002-12-13 20:15:29 +00002288 }
2289
2290 /* Status must be Established. */
2291 if (peer->status != Established)
2292 {
2293 plog_err (peer->log,
2294 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2295 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002296 return -1;
paul718e3742002-12-13 20:15:29 +00002297 }
2298
2299 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002300 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002301}
2302
2303/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002304static int
paul718e3742002-12-13 20:15:29 +00002305bgp_read_packet (struct peer *peer)
2306{
2307 int nbytes;
2308 int readsize;
2309
paul9985f832005-02-09 15:51:56 +00002310 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002311
2312 /* If size is zero then return. */
2313 if (! readsize)
2314 return 0;
2315
2316 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002317 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002318
2319 /* If read byte is smaller than zero then error occured. */
2320 if (nbytes < 0)
2321 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002322 /* Transient error should retry */
2323 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002324 return -1;
2325
2326 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002327 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002328
2329 if (peer->status == Established)
2330 {
2331 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2332 {
2333 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2334 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2335 }
2336 else
2337 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2338 }
2339
paul718e3742002-12-13 20:15:29 +00002340 BGP_EVENT_ADD (peer, TCP_fatal_error);
2341 return -1;
2342 }
2343
2344 /* When read byte is zero : clear bgp peer and return */
2345 if (nbytes == 0)
2346 {
2347 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002348 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002349 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002350
2351 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002352 {
2353 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2354 {
2355 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2356 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2357 }
2358 else
2359 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2360 }
hassoe0701b72004-05-20 09:19:34 +00002361
paul718e3742002-12-13 20:15:29 +00002362 BGP_EVENT_ADD (peer, TCP_connection_closed);
2363 return -1;
2364 }
2365
2366 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002367 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002368 return -1;
2369
2370 return 0;
2371}
2372
2373/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002374static int
paul718e3742002-12-13 20:15:29 +00002375bgp_marker_all_one (struct stream *s, int length)
2376{
2377 int i;
2378
2379 for (i = 0; i < length; i++)
2380 if (s->data[i] != 0xff)
2381 return 0;
2382
2383 return 1;
2384}
2385
2386/* Starting point of packet process function. */
2387int
2388bgp_read (struct thread *thread)
2389{
2390 int ret;
2391 u_char type = 0;
2392 struct peer *peer;
2393 bgp_size_t size;
2394 char notify_data_length[2];
2395
2396 /* Yes first of all get peer pointer. */
2397 peer = THREAD_ARG (thread);
2398 peer->t_read = NULL;
2399
2400 /* For non-blocking IO check. */
2401 if (peer->status == Connect)
2402 {
2403 bgp_connect_check (peer);
2404 goto done;
2405 }
2406 else
2407 {
pauleb821182004-05-01 08:44:08 +00002408 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002409 {
pauleb821182004-05-01 08:44:08 +00002410 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002411 return -1;
2412 }
pauleb821182004-05-01 08:44:08 +00002413 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002414 }
2415
2416 /* Read packet header to determine type of the packet */
2417 if (peer->packet_size == 0)
2418 peer->packet_size = BGP_HEADER_SIZE;
2419
paul9985f832005-02-09 15:51:56 +00002420 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002421 {
2422 ret = bgp_read_packet (peer);
2423
2424 /* Header read error or partial read packet. */
2425 if (ret < 0)
2426 goto done;
2427
2428 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002429 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002430 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2431 size = stream_getw (peer->ibuf);
2432 type = stream_getc (peer->ibuf);
2433
2434 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002435 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002436 peer->host, type, size - BGP_HEADER_SIZE);
2437
2438 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002439 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002440 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2441 {
2442 bgp_notify_send (peer,
2443 BGP_NOTIFY_HEADER_ERR,
2444 BGP_NOTIFY_HEADER_NOT_SYNC);
2445 goto done;
2446 }
2447
2448 /* BGP type check. */
2449 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2450 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2451 && type != BGP_MSG_ROUTE_REFRESH_NEW
2452 && type != BGP_MSG_ROUTE_REFRESH_OLD
2453 && type != BGP_MSG_CAPABILITY)
2454 {
2455 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002456 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002457 "%s unknown message type 0x%02x",
2458 peer->host, type);
2459 bgp_notify_send_with_data (peer,
2460 BGP_NOTIFY_HEADER_ERR,
2461 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2462 &type, 1);
2463 goto done;
2464 }
2465 /* Mimimum packet length check. */
2466 if ((size < BGP_HEADER_SIZE)
2467 || (size > BGP_MAX_PACKET_SIZE)
2468 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2469 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2470 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2471 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2472 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2473 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2474 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2475 {
2476 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002477 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002478 "%s bad message length - %d for %s",
2479 peer->host, size,
2480 type == 128 ? "ROUTE-REFRESH" :
2481 bgp_type_str[(int) type]);
2482 bgp_notify_send_with_data (peer,
2483 BGP_NOTIFY_HEADER_ERR,
2484 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002485 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002486 goto done;
2487 }
2488
2489 /* Adjust size to message length. */
2490 peer->packet_size = size;
2491 }
2492
2493 ret = bgp_read_packet (peer);
2494 if (ret < 0)
2495 goto done;
2496
2497 /* Get size and type again. */
2498 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2499 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2500
2501 /* BGP packet dump function. */
2502 bgp_dump_packet (peer, type, peer->ibuf);
2503
2504 size = (peer->packet_size - BGP_HEADER_SIZE);
2505
2506 /* Read rest of the packet and call each sort of packet routine */
2507 switch (type)
2508 {
2509 case BGP_MSG_OPEN:
2510 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002511 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002512 break;
2513 case BGP_MSG_UPDATE:
2514 peer->readtime = time(NULL); /* Last read timer reset */
2515 bgp_update_receive (peer, size);
2516 break;
2517 case BGP_MSG_NOTIFY:
2518 bgp_notify_receive (peer, size);
2519 break;
2520 case BGP_MSG_KEEPALIVE:
2521 peer->readtime = time(NULL); /* Last read timer reset */
2522 bgp_keepalive_receive (peer, size);
2523 break;
2524 case BGP_MSG_ROUTE_REFRESH_NEW:
2525 case BGP_MSG_ROUTE_REFRESH_OLD:
2526 peer->refresh_in++;
2527 bgp_route_refresh_receive (peer, size);
2528 break;
2529 case BGP_MSG_CAPABILITY:
2530 peer->dynamic_cap_in++;
2531 bgp_capability_receive (peer, size);
2532 break;
2533 }
2534
2535 /* Clear input buffer. */
2536 peer->packet_size = 0;
2537 if (peer->ibuf)
2538 stream_reset (peer->ibuf);
2539
2540 done:
2541 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2542 {
2543 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002544 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002545 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002546 }
2547 return 0;
2548}