blob: 1fa2fdfde988a7a99a71814e9899196e9320a68f [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
31#include "linklist.h"
32#include "plist.h"
33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_table.h"
36#include "bgpd/bgp_dump.h"
37#include "bgpd/bgp_attr.h"
38#include "bgpd/bgp_debug.h"
39#include "bgpd/bgp_fsm.h"
40#include "bgpd/bgp_route.h"
41#include "bgpd/bgp_packet.h"
42#include "bgpd/bgp_open.h"
43#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_community.h"
45#include "bgpd/bgp_ecommunity.h"
46#include "bgpd/bgp_network.h"
47#include "bgpd/bgp_mplsvpn.h"
48#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000049#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000050
51int stream_put_prefix (struct stream *, struct prefix *);
52
53/* Set up BGP packet marker and packet type. */
54static int
55bgp_packet_set_marker (struct stream *s, u_char type)
56{
57 int i;
58
59 /* Fill in marker. */
60 for (i = 0; i < BGP_MARKER_SIZE; i++)
61 stream_putc (s, 0xff);
62
63 /* Dummy total length. This field is should be filled in later on. */
64 stream_putw (s, 0);
65
66 /* BGP packet type. */
67 stream_putc (s, type);
68
69 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000070 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000071}
72
73/* Set BGP packet header size entry. If size is zero then use current
74 stream size. */
75static int
76bgp_packet_set_size (struct stream *s)
77{
78 int cp;
79
80 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000081 cp = stream_get_endp (s);
82 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000083
84 return cp;
85}
86
87/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000088static void
paul718e3742002-12-13 20:15:29 +000089bgp_packet_add (struct peer *peer, struct stream *s)
90{
91 /* Add packet to the end of list. */
92 stream_fifo_push (peer->obuf, s);
93}
94
95/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000096static void
paul718e3742002-12-13 20:15:29 +000097bgp_packet_delete (struct peer *peer)
98{
99 stream_free (stream_fifo_pop (peer->obuf));
100}
101
paul718e3742002-12-13 20:15:29 +0000102/* Check file descriptor whether connect is established. */
103static void
104bgp_connect_check (struct peer *peer)
105{
106 int status;
paul5228ad22004-06-04 17:58:18 +0000107 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000108 int ret;
109
110 /* Anyway I have to reset read and write thread. */
111 BGP_READ_OFF (peer->t_read);
112 BGP_WRITE_OFF (peer->t_write);
113
114 /* Check file descriptor. */
115 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000116 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000117
118 /* If getsockopt is fail, this is fatal error. */
119 if (ret < 0)
120 {
121 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
122 BGP_EVENT_ADD (peer, TCP_fatal_error);
123 return;
124 }
125
126 /* When status is 0 then TCP connection is established. */
127 if (status == 0)
128 {
129 BGP_EVENT_ADD (peer, TCP_connection_open);
130 }
131 else
132 {
133 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000134 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000135 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000136 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
137 }
138}
139
140/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000141static struct stream *
paul718e3742002-12-13 20:15:29 +0000142bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
143{
144 struct stream *s;
145 struct bgp_adj_out *adj;
146 struct bgp_advertise *adv;
147 struct stream *packet;
148 struct bgp_node *rn = NULL;
149 struct bgp_info *binfo = NULL;
150 bgp_size_t total_attr_len = 0;
151 unsigned long pos;
152 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000153
154 s = peer->work;
155 stream_reset (s);
156
157 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
158
159 while (adv)
160 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000161 assert (adv->rn);
162 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000163 adj = adv->adj;
164 if (adv->binfo)
165 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000166
167 /* When remaining space can't include NLRI and it's length. */
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000168 if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
paul718e3742002-12-13 20:15:29 +0000169 break;
170
171 /* If packet is empty, set attribute. */
172 if (stream_empty (s))
173 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000174 struct prefix_rd *prd = NULL;
175 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000176 struct peer *from = NULL;
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000177
178 if (rn->prn)
179 prd = (struct prefix_rd *) &rn->prn->p;
Paul Jakmafb982c22007-05-04 20:15:47 +0000180 if (binfo && binfo->extra)
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000182 tag = binfo->extra->tag;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000183 from = binfo->peer;
184 }
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000185
paul718e3742002-12-13 20:15:29 +0000186 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
187 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000188 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000189 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000190 total_attr_len = bgp_packet_attribute (NULL, peer, s,
191 adv->baa->attr,
192 &rn->p, afi, safi,
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000193 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000194 stream_putw_at (s, pos, total_attr_len);
195 }
196
197 if (afi == AFI_IP && safi == SAFI_UNICAST)
198 stream_put_prefix (s, &rn->p);
199
200 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000201 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000202 peer->host,
203 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
204 rn->p.prefixlen);
205
206 /* Synchnorize attribute. */
207 if (adj->attr)
208 bgp_attr_unintern (adj->attr);
209 else
210 peer->scount[afi][safi]++;
211
212 adj->attr = bgp_attr_intern (adv->baa->attr);
213
214 adv = bgp_advertise_clean (peer, adj, afi, safi);
215
216 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
217 break;
218 }
219
220 if (! stream_empty (s))
221 {
222 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000223 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000224 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000225 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000226 stream_reset (s);
227 return packet;
228 }
229 return NULL;
hasso93406d82005-02-02 14:40:33 +0000230}
paul718e3742002-12-13 20:15:29 +0000231
paul94f2b392005-06-28 12:44:16 +0000232static struct stream *
hasso93406d82005-02-02 14:40:33 +0000233bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
234{
235 struct stream *s;
236 struct stream *packet;
237
238#ifdef DISABLE_BGP_ANNOUNCE
239 return;
240#endif /* DISABLE_BGP_ANNOUNCE */
241
242 if (BGP_DEBUG (normal, NORMAL))
243 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
244
245 s = stream_new (BGP_MAX_PACKET_SIZE);
246
247 /* Make BGP update packet. */
248 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
249
250 /* Unfeasible Routes Length */
251 stream_putw (s, 0);
252
253 if (afi == AFI_IP && safi == SAFI_UNICAST)
254 {
255 /* Total Path Attribute Length */
256 stream_putw (s, 0);
257 }
258 else
259 {
260 /* Total Path Attribute Length */
261 stream_putw (s, 6);
262 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
263 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
264 stream_putc (s, 3);
265 stream_putw (s, afi);
266 stream_putc (s, safi);
267 }
268
269 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000270 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000271 bgp_packet_add (peer, packet);
272 stream_free (s);
273 return packet;
paul718e3742002-12-13 20:15:29 +0000274}
275
276/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000277static struct stream *
paul718e3742002-12-13 20:15:29 +0000278bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
279{
280 struct stream *s;
281 struct stream *packet;
282 struct bgp_adj_out *adj;
283 struct bgp_advertise *adv;
284 struct bgp_node *rn;
285 unsigned long pos;
286 bgp_size_t unfeasible_len;
287 bgp_size_t total_attr_len;
288 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000289
290 s = peer->work;
291 stream_reset (s);
292
293 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
294 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000295 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000296 adj = adv->adj;
297 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000298
299 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000300 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000301 break;
302
303 if (stream_empty (s))
304 {
305 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
306 stream_putw (s, 0);
307 }
308
309 if (afi == AFI_IP && safi == SAFI_UNICAST)
310 stream_put_prefix (s, &rn->p);
311 else
312 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000313 struct prefix_rd *prd = NULL;
314
315 if (rn->prn)
316 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000317 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000318 stream_putw (s, 0);
319 total_attr_len
320 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
321
322 /* Set total path attribute length. */
323 stream_putw_at (s, pos, total_attr_len);
324 }
325
326 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000327 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000328 peer->host,
329 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
330 rn->p.prefixlen);
331
332 peer->scount[afi][safi]--;
333
334 bgp_adj_out_remove (rn, adj, peer, afi, safi);
335 bgp_unlock_node (rn);
336
337 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
338 break;
339 }
340
341 if (! stream_empty (s))
342 {
343 if (afi == AFI_IP && safi == SAFI_UNICAST)
344 {
345 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000346 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000347 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
348 stream_putw (s, 0);
349 }
350 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000351 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000352 bgp_packet_add (peer, packet);
353 stream_reset (s);
354 return packet;
355 }
356
357 return NULL;
358}
359
360void
361bgp_default_update_send (struct peer *peer, struct attr *attr,
362 afi_t afi, safi_t safi, struct peer *from)
363{
364 struct stream *s;
365 struct stream *packet;
366 struct prefix p;
367 unsigned long pos;
368 bgp_size_t total_attr_len;
369 char attrstr[BUFSIZ];
370 char buf[BUFSIZ];
371
372#ifdef DISABLE_BGP_ANNOUNCE
373 return;
374#endif /* DISABLE_BGP_ANNOUNCE */
375
376 if (afi == AFI_IP)
377 str2prefix ("0.0.0.0/0", &p);
378#ifdef HAVE_IPV6
379 else
380 str2prefix ("::/0", &p);
381#endif /* HAVE_IPV6 */
382
383 /* Logging the attribute. */
384 if (BGP_DEBUG (update, UPDATE_OUT))
385 {
386 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000387 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000388 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
389 p.prefixlen, attrstr);
390 }
391
392 s = stream_new (BGP_MAX_PACKET_SIZE);
393
394 /* Make BGP update packet. */
395 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
396
397 /* Unfeasible Routes Length. */
398 stream_putw (s, 0);
399
400 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000401 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000402 stream_putw (s, 0);
403 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
404
405 /* Set Total Path Attribute Length. */
406 stream_putw_at (s, pos, total_attr_len);
407
408 /* NLRI set. */
409 if (p.family == AF_INET && safi == SAFI_UNICAST)
410 stream_put_prefix (s, &p);
411
412 /* Set size. */
413 bgp_packet_set_size (s);
414
paule83e2082005-05-19 02:12:25 +0000415 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000416 stream_free (s);
417
418 /* Dump packet if debug option is set. */
419#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000420 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000421#endif /* DEBUG */
422
423 /* Add packet to the peer. */
424 bgp_packet_add (peer, packet);
425
pauleb821182004-05-01 08:44:08 +0000426 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000427}
428
429void
430bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
431{
432 struct stream *s;
433 struct stream *packet;
434 struct prefix p;
435 unsigned long pos;
436 unsigned long cp;
437 bgp_size_t unfeasible_len;
438 bgp_size_t total_attr_len;
439 char buf[BUFSIZ];
440
441#ifdef DISABLE_BGP_ANNOUNCE
442 return;
443#endif /* DISABLE_BGP_ANNOUNCE */
444
445 if (afi == AFI_IP)
446 str2prefix ("0.0.0.0/0", &p);
447#ifdef HAVE_IPV6
448 else
449 str2prefix ("::/0", &p);
450#endif /* HAVE_IPV6 */
451
452 total_attr_len = 0;
453 pos = 0;
454
455 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000456 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000457 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
458 p.prefixlen);
459
460 s = stream_new (BGP_MAX_PACKET_SIZE);
461
462 /* Make BGP update packet. */
463 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
464
465 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000466 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000467 stream_putw (s, 0);
468
469 /* Withdrawn Routes. */
470 if (p.family == AF_INET && safi == SAFI_UNICAST)
471 {
472 stream_put_prefix (s, &p);
473
paul9985f832005-02-09 15:51:56 +0000474 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000475
476 /* Set unfeasible len. */
477 stream_putw_at (s, cp, unfeasible_len);
478
479 /* Set total path attribute length. */
480 stream_putw (s, 0);
481 }
482 else
483 {
paul9985f832005-02-09 15:51:56 +0000484 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000485 stream_putw (s, 0);
486 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
487
488 /* Set total path attribute length. */
489 stream_putw_at (s, pos, total_attr_len);
490 }
491
492 bgp_packet_set_size (s);
493
paule83e2082005-05-19 02:12:25 +0000494 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000495 stream_free (s);
496
497 /* Add packet to the peer. */
498 bgp_packet_add (peer, packet);
499
pauleb821182004-05-01 08:44:08 +0000500 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000501}
502
503/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000504static struct stream *
paul718e3742002-12-13 20:15:29 +0000505bgp_write_packet (struct peer *peer)
506{
507 afi_t afi;
508 safi_t safi;
509 struct stream *s = NULL;
510 struct bgp_advertise *adv;
511
512 s = stream_fifo_head (peer->obuf);
513 if (s)
514 return s;
515
516 for (afi = AFI_IP; afi < AFI_MAX; afi++)
517 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
518 {
519 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
520 if (adv)
521 {
522 s = bgp_withdraw_packet (peer, afi, safi);
523 if (s)
524 return s;
525 }
526 }
527
528 for (afi = AFI_IP; afi < AFI_MAX; afi++)
529 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
530 {
531 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
532 if (adv)
533 {
534 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000535 {
536 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
537 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
538 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
539 && safi != SAFI_MPLS_VPN)
540 {
541 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
542 PEER_STATUS_EOR_RECEIVED))
543 s = bgp_update_packet (peer, afi, safi);
544 }
545 else
546 s = bgp_update_packet (peer, afi, safi);
547 }
paul718e3742002-12-13 20:15:29 +0000548
549 if (s)
550 return s;
551 }
hasso93406d82005-02-02 14:40:33 +0000552
553 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
554 {
555 if (peer->afc_nego[afi][safi] && peer->synctime
556 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
557 && safi != SAFI_MPLS_VPN)
558 {
559 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
560 return bgp_update_packet_eor (peer, afi, safi);
561 }
562 }
paul718e3742002-12-13 20:15:29 +0000563 }
564
565 return NULL;
566}
567
568/* Is there partially written packet or updates we can send right
569 now. */
paul94f2b392005-06-28 12:44:16 +0000570static int
paul718e3742002-12-13 20:15:29 +0000571bgp_write_proceed (struct peer *peer)
572{
573 afi_t afi;
574 safi_t safi;
575 struct bgp_advertise *adv;
576
577 if (stream_fifo_head (peer->obuf))
578 return 1;
579
580 for (afi = AFI_IP; afi < AFI_MAX; afi++)
581 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
582 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
583 return 1;
584
585 for (afi = AFI_IP; afi < AFI_MAX; afi++)
586 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
587 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
588 if (adv->binfo->uptime < peer->synctime)
589 return 1;
590
591 return 0;
592}
593
594/* Write packet to the peer. */
595int
596bgp_write (struct thread *thread)
597{
598 struct peer *peer;
599 u_char type;
600 struct stream *s;
601 int num;
paulfd79ac92004-10-13 05:06:08 +0000602 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000603 int write_errno;
604
605 /* Yes first of all get peer pointer. */
606 peer = THREAD_ARG (thread);
607 peer->t_write = NULL;
608
609 /* For non-blocking IO check. */
610 if (peer->status == Connect)
611 {
612 bgp_connect_check (peer);
613 return 0;
614 }
615
616 /* Nonblocking write until TCP output buffer is full. */
617 while (1)
618 {
619 int writenum;
paula24a7e12005-01-05 08:14:13 +0000620 int val;
paul718e3742002-12-13 20:15:29 +0000621
622 s = bgp_write_packet (peer);
623 if (! s)
624 return 0;
paula24a7e12005-01-05 08:14:13 +0000625
626 /* XXX: FIXME, the socket should be NONBLOCK from the start
627 * status shouldnt need to be toggled on each write
628 */
629 val = fcntl (peer->fd, F_GETFL, 0);
630 fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
paul718e3742002-12-13 20:15:29 +0000631
632 /* Number of bytes to be sent. */
633 writenum = stream_get_endp (s) - stream_get_getp (s);
634
635 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000636 num = write (peer->fd, STREAM_PNT (s), writenum);
paul718e3742002-12-13 20:15:29 +0000637 write_errno = errno;
paula24a7e12005-01-05 08:14:13 +0000638 fcntl (peer->fd, F_SETFL, val);
paul718e3742002-12-13 20:15:29 +0000639 if (num <= 0)
640 {
641 /* Partial write. */
642 if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
643 break;
644
Paul Jakmadcdf3992006-10-15 23:39:59 +0000645 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000646 return 0;
647 }
648 if (num != writenum)
649 {
paul9985f832005-02-09 15:51:56 +0000650 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000651
652 if (write_errno == EAGAIN)
653 break;
654
655 continue;
656 }
657
658 /* Retrieve BGP packet type. */
659 stream_set_getp (s, BGP_MARKER_SIZE + 2);
660 type = stream_getc (s);
661
662 switch (type)
663 {
664 case BGP_MSG_OPEN:
665 peer->open_out++;
666 break;
667 case BGP_MSG_UPDATE:
668 peer->update_out++;
669 break;
670 case BGP_MSG_NOTIFY:
671 peer->notify_out++;
672 /* Double start timer. */
673 peer->v_start *= 2;
674
675 /* Overflow check. */
676 if (peer->v_start >= (60 * 2))
677 peer->v_start = (60 * 2);
678
Paul Jakmaca058a32006-09-14 02:58:49 +0000679 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000680 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000681 return 0;
paul718e3742002-12-13 20:15:29 +0000682 case BGP_MSG_KEEPALIVE:
683 peer->keepalive_out++;
684 break;
685 case BGP_MSG_ROUTE_REFRESH_NEW:
686 case BGP_MSG_ROUTE_REFRESH_OLD:
687 peer->refresh_out++;
688 break;
689 case BGP_MSG_CAPABILITY:
690 peer->dynamic_cap_out++;
691 break;
692 }
693
694 /* OK we send packet so delete it. */
695 bgp_packet_delete (peer);
696
697 if (++count >= BGP_WRITE_PACKET_MAX)
698 break;
699 }
700
701 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000702 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
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{
711 int ret;
712 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
721 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000722 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000723 if (ret <= 0)
724 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000725 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000726 return 0;
727 }
728
729 /* Retrieve BGP packet type. */
730 stream_set_getp (s, BGP_MARKER_SIZE + 2);
731 type = stream_getc (s);
732
733 assert (type == BGP_MSG_NOTIFY);
734
735 /* Type should be notify. */
736 peer->notify_out++;
737
738 /* Double start timer. */
739 peer->v_start *= 2;
740
741 /* Overflow check. */
742 if (peer->v_start >= (60 * 2))
743 peer->v_start = (60 * 2);
744
Paul Jakmadcdf3992006-10-15 23:39:59 +0000745 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000746
747 return 0;
748}
749
750/* Make keepalive packet and send it to the peer. */
751void
752bgp_keepalive_send (struct peer *peer)
753{
754 struct stream *s;
755 int length;
756
757 s = stream_new (BGP_MAX_PACKET_SIZE);
758
759 /* Make keepalive packet. */
760 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
761
762 /* Set packet size. */
763 length = bgp_packet_set_size (s);
764
765 /* Dump packet if debug option is set. */
766 /* bgp_packet_dump (s); */
767
768 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000769 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000770 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000771 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000772 peer->host, BGP_MSG_KEEPALIVE, length);
773
774 /* Add packet to the peer. */
775 bgp_packet_add (peer, s);
776
pauleb821182004-05-01 08:44:08 +0000777 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000778}
779
780/* Make open packet and send it to the peer. */
781void
782bgp_open_send (struct peer *peer)
783{
784 struct stream *s;
785 int length;
786 u_int16_t send_holdtime;
787 as_t local_as;
788
789 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
790 send_holdtime = peer->holdtime;
791 else
792 send_holdtime = peer->bgp->default_holdtime;
793
794 /* local-as Change */
795 if (peer->change_local_as)
796 local_as = peer->change_local_as;
797 else
798 local_as = peer->local_as;
799
800 s = stream_new (BGP_MAX_PACKET_SIZE);
801
802 /* Make open packet. */
803 bgp_packet_set_marker (s, BGP_MSG_OPEN);
804
805 /* Set open packet values. */
806 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000807 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
808 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000809 stream_putw (s, send_holdtime); /* Hold Time */
810 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
811
812 /* Set capability code. */
813 bgp_open_capability (s, peer);
814
815 /* Set BGP packet length. */
816 length = bgp_packet_set_size (s);
817
818 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000819 zlog_debug ("%s sending OPEN, version %d, my as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000820 peer->host, BGP_VERSION_4, local_as,
821 send_holdtime, inet_ntoa (peer->local_id));
822
823 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000824 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000825 peer->host, BGP_MSG_OPEN, length);
826
827 /* Dump packet if debug option is set. */
828 /* bgp_packet_dump (s); */
829
830 /* Add packet to the peer. */
831 bgp_packet_add (peer, s);
832
pauleb821182004-05-01 08:44:08 +0000833 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000834}
835
836/* Send BGP notify packet with data potion. */
837void
838bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
839 u_char *data, size_t datalen)
840{
841 struct stream *s;
842 int length;
843
844 /* Allocate new stream. */
845 s = stream_new (BGP_MAX_PACKET_SIZE);
846
847 /* Make nitify packet. */
848 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
849
850 /* Set notify packet values. */
851 stream_putc (s, code); /* BGP notify code */
852 stream_putc (s, sub_code); /* BGP notify sub_code */
853
854 /* If notify data is present. */
855 if (data)
856 stream_write (s, data, datalen);
857
858 /* Set BGP packet length. */
859 length = bgp_packet_set_size (s);
860
861 /* Add packet to the peer. */
862 stream_fifo_clean (peer->obuf);
863 bgp_packet_add (peer, s);
864
865 /* For debug */
866 {
867 struct bgp_notify bgp_notify;
868 int first = 0;
869 int i;
870 char c[4];
871
872 bgp_notify.code = code;
873 bgp_notify.subcode = sub_code;
874 bgp_notify.data = NULL;
875 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
876
877 if (bgp_notify.length)
878 {
879 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
880 for (i = 0; i < bgp_notify.length; i++)
881 if (first)
882 {
883 sprintf (c, " %02x", data[i]);
884 strcat (bgp_notify.data, c);
885 }
886 else
887 {
888 first = 1;
889 sprintf (c, "%02x", data[i]);
890 strcpy (bgp_notify.data, c);
891 }
892 }
893 bgp_notify_print (peer, &bgp_notify, "sending");
894 if (bgp_notify.data)
895 XFREE (MTYPE_TMP, bgp_notify.data);
896 }
897
898 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000899 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000900 peer->host, BGP_MSG_NOTIFY, length);
901
hassoe0701b72004-05-20 09:19:34 +0000902 /* peer reset cause */
903 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
904 {
905 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
906 peer->last_reset = PEER_DOWN_USER_RESET;
907 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
908 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
909 else
910 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
911 }
912
paul718e3742002-12-13 20:15:29 +0000913 /* Call imidiately. */
914 BGP_WRITE_OFF (peer->t_write);
915
916 bgp_write_notify (peer);
917}
918
919/* Send BGP notify packet. */
920void
921bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
922{
923 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
924}
925
paul94f2b392005-06-28 12:44:16 +0000926static const char *
paul718e3742002-12-13 20:15:29 +0000927afi2str (afi_t afi)
928{
929 if (afi == AFI_IP)
930 return "AFI_IP";
931 else if (afi == AFI_IP6)
932 return "AFI_IP6";
933 else
934 return "Unknown AFI";
935}
936
paul94f2b392005-06-28 12:44:16 +0000937static const char *
paul718e3742002-12-13 20:15:29 +0000938safi2str (safi_t safi)
939{
940 if (safi == SAFI_UNICAST)
941 return "SAFI_UNICAST";
942 else if (safi == SAFI_MULTICAST)
943 return "SAFI_MULTICAST";
944 else if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPNV4)
945 return "SAFI_MPLS_VPN";
946 else
947 return "Unknown SAFI";
948}
949
950/* Send route refresh message to the peer. */
951void
952bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
953 u_char orf_type, u_char when_to_refresh, int remove)
954{
955 struct stream *s;
956 struct stream *packet;
957 int length;
958 struct bgp_filter *filter;
959 int orf_refresh = 0;
960
961#ifdef DISABLE_BGP_ANNOUNCE
962 return;
963#endif /* DISABLE_BGP_ANNOUNCE */
964
965 filter = &peer->filter[afi][safi];
966
967 /* Adjust safi code. */
968 if (safi == SAFI_MPLS_VPN)
969 safi = BGP_SAFI_VPNV4;
970
971 s = stream_new (BGP_MAX_PACKET_SIZE);
972
973 /* Make BGP update packet. */
974 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
975 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
976 else
977 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
978
979 /* Encode Route Refresh message. */
980 stream_putw (s, afi);
981 stream_putc (s, 0);
982 stream_putc (s, safi);
983
984 if (orf_type == ORF_TYPE_PREFIX
985 || orf_type == ORF_TYPE_PREFIX_OLD)
986 if (remove || filter->plist[FILTER_IN].plist)
987 {
988 u_int16_t orf_len;
989 unsigned long orfp;
990
991 orf_refresh = 1;
992 stream_putc (s, when_to_refresh);
993 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000994 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000995 stream_putw (s, 0);
996
997 if (remove)
998 {
999 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1000 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1001 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001002 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001003 peer->host, orf_type,
1004 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1005 afi, safi);
1006 }
1007 else
1008 {
1009 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1010 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1011 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1012 ORF_COMMON_PART_DENY);
1013 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001014 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001015 peer->host, orf_type,
1016 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1017 afi, safi);
1018 }
1019
1020 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001021 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001022 stream_putw_at (s, orfp, orf_len);
1023 }
1024
1025 /* Set packet size. */
1026 length = bgp_packet_set_size (s);
1027
1028 if (BGP_DEBUG (normal, NORMAL))
1029 {
1030 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001031 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001032 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001033 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001034 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1035 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1036 }
1037
1038 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001039 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001040 stream_free (s);
1041
1042 /* Add packet to the peer. */
1043 bgp_packet_add (peer, packet);
1044
pauleb821182004-05-01 08:44:08 +00001045 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001046}
1047
1048/* Send capability message to the peer. */
1049void
1050bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1051 int capability_code, int action)
1052{
1053 struct stream *s;
1054 struct stream *packet;
1055 int length;
1056
1057 /* Adjust safi code. */
1058 if (safi == SAFI_MPLS_VPN)
1059 safi = BGP_SAFI_VPNV4;
1060
1061 s = stream_new (BGP_MAX_PACKET_SIZE);
1062
1063 /* Make BGP update packet. */
1064 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1065
1066 /* Encode MP_EXT capability. */
1067 if (capability_code == CAPABILITY_CODE_MP)
1068 {
1069 stream_putc (s, action);
1070 stream_putc (s, CAPABILITY_CODE_MP);
1071 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1072 stream_putw (s, afi);
1073 stream_putc (s, 0);
1074 stream_putc (s, safi);
1075
1076 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001077 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001078 peer->host, action == CAPABILITY_ACTION_SET ?
1079 "Advertising" : "Removing", afi, safi);
1080 }
1081
paul718e3742002-12-13 20:15:29 +00001082 /* Set packet size. */
1083 length = bgp_packet_set_size (s);
1084
1085 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001086 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001087 stream_free (s);
1088
1089 /* Add packet to the peer. */
1090 bgp_packet_add (peer, packet);
1091
1092 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001093 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001094 peer->host, BGP_MSG_CAPABILITY, length);
1095
pauleb821182004-05-01 08:44:08 +00001096 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001097}
1098
1099/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001100static int
pauleb821182004-05-01 08:44:08 +00001101bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001102{
pauleb821182004-05-01 08:44:08 +00001103 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001104 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001105 struct bgp *bgp;
1106
1107 bgp = bgp_get_default ();
1108 if (! bgp)
1109 return 0;
1110
1111 /* Upon receipt of an OPEN message, the local system must examine
1112 all of its connections that are in the OpenConfirm state. A BGP
1113 speaker may also examine connections in an OpenSent state if it
1114 knows the BGP Identifier of the peer by means outside of the
1115 protocol. If among these connections there is a connection to a
1116 remote BGP speaker whose BGP Identifier equals the one in the
1117 OPEN message, then the local system performs the following
1118 collision resolution procedure: */
1119
paul1eb8ef22005-04-07 07:30:20 +00001120 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001121 {
1122 /* Under OpenConfirm status, local peer structure already hold
1123 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001124
1125 if (peer != new
1126 && (peer->status == OpenConfirm || peer->status == OpenSent)
1127 && sockunion_same (&peer->su, &new->su))
1128 {
paul718e3742002-12-13 20:15:29 +00001129 /* 1. The BGP Identifier of the local system is compared to
1130 the BGP Identifier of the remote system (as specified in
1131 the OPEN message). */
1132
1133 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1134 {
1135 /* 2. If the value of the local BGP Identifier is less
1136 than the remote one, the local system closes BGP
1137 connection that already exists (the one that is
1138 already in the OpenConfirm state), and accepts BGP
1139 connection initiated by the remote system. */
1140
pauleb821182004-05-01 08:44:08 +00001141 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001142 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001143 return 1;
1144 }
1145 else
1146 {
1147 /* 3. Otherwise, the local system closes newly created
1148 BGP connection (the one associated with the newly
1149 received OPEN message), and continues to use the
1150 existing one (the one that is already in the
1151 OpenConfirm state). */
1152
pauleb821182004-05-01 08:44:08 +00001153 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001154 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1155 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001156 return -1;
1157 }
pauleb821182004-05-01 08:44:08 +00001158 }
1159 }
paul718e3742002-12-13 20:15:29 +00001160 return 0;
1161}
1162
paul94f2b392005-06-28 12:44:16 +00001163static int
paul718e3742002-12-13 20:15:29 +00001164bgp_open_receive (struct peer *peer, bgp_size_t size)
1165{
1166 int ret;
1167 u_char version;
1168 u_char optlen;
1169 u_int16_t holdtime;
1170 u_int16_t send_holdtime;
1171 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001172 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001173 struct peer *realpeer;
1174 struct in_addr remote_id;
1175 int capability;
paul5228ad22004-06-04 17:58:18 +00001176 u_int8_t notify_data_remote_as[2];
1177 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001178
1179 realpeer = NULL;
1180
1181 /* Parse open packet. */
1182 version = stream_getc (peer->ibuf);
1183 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1184 remote_as = stream_getw (peer->ibuf);
1185 holdtime = stream_getw (peer->ibuf);
1186 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1187 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1188
1189 /* Receive OPEN message log */
1190 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001191 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %d,"
1192 " holdtime %d, id %s",
1193 peer->host, version, remote_as, holdtime,
1194 inet_ntoa (remote_id));
1195
1196 /* BEGIN to read the capability here, but dont do it yet */
1197 capability = 0;
1198 optlen = stream_getc (peer->ibuf);
1199
1200 if (optlen != 0)
1201 {
1202 /* We need the as4 capability value *right now* because
1203 * if it is there, we have not got the remote_as yet, and without
1204 * that we do not know which peer is connecting to us now.
1205 */
1206 as4 = peek_for_as4_capability (peer, optlen);
1207 }
1208
1209 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1210 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1211 {
1212 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1213 peer->host);
1214 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1215 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1216 return -1;
1217 }
1218
1219 if (remote_as == BGP_AS_TRANS)
1220 {
1221 /* Take the AS4 from the capability. We must have received the
1222 * capability now! Otherwise we have a asn16 peer who uses
1223 * BGP_AS_TRANS, for some unknown reason.
1224 */
1225 if (as4 == BGP_AS_TRANS)
1226 {
1227 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1228 peer->host);
1229 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1230 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1231 return -1;
1232 }
1233
1234 if (!as4 && BGP_DEBUG (as4, AS4))
1235 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1236 " Odd, but proceeding.", peer->host);
1237 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
1238 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 fits "
1239 "in 2-bytes, very odd peer.", peer->host, as4);
1240 if (as4)
1241 remote_as = as4;
1242 }
1243 else
1244 {
1245 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1246 /* If we have got the capability, peer->as4cap must match remote_as */
1247 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1248 && as4 != remote_as)
1249 {
1250 /* raise error, log this, close session */
1251 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1252 " mismatch with 16bit 'myasn' %u in open",
1253 peer->host, as4, remote_as);
1254 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1255 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1256 return -1;
1257 }
1258 }
1259
paul718e3742002-12-13 20:15:29 +00001260 /* Lookup peer from Open packet. */
1261 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1262 {
1263 int as = 0;
1264
1265 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1266
1267 if (! realpeer)
1268 {
1269 /* Peer's source IP address is check in bgp_accept(), so this
1270 must be AS number mismatch or remote-id configuration
1271 mismatch. */
1272 if (as)
1273 {
1274 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001275 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1276 peer->host, inet_ntoa (remote_id));
1277 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1278 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1279 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001280 }
1281 else
1282 {
1283 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001284 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
1285 peer->host, remote_as, peer->as);
1286 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1287 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1288 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001289 }
1290 return -1;
1291 }
1292 }
1293
1294 /* When collision is detected and this peer is closed. Retrun
1295 immidiately. */
1296 ret = bgp_collision_detect (peer, remote_id);
1297 if (ret < 0)
1298 return ret;
1299
pauleb821182004-05-01 08:44:08 +00001300 /* Hack part. */
1301 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1302 {
hasso93406d82005-02-02 14:40:33 +00001303 if (realpeer->status == Established
1304 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1305 {
1306 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1307 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1308 }
1309 else if (ret == 0 && realpeer->status != Active
1310 && realpeer->status != OpenSent
1311 && realpeer->status != OpenConfirm)
1312
pauleb821182004-05-01 08:44:08 +00001313 {
1314 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001315 zlog_debug ("%s peer status is %s close connection",
1316 realpeer->host, LOOKUP (bgp_status_msg,
1317 realpeer->status));
1318 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1319 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1320
pauleb821182004-05-01 08:44:08 +00001321 return -1;
1322 }
1323
1324 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00001325 zlog_debug ("%s [Event] Transfer temporary BGP peer to existing one",
pauleb821182004-05-01 08:44:08 +00001326 peer->host);
1327
1328 bgp_stop (realpeer);
1329
1330 /* Transfer file descriptor. */
1331 realpeer->fd = peer->fd;
1332 peer->fd = -1;
1333
1334 /* Transfer input buffer. */
1335 stream_free (realpeer->ibuf);
1336 realpeer->ibuf = peer->ibuf;
1337 realpeer->packet_size = peer->packet_size;
1338 peer->ibuf = NULL;
1339
1340 /* Transfer status. */
1341 realpeer->status = peer->status;
1342 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001343
pauleb821182004-05-01 08:44:08 +00001344 /* peer pointer change. Open packet send to neighbor. */
1345 peer = realpeer;
1346 bgp_open_send (peer);
1347 if (peer->fd < 0)
1348 {
1349 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1350 peer->fd);
1351 return -1;
1352 }
1353 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1354 }
1355
paul718e3742002-12-13 20:15:29 +00001356 /* remote router-id check. */
1357 if (remote_id.s_addr == 0
1358 || ntohl (remote_id.s_addr) >= 0xe0000000
1359 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1360 {
1361 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001362 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001363 peer->host, inet_ntoa (remote_id));
1364 bgp_notify_send_with_data (peer,
1365 BGP_NOTIFY_OPEN_ERR,
1366 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1367 notify_data_remote_id, 4);
1368 return -1;
1369 }
1370
1371 /* Set remote router-id */
1372 peer->remote_id = remote_id;
1373
1374 /* Peer BGP version check. */
1375 if (version != BGP_VERSION_4)
1376 {
paul5228ad22004-06-04 17:58:18 +00001377 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001378 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001379 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001380 peer->host, version, BGP_VERSION_4);
1381 bgp_notify_send_with_data (peer,
1382 BGP_NOTIFY_OPEN_ERR,
1383 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001384 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001385 return -1;
1386 }
1387
1388 /* Check neighbor as number. */
1389 if (remote_as != peer->as)
1390 {
1391 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001392 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
paul718e3742002-12-13 20:15:29 +00001393 peer->host, remote_as, peer->as);
1394 bgp_notify_send_with_data (peer,
1395 BGP_NOTIFY_OPEN_ERR,
1396 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1397 notify_data_remote_as, 2);
1398 return -1;
1399 }
1400
1401 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1402 calculate the value of the Hold Timer by using the smaller of its
1403 configured Hold Time and the Hold Time received in the OPEN message.
1404 The Hold Time MUST be either zero or at least three seconds. An
1405 implementation may reject connections on the basis of the Hold Time. */
1406
1407 if (holdtime < 3 && holdtime != 0)
1408 {
1409 bgp_notify_send (peer,
1410 BGP_NOTIFY_OPEN_ERR,
1411 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1412 return -1;
1413 }
1414
1415 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1416 would be one third of the Hold Time interval. KEEPALIVE messages
1417 MUST NOT be sent more frequently than one per second. An
1418 implementation MAY adjust the rate at which it sends KEEPALIVE
1419 messages as a function of the Hold Time interval. */
1420
1421 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1422 send_holdtime = peer->holdtime;
1423 else
1424 send_holdtime = peer->bgp->default_holdtime;
1425
1426 if (holdtime < send_holdtime)
1427 peer->v_holdtime = holdtime;
1428 else
1429 peer->v_holdtime = send_holdtime;
1430
1431 peer->v_keepalive = peer->v_holdtime / 3;
1432
1433 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001434 if (optlen != 0)
1435 {
1436 ret = bgp_open_option_parse (peer, optlen, &capability);
1437 if (ret < 0)
1438 return ret;
paul718e3742002-12-13 20:15:29 +00001439 }
1440 else
1441 {
1442 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001443 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001444 peer->host);
1445 }
1446
1447 /* Override capability. */
1448 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1449 {
1450 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1451 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1452 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1453 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1454 }
1455
1456 /* Get sockname. */
1457 bgp_getsockname (peer);
1458
1459 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1460
1461 peer->packet_size = 0;
1462 if (peer->ibuf)
1463 stream_reset (peer->ibuf);
1464
1465 return 0;
1466}
1467
1468/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001469static int
paul718e3742002-12-13 20:15:29 +00001470bgp_update_receive (struct peer *peer, bgp_size_t size)
1471{
1472 int ret;
1473 u_char *end;
1474 struct stream *s;
1475 struct attr attr;
1476 bgp_size_t attribute_len;
1477 bgp_size_t update_len;
1478 bgp_size_t withdraw_len;
1479 struct bgp_nlri update;
1480 struct bgp_nlri withdraw;
1481 struct bgp_nlri mp_update;
1482 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001483 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001484
1485 /* Status must be Established. */
1486 if (peer->status != Established)
1487 {
1488 zlog_err ("%s [FSM] Update packet received under status %s",
1489 peer->host, LOOKUP (bgp_status_msg, peer->status));
1490 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1491 return -1;
1492 }
1493
1494 /* Set initial values. */
1495 memset (&attr, 0, sizeof (struct attr));
1496 memset (&update, 0, sizeof (struct bgp_nlri));
1497 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1498 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1499 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1500
1501 s = peer->ibuf;
1502 end = stream_pnt (s) + size;
1503
1504 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1505 Length is too large (i.e., if Unfeasible Routes Length + Total
1506 Attribute Length + 23 exceeds the message Length), then the Error
1507 Subcode is set to Malformed Attribute List. */
1508 if (stream_pnt (s) + 2 > end)
1509 {
1510 zlog_err ("%s [Error] Update packet error"
1511 " (packet length is short for unfeasible length)",
1512 peer->host);
1513 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1514 BGP_NOTIFY_UPDATE_MAL_ATTR);
1515 return -1;
1516 }
1517
1518 /* Unfeasible Route Length. */
1519 withdraw_len = stream_getw (s);
1520
1521 /* Unfeasible Route Length check. */
1522 if (stream_pnt (s) + withdraw_len > end)
1523 {
1524 zlog_err ("%s [Error] Update packet error"
1525 " (packet unfeasible length overflow %d)",
1526 peer->host, withdraw_len);
1527 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1528 BGP_NOTIFY_UPDATE_MAL_ATTR);
1529 return -1;
1530 }
1531
1532 /* Unfeasible Route packet format check. */
1533 if (withdraw_len > 0)
1534 {
1535 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1536 if (ret < 0)
1537 return -1;
1538
1539 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001540 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001541
1542 withdraw.afi = AFI_IP;
1543 withdraw.safi = SAFI_UNICAST;
1544 withdraw.nlri = stream_pnt (s);
1545 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001546 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001547 }
1548
1549 /* Attribute total length check. */
1550 if (stream_pnt (s) + 2 > end)
1551 {
1552 zlog_warn ("%s [Error] Packet Error"
1553 " (update packet is short for attribute length)",
1554 peer->host);
1555 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1556 BGP_NOTIFY_UPDATE_MAL_ATTR);
1557 return -1;
1558 }
1559
1560 /* Fetch attribute total length. */
1561 attribute_len = stream_getw (s);
1562
1563 /* Attribute length check. */
1564 if (stream_pnt (s) + attribute_len > end)
1565 {
1566 zlog_warn ("%s [Error] Packet Error"
1567 " (update packet attribute length overflow %d)",
1568 peer->host, attribute_len);
1569 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1570 BGP_NOTIFY_UPDATE_MAL_ATTR);
1571 return -1;
1572 }
1573
1574 /* Parse attribute when it exists. */
1575 if (attribute_len)
1576 {
1577 ret = bgp_attr_parse (peer, &attr, attribute_len,
1578 &mp_update, &mp_withdraw);
1579 if (ret < 0)
1580 return -1;
1581 }
1582
1583 /* Logging the attribute. */
1584 if (BGP_DEBUG (update, UPDATE_IN))
1585 {
paule01f9cb2004-07-09 17:48:53 +00001586 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1587
1588 if (ret)
ajs6b514742004-12-08 21:03:23 +00001589 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001590 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001591 }
1592
1593 /* Network Layer Reachability Information. */
1594 update_len = end - stream_pnt (s);
1595
1596 if (update_len)
1597 {
1598 /* Check NLRI packet format and prefix length. */
1599 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1600 if (ret < 0)
1601 return -1;
1602
1603 /* Set NLRI portion to structure. */
1604 update.afi = AFI_IP;
1605 update.safi = SAFI_UNICAST;
1606 update.nlri = stream_pnt (s);
1607 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001608 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001609 }
1610
1611 /* NLRI is processed only when the peer is configured specific
1612 Address Family and Subsequent Address Family. */
1613 if (peer->afc[AFI_IP][SAFI_UNICAST])
1614 {
1615 if (withdraw.length)
1616 bgp_nlri_parse (peer, NULL, &withdraw);
1617
1618 if (update.length)
1619 {
1620 /* We check well-known attribute only for IPv4 unicast
1621 update. */
1622 ret = bgp_attr_check (peer, &attr);
1623 if (ret < 0)
1624 return -1;
1625
1626 bgp_nlri_parse (peer, &attr, &update);
1627 }
paule01f9cb2004-07-09 17:48:53 +00001628
hassof4184462005-02-01 20:13:16 +00001629 if (mp_update.length
1630 && mp_update.afi == AFI_IP
1631 && mp_update.safi == SAFI_UNICAST)
1632 bgp_nlri_parse (peer, &attr, &mp_update);
1633
1634 if (mp_withdraw.length
1635 && mp_withdraw.afi == AFI_IP
1636 && mp_withdraw.safi == SAFI_UNICAST)
1637 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1638
paule01f9cb2004-07-09 17:48:53 +00001639 if (! attribute_len && ! withdraw_len)
1640 {
1641 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001642 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1643 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001644
hasso93406d82005-02-02 14:40:33 +00001645 /* NSF delete stale route */
1646 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1647 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1648
1649 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001650 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001651 peer->host);
1652 }
paul718e3742002-12-13 20:15:29 +00001653 }
1654 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1655 {
1656 if (mp_update.length
1657 && mp_update.afi == AFI_IP
1658 && mp_update.safi == SAFI_MULTICAST)
1659 bgp_nlri_parse (peer, &attr, &mp_update);
1660
1661 if (mp_withdraw.length
1662 && mp_withdraw.afi == AFI_IP
1663 && mp_withdraw.safi == SAFI_MULTICAST)
1664 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001665
hasso93406d82005-02-02 14:40:33 +00001666 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001667 && mp_withdraw.afi == AFI_IP
1668 && mp_withdraw.safi == SAFI_MULTICAST
1669 && mp_withdraw.length == 0)
1670 {
1671 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001672 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1673 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001674
hasso93406d82005-02-02 14:40:33 +00001675 /* NSF delete stale route */
1676 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1677 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1678
1679 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001680 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001681 peer->host);
1682 }
paul718e3742002-12-13 20:15:29 +00001683 }
1684 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1685 {
1686 if (mp_update.length
1687 && mp_update.afi == AFI_IP6
1688 && mp_update.safi == SAFI_UNICAST)
1689 bgp_nlri_parse (peer, &attr, &mp_update);
1690
1691 if (mp_withdraw.length
1692 && mp_withdraw.afi == AFI_IP6
1693 && mp_withdraw.safi == SAFI_UNICAST)
1694 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001695
hasso93406d82005-02-02 14:40:33 +00001696 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001697 && mp_withdraw.afi == AFI_IP6
1698 && mp_withdraw.safi == SAFI_UNICAST
1699 && mp_withdraw.length == 0)
1700 {
1701 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001702 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001703
hasso93406d82005-02-02 14:40:33 +00001704 /* NSF delete stale route */
1705 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1706 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1707
1708 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001709 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001710 peer->host);
1711 }
paul718e3742002-12-13 20:15:29 +00001712 }
1713 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1714 {
1715 if (mp_update.length
1716 && mp_update.afi == AFI_IP6
1717 && mp_update.safi == SAFI_MULTICAST)
1718 bgp_nlri_parse (peer, &attr, &mp_update);
1719
1720 if (mp_withdraw.length
1721 && mp_withdraw.afi == AFI_IP6
1722 && mp_withdraw.safi == SAFI_MULTICAST)
1723 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001724
hasso93406d82005-02-02 14:40:33 +00001725 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001726 && mp_withdraw.afi == AFI_IP6
1727 && mp_withdraw.safi == SAFI_MULTICAST
1728 && mp_withdraw.length == 0)
1729 {
1730 /* End-of-RIB received */
1731
hasso93406d82005-02-02 14:40:33 +00001732 /* NSF delete stale route */
1733 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1734 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1735
paule01f9cb2004-07-09 17:48:53 +00001736 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001737 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001738 peer->host);
1739 }
paul718e3742002-12-13 20:15:29 +00001740 }
1741 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1742 {
1743 if (mp_update.length
1744 && mp_update.afi == AFI_IP
1745 && mp_update.safi == BGP_SAFI_VPNV4)
1746 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1747
1748 if (mp_withdraw.length
1749 && mp_withdraw.afi == AFI_IP
1750 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1751 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001752
hasso93406d82005-02-02 14:40:33 +00001753 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001754 && mp_withdraw.afi == AFI_IP
1755 && mp_withdraw.safi == BGP_SAFI_VPNV4
1756 && mp_withdraw.length == 0)
1757 {
1758 /* End-of-RIB received */
1759
1760 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001761 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001762 peer->host);
1763 }
paul718e3742002-12-13 20:15:29 +00001764 }
1765
1766 /* Everything is done. We unintern temporary structures which
1767 interned in bgp_attr_parse(). */
1768 if (attr.aspath)
1769 aspath_unintern (attr.aspath);
1770 if (attr.community)
1771 community_unintern (attr.community);
Paul Jakmafb982c22007-05-04 20:15:47 +00001772 if (attr.extra)
1773 {
1774 if (attr.extra->ecommunity)
1775 ecommunity_unintern (attr.extra->ecommunity);
1776 if (attr.extra->cluster)
1777 cluster_unintern (attr.extra->cluster);
1778 if (attr.extra->transit)
1779 transit_unintern (attr.extra->transit);
1780 bgp_attr_extra_free (&attr);
1781 }
paul718e3742002-12-13 20:15:29 +00001782
1783 /* If peering is stopped due to some reason, do not generate BGP
1784 event. */
1785 if (peer->status != Established)
1786 return 0;
1787
1788 /* Increment packet counter. */
1789 peer->update_in++;
1790 peer->update_time = time (NULL);
1791
1792 /* Generate BGP event. */
1793 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1794
1795 return 0;
1796}
1797
1798/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001799static void
paul718e3742002-12-13 20:15:29 +00001800bgp_notify_receive (struct peer *peer, bgp_size_t size)
1801{
1802 struct bgp_notify bgp_notify;
1803
1804 if (peer->notify.data)
1805 {
1806 XFREE (MTYPE_TMP, peer->notify.data);
1807 peer->notify.data = NULL;
1808 peer->notify.length = 0;
1809 }
1810
1811 bgp_notify.code = stream_getc (peer->ibuf);
1812 bgp_notify.subcode = stream_getc (peer->ibuf);
1813 bgp_notify.length = size - 2;
1814 bgp_notify.data = NULL;
1815
1816 /* Preserv notify code and sub code. */
1817 peer->notify.code = bgp_notify.code;
1818 peer->notify.subcode = bgp_notify.subcode;
1819 /* For further diagnostic record returned Data. */
1820 if (bgp_notify.length)
1821 {
1822 peer->notify.length = size - 2;
1823 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1824 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1825 }
1826
1827 /* For debug */
1828 {
1829 int i;
1830 int first = 0;
1831 char c[4];
1832
1833 if (bgp_notify.length)
1834 {
1835 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1836 for (i = 0; i < bgp_notify.length; i++)
1837 if (first)
1838 {
1839 sprintf (c, " %02x", stream_getc (peer->ibuf));
1840 strcat (bgp_notify.data, c);
1841 }
1842 else
1843 {
1844 first = 1;
1845 sprintf (c, "%02x", stream_getc (peer->ibuf));
1846 strcpy (bgp_notify.data, c);
1847 }
1848 }
1849
1850 bgp_notify_print(peer, &bgp_notify, "received");
1851 if (bgp_notify.data)
1852 XFREE (MTYPE_TMP, bgp_notify.data);
1853 }
1854
1855 /* peer count update */
1856 peer->notify_in++;
1857
hassoe0701b72004-05-20 09:19:34 +00001858 if (peer->status == Established)
1859 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1860
paul718e3742002-12-13 20:15:29 +00001861 /* We have to check for Notify with Unsupported Optional Parameter.
1862 in that case we fallback to open without the capability option.
1863 But this done in bgp_stop. We just mark it here to avoid changing
1864 the fsm tables. */
1865 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1866 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1867 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1868
1869 /* Also apply to Unsupported Capability until remote router support
1870 capability. */
1871 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1872 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
1873 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1874
1875 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1876}
1877
1878/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001879static void
paul718e3742002-12-13 20:15:29 +00001880bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1881{
1882 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001883 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001884
1885 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1886}
1887
1888/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001889static void
paul718e3742002-12-13 20:15:29 +00001890bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1891{
1892 afi_t afi;
1893 safi_t safi;
1894 u_char reserved;
1895 struct stream *s;
1896
1897 /* If peer does not have the capability, send notification. */
1898 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1899 {
1900 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1901 peer->host);
1902 bgp_notify_send (peer,
1903 BGP_NOTIFY_HEADER_ERR,
1904 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1905 return;
1906 }
1907
1908 /* Status must be Established. */
1909 if (peer->status != Established)
1910 {
1911 plog_err (peer->log,
1912 "%s [Error] Route refresh packet received under status %s",
1913 peer->host, LOOKUP (bgp_status_msg, peer->status));
1914 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1915 return;
1916 }
1917
1918 s = peer->ibuf;
1919
1920 /* Parse packet. */
1921 afi = stream_getw (s);
1922 reserved = stream_getc (s);
1923 safi = stream_getc (s);
1924
1925 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001926 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001927 peer->host, afi, safi);
1928
1929 /* Check AFI and SAFI. */
1930 if ((afi != AFI_IP && afi != AFI_IP6)
1931 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1932 && safi != BGP_SAFI_VPNV4))
1933 {
1934 if (BGP_DEBUG (normal, NORMAL))
1935 {
ajs6b514742004-12-08 21:03:23 +00001936 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001937 peer->host, afi, safi);
1938 }
1939 return;
1940 }
1941
1942 /* Adjust safi code. */
1943 if (safi == BGP_SAFI_VPNV4)
1944 safi = SAFI_MPLS_VPN;
1945
1946 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1947 {
1948 u_char *end;
1949 u_char when_to_refresh;
1950 u_char orf_type;
1951 u_int16_t orf_len;
1952
1953 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1954 {
1955 zlog_info ("%s ORF route refresh length error", peer->host);
1956 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1957 return;
1958 }
1959
1960 when_to_refresh = stream_getc (s);
1961 end = stream_pnt (s) + (size - 5);
1962
1963 while (stream_pnt (s) < end)
1964 {
1965 orf_type = stream_getc (s);
1966 orf_len = stream_getw (s);
1967
1968 if (orf_type == ORF_TYPE_PREFIX
1969 || orf_type == ORF_TYPE_PREFIX_OLD)
1970 {
1971 u_char *p_pnt = stream_pnt (s);
1972 u_char *p_end = stream_pnt (s) + orf_len;
1973 struct orf_prefix orfp;
1974 u_char common = 0;
1975 u_int32_t seq;
1976 int psize;
1977 char name[BUFSIZ];
1978 char buf[BUFSIZ];
1979 int ret;
1980
1981 if (BGP_DEBUG (normal, NORMAL))
1982 {
ajs6b514742004-12-08 21:03:23 +00001983 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00001984 peer->host, orf_type, orf_len);
1985 }
1986
1987 /* ORF prefix-list name */
1988 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
1989
1990 while (p_pnt < p_end)
1991 {
1992 memset (&orfp, 0, sizeof (struct orf_prefix));
1993 common = *p_pnt++;
1994 if (common & ORF_COMMON_PART_REMOVE_ALL)
1995 {
1996 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001997 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00001998 prefix_bgp_orf_remove_all (name);
1999 break;
2000 }
2001 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2002 p_pnt += sizeof (u_int32_t);
2003 orfp.seq = ntohl (seq);
2004 orfp.ge = *p_pnt++;
2005 orfp.le = *p_pnt++;
2006 orfp.p.prefixlen = *p_pnt++;
2007 orfp.p.family = afi2family (afi);
2008 psize = PSIZE (orfp.p.prefixlen);
2009 memcpy (&orfp.p.u.prefix, p_pnt, psize);
2010 p_pnt += psize;
2011
2012 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002013 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
paul718e3742002-12-13 20:15:29 +00002014 peer->host,
2015 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2016 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2017 orfp.seq,
2018 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
2019 orfp.p.prefixlen, orfp.ge, orfp.le);
2020
2021 ret = prefix_bgp_orf_set (name, afi, &orfp,
2022 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2023 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
2024
2025 if (ret != CMD_SUCCESS)
2026 {
2027 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002028 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002029 prefix_bgp_orf_remove_all (name);
2030 break;
2031 }
2032 }
2033 peer->orf_plist[afi][safi] =
2034 prefix_list_lookup (AFI_ORF_PREFIX, name);
2035 }
paul9985f832005-02-09 15:51:56 +00002036 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002037 }
2038 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002039 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002040 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2041 if (when_to_refresh == REFRESH_DEFER)
2042 return;
2043 }
2044
2045 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2046 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2047 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2048
2049 /* Perform route refreshment to the peer */
2050 bgp_announce_route (peer, afi, safi);
2051}
2052
paul94f2b392005-06-28 12:44:16 +00002053static int
paul718e3742002-12-13 20:15:29 +00002054bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2055{
2056 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002057 struct capability_mp_data mpc;
2058 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002059 u_char action;
2060 struct bgp *bgp;
2061 afi_t afi;
2062 safi_t safi;
2063
2064 bgp = peer->bgp;
2065 end = pnt + length;
2066
2067 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002068 {
paul718e3742002-12-13 20:15:29 +00002069 /* We need at least action, capability code and capability length. */
2070 if (pnt + 3 > end)
2071 {
2072 zlog_info ("%s Capability length error", peer->host);
2073 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2074 return -1;
2075 }
paul718e3742002-12-13 20:15:29 +00002076 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002077 hdr = (struct capability_header *)(pnt + 1);
2078
paul718e3742002-12-13 20:15:29 +00002079 /* Action value check. */
2080 if (action != CAPABILITY_ACTION_SET
2081 && action != CAPABILITY_ACTION_UNSET)
2082 {
2083 zlog_info ("%s Capability Action Value error %d",
2084 peer->host, action);
2085 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2086 return -1;
2087 }
2088
2089 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002090 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002091 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002092
2093 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002094 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002095 {
2096 zlog_info ("%s Capability length error", peer->host);
2097 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2098 return -1;
2099 }
2100
Paul Jakma6d582722007-08-06 15:21:45 +00002101 /* Fetch structure to the byte stream. */
2102 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2103
paul718e3742002-12-13 20:15:29 +00002104 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002105 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002106 {
Paul Jakma6d582722007-08-06 15:21:45 +00002107 afi = ntohs (mpc.afi);
2108 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002109
2110 /* Ignore capability when override-capability is set. */
2111 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2112 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002113
2114 if (!bgp_afi_safi_valid_indices (afi, &safi))
2115 {
2116 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002117 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2118 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002119 continue;
2120 }
2121
paul718e3742002-12-13 20:15:29 +00002122 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002123 if (BGP_DEBUG (normal, NORMAL))
2124 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2125 peer->host,
2126 action == CAPABILITY_ACTION_SET
2127 ? "Advertising" : "Removing",
2128 ntohs(mpc.afi) , mpc.safi);
2129
2130 if (action == CAPABILITY_ACTION_SET)
2131 {
2132 peer->afc_recv[afi][safi] = 1;
2133 if (peer->afc[afi][safi])
2134 {
2135 peer->afc_nego[afi][safi] = 1;
2136 bgp_announce_route (peer, afi, safi);
2137 }
2138 }
2139 else
2140 {
2141 peer->afc_recv[afi][safi] = 0;
2142 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002143
Paul Jakma6d582722007-08-06 15:21:45 +00002144 if (peer_active_nego (peer))
2145 bgp_clear_route (peer, afi, safi);
2146 else
2147 BGP_EVENT_ADD (peer, BGP_Stop);
2148 }
paul718e3742002-12-13 20:15:29 +00002149 }
paul718e3742002-12-13 20:15:29 +00002150 else
2151 {
2152 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002153 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002154 }
Paul Jakma6d582722007-08-06 15:21:45 +00002155 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002156 }
2157 return 0;
2158}
2159
2160/* Dynamic Capability is received. */
Paul Jakma6d582722007-08-06 15:21:45 +00002161int
paul718e3742002-12-13 20:15:29 +00002162bgp_capability_receive (struct peer *peer, bgp_size_t size)
2163{
2164 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002165
2166 /* Fetch pointer. */
2167 pnt = stream_pnt (peer->ibuf);
2168
2169 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002170 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002171
2172 /* If peer does not have the capability, send notification. */
2173 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2174 {
2175 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2176 peer->host);
2177 bgp_notify_send (peer,
2178 BGP_NOTIFY_HEADER_ERR,
2179 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002180 return -1;
paul718e3742002-12-13 20:15:29 +00002181 }
2182
2183 /* Status must be Established. */
2184 if (peer->status != Established)
2185 {
2186 plog_err (peer->log,
2187 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2188 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002189 return -1;
paul718e3742002-12-13 20:15:29 +00002190 }
2191
2192 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002193 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002194}
2195
2196/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002197static int
paul718e3742002-12-13 20:15:29 +00002198bgp_read_packet (struct peer *peer)
2199{
2200 int nbytes;
2201 int readsize;
2202
paul9985f832005-02-09 15:51:56 +00002203 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002204
2205 /* If size is zero then return. */
2206 if (! readsize)
2207 return 0;
2208
2209 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002210 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002211
2212 /* If read byte is smaller than zero then error occured. */
2213 if (nbytes < 0)
2214 {
2215 if (errno == EAGAIN)
2216 return -1;
2217
2218 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002219 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002220
2221 if (peer->status == Established)
2222 {
2223 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2224 {
2225 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2226 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2227 }
2228 else
2229 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2230 }
2231
paul718e3742002-12-13 20:15:29 +00002232 BGP_EVENT_ADD (peer, TCP_fatal_error);
2233 return -1;
2234 }
2235
2236 /* When read byte is zero : clear bgp peer and return */
2237 if (nbytes == 0)
2238 {
2239 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002240 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002241 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002242
2243 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002244 {
2245 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2246 {
2247 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2248 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2249 }
2250 else
2251 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2252 }
hassoe0701b72004-05-20 09:19:34 +00002253
paul718e3742002-12-13 20:15:29 +00002254 BGP_EVENT_ADD (peer, TCP_connection_closed);
2255 return -1;
2256 }
2257
2258 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002259 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002260 return -1;
2261
2262 return 0;
2263}
2264
2265/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002266static int
paul718e3742002-12-13 20:15:29 +00002267bgp_marker_all_one (struct stream *s, int length)
2268{
2269 int i;
2270
2271 for (i = 0; i < length; i++)
2272 if (s->data[i] != 0xff)
2273 return 0;
2274
2275 return 1;
2276}
2277
2278/* Starting point of packet process function. */
2279int
2280bgp_read (struct thread *thread)
2281{
2282 int ret;
2283 u_char type = 0;
2284 struct peer *peer;
2285 bgp_size_t size;
2286 char notify_data_length[2];
2287
2288 /* Yes first of all get peer pointer. */
2289 peer = THREAD_ARG (thread);
2290 peer->t_read = NULL;
2291
2292 /* For non-blocking IO check. */
2293 if (peer->status == Connect)
2294 {
2295 bgp_connect_check (peer);
2296 goto done;
2297 }
2298 else
2299 {
pauleb821182004-05-01 08:44:08 +00002300 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002301 {
pauleb821182004-05-01 08:44:08 +00002302 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002303 return -1;
2304 }
pauleb821182004-05-01 08:44:08 +00002305 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002306 }
2307
2308 /* Read packet header to determine type of the packet */
2309 if (peer->packet_size == 0)
2310 peer->packet_size = BGP_HEADER_SIZE;
2311
paul9985f832005-02-09 15:51:56 +00002312 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002313 {
2314 ret = bgp_read_packet (peer);
2315
2316 /* Header read error or partial read packet. */
2317 if (ret < 0)
2318 goto done;
2319
2320 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002321 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002322 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2323 size = stream_getw (peer->ibuf);
2324 type = stream_getc (peer->ibuf);
2325
2326 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002327 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002328 peer->host, type, size - BGP_HEADER_SIZE);
2329
2330 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002331 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002332 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2333 {
2334 bgp_notify_send (peer,
2335 BGP_NOTIFY_HEADER_ERR,
2336 BGP_NOTIFY_HEADER_NOT_SYNC);
2337 goto done;
2338 }
2339
2340 /* BGP type check. */
2341 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2342 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2343 && type != BGP_MSG_ROUTE_REFRESH_NEW
2344 && type != BGP_MSG_ROUTE_REFRESH_OLD
2345 && type != BGP_MSG_CAPABILITY)
2346 {
2347 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002348 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002349 "%s unknown message type 0x%02x",
2350 peer->host, type);
2351 bgp_notify_send_with_data (peer,
2352 BGP_NOTIFY_HEADER_ERR,
2353 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2354 &type, 1);
2355 goto done;
2356 }
2357 /* Mimimum packet length check. */
2358 if ((size < BGP_HEADER_SIZE)
2359 || (size > BGP_MAX_PACKET_SIZE)
2360 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2361 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2362 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2363 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2364 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2365 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2366 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2367 {
2368 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002369 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002370 "%s bad message length - %d for %s",
2371 peer->host, size,
2372 type == 128 ? "ROUTE-REFRESH" :
2373 bgp_type_str[(int) type]);
2374 bgp_notify_send_with_data (peer,
2375 BGP_NOTIFY_HEADER_ERR,
2376 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002377 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002378 goto done;
2379 }
2380
2381 /* Adjust size to message length. */
2382 peer->packet_size = size;
2383 }
2384
2385 ret = bgp_read_packet (peer);
2386 if (ret < 0)
2387 goto done;
2388
2389 /* Get size and type again. */
2390 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2391 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2392
2393 /* BGP packet dump function. */
2394 bgp_dump_packet (peer, type, peer->ibuf);
2395
2396 size = (peer->packet_size - BGP_HEADER_SIZE);
2397
2398 /* Read rest of the packet and call each sort of packet routine */
2399 switch (type)
2400 {
2401 case BGP_MSG_OPEN:
2402 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002403 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002404 break;
2405 case BGP_MSG_UPDATE:
2406 peer->readtime = time(NULL); /* Last read timer reset */
2407 bgp_update_receive (peer, size);
2408 break;
2409 case BGP_MSG_NOTIFY:
2410 bgp_notify_receive (peer, size);
2411 break;
2412 case BGP_MSG_KEEPALIVE:
2413 peer->readtime = time(NULL); /* Last read timer reset */
2414 bgp_keepalive_receive (peer, size);
2415 break;
2416 case BGP_MSG_ROUTE_REFRESH_NEW:
2417 case BGP_MSG_ROUTE_REFRESH_OLD:
2418 peer->refresh_in++;
2419 bgp_route_refresh_receive (peer, size);
2420 break;
2421 case BGP_MSG_CAPABILITY:
2422 peer->dynamic_cap_in++;
2423 bgp_capability_receive (peer, size);
2424 break;
2425 }
2426
2427 /* Clear input buffer. */
2428 peer->packet_size = 0;
2429 if (peer->ibuf)
2430 stream_reset (peer->ibuf);
2431
2432 done:
2433 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2434 {
2435 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002436 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002437 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002438 }
2439 return 0;
2440}