blob: 4d7f32dee96945fae8be54cfebcec3e7c9d24e7b [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
31#include "linklist.h"
32#include "plist.h"
33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_table.h"
36#include "bgpd/bgp_dump.h"
37#include "bgpd/bgp_attr.h"
38#include "bgpd/bgp_debug.h"
39#include "bgpd/bgp_fsm.h"
40#include "bgpd/bgp_route.h"
41#include "bgpd/bgp_packet.h"
42#include "bgpd/bgp_open.h"
43#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_community.h"
45#include "bgpd/bgp_ecommunity.h"
46#include "bgpd/bgp_network.h"
47#include "bgpd/bgp_mplsvpn.h"
48#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000049#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000050
51int stream_put_prefix (struct stream *, struct prefix *);
52
53/* Set up BGP packet marker and packet type. */
54static int
55bgp_packet_set_marker (struct stream *s, u_char type)
56{
57 int i;
58
59 /* Fill in marker. */
60 for (i = 0; i < BGP_MARKER_SIZE; i++)
61 stream_putc (s, 0xff);
62
63 /* Dummy total length. This field is should be filled in later on. */
64 stream_putw (s, 0);
65
66 /* BGP packet type. */
67 stream_putc (s, type);
68
69 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000070 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000071}
72
73/* Set BGP packet header size entry. If size is zero then use current
74 stream size. */
75static int
76bgp_packet_set_size (struct stream *s)
77{
78 int cp;
79
80 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000081 cp = stream_get_endp (s);
82 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000083
84 return cp;
85}
86
87/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000088static void
paul718e3742002-12-13 20:15:29 +000089bgp_packet_add (struct peer *peer, struct stream *s)
90{
91 /* Add packet to the end of list. */
92 stream_fifo_push (peer->obuf, s);
93}
94
95/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000096static void
paul718e3742002-12-13 20:15:29 +000097bgp_packet_delete (struct peer *peer)
98{
99 stream_free (stream_fifo_pop (peer->obuf));
100}
101
paul718e3742002-12-13 20:15:29 +0000102/* Check file descriptor whether connect is established. */
103static void
104bgp_connect_check (struct peer *peer)
105{
106 int status;
paul5228ad22004-06-04 17:58:18 +0000107 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000108 int ret;
109
110 /* Anyway I have to reset read and write thread. */
111 BGP_READ_OFF (peer->t_read);
112 BGP_WRITE_OFF (peer->t_write);
113
114 /* Check file descriptor. */
115 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000116 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000117
118 /* If getsockopt is fail, this is fatal error. */
119 if (ret < 0)
120 {
121 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
122 BGP_EVENT_ADD (peer, TCP_fatal_error);
123 return;
124 }
125
126 /* When status is 0 then TCP connection is established. */
127 if (status == 0)
128 {
129 BGP_EVENT_ADD (peer, TCP_connection_open);
130 }
131 else
132 {
133 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000134 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000135 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000136 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
137 }
138}
139
140/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000141static struct stream *
paul718e3742002-12-13 20:15:29 +0000142bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
143{
144 struct stream *s;
145 struct bgp_adj_out *adj;
146 struct bgp_advertise *adv;
147 struct stream *packet;
148 struct bgp_node *rn = NULL;
149 struct bgp_info *binfo = NULL;
150 bgp_size_t total_attr_len = 0;
151 unsigned long pos;
152 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000153
154 s = peer->work;
155 stream_reset (s);
156
157 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
158
159 while (adv)
160 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000161 assert (adv->rn);
162 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000163 adj = adv->adj;
164 if (adv->binfo)
165 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000166
167 /* When remaining space can't include NLRI and it's length. */
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000168 if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
paul718e3742002-12-13 20:15:29 +0000169 break;
170
171 /* If packet is empty, set attribute. */
172 if (stream_empty (s))
173 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000174 struct prefix_rd *prd = NULL;
175 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000176 struct peer *from = NULL;
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000177
178 if (rn->prn)
179 prd = (struct prefix_rd *) &rn->prn->p;
Paul Jakmafb982c22007-05-04 20:15:47 +0000180 if (binfo && binfo->extra)
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000182 tag = binfo->extra->tag;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000183 from = binfo->peer;
184 }
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000185
paul718e3742002-12-13 20:15:29 +0000186 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
187 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000188 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000189 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000190 total_attr_len = bgp_packet_attribute (NULL, peer, s,
191 adv->baa->attr,
192 &rn->p, afi, safi,
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000193 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000194 stream_putw_at (s, pos, total_attr_len);
195 }
196
197 if (afi == AFI_IP && safi == SAFI_UNICAST)
198 stream_put_prefix (s, &rn->p);
199
200 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000201 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000202 peer->host,
203 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
204 rn->p.prefixlen);
205
206 /* Synchnorize attribute. */
207 if (adj->attr)
208 bgp_attr_unintern (adj->attr);
209 else
210 peer->scount[afi][safi]++;
211
212 adj->attr = bgp_attr_intern (adv->baa->attr);
213
214 adv = bgp_advertise_clean (peer, adj, afi, safi);
215
216 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
217 break;
218 }
219
220 if (! stream_empty (s))
221 {
222 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000223 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000224 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000225 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000226 stream_reset (s);
227 return packet;
228 }
229 return NULL;
hasso93406d82005-02-02 14:40:33 +0000230}
paul718e3742002-12-13 20:15:29 +0000231
paul94f2b392005-06-28 12:44:16 +0000232static struct stream *
hasso93406d82005-02-02 14:40:33 +0000233bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
234{
235 struct stream *s;
236 struct stream *packet;
237
Paul Jakma750e8142008-07-22 21:11:48 +0000238 if (DISABLE_BGP_ANNOUNCE)
239 return NULL;
hasso93406d82005-02-02 14:40:33 +0000240
241 if (BGP_DEBUG (normal, NORMAL))
242 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
243
244 s = stream_new (BGP_MAX_PACKET_SIZE);
245
246 /* Make BGP update packet. */
247 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
248
249 /* Unfeasible Routes Length */
250 stream_putw (s, 0);
251
252 if (afi == AFI_IP && safi == SAFI_UNICAST)
253 {
254 /* Total Path Attribute Length */
255 stream_putw (s, 0);
256 }
257 else
258 {
259 /* Total Path Attribute Length */
260 stream_putw (s, 6);
261 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
262 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
263 stream_putc (s, 3);
264 stream_putw (s, afi);
265 stream_putc (s, safi);
266 }
267
268 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000269 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000270 bgp_packet_add (peer, packet);
271 stream_free (s);
272 return packet;
paul718e3742002-12-13 20:15:29 +0000273}
274
275/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000276static struct stream *
paul718e3742002-12-13 20:15:29 +0000277bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
278{
279 struct stream *s;
280 struct stream *packet;
281 struct bgp_adj_out *adj;
282 struct bgp_advertise *adv;
283 struct bgp_node *rn;
284 unsigned long pos;
285 bgp_size_t unfeasible_len;
286 bgp_size_t total_attr_len;
287 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000288
289 s = peer->work;
290 stream_reset (s);
291
292 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
293 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000294 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000295 adj = adv->adj;
296 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000297
298 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000299 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000300 break;
301
302 if (stream_empty (s))
303 {
304 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
305 stream_putw (s, 0);
306 }
307
308 if (afi == AFI_IP && safi == SAFI_UNICAST)
309 stream_put_prefix (s, &rn->p);
310 else
311 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000312 struct prefix_rd *prd = NULL;
313
314 if (rn->prn)
315 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000316 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000317 stream_putw (s, 0);
318 total_attr_len
319 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
320
321 /* Set total path attribute length. */
322 stream_putw_at (s, pos, total_attr_len);
323 }
324
325 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000326 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000327 peer->host,
328 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
329 rn->p.prefixlen);
330
331 peer->scount[afi][safi]--;
332
333 bgp_adj_out_remove (rn, adj, peer, afi, safi);
334 bgp_unlock_node (rn);
335
336 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
337 break;
338 }
339
340 if (! stream_empty (s))
341 {
342 if (afi == AFI_IP && safi == SAFI_UNICAST)
343 {
344 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000345 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000346 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
347 stream_putw (s, 0);
348 }
349 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000350 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000351 bgp_packet_add (peer, packet);
352 stream_reset (s);
353 return packet;
354 }
355
356 return NULL;
357}
358
359void
360bgp_default_update_send (struct peer *peer, struct attr *attr,
361 afi_t afi, safi_t safi, struct peer *from)
362{
363 struct stream *s;
364 struct stream *packet;
365 struct prefix p;
366 unsigned long pos;
367 bgp_size_t total_attr_len;
368 char attrstr[BUFSIZ];
369 char buf[BUFSIZ];
370
Paul Jakma750e8142008-07-22 21:11:48 +0000371 if (DISABLE_BGP_ANNOUNCE)
372 return;
paul718e3742002-12-13 20:15:29 +0000373
374 if (afi == AFI_IP)
375 str2prefix ("0.0.0.0/0", &p);
376#ifdef HAVE_IPV6
377 else
378 str2prefix ("::/0", &p);
379#endif /* HAVE_IPV6 */
380
381 /* Logging the attribute. */
382 if (BGP_DEBUG (update, UPDATE_OUT))
383 {
384 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000385 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000386 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
387 p.prefixlen, attrstr);
388 }
389
390 s = stream_new (BGP_MAX_PACKET_SIZE);
391
392 /* Make BGP update packet. */
393 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
394
395 /* Unfeasible Routes Length. */
396 stream_putw (s, 0);
397
398 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000399 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000400 stream_putw (s, 0);
401 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
402
403 /* Set Total Path Attribute Length. */
404 stream_putw_at (s, pos, total_attr_len);
405
406 /* NLRI set. */
407 if (p.family == AF_INET && safi == SAFI_UNICAST)
408 stream_put_prefix (s, &p);
409
410 /* Set size. */
411 bgp_packet_set_size (s);
412
paule83e2082005-05-19 02:12:25 +0000413 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000414 stream_free (s);
415
416 /* Dump packet if debug option is set. */
417#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000418 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000419#endif /* DEBUG */
420
421 /* Add packet to the peer. */
422 bgp_packet_add (peer, packet);
423
pauleb821182004-05-01 08:44:08 +0000424 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000425}
426
427void
428bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
429{
430 struct stream *s;
431 struct stream *packet;
432 struct prefix p;
433 unsigned long pos;
434 unsigned long cp;
435 bgp_size_t unfeasible_len;
436 bgp_size_t total_attr_len;
437 char buf[BUFSIZ];
438
Paul Jakma750e8142008-07-22 21:11:48 +0000439 if (DISABLE_BGP_ANNOUNCE)
440 return;
paul718e3742002-12-13 20:15:29 +0000441
442 if (afi == AFI_IP)
443 str2prefix ("0.0.0.0/0", &p);
444#ifdef HAVE_IPV6
445 else
446 str2prefix ("::/0", &p);
447#endif /* HAVE_IPV6 */
448
449 total_attr_len = 0;
450 pos = 0;
451
452 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000453 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000454 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
455 p.prefixlen);
456
457 s = stream_new (BGP_MAX_PACKET_SIZE);
458
459 /* Make BGP update packet. */
460 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
461
462 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000463 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000464 stream_putw (s, 0);
465
466 /* Withdrawn Routes. */
467 if (p.family == AF_INET && safi == SAFI_UNICAST)
468 {
469 stream_put_prefix (s, &p);
470
paul9985f832005-02-09 15:51:56 +0000471 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000472
473 /* Set unfeasible len. */
474 stream_putw_at (s, cp, unfeasible_len);
475
476 /* Set total path attribute length. */
477 stream_putw (s, 0);
478 }
479 else
480 {
paul9985f832005-02-09 15:51:56 +0000481 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000482 stream_putw (s, 0);
483 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
484
485 /* Set total path attribute length. */
486 stream_putw_at (s, pos, total_attr_len);
487 }
488
489 bgp_packet_set_size (s);
490
paule83e2082005-05-19 02:12:25 +0000491 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000492 stream_free (s);
493
494 /* Add packet to the peer. */
495 bgp_packet_add (peer, packet);
496
pauleb821182004-05-01 08:44:08 +0000497 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000498}
499
500/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000501static struct stream *
paul718e3742002-12-13 20:15:29 +0000502bgp_write_packet (struct peer *peer)
503{
504 afi_t afi;
505 safi_t safi;
506 struct stream *s = NULL;
507 struct bgp_advertise *adv;
508
509 s = stream_fifo_head (peer->obuf);
510 if (s)
511 return s;
512
513 for (afi = AFI_IP; afi < AFI_MAX; afi++)
514 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
515 {
516 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
517 if (adv)
518 {
519 s = bgp_withdraw_packet (peer, afi, safi);
520 if (s)
521 return s;
522 }
523 }
524
525 for (afi = AFI_IP; afi < AFI_MAX; afi++)
526 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
527 {
528 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
529 if (adv)
530 {
531 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000532 {
533 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
534 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
535 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
536 && safi != SAFI_MPLS_VPN)
537 {
538 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
539 PEER_STATUS_EOR_RECEIVED))
540 s = bgp_update_packet (peer, afi, safi);
541 }
542 else
543 s = bgp_update_packet (peer, afi, safi);
544 }
paul718e3742002-12-13 20:15:29 +0000545
546 if (s)
547 return s;
548 }
hasso93406d82005-02-02 14:40:33 +0000549
550 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
551 {
552 if (peer->afc_nego[afi][safi] && peer->synctime
553 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
554 && safi != SAFI_MPLS_VPN)
555 {
556 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
557 return bgp_update_packet_eor (peer, afi, safi);
558 }
559 }
paul718e3742002-12-13 20:15:29 +0000560 }
561
562 return NULL;
563}
564
565/* Is there partially written packet or updates we can send right
566 now. */
paul94f2b392005-06-28 12:44:16 +0000567static int
paul718e3742002-12-13 20:15:29 +0000568bgp_write_proceed (struct peer *peer)
569{
570 afi_t afi;
571 safi_t safi;
572 struct bgp_advertise *adv;
573
574 if (stream_fifo_head (peer->obuf))
575 return 1;
576
577 for (afi = AFI_IP; afi < AFI_MAX; afi++)
578 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
579 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
580 return 1;
581
582 for (afi = AFI_IP; afi < AFI_MAX; afi++)
583 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
584 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
585 if (adv->binfo->uptime < peer->synctime)
586 return 1;
587
588 return 0;
589}
590
591/* Write packet to the peer. */
592int
593bgp_write (struct thread *thread)
594{
595 struct peer *peer;
596 u_char type;
597 struct stream *s;
598 int num;
paulfd79ac92004-10-13 05:06:08 +0000599 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000600 int write_errno;
601
602 /* Yes first of all get peer pointer. */
603 peer = THREAD_ARG (thread);
604 peer->t_write = NULL;
605
606 /* For non-blocking IO check. */
607 if (peer->status == Connect)
608 {
609 bgp_connect_check (peer);
610 return 0;
611 }
612
613 /* Nonblocking write until TCP output buffer is full. */
614 while (1)
615 {
616 int writenum;
paula24a7e12005-01-05 08:14:13 +0000617 int val;
paul718e3742002-12-13 20:15:29 +0000618
619 s = bgp_write_packet (peer);
620 if (! s)
621 return 0;
paula24a7e12005-01-05 08:14:13 +0000622
623 /* XXX: FIXME, the socket should be NONBLOCK from the start
624 * status shouldnt need to be toggled on each write
625 */
626 val = fcntl (peer->fd, F_GETFL, 0);
627 fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
paul718e3742002-12-13 20:15:29 +0000628
629 /* Number of bytes to be sent. */
630 writenum = stream_get_endp (s) - stream_get_getp (s);
631
632 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000633 num = write (peer->fd, STREAM_PNT (s), writenum);
paul718e3742002-12-13 20:15:29 +0000634 write_errno = errno;
paula24a7e12005-01-05 08:14:13 +0000635 fcntl (peer->fd, F_SETFL, val);
paul718e3742002-12-13 20:15:29 +0000636 if (num <= 0)
637 {
638 /* Partial write. */
639 if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
640 break;
641
Paul Jakmadcdf3992006-10-15 23:39:59 +0000642 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000643 return 0;
644 }
645 if (num != writenum)
646 {
paul9985f832005-02-09 15:51:56 +0000647 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000648
649 if (write_errno == EAGAIN)
650 break;
651
652 continue;
653 }
654
655 /* Retrieve BGP packet type. */
656 stream_set_getp (s, BGP_MARKER_SIZE + 2);
657 type = stream_getc (s);
658
659 switch (type)
660 {
661 case BGP_MSG_OPEN:
662 peer->open_out++;
663 break;
664 case BGP_MSG_UPDATE:
665 peer->update_out++;
666 break;
667 case BGP_MSG_NOTIFY:
668 peer->notify_out++;
669 /* Double start timer. */
670 peer->v_start *= 2;
671
672 /* Overflow check. */
673 if (peer->v_start >= (60 * 2))
674 peer->v_start = (60 * 2);
675
Paul Jakmaca058a32006-09-14 02:58:49 +0000676 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000677 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000678 return 0;
paul718e3742002-12-13 20:15:29 +0000679 case BGP_MSG_KEEPALIVE:
680 peer->keepalive_out++;
681 break;
682 case BGP_MSG_ROUTE_REFRESH_NEW:
683 case BGP_MSG_ROUTE_REFRESH_OLD:
684 peer->refresh_out++;
685 break;
686 case BGP_MSG_CAPABILITY:
687 peer->dynamic_cap_out++;
688 break;
689 }
690
691 /* OK we send packet so delete it. */
692 bgp_packet_delete (peer);
693
694 if (++count >= BGP_WRITE_PACKET_MAX)
695 break;
696 }
697
698 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000699 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000700
701 return 0;
702}
703
704/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000705static int
paul718e3742002-12-13 20:15:29 +0000706bgp_write_notify (struct peer *peer)
707{
708 int ret;
709 u_char type;
710 struct stream *s;
711
712 /* There should be at least one packet. */
713 s = stream_fifo_head (peer->obuf);
714 if (!s)
715 return 0;
716 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
717
718 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000719 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000720 if (ret <= 0)
721 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000722 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000723 return 0;
724 }
725
726 /* Retrieve BGP packet type. */
727 stream_set_getp (s, BGP_MARKER_SIZE + 2);
728 type = stream_getc (s);
729
730 assert (type == BGP_MSG_NOTIFY);
731
732 /* Type should be notify. */
733 peer->notify_out++;
734
735 /* Double start timer. */
736 peer->v_start *= 2;
737
738 /* Overflow check. */
739 if (peer->v_start >= (60 * 2))
740 peer->v_start = (60 * 2);
741
Paul Jakmadcdf3992006-10-15 23:39:59 +0000742 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000743
744 return 0;
745}
746
747/* Make keepalive packet and send it to the peer. */
748void
749bgp_keepalive_send (struct peer *peer)
750{
751 struct stream *s;
752 int length;
753
754 s = stream_new (BGP_MAX_PACKET_SIZE);
755
756 /* Make keepalive packet. */
757 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
758
759 /* Set packet size. */
760 length = bgp_packet_set_size (s);
761
762 /* Dump packet if debug option is set. */
763 /* bgp_packet_dump (s); */
764
765 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000766 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000767 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000768 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000769 peer->host, BGP_MSG_KEEPALIVE, length);
770
771 /* Add packet to the peer. */
772 bgp_packet_add (peer, s);
773
pauleb821182004-05-01 08:44:08 +0000774 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000775}
776
777/* Make open packet and send it to the peer. */
778void
779bgp_open_send (struct peer *peer)
780{
781 struct stream *s;
782 int length;
783 u_int16_t send_holdtime;
784 as_t local_as;
785
786 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
787 send_holdtime = peer->holdtime;
788 else
789 send_holdtime = peer->bgp->default_holdtime;
790
791 /* local-as Change */
792 if (peer->change_local_as)
793 local_as = peer->change_local_as;
794 else
795 local_as = peer->local_as;
796
797 s = stream_new (BGP_MAX_PACKET_SIZE);
798
799 /* Make open packet. */
800 bgp_packet_set_marker (s, BGP_MSG_OPEN);
801
802 /* Set open packet values. */
803 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000804 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
805 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000806 stream_putw (s, send_holdtime); /* Hold Time */
807 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
808
809 /* Set capability code. */
810 bgp_open_capability (s, peer);
811
812 /* Set BGP packet length. */
813 length = bgp_packet_set_size (s);
814
815 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000816 zlog_debug ("%s sending OPEN, version %d, my as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000817 peer->host, BGP_VERSION_4, local_as,
818 send_holdtime, inet_ntoa (peer->local_id));
819
820 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000821 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000822 peer->host, BGP_MSG_OPEN, length);
823
824 /* Dump packet if debug option is set. */
825 /* bgp_packet_dump (s); */
826
827 /* Add packet to the peer. */
828 bgp_packet_add (peer, s);
829
pauleb821182004-05-01 08:44:08 +0000830 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000831}
832
833/* Send BGP notify packet with data potion. */
834void
835bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
836 u_char *data, size_t datalen)
837{
838 struct stream *s;
839 int length;
840
841 /* Allocate new stream. */
842 s = stream_new (BGP_MAX_PACKET_SIZE);
843
844 /* Make nitify packet. */
845 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
846
847 /* Set notify packet values. */
848 stream_putc (s, code); /* BGP notify code */
849 stream_putc (s, sub_code); /* BGP notify sub_code */
850
851 /* If notify data is present. */
852 if (data)
853 stream_write (s, data, datalen);
854
855 /* Set BGP packet length. */
856 length = bgp_packet_set_size (s);
857
858 /* Add packet to the peer. */
859 stream_fifo_clean (peer->obuf);
860 bgp_packet_add (peer, s);
861
862 /* For debug */
863 {
864 struct bgp_notify bgp_notify;
865 int first = 0;
866 int i;
867 char c[4];
868
869 bgp_notify.code = code;
870 bgp_notify.subcode = sub_code;
871 bgp_notify.data = NULL;
872 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
873
874 if (bgp_notify.length)
875 {
876 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
877 for (i = 0; i < bgp_notify.length; i++)
878 if (first)
879 {
880 sprintf (c, " %02x", data[i]);
881 strcat (bgp_notify.data, c);
882 }
883 else
884 {
885 first = 1;
886 sprintf (c, "%02x", data[i]);
887 strcpy (bgp_notify.data, c);
888 }
889 }
890 bgp_notify_print (peer, &bgp_notify, "sending");
891 if (bgp_notify.data)
892 XFREE (MTYPE_TMP, bgp_notify.data);
893 }
894
895 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000896 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000897 peer->host, BGP_MSG_NOTIFY, length);
898
hassoe0701b72004-05-20 09:19:34 +0000899 /* peer reset cause */
900 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
901 {
902 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
903 peer->last_reset = PEER_DOWN_USER_RESET;
904 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
905 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
906 else
907 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
908 }
909
paul718e3742002-12-13 20:15:29 +0000910 /* Call imidiately. */
911 BGP_WRITE_OFF (peer->t_write);
912
913 bgp_write_notify (peer);
914}
915
916/* Send BGP notify packet. */
917void
918bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
919{
920 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
921}
922
paul94f2b392005-06-28 12:44:16 +0000923static const char *
paul718e3742002-12-13 20:15:29 +0000924afi2str (afi_t afi)
925{
926 if (afi == AFI_IP)
927 return "AFI_IP";
928 else if (afi == AFI_IP6)
929 return "AFI_IP6";
930 else
931 return "Unknown AFI";
932}
933
paul94f2b392005-06-28 12:44:16 +0000934static const char *
paul718e3742002-12-13 20:15:29 +0000935safi2str (safi_t safi)
936{
937 if (safi == SAFI_UNICAST)
938 return "SAFI_UNICAST";
939 else if (safi == SAFI_MULTICAST)
940 return "SAFI_MULTICAST";
941 else if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPNV4)
942 return "SAFI_MPLS_VPN";
943 else
944 return "Unknown SAFI";
945}
946
947/* Send route refresh message to the peer. */
948void
949bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
950 u_char orf_type, u_char when_to_refresh, int remove)
951{
952 struct stream *s;
953 struct stream *packet;
954 int length;
955 struct bgp_filter *filter;
956 int orf_refresh = 0;
957
Paul Jakma750e8142008-07-22 21:11:48 +0000958 if (DISABLE_BGP_ANNOUNCE)
959 return;
paul718e3742002-12-13 20:15:29 +0000960
961 filter = &peer->filter[afi][safi];
962
963 /* Adjust safi code. */
964 if (safi == SAFI_MPLS_VPN)
965 safi = BGP_SAFI_VPNV4;
966
967 s = stream_new (BGP_MAX_PACKET_SIZE);
968
969 /* Make BGP update packet. */
970 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
971 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
972 else
973 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
974
975 /* Encode Route Refresh message. */
976 stream_putw (s, afi);
977 stream_putc (s, 0);
978 stream_putc (s, safi);
979
980 if (orf_type == ORF_TYPE_PREFIX
981 || orf_type == ORF_TYPE_PREFIX_OLD)
982 if (remove || filter->plist[FILTER_IN].plist)
983 {
984 u_int16_t orf_len;
985 unsigned long orfp;
986
987 orf_refresh = 1;
988 stream_putc (s, when_to_refresh);
989 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000990 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000991 stream_putw (s, 0);
992
993 if (remove)
994 {
995 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
996 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
997 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000998 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000999 peer->host, orf_type,
1000 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1001 afi, safi);
1002 }
1003 else
1004 {
1005 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1006 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1007 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1008 ORF_COMMON_PART_DENY);
1009 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001010 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001011 peer->host, orf_type,
1012 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1013 afi, safi);
1014 }
1015
1016 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001017 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001018 stream_putw_at (s, orfp, orf_len);
1019 }
1020
1021 /* Set packet size. */
1022 length = bgp_packet_set_size (s);
1023
1024 if (BGP_DEBUG (normal, NORMAL))
1025 {
1026 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001027 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001028 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001029 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001030 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1031 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1032 }
1033
1034 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001035 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001036 stream_free (s);
1037
1038 /* Add packet to the peer. */
1039 bgp_packet_add (peer, packet);
1040
pauleb821182004-05-01 08:44:08 +00001041 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001042}
1043
1044/* Send capability message to the peer. */
1045void
1046bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1047 int capability_code, int action)
1048{
1049 struct stream *s;
1050 struct stream *packet;
1051 int length;
1052
1053 /* Adjust safi code. */
1054 if (safi == SAFI_MPLS_VPN)
1055 safi = BGP_SAFI_VPNV4;
1056
1057 s = stream_new (BGP_MAX_PACKET_SIZE);
1058
1059 /* Make BGP update packet. */
1060 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1061
1062 /* Encode MP_EXT capability. */
1063 if (capability_code == CAPABILITY_CODE_MP)
1064 {
1065 stream_putc (s, action);
1066 stream_putc (s, CAPABILITY_CODE_MP);
1067 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1068 stream_putw (s, afi);
1069 stream_putc (s, 0);
1070 stream_putc (s, safi);
1071
1072 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001073 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001074 peer->host, action == CAPABILITY_ACTION_SET ?
1075 "Advertising" : "Removing", afi, safi);
1076 }
1077
paul718e3742002-12-13 20:15:29 +00001078 /* Set packet size. */
1079 length = bgp_packet_set_size (s);
1080
1081 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001082 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001083 stream_free (s);
1084
1085 /* Add packet to the peer. */
1086 bgp_packet_add (peer, packet);
1087
1088 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001089 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001090 peer->host, BGP_MSG_CAPABILITY, length);
1091
pauleb821182004-05-01 08:44:08 +00001092 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001093}
1094
1095/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001096static int
pauleb821182004-05-01 08:44:08 +00001097bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001098{
pauleb821182004-05-01 08:44:08 +00001099 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001100 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001101 struct bgp *bgp;
1102
1103 bgp = bgp_get_default ();
1104 if (! bgp)
1105 return 0;
1106
1107 /* Upon receipt of an OPEN message, the local system must examine
1108 all of its connections that are in the OpenConfirm state. A BGP
1109 speaker may also examine connections in an OpenSent state if it
1110 knows the BGP Identifier of the peer by means outside of the
1111 protocol. If among these connections there is a connection to a
1112 remote BGP speaker whose BGP Identifier equals the one in the
1113 OPEN message, then the local system performs the following
1114 collision resolution procedure: */
1115
paul1eb8ef22005-04-07 07:30:20 +00001116 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001117 {
1118 /* Under OpenConfirm status, local peer structure already hold
1119 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001120
1121 if (peer != new
1122 && (peer->status == OpenConfirm || peer->status == OpenSent)
1123 && sockunion_same (&peer->su, &new->su))
1124 {
paul718e3742002-12-13 20:15:29 +00001125 /* 1. The BGP Identifier of the local system is compared to
1126 the BGP Identifier of the remote system (as specified in
1127 the OPEN message). */
1128
1129 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1130 {
1131 /* 2. If the value of the local BGP Identifier is less
1132 than the remote one, the local system closes BGP
1133 connection that already exists (the one that is
1134 already in the OpenConfirm state), and accepts BGP
1135 connection initiated by the remote system. */
1136
pauleb821182004-05-01 08:44:08 +00001137 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001138 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001139 return 1;
1140 }
1141 else
1142 {
1143 /* 3. Otherwise, the local system closes newly created
1144 BGP connection (the one associated with the newly
1145 received OPEN message), and continues to use the
1146 existing one (the one that is already in the
1147 OpenConfirm state). */
1148
pauleb821182004-05-01 08:44:08 +00001149 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001150 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1151 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001152 return -1;
1153 }
pauleb821182004-05-01 08:44:08 +00001154 }
1155 }
paul718e3742002-12-13 20:15:29 +00001156 return 0;
1157}
1158
paul94f2b392005-06-28 12:44:16 +00001159static int
paul718e3742002-12-13 20:15:29 +00001160bgp_open_receive (struct peer *peer, bgp_size_t size)
1161{
1162 int ret;
1163 u_char version;
1164 u_char optlen;
1165 u_int16_t holdtime;
1166 u_int16_t send_holdtime;
1167 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001168 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001169 struct peer *realpeer;
1170 struct in_addr remote_id;
1171 int capability;
paul5228ad22004-06-04 17:58:18 +00001172 u_int8_t notify_data_remote_as[2];
1173 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001174
1175 realpeer = NULL;
1176
1177 /* Parse open packet. */
1178 version = stream_getc (peer->ibuf);
1179 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1180 remote_as = stream_getw (peer->ibuf);
1181 holdtime = stream_getw (peer->ibuf);
1182 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1183 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1184
1185 /* Receive OPEN message log */
1186 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001187 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %d,"
1188 " holdtime %d, id %s",
1189 peer->host, version, remote_as, holdtime,
1190 inet_ntoa (remote_id));
1191
1192 /* BEGIN to read the capability here, but dont do it yet */
1193 capability = 0;
1194 optlen = stream_getc (peer->ibuf);
1195
1196 if (optlen != 0)
1197 {
1198 /* We need the as4 capability value *right now* because
1199 * if it is there, we have not got the remote_as yet, and without
1200 * that we do not know which peer is connecting to us now.
1201 */
1202 as4 = peek_for_as4_capability (peer, optlen);
1203 }
1204
1205 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1206 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1207 {
1208 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1209 peer->host);
1210 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1211 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1212 return -1;
1213 }
1214
1215 if (remote_as == BGP_AS_TRANS)
1216 {
1217 /* Take the AS4 from the capability. We must have received the
1218 * capability now! Otherwise we have a asn16 peer who uses
1219 * BGP_AS_TRANS, for some unknown reason.
1220 */
1221 if (as4 == BGP_AS_TRANS)
1222 {
1223 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1224 peer->host);
1225 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1226 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1227 return -1;
1228 }
1229
1230 if (!as4 && BGP_DEBUG (as4, AS4))
1231 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1232 " Odd, but proceeding.", peer->host);
1233 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001234 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001235 "in 2-bytes, very odd peer.", peer->host, as4);
1236 if (as4)
1237 remote_as = as4;
1238 }
1239 else
1240 {
1241 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1242 /* If we have got the capability, peer->as4cap must match remote_as */
1243 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1244 && as4 != remote_as)
1245 {
1246 /* raise error, log this, close session */
1247 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1248 " mismatch with 16bit 'myasn' %u in open",
1249 peer->host, as4, remote_as);
1250 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1251 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1252 return -1;
1253 }
1254 }
1255
paul718e3742002-12-13 20:15:29 +00001256 /* Lookup peer from Open packet. */
1257 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1258 {
1259 int as = 0;
1260
1261 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1262
1263 if (! realpeer)
1264 {
1265 /* Peer's source IP address is check in bgp_accept(), so this
1266 must be AS number mismatch or remote-id configuration
1267 mismatch. */
1268 if (as)
1269 {
1270 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001271 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1272 peer->host, inet_ntoa (remote_id));
1273 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1274 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1275 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001276 }
1277 else
1278 {
1279 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001280 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
1281 peer->host, remote_as, peer->as);
1282 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1283 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1284 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001285 }
1286 return -1;
1287 }
1288 }
1289
1290 /* When collision is detected and this peer is closed. Retrun
1291 immidiately. */
1292 ret = bgp_collision_detect (peer, remote_id);
1293 if (ret < 0)
1294 return ret;
1295
pauleb821182004-05-01 08:44:08 +00001296 /* Hack part. */
1297 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1298 {
hasso93406d82005-02-02 14:40:33 +00001299 if (realpeer->status == Established
1300 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1301 {
1302 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1303 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1304 }
1305 else if (ret == 0 && realpeer->status != Active
1306 && realpeer->status != OpenSent
1307 && realpeer->status != OpenConfirm)
1308
pauleb821182004-05-01 08:44:08 +00001309 {
1310 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001311 zlog_debug ("%s peer status is %s close connection",
1312 realpeer->host, LOOKUP (bgp_status_msg,
1313 realpeer->status));
1314 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1315 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1316
pauleb821182004-05-01 08:44:08 +00001317 return -1;
1318 }
1319
1320 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00001321 zlog_debug ("%s [Event] Transfer temporary BGP peer to existing one",
pauleb821182004-05-01 08:44:08 +00001322 peer->host);
1323
1324 bgp_stop (realpeer);
1325
1326 /* Transfer file descriptor. */
1327 realpeer->fd = peer->fd;
1328 peer->fd = -1;
1329
1330 /* Transfer input buffer. */
1331 stream_free (realpeer->ibuf);
1332 realpeer->ibuf = peer->ibuf;
1333 realpeer->packet_size = peer->packet_size;
1334 peer->ibuf = NULL;
1335
1336 /* Transfer status. */
1337 realpeer->status = peer->status;
1338 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001339
pauleb821182004-05-01 08:44:08 +00001340 /* peer pointer change. Open packet send to neighbor. */
1341 peer = realpeer;
1342 bgp_open_send (peer);
1343 if (peer->fd < 0)
1344 {
1345 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1346 peer->fd);
1347 return -1;
1348 }
1349 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1350 }
1351
paul718e3742002-12-13 20:15:29 +00001352 /* remote router-id check. */
1353 if (remote_id.s_addr == 0
1354 || ntohl (remote_id.s_addr) >= 0xe0000000
1355 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1356 {
1357 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001358 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001359 peer->host, inet_ntoa (remote_id));
1360 bgp_notify_send_with_data (peer,
1361 BGP_NOTIFY_OPEN_ERR,
1362 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1363 notify_data_remote_id, 4);
1364 return -1;
1365 }
1366
1367 /* Set remote router-id */
1368 peer->remote_id = remote_id;
1369
1370 /* Peer BGP version check. */
1371 if (version != BGP_VERSION_4)
1372 {
paul5228ad22004-06-04 17:58:18 +00001373 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001374 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001375 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001376 peer->host, version, BGP_VERSION_4);
1377 bgp_notify_send_with_data (peer,
1378 BGP_NOTIFY_OPEN_ERR,
1379 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001380 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001381 return -1;
1382 }
1383
1384 /* Check neighbor as number. */
1385 if (remote_as != peer->as)
1386 {
1387 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001388 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
paul718e3742002-12-13 20:15:29 +00001389 peer->host, remote_as, peer->as);
1390 bgp_notify_send_with_data (peer,
1391 BGP_NOTIFY_OPEN_ERR,
1392 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1393 notify_data_remote_as, 2);
1394 return -1;
1395 }
1396
1397 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1398 calculate the value of the Hold Timer by using the smaller of its
1399 configured Hold Time and the Hold Time received in the OPEN message.
1400 The Hold Time MUST be either zero or at least three seconds. An
1401 implementation may reject connections on the basis of the Hold Time. */
1402
1403 if (holdtime < 3 && holdtime != 0)
1404 {
1405 bgp_notify_send (peer,
1406 BGP_NOTIFY_OPEN_ERR,
1407 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1408 return -1;
1409 }
1410
1411 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1412 would be one third of the Hold Time interval. KEEPALIVE messages
1413 MUST NOT be sent more frequently than one per second. An
1414 implementation MAY adjust the rate at which it sends KEEPALIVE
1415 messages as a function of the Hold Time interval. */
1416
1417 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1418 send_holdtime = peer->holdtime;
1419 else
1420 send_holdtime = peer->bgp->default_holdtime;
1421
1422 if (holdtime < send_holdtime)
1423 peer->v_holdtime = holdtime;
1424 else
1425 peer->v_holdtime = send_holdtime;
1426
1427 peer->v_keepalive = peer->v_holdtime / 3;
1428
1429 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001430 if (optlen != 0)
1431 {
1432 ret = bgp_open_option_parse (peer, optlen, &capability);
1433 if (ret < 0)
1434 return ret;
paul718e3742002-12-13 20:15:29 +00001435 }
1436 else
1437 {
1438 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001439 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001440 peer->host);
1441 }
1442
1443 /* Override capability. */
1444 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1445 {
1446 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1447 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1448 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1449 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1450 }
1451
1452 /* Get sockname. */
1453 bgp_getsockname (peer);
1454
1455 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1456
1457 peer->packet_size = 0;
1458 if (peer->ibuf)
1459 stream_reset (peer->ibuf);
1460
1461 return 0;
1462}
1463
1464/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001465static int
paul718e3742002-12-13 20:15:29 +00001466bgp_update_receive (struct peer *peer, bgp_size_t size)
1467{
1468 int ret;
1469 u_char *end;
1470 struct stream *s;
1471 struct attr attr;
1472 bgp_size_t attribute_len;
1473 bgp_size_t update_len;
1474 bgp_size_t withdraw_len;
1475 struct bgp_nlri update;
1476 struct bgp_nlri withdraw;
1477 struct bgp_nlri mp_update;
1478 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001479 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001480
1481 /* Status must be Established. */
1482 if (peer->status != Established)
1483 {
1484 zlog_err ("%s [FSM] Update packet received under status %s",
1485 peer->host, LOOKUP (bgp_status_msg, peer->status));
1486 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1487 return -1;
1488 }
1489
1490 /* Set initial values. */
1491 memset (&attr, 0, sizeof (struct attr));
1492 memset (&update, 0, sizeof (struct bgp_nlri));
1493 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1494 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1495 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1496
1497 s = peer->ibuf;
1498 end = stream_pnt (s) + size;
1499
1500 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1501 Length is too large (i.e., if Unfeasible Routes Length + Total
1502 Attribute Length + 23 exceeds the message Length), then the Error
1503 Subcode is set to Malformed Attribute List. */
1504 if (stream_pnt (s) + 2 > end)
1505 {
1506 zlog_err ("%s [Error] Update packet error"
1507 " (packet length is short for unfeasible length)",
1508 peer->host);
1509 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1510 BGP_NOTIFY_UPDATE_MAL_ATTR);
1511 return -1;
1512 }
1513
1514 /* Unfeasible Route Length. */
1515 withdraw_len = stream_getw (s);
1516
1517 /* Unfeasible Route Length check. */
1518 if (stream_pnt (s) + withdraw_len > end)
1519 {
1520 zlog_err ("%s [Error] Update packet error"
1521 " (packet unfeasible length overflow %d)",
1522 peer->host, withdraw_len);
1523 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1524 BGP_NOTIFY_UPDATE_MAL_ATTR);
1525 return -1;
1526 }
1527
1528 /* Unfeasible Route packet format check. */
1529 if (withdraw_len > 0)
1530 {
1531 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1532 if (ret < 0)
1533 return -1;
1534
1535 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001536 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001537
1538 withdraw.afi = AFI_IP;
1539 withdraw.safi = SAFI_UNICAST;
1540 withdraw.nlri = stream_pnt (s);
1541 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001542 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001543 }
1544
1545 /* Attribute total length check. */
1546 if (stream_pnt (s) + 2 > end)
1547 {
1548 zlog_warn ("%s [Error] Packet Error"
1549 " (update packet is short for attribute length)",
1550 peer->host);
1551 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1552 BGP_NOTIFY_UPDATE_MAL_ATTR);
1553 return -1;
1554 }
1555
1556 /* Fetch attribute total length. */
1557 attribute_len = stream_getw (s);
1558
1559 /* Attribute length check. */
1560 if (stream_pnt (s) + attribute_len > end)
1561 {
1562 zlog_warn ("%s [Error] Packet Error"
1563 " (update packet attribute length overflow %d)",
1564 peer->host, attribute_len);
1565 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1566 BGP_NOTIFY_UPDATE_MAL_ATTR);
1567 return -1;
1568 }
1569
1570 /* Parse attribute when it exists. */
1571 if (attribute_len)
1572 {
1573 ret = bgp_attr_parse (peer, &attr, attribute_len,
1574 &mp_update, &mp_withdraw);
1575 if (ret < 0)
1576 return -1;
1577 }
1578
1579 /* Logging the attribute. */
1580 if (BGP_DEBUG (update, UPDATE_IN))
1581 {
paule01f9cb2004-07-09 17:48:53 +00001582 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1583
1584 if (ret)
ajs6b514742004-12-08 21:03:23 +00001585 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001586 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001587 }
1588
1589 /* Network Layer Reachability Information. */
1590 update_len = end - stream_pnt (s);
1591
1592 if (update_len)
1593 {
1594 /* Check NLRI packet format and prefix length. */
1595 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1596 if (ret < 0)
1597 return -1;
1598
1599 /* Set NLRI portion to structure. */
1600 update.afi = AFI_IP;
1601 update.safi = SAFI_UNICAST;
1602 update.nlri = stream_pnt (s);
1603 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001604 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001605 }
1606
1607 /* NLRI is processed only when the peer is configured specific
1608 Address Family and Subsequent Address Family. */
1609 if (peer->afc[AFI_IP][SAFI_UNICAST])
1610 {
1611 if (withdraw.length)
1612 bgp_nlri_parse (peer, NULL, &withdraw);
1613
1614 if (update.length)
1615 {
1616 /* We check well-known attribute only for IPv4 unicast
1617 update. */
1618 ret = bgp_attr_check (peer, &attr);
1619 if (ret < 0)
1620 return -1;
1621
1622 bgp_nlri_parse (peer, &attr, &update);
1623 }
paule01f9cb2004-07-09 17:48:53 +00001624
hassof4184462005-02-01 20:13:16 +00001625 if (mp_update.length
1626 && mp_update.afi == AFI_IP
1627 && mp_update.safi == SAFI_UNICAST)
1628 bgp_nlri_parse (peer, &attr, &mp_update);
1629
1630 if (mp_withdraw.length
1631 && mp_withdraw.afi == AFI_IP
1632 && mp_withdraw.safi == SAFI_UNICAST)
1633 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1634
paule01f9cb2004-07-09 17:48:53 +00001635 if (! attribute_len && ! withdraw_len)
1636 {
1637 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001638 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1639 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001640
hasso93406d82005-02-02 14:40:33 +00001641 /* NSF delete stale route */
1642 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1643 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1644
1645 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001646 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001647 peer->host);
1648 }
paul718e3742002-12-13 20:15:29 +00001649 }
1650 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1651 {
1652 if (mp_update.length
1653 && mp_update.afi == AFI_IP
1654 && mp_update.safi == SAFI_MULTICAST)
1655 bgp_nlri_parse (peer, &attr, &mp_update);
1656
1657 if (mp_withdraw.length
1658 && mp_withdraw.afi == AFI_IP
1659 && mp_withdraw.safi == SAFI_MULTICAST)
1660 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001661
hasso93406d82005-02-02 14:40:33 +00001662 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001663 && mp_withdraw.afi == AFI_IP
1664 && mp_withdraw.safi == SAFI_MULTICAST
1665 && mp_withdraw.length == 0)
1666 {
1667 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001668 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1669 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001670
hasso93406d82005-02-02 14:40:33 +00001671 /* NSF delete stale route */
1672 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1673 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1674
1675 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001676 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001677 peer->host);
1678 }
paul718e3742002-12-13 20:15:29 +00001679 }
1680 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1681 {
1682 if (mp_update.length
1683 && mp_update.afi == AFI_IP6
1684 && mp_update.safi == SAFI_UNICAST)
1685 bgp_nlri_parse (peer, &attr, &mp_update);
1686
1687 if (mp_withdraw.length
1688 && mp_withdraw.afi == AFI_IP6
1689 && mp_withdraw.safi == SAFI_UNICAST)
1690 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001691
hasso93406d82005-02-02 14:40:33 +00001692 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001693 && mp_withdraw.afi == AFI_IP6
1694 && mp_withdraw.safi == SAFI_UNICAST
1695 && mp_withdraw.length == 0)
1696 {
1697 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001698 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001699
hasso93406d82005-02-02 14:40:33 +00001700 /* NSF delete stale route */
1701 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1702 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1703
1704 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001705 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001706 peer->host);
1707 }
paul718e3742002-12-13 20:15:29 +00001708 }
1709 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1710 {
1711 if (mp_update.length
1712 && mp_update.afi == AFI_IP6
1713 && mp_update.safi == SAFI_MULTICAST)
1714 bgp_nlri_parse (peer, &attr, &mp_update);
1715
1716 if (mp_withdraw.length
1717 && mp_withdraw.afi == AFI_IP6
1718 && mp_withdraw.safi == SAFI_MULTICAST)
1719 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001720
hasso93406d82005-02-02 14:40:33 +00001721 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001722 && mp_withdraw.afi == AFI_IP6
1723 && mp_withdraw.safi == SAFI_MULTICAST
1724 && mp_withdraw.length == 0)
1725 {
1726 /* End-of-RIB received */
1727
hasso93406d82005-02-02 14:40:33 +00001728 /* NSF delete stale route */
1729 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1730 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1731
paule01f9cb2004-07-09 17:48:53 +00001732 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001733 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001734 peer->host);
1735 }
paul718e3742002-12-13 20:15:29 +00001736 }
1737 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1738 {
1739 if (mp_update.length
1740 && mp_update.afi == AFI_IP
1741 && mp_update.safi == BGP_SAFI_VPNV4)
1742 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1743
1744 if (mp_withdraw.length
1745 && mp_withdraw.afi == AFI_IP
1746 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1747 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001748
hasso93406d82005-02-02 14:40:33 +00001749 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001750 && mp_withdraw.afi == AFI_IP
1751 && mp_withdraw.safi == BGP_SAFI_VPNV4
1752 && mp_withdraw.length == 0)
1753 {
1754 /* End-of-RIB received */
1755
1756 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001757 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001758 peer->host);
1759 }
paul718e3742002-12-13 20:15:29 +00001760 }
1761
1762 /* Everything is done. We unintern temporary structures which
1763 interned in bgp_attr_parse(). */
1764 if (attr.aspath)
1765 aspath_unintern (attr.aspath);
1766 if (attr.community)
1767 community_unintern (attr.community);
Paul Jakmafb982c22007-05-04 20:15:47 +00001768 if (attr.extra)
1769 {
1770 if (attr.extra->ecommunity)
1771 ecommunity_unintern (attr.extra->ecommunity);
1772 if (attr.extra->cluster)
1773 cluster_unintern (attr.extra->cluster);
1774 if (attr.extra->transit)
1775 transit_unintern (attr.extra->transit);
1776 bgp_attr_extra_free (&attr);
1777 }
paul718e3742002-12-13 20:15:29 +00001778
1779 /* If peering is stopped due to some reason, do not generate BGP
1780 event. */
1781 if (peer->status != Established)
1782 return 0;
1783
1784 /* Increment packet counter. */
1785 peer->update_in++;
1786 peer->update_time = time (NULL);
1787
1788 /* Generate BGP event. */
1789 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1790
1791 return 0;
1792}
1793
1794/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001795static void
paul718e3742002-12-13 20:15:29 +00001796bgp_notify_receive (struct peer *peer, bgp_size_t size)
1797{
1798 struct bgp_notify bgp_notify;
1799
1800 if (peer->notify.data)
1801 {
1802 XFREE (MTYPE_TMP, peer->notify.data);
1803 peer->notify.data = NULL;
1804 peer->notify.length = 0;
1805 }
1806
1807 bgp_notify.code = stream_getc (peer->ibuf);
1808 bgp_notify.subcode = stream_getc (peer->ibuf);
1809 bgp_notify.length = size - 2;
1810 bgp_notify.data = NULL;
1811
1812 /* Preserv notify code and sub code. */
1813 peer->notify.code = bgp_notify.code;
1814 peer->notify.subcode = bgp_notify.subcode;
1815 /* For further diagnostic record returned Data. */
1816 if (bgp_notify.length)
1817 {
1818 peer->notify.length = size - 2;
1819 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1820 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1821 }
1822
1823 /* For debug */
1824 {
1825 int i;
1826 int first = 0;
1827 char c[4];
1828
1829 if (bgp_notify.length)
1830 {
1831 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1832 for (i = 0; i < bgp_notify.length; i++)
1833 if (first)
1834 {
1835 sprintf (c, " %02x", stream_getc (peer->ibuf));
1836 strcat (bgp_notify.data, c);
1837 }
1838 else
1839 {
1840 first = 1;
1841 sprintf (c, "%02x", stream_getc (peer->ibuf));
1842 strcpy (bgp_notify.data, c);
1843 }
1844 }
1845
1846 bgp_notify_print(peer, &bgp_notify, "received");
1847 if (bgp_notify.data)
1848 XFREE (MTYPE_TMP, bgp_notify.data);
1849 }
1850
1851 /* peer count update */
1852 peer->notify_in++;
1853
hassoe0701b72004-05-20 09:19:34 +00001854 if (peer->status == Established)
1855 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1856
paul718e3742002-12-13 20:15:29 +00001857 /* We have to check for Notify with Unsupported Optional Parameter.
1858 in that case we fallback to open without the capability option.
1859 But this done in bgp_stop. We just mark it here to avoid changing
1860 the fsm tables. */
1861 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1862 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1863 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1864
1865 /* Also apply to Unsupported Capability until remote router support
1866 capability. */
1867 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1868 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
1869 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1870
1871 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1872}
1873
1874/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001875static void
paul718e3742002-12-13 20:15:29 +00001876bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1877{
1878 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001879 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001880
1881 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1882}
1883
1884/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001885static void
paul718e3742002-12-13 20:15:29 +00001886bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1887{
1888 afi_t afi;
1889 safi_t safi;
1890 u_char reserved;
1891 struct stream *s;
1892
1893 /* If peer does not have the capability, send notification. */
1894 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1895 {
1896 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1897 peer->host);
1898 bgp_notify_send (peer,
1899 BGP_NOTIFY_HEADER_ERR,
1900 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1901 return;
1902 }
1903
1904 /* Status must be Established. */
1905 if (peer->status != Established)
1906 {
1907 plog_err (peer->log,
1908 "%s [Error] Route refresh packet received under status %s",
1909 peer->host, LOOKUP (bgp_status_msg, peer->status));
1910 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1911 return;
1912 }
1913
1914 s = peer->ibuf;
1915
1916 /* Parse packet. */
1917 afi = stream_getw (s);
1918 reserved = stream_getc (s);
1919 safi = stream_getc (s);
1920
1921 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001922 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001923 peer->host, afi, safi);
1924
1925 /* Check AFI and SAFI. */
1926 if ((afi != AFI_IP && afi != AFI_IP6)
1927 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1928 && safi != BGP_SAFI_VPNV4))
1929 {
1930 if (BGP_DEBUG (normal, NORMAL))
1931 {
ajs6b514742004-12-08 21:03:23 +00001932 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001933 peer->host, afi, safi);
1934 }
1935 return;
1936 }
1937
1938 /* Adjust safi code. */
1939 if (safi == BGP_SAFI_VPNV4)
1940 safi = SAFI_MPLS_VPN;
1941
1942 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1943 {
1944 u_char *end;
1945 u_char when_to_refresh;
1946 u_char orf_type;
1947 u_int16_t orf_len;
1948
1949 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1950 {
1951 zlog_info ("%s ORF route refresh length error", peer->host);
1952 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1953 return;
1954 }
1955
1956 when_to_refresh = stream_getc (s);
1957 end = stream_pnt (s) + (size - 5);
1958
Paul Jakma370b64a2007-12-22 16:49:52 +00001959 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00001960 {
1961 orf_type = stream_getc (s);
1962 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00001963
1964 /* orf_len in bounds? */
1965 if ((stream_pnt (s) + orf_len) > end)
1966 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00001967 if (orf_type == ORF_TYPE_PREFIX
1968 || orf_type == ORF_TYPE_PREFIX_OLD)
1969 {
1970 u_char *p_pnt = stream_pnt (s);
1971 u_char *p_end = stream_pnt (s) + orf_len;
1972 struct orf_prefix orfp;
1973 u_char common = 0;
1974 u_int32_t seq;
1975 int psize;
1976 char name[BUFSIZ];
1977 char buf[BUFSIZ];
1978 int ret;
1979
1980 if (BGP_DEBUG (normal, NORMAL))
1981 {
ajs6b514742004-12-08 21:03:23 +00001982 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00001983 peer->host, orf_type, orf_len);
1984 }
1985
Paul Jakma370b64a2007-12-22 16:49:52 +00001986 /* we're going to read at least 1 byte of common ORF header,
1987 * and 7 bytes of ORF Address-filter entry from the stream
1988 */
1989 if (orf_len < 7)
1990 break;
1991
paul718e3742002-12-13 20:15:29 +00001992 /* ORF prefix-list name */
1993 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
1994
1995 while (p_pnt < p_end)
1996 {
1997 memset (&orfp, 0, sizeof (struct orf_prefix));
1998 common = *p_pnt++;
1999 if (common & ORF_COMMON_PART_REMOVE_ALL)
2000 {
2001 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002002 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00002003 prefix_bgp_orf_remove_all (name);
2004 break;
2005 }
2006 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2007 p_pnt += sizeof (u_int32_t);
2008 orfp.seq = ntohl (seq);
2009 orfp.ge = *p_pnt++;
2010 orfp.le = *p_pnt++;
2011 orfp.p.prefixlen = *p_pnt++;
2012 orfp.p.family = afi2family (afi);
2013 psize = PSIZE (orfp.p.prefixlen);
2014 memcpy (&orfp.p.u.prefix, p_pnt, psize);
2015 p_pnt += psize;
2016
2017 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002018 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
paul718e3742002-12-13 20:15:29 +00002019 peer->host,
2020 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2021 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2022 orfp.seq,
2023 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
2024 orfp.p.prefixlen, orfp.ge, orfp.le);
2025
2026 ret = prefix_bgp_orf_set (name, afi, &orfp,
2027 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2028 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
2029
2030 if (ret != CMD_SUCCESS)
2031 {
2032 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002033 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002034 prefix_bgp_orf_remove_all (name);
2035 break;
2036 }
2037 }
2038 peer->orf_plist[afi][safi] =
2039 prefix_list_lookup (AFI_ORF_PREFIX, name);
2040 }
paul9985f832005-02-09 15:51:56 +00002041 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002042 }
2043 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002044 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002045 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2046 if (when_to_refresh == REFRESH_DEFER)
2047 return;
2048 }
2049
2050 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2051 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2052 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2053
2054 /* Perform route refreshment to the peer */
2055 bgp_announce_route (peer, afi, safi);
2056}
2057
paul94f2b392005-06-28 12:44:16 +00002058static int
paul718e3742002-12-13 20:15:29 +00002059bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2060{
2061 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002062 struct capability_mp_data mpc;
2063 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002064 u_char action;
2065 struct bgp *bgp;
2066 afi_t afi;
2067 safi_t safi;
2068
2069 bgp = peer->bgp;
2070 end = pnt + length;
2071
2072 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002073 {
paul718e3742002-12-13 20:15:29 +00002074 /* We need at least action, capability code and capability length. */
2075 if (pnt + 3 > end)
2076 {
2077 zlog_info ("%s Capability length error", peer->host);
2078 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2079 return -1;
2080 }
paul718e3742002-12-13 20:15:29 +00002081 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002082 hdr = (struct capability_header *)(pnt + 1);
2083
paul718e3742002-12-13 20:15:29 +00002084 /* Action value check. */
2085 if (action != CAPABILITY_ACTION_SET
2086 && action != CAPABILITY_ACTION_UNSET)
2087 {
2088 zlog_info ("%s Capability Action Value error %d",
2089 peer->host, action);
2090 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2091 return -1;
2092 }
2093
2094 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002095 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002096 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002097
2098 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002099 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002100 {
2101 zlog_info ("%s Capability length error", peer->host);
2102 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2103 return -1;
2104 }
2105
Paul Jakma6d582722007-08-06 15:21:45 +00002106 /* Fetch structure to the byte stream. */
2107 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2108
paul718e3742002-12-13 20:15:29 +00002109 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002110 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002111 {
Paul Jakma6d582722007-08-06 15:21:45 +00002112 afi = ntohs (mpc.afi);
2113 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002114
2115 /* Ignore capability when override-capability is set. */
2116 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2117 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002118
2119 if (!bgp_afi_safi_valid_indices (afi, &safi))
2120 {
2121 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002122 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2123 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002124 continue;
2125 }
2126
paul718e3742002-12-13 20:15:29 +00002127 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002128 if (BGP_DEBUG (normal, NORMAL))
2129 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2130 peer->host,
2131 action == CAPABILITY_ACTION_SET
2132 ? "Advertising" : "Removing",
2133 ntohs(mpc.afi) , mpc.safi);
2134
2135 if (action == CAPABILITY_ACTION_SET)
2136 {
2137 peer->afc_recv[afi][safi] = 1;
2138 if (peer->afc[afi][safi])
2139 {
2140 peer->afc_nego[afi][safi] = 1;
2141 bgp_announce_route (peer, afi, safi);
2142 }
2143 }
2144 else
2145 {
2146 peer->afc_recv[afi][safi] = 0;
2147 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002148
Paul Jakma6d582722007-08-06 15:21:45 +00002149 if (peer_active_nego (peer))
2150 bgp_clear_route (peer, afi, safi);
2151 else
2152 BGP_EVENT_ADD (peer, BGP_Stop);
2153 }
paul718e3742002-12-13 20:15:29 +00002154 }
paul718e3742002-12-13 20:15:29 +00002155 else
2156 {
2157 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002158 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002159 }
Paul Jakma6d582722007-08-06 15:21:45 +00002160 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002161 }
2162 return 0;
2163}
2164
2165/* Dynamic Capability is received. */
Paul Jakma6d582722007-08-06 15:21:45 +00002166int
paul718e3742002-12-13 20:15:29 +00002167bgp_capability_receive (struct peer *peer, bgp_size_t size)
2168{
2169 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002170
2171 /* Fetch pointer. */
2172 pnt = stream_pnt (peer->ibuf);
2173
2174 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002175 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002176
2177 /* If peer does not have the capability, send notification. */
2178 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2179 {
2180 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2181 peer->host);
2182 bgp_notify_send (peer,
2183 BGP_NOTIFY_HEADER_ERR,
2184 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002185 return -1;
paul718e3742002-12-13 20:15:29 +00002186 }
2187
2188 /* Status must be Established. */
2189 if (peer->status != Established)
2190 {
2191 plog_err (peer->log,
2192 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2193 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002194 return -1;
paul718e3742002-12-13 20:15:29 +00002195 }
2196
2197 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002198 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002199}
2200
2201/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002202static int
paul718e3742002-12-13 20:15:29 +00002203bgp_read_packet (struct peer *peer)
2204{
2205 int nbytes;
2206 int readsize;
2207
paul9985f832005-02-09 15:51:56 +00002208 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002209
2210 /* If size is zero then return. */
2211 if (! readsize)
2212 return 0;
2213
2214 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002215 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002216
2217 /* If read byte is smaller than zero then error occured. */
2218 if (nbytes < 0)
2219 {
2220 if (errno == EAGAIN)
2221 return -1;
2222
2223 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002224 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002225
2226 if (peer->status == Established)
2227 {
2228 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2229 {
2230 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2231 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2232 }
2233 else
2234 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2235 }
2236
paul718e3742002-12-13 20:15:29 +00002237 BGP_EVENT_ADD (peer, TCP_fatal_error);
2238 return -1;
2239 }
2240
2241 /* When read byte is zero : clear bgp peer and return */
2242 if (nbytes == 0)
2243 {
2244 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002245 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002246 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002247
2248 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002249 {
2250 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2251 {
2252 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2253 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2254 }
2255 else
2256 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2257 }
hassoe0701b72004-05-20 09:19:34 +00002258
paul718e3742002-12-13 20:15:29 +00002259 BGP_EVENT_ADD (peer, TCP_connection_closed);
2260 return -1;
2261 }
2262
2263 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002264 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002265 return -1;
2266
2267 return 0;
2268}
2269
2270/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002271static int
paul718e3742002-12-13 20:15:29 +00002272bgp_marker_all_one (struct stream *s, int length)
2273{
2274 int i;
2275
2276 for (i = 0; i < length; i++)
2277 if (s->data[i] != 0xff)
2278 return 0;
2279
2280 return 1;
2281}
2282
2283/* Starting point of packet process function. */
2284int
2285bgp_read (struct thread *thread)
2286{
2287 int ret;
2288 u_char type = 0;
2289 struct peer *peer;
2290 bgp_size_t size;
2291 char notify_data_length[2];
2292
2293 /* Yes first of all get peer pointer. */
2294 peer = THREAD_ARG (thread);
2295 peer->t_read = NULL;
2296
2297 /* For non-blocking IO check. */
2298 if (peer->status == Connect)
2299 {
2300 bgp_connect_check (peer);
2301 goto done;
2302 }
2303 else
2304 {
pauleb821182004-05-01 08:44:08 +00002305 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002306 {
pauleb821182004-05-01 08:44:08 +00002307 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002308 return -1;
2309 }
pauleb821182004-05-01 08:44:08 +00002310 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002311 }
2312
2313 /* Read packet header to determine type of the packet */
2314 if (peer->packet_size == 0)
2315 peer->packet_size = BGP_HEADER_SIZE;
2316
paul9985f832005-02-09 15:51:56 +00002317 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002318 {
2319 ret = bgp_read_packet (peer);
2320
2321 /* Header read error or partial read packet. */
2322 if (ret < 0)
2323 goto done;
2324
2325 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002326 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002327 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2328 size = stream_getw (peer->ibuf);
2329 type = stream_getc (peer->ibuf);
2330
2331 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002332 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002333 peer->host, type, size - BGP_HEADER_SIZE);
2334
2335 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002336 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002337 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2338 {
2339 bgp_notify_send (peer,
2340 BGP_NOTIFY_HEADER_ERR,
2341 BGP_NOTIFY_HEADER_NOT_SYNC);
2342 goto done;
2343 }
2344
2345 /* BGP type check. */
2346 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2347 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2348 && type != BGP_MSG_ROUTE_REFRESH_NEW
2349 && type != BGP_MSG_ROUTE_REFRESH_OLD
2350 && type != BGP_MSG_CAPABILITY)
2351 {
2352 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002353 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002354 "%s unknown message type 0x%02x",
2355 peer->host, type);
2356 bgp_notify_send_with_data (peer,
2357 BGP_NOTIFY_HEADER_ERR,
2358 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2359 &type, 1);
2360 goto done;
2361 }
2362 /* Mimimum packet length check. */
2363 if ((size < BGP_HEADER_SIZE)
2364 || (size > BGP_MAX_PACKET_SIZE)
2365 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2366 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2367 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2368 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2369 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2370 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2371 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2372 {
2373 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002374 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002375 "%s bad message length - %d for %s",
2376 peer->host, size,
2377 type == 128 ? "ROUTE-REFRESH" :
2378 bgp_type_str[(int) type]);
2379 bgp_notify_send_with_data (peer,
2380 BGP_NOTIFY_HEADER_ERR,
2381 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002382 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002383 goto done;
2384 }
2385
2386 /* Adjust size to message length. */
2387 peer->packet_size = size;
2388 }
2389
2390 ret = bgp_read_packet (peer);
2391 if (ret < 0)
2392 goto done;
2393
2394 /* Get size and type again. */
2395 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2396 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2397
2398 /* BGP packet dump function. */
2399 bgp_dump_packet (peer, type, peer->ibuf);
2400
2401 size = (peer->packet_size - BGP_HEADER_SIZE);
2402
2403 /* Read rest of the packet and call each sort of packet routine */
2404 switch (type)
2405 {
2406 case BGP_MSG_OPEN:
2407 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002408 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002409 break;
2410 case BGP_MSG_UPDATE:
2411 peer->readtime = time(NULL); /* Last read timer reset */
2412 bgp_update_receive (peer, size);
2413 break;
2414 case BGP_MSG_NOTIFY:
2415 bgp_notify_receive (peer, size);
2416 break;
2417 case BGP_MSG_KEEPALIVE:
2418 peer->readtime = time(NULL); /* Last read timer reset */
2419 bgp_keepalive_receive (peer, size);
2420 break;
2421 case BGP_MSG_ROUTE_REFRESH_NEW:
2422 case BGP_MSG_ROUTE_REFRESH_OLD:
2423 peer->refresh_in++;
2424 bgp_route_refresh_receive (peer, size);
2425 break;
2426 case BGP_MSG_CAPABILITY:
2427 peer->dynamic_cap_in++;
2428 bgp_capability_receive (peer, size);
2429 break;
2430 }
2431
2432 /* Clear input buffer. */
2433 peer->packet_size = 0;
2434 if (peer->ibuf)
2435 stream_reset (peer->ibuf);
2436
2437 done:
2438 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2439 {
2440 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002441 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002442 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002443 }
2444 return 0;
2445}