blob: 8de78c7535bf95f594a34b2441f2068bf6b51d6c [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
31#include "linklist.h"
32#include "plist.h"
33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_table.h"
36#include "bgpd/bgp_dump.h"
37#include "bgpd/bgp_attr.h"
38#include "bgpd/bgp_debug.h"
39#include "bgpd/bgp_fsm.h"
40#include "bgpd/bgp_route.h"
41#include "bgpd/bgp_packet.h"
42#include "bgpd/bgp_open.h"
43#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_community.h"
45#include "bgpd/bgp_ecommunity.h"
46#include "bgpd/bgp_network.h"
47#include "bgpd/bgp_mplsvpn.h"
48#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000049#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000050
51int stream_put_prefix (struct stream *, struct prefix *);
52
53/* Set up BGP packet marker and packet type. */
54static int
55bgp_packet_set_marker (struct stream *s, u_char type)
56{
57 int i;
58
59 /* Fill in marker. */
60 for (i = 0; i < BGP_MARKER_SIZE; i++)
61 stream_putc (s, 0xff);
62
63 /* Dummy total length. This field is should be filled in later on. */
64 stream_putw (s, 0);
65
66 /* BGP packet type. */
67 stream_putc (s, type);
68
69 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000070 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000071}
72
73/* Set BGP packet header size entry. If size is zero then use current
74 stream size. */
75static int
76bgp_packet_set_size (struct stream *s)
77{
78 int cp;
79
80 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000081 cp = stream_get_endp (s);
82 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000083
84 return cp;
85}
86
87/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000088static void
paul718e3742002-12-13 20:15:29 +000089bgp_packet_add (struct peer *peer, struct stream *s)
90{
91 /* Add packet to the end of list. */
92 stream_fifo_push (peer->obuf, s);
93}
94
95/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000096static void
paul718e3742002-12-13 20:15:29 +000097bgp_packet_delete (struct peer *peer)
98{
99 stream_free (stream_fifo_pop (peer->obuf));
100}
101
paul718e3742002-12-13 20:15:29 +0000102/* Check file descriptor whether connect is established. */
103static void
104bgp_connect_check (struct peer *peer)
105{
106 int status;
paul5228ad22004-06-04 17:58:18 +0000107 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000108 int ret;
109
110 /* Anyway I have to reset read and write thread. */
111 BGP_READ_OFF (peer->t_read);
112 BGP_WRITE_OFF (peer->t_write);
113
114 /* Check file descriptor. */
115 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000116 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000117
118 /* If getsockopt is fail, this is fatal error. */
119 if (ret < 0)
120 {
121 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
122 BGP_EVENT_ADD (peer, TCP_fatal_error);
123 return;
124 }
125
126 /* When status is 0 then TCP connection is established. */
127 if (status == 0)
128 {
129 BGP_EVENT_ADD (peer, TCP_connection_open);
130 }
131 else
132 {
133 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000134 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000135 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000136 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
137 }
138}
139
140/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000141static struct stream *
paul718e3742002-12-13 20:15:29 +0000142bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
143{
144 struct stream *s;
145 struct bgp_adj_out *adj;
146 struct bgp_advertise *adv;
147 struct stream *packet;
148 struct bgp_node *rn = NULL;
149 struct bgp_info *binfo = NULL;
150 bgp_size_t total_attr_len = 0;
151 unsigned long pos;
152 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000153
154 s = peer->work;
155 stream_reset (s);
156
157 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
158
159 while (adv)
160 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000161 assert (adv->rn);
162 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000163 adj = adv->adj;
164 if (adv->binfo)
165 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000166
167 /* When remaining space can't include NLRI and it's length. */
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000168 if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
paul718e3742002-12-13 20:15:29 +0000169 break;
170
171 /* If packet is empty, set attribute. */
172 if (stream_empty (s))
173 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000174 struct prefix_rd *prd = NULL;
175 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000176 struct peer *from = NULL;
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000177
178 if (rn->prn)
179 prd = (struct prefix_rd *) &rn->prn->p;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400180 if (binfo)
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000182 from = binfo->peer;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400183 if (binfo->extra)
184 tag = binfo->extra->tag;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000185 }
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000186
paul718e3742002-12-13 20:15:29 +0000187 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
188 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000189 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000190 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000191 total_attr_len = bgp_packet_attribute (NULL, peer, s,
192 adv->baa->attr,
193 &rn->p, afi, safi,
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000194 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000195 stream_putw_at (s, pos, total_attr_len);
196 }
197
198 if (afi == AFI_IP && safi == SAFI_UNICAST)
199 stream_put_prefix (s, &rn->p);
200
201 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000202 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000203 peer->host,
204 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
205 rn->p.prefixlen);
206
207 /* Synchnorize attribute. */
208 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000209 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000210 else
211 peer->scount[afi][safi]++;
212
213 adj->attr = bgp_attr_intern (adv->baa->attr);
214
215 adv = bgp_advertise_clean (peer, adj, afi, safi);
216
217 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
218 break;
219 }
220
221 if (! stream_empty (s))
222 {
223 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000224 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000225 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000226 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000227 stream_reset (s);
228 return packet;
229 }
230 return NULL;
hasso93406d82005-02-02 14:40:33 +0000231}
paul718e3742002-12-13 20:15:29 +0000232
paul94f2b392005-06-28 12:44:16 +0000233static struct stream *
hasso93406d82005-02-02 14:40:33 +0000234bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
235{
236 struct stream *s;
237 struct stream *packet;
238
Paul Jakma750e8142008-07-22 21:11:48 +0000239 if (DISABLE_BGP_ANNOUNCE)
240 return NULL;
hasso93406d82005-02-02 14:40:33 +0000241
242 if (BGP_DEBUG (normal, NORMAL))
243 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
244
245 s = stream_new (BGP_MAX_PACKET_SIZE);
246
247 /* Make BGP update packet. */
248 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
249
250 /* Unfeasible Routes Length */
251 stream_putw (s, 0);
252
253 if (afi == AFI_IP && safi == SAFI_UNICAST)
254 {
255 /* Total Path Attribute Length */
256 stream_putw (s, 0);
257 }
258 else
259 {
260 /* Total Path Attribute Length */
261 stream_putw (s, 6);
262 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
263 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
264 stream_putc (s, 3);
265 stream_putw (s, afi);
266 stream_putc (s, safi);
267 }
268
269 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000270 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000271 bgp_packet_add (peer, packet);
272 stream_free (s);
273 return packet;
paul718e3742002-12-13 20:15:29 +0000274}
275
276/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000277static struct stream *
paul718e3742002-12-13 20:15:29 +0000278bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
279{
280 struct stream *s;
281 struct stream *packet;
282 struct bgp_adj_out *adj;
283 struct bgp_advertise *adv;
284 struct bgp_node *rn;
285 unsigned long pos;
286 bgp_size_t unfeasible_len;
287 bgp_size_t total_attr_len;
288 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000289
290 s = peer->work;
291 stream_reset (s);
292
293 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
294 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000295 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000296 adj = adv->adj;
297 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000298
299 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000300 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000301 break;
302
303 if (stream_empty (s))
304 {
305 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
306 stream_putw (s, 0);
307 }
308
309 if (afi == AFI_IP && safi == SAFI_UNICAST)
310 stream_put_prefix (s, &rn->p);
311 else
312 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000313 struct prefix_rd *prd = NULL;
314
315 if (rn->prn)
316 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000317 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000318 stream_putw (s, 0);
319 total_attr_len
320 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
321
322 /* Set total path attribute length. */
323 stream_putw_at (s, pos, total_attr_len);
324 }
325
326 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000327 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000328 peer->host,
329 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
330 rn->p.prefixlen);
331
332 peer->scount[afi][safi]--;
333
334 bgp_adj_out_remove (rn, adj, peer, afi, safi);
335 bgp_unlock_node (rn);
336
337 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
338 break;
339 }
340
341 if (! stream_empty (s))
342 {
343 if (afi == AFI_IP && safi == SAFI_UNICAST)
344 {
345 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000346 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000347 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
348 stream_putw (s, 0);
349 }
350 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000351 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000352 bgp_packet_add (peer, packet);
353 stream_reset (s);
354 return packet;
355 }
356
357 return NULL;
358}
359
360void
361bgp_default_update_send (struct peer *peer, struct attr *attr,
362 afi_t afi, safi_t safi, struct peer *from)
363{
364 struct stream *s;
365 struct stream *packet;
366 struct prefix p;
367 unsigned long pos;
368 bgp_size_t total_attr_len;
369 char attrstr[BUFSIZ];
370 char buf[BUFSIZ];
371
Paul Jakma750e8142008-07-22 21:11:48 +0000372 if (DISABLE_BGP_ANNOUNCE)
373 return;
paul718e3742002-12-13 20:15:29 +0000374
375 if (afi == AFI_IP)
376 str2prefix ("0.0.0.0/0", &p);
377#ifdef HAVE_IPV6
378 else
379 str2prefix ("::/0", &p);
380#endif /* HAVE_IPV6 */
381
382 /* Logging the attribute. */
383 if (BGP_DEBUG (update, UPDATE_OUT))
384 {
385 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000386 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000387 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
388 p.prefixlen, attrstr);
389 }
390
391 s = stream_new (BGP_MAX_PACKET_SIZE);
392
393 /* Make BGP update packet. */
394 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
395
396 /* Unfeasible Routes Length. */
397 stream_putw (s, 0);
398
399 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000400 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000401 stream_putw (s, 0);
402 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
403
404 /* Set Total Path Attribute Length. */
405 stream_putw_at (s, pos, total_attr_len);
406
407 /* NLRI set. */
408 if (p.family == AF_INET && safi == SAFI_UNICAST)
409 stream_put_prefix (s, &p);
410
411 /* Set size. */
412 bgp_packet_set_size (s);
413
paule83e2082005-05-19 02:12:25 +0000414 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000415 stream_free (s);
416
417 /* Dump packet if debug option is set. */
418#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000419 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000420#endif /* DEBUG */
421
422 /* Add packet to the peer. */
423 bgp_packet_add (peer, packet);
424
pauleb821182004-05-01 08:44:08 +0000425 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000426}
427
428void
429bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
430{
431 struct stream *s;
432 struct stream *packet;
433 struct prefix p;
434 unsigned long pos;
435 unsigned long cp;
436 bgp_size_t unfeasible_len;
437 bgp_size_t total_attr_len;
438 char buf[BUFSIZ];
439
Paul Jakma750e8142008-07-22 21:11:48 +0000440 if (DISABLE_BGP_ANNOUNCE)
441 return;
paul718e3742002-12-13 20:15:29 +0000442
443 if (afi == AFI_IP)
444 str2prefix ("0.0.0.0/0", &p);
445#ifdef HAVE_IPV6
446 else
447 str2prefix ("::/0", &p);
448#endif /* HAVE_IPV6 */
449
450 total_attr_len = 0;
451 pos = 0;
452
453 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000454 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000455 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
456 p.prefixlen);
457
458 s = stream_new (BGP_MAX_PACKET_SIZE);
459
460 /* Make BGP update packet. */
461 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
462
463 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000464 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000465 stream_putw (s, 0);
466
467 /* Withdrawn Routes. */
468 if (p.family == AF_INET && safi == SAFI_UNICAST)
469 {
470 stream_put_prefix (s, &p);
471
paul9985f832005-02-09 15:51:56 +0000472 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000473
474 /* Set unfeasible len. */
475 stream_putw_at (s, cp, unfeasible_len);
476
477 /* Set total path attribute length. */
478 stream_putw (s, 0);
479 }
480 else
481 {
paul9985f832005-02-09 15:51:56 +0000482 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000483 stream_putw (s, 0);
484 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
485
486 /* Set total path attribute length. */
487 stream_putw_at (s, pos, total_attr_len);
488 }
489
490 bgp_packet_set_size (s);
491
paule83e2082005-05-19 02:12:25 +0000492 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000493 stream_free (s);
494
495 /* Add packet to the peer. */
496 bgp_packet_add (peer, packet);
497
pauleb821182004-05-01 08:44:08 +0000498 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000499}
500
501/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000502static struct stream *
paul718e3742002-12-13 20:15:29 +0000503bgp_write_packet (struct peer *peer)
504{
505 afi_t afi;
506 safi_t safi;
507 struct stream *s = NULL;
508 struct bgp_advertise *adv;
509
510 s = stream_fifo_head (peer->obuf);
511 if (s)
512 return s;
513
514 for (afi = AFI_IP; afi < AFI_MAX; afi++)
515 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
516 {
517 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
518 if (adv)
519 {
520 s = bgp_withdraw_packet (peer, afi, safi);
521 if (s)
522 return s;
523 }
524 }
525
526 for (afi = AFI_IP; afi < AFI_MAX; afi++)
527 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
528 {
529 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
530 if (adv)
531 {
532 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000533 {
534 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
535 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
536 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
537 && safi != SAFI_MPLS_VPN)
538 {
539 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
540 PEER_STATUS_EOR_RECEIVED))
541 s = bgp_update_packet (peer, afi, safi);
542 }
543 else
544 s = bgp_update_packet (peer, afi, safi);
545 }
paul718e3742002-12-13 20:15:29 +0000546
547 if (s)
548 return s;
549 }
hasso93406d82005-02-02 14:40:33 +0000550
551 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
552 {
553 if (peer->afc_nego[afi][safi] && peer->synctime
554 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
555 && safi != SAFI_MPLS_VPN)
556 {
557 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
558 return bgp_update_packet_eor (peer, afi, safi);
559 }
560 }
paul718e3742002-12-13 20:15:29 +0000561 }
562
563 return NULL;
564}
565
566/* Is there partially written packet or updates we can send right
567 now. */
paul94f2b392005-06-28 12:44:16 +0000568static int
paul718e3742002-12-13 20:15:29 +0000569bgp_write_proceed (struct peer *peer)
570{
571 afi_t afi;
572 safi_t safi;
573 struct bgp_advertise *adv;
574
575 if (stream_fifo_head (peer->obuf))
576 return 1;
577
578 for (afi = AFI_IP; afi < AFI_MAX; afi++)
579 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
580 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
581 return 1;
582
583 for (afi = AFI_IP; afi < AFI_MAX; afi++)
584 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
585 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
586 if (adv->binfo->uptime < peer->synctime)
587 return 1;
588
589 return 0;
590}
591
592/* Write packet to the peer. */
593int
594bgp_write (struct thread *thread)
595{
596 struct peer *peer;
597 u_char type;
598 struct stream *s;
599 int num;
paulfd79ac92004-10-13 05:06:08 +0000600 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000601 int write_errno;
602
603 /* Yes first of all get peer pointer. */
604 peer = THREAD_ARG (thread);
605 peer->t_write = NULL;
606
607 /* For non-blocking IO check. */
608 if (peer->status == Connect)
609 {
610 bgp_connect_check (peer);
611 return 0;
612 }
613
614 /* Nonblocking write until TCP output buffer is full. */
615 while (1)
616 {
617 int writenum;
paula24a7e12005-01-05 08:14:13 +0000618 int val;
paul718e3742002-12-13 20:15:29 +0000619
620 s = bgp_write_packet (peer);
621 if (! s)
622 return 0;
paula24a7e12005-01-05 08:14:13 +0000623
624 /* XXX: FIXME, the socket should be NONBLOCK from the start
625 * status shouldnt need to be toggled on each write
626 */
627 val = fcntl (peer->fd, F_GETFL, 0);
628 fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
paul718e3742002-12-13 20:15:29 +0000629
630 /* Number of bytes to be sent. */
631 writenum = stream_get_endp (s) - stream_get_getp (s);
632
633 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000634 num = write (peer->fd, STREAM_PNT (s), writenum);
paul718e3742002-12-13 20:15:29 +0000635 write_errno = errno;
paula24a7e12005-01-05 08:14:13 +0000636 fcntl (peer->fd, F_SETFL, val);
paul718e3742002-12-13 20:15:29 +0000637 if (num <= 0)
638 {
639 /* Partial write. */
640 if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
641 break;
642
Paul Jakmadcdf3992006-10-15 23:39:59 +0000643 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000644 return 0;
645 }
646 if (num != writenum)
647 {
paul9985f832005-02-09 15:51:56 +0000648 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000649
650 if (write_errno == EAGAIN)
651 break;
652
653 continue;
654 }
655
656 /* Retrieve BGP packet type. */
657 stream_set_getp (s, BGP_MARKER_SIZE + 2);
658 type = stream_getc (s);
659
660 switch (type)
661 {
662 case BGP_MSG_OPEN:
663 peer->open_out++;
664 break;
665 case BGP_MSG_UPDATE:
666 peer->update_out++;
667 break;
668 case BGP_MSG_NOTIFY:
669 peer->notify_out++;
670 /* Double start timer. */
671 peer->v_start *= 2;
672
673 /* Overflow check. */
674 if (peer->v_start >= (60 * 2))
675 peer->v_start = (60 * 2);
676
Paul Jakmaca058a32006-09-14 02:58:49 +0000677 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000678 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000679 return 0;
paul718e3742002-12-13 20:15:29 +0000680 case BGP_MSG_KEEPALIVE:
681 peer->keepalive_out++;
682 break;
683 case BGP_MSG_ROUTE_REFRESH_NEW:
684 case BGP_MSG_ROUTE_REFRESH_OLD:
685 peer->refresh_out++;
686 break;
687 case BGP_MSG_CAPABILITY:
688 peer->dynamic_cap_out++;
689 break;
690 }
691
692 /* OK we send packet so delete it. */
693 bgp_packet_delete (peer);
694
695 if (++count >= BGP_WRITE_PACKET_MAX)
696 break;
697 }
698
699 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000700 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000701
702 return 0;
703}
704
705/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000706static int
paul718e3742002-12-13 20:15:29 +0000707bgp_write_notify (struct peer *peer)
708{
709 int ret;
710 u_char type;
711 struct stream *s;
712
713 /* There should be at least one packet. */
714 s = stream_fifo_head (peer->obuf);
715 if (!s)
716 return 0;
717 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
718
719 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000720 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000721 if (ret <= 0)
722 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000723 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000724 return 0;
725 }
726
727 /* Retrieve BGP packet type. */
728 stream_set_getp (s, BGP_MARKER_SIZE + 2);
729 type = stream_getc (s);
730
731 assert (type == BGP_MSG_NOTIFY);
732
733 /* Type should be notify. */
734 peer->notify_out++;
735
736 /* Double start timer. */
737 peer->v_start *= 2;
738
739 /* Overflow check. */
740 if (peer->v_start >= (60 * 2))
741 peer->v_start = (60 * 2);
742
Paul Jakmadcdf3992006-10-15 23:39:59 +0000743 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000744
745 return 0;
746}
747
748/* Make keepalive packet and send it to the peer. */
749void
750bgp_keepalive_send (struct peer *peer)
751{
752 struct stream *s;
753 int length;
754
755 s = stream_new (BGP_MAX_PACKET_SIZE);
756
757 /* Make keepalive packet. */
758 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
759
760 /* Set packet size. */
761 length = bgp_packet_set_size (s);
762
763 /* Dump packet if debug option is set. */
764 /* bgp_packet_dump (s); */
765
766 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000767 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000768 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000769 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000770 peer->host, BGP_MSG_KEEPALIVE, length);
771
772 /* Add packet to the peer. */
773 bgp_packet_add (peer, s);
774
pauleb821182004-05-01 08:44:08 +0000775 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000776}
777
778/* Make open packet and send it to the peer. */
779void
780bgp_open_send (struct peer *peer)
781{
782 struct stream *s;
783 int length;
784 u_int16_t send_holdtime;
785 as_t local_as;
786
787 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
788 send_holdtime = peer->holdtime;
789 else
790 send_holdtime = peer->bgp->default_holdtime;
791
792 /* local-as Change */
793 if (peer->change_local_as)
794 local_as = peer->change_local_as;
795 else
796 local_as = peer->local_as;
797
798 s = stream_new (BGP_MAX_PACKET_SIZE);
799
800 /* Make open packet. */
801 bgp_packet_set_marker (s, BGP_MSG_OPEN);
802
803 /* Set open packet values. */
804 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000805 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
806 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000807 stream_putw (s, send_holdtime); /* Hold Time */
808 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
809
810 /* Set capability code. */
811 bgp_open_capability (s, peer);
812
813 /* Set BGP packet length. */
814 length = bgp_packet_set_size (s);
815
816 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400817 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000818 peer->host, BGP_VERSION_4, local_as,
819 send_holdtime, inet_ntoa (peer->local_id));
820
821 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000822 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000823 peer->host, BGP_MSG_OPEN, length);
824
825 /* Dump packet if debug option is set. */
826 /* bgp_packet_dump (s); */
827
828 /* Add packet to the peer. */
829 bgp_packet_add (peer, s);
830
pauleb821182004-05-01 08:44:08 +0000831 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000832}
833
834/* Send BGP notify packet with data potion. */
835void
836bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
837 u_char *data, size_t datalen)
838{
839 struct stream *s;
840 int length;
841
842 /* Allocate new stream. */
843 s = stream_new (BGP_MAX_PACKET_SIZE);
844
845 /* Make nitify packet. */
846 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
847
848 /* Set notify packet values. */
849 stream_putc (s, code); /* BGP notify code */
850 stream_putc (s, sub_code); /* BGP notify sub_code */
851
852 /* If notify data is present. */
853 if (data)
854 stream_write (s, data, datalen);
855
856 /* Set BGP packet length. */
857 length = bgp_packet_set_size (s);
858
859 /* Add packet to the peer. */
860 stream_fifo_clean (peer->obuf);
861 bgp_packet_add (peer, s);
862
863 /* For debug */
864 {
865 struct bgp_notify bgp_notify;
866 int first = 0;
867 int i;
868 char c[4];
869
870 bgp_notify.code = code;
871 bgp_notify.subcode = sub_code;
872 bgp_notify.data = NULL;
873 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
874
875 if (bgp_notify.length)
876 {
877 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
878 for (i = 0; i < bgp_notify.length; i++)
879 if (first)
880 {
881 sprintf (c, " %02x", data[i]);
882 strcat (bgp_notify.data, c);
883 }
884 else
885 {
886 first = 1;
887 sprintf (c, "%02x", data[i]);
888 strcpy (bgp_notify.data, c);
889 }
890 }
891 bgp_notify_print (peer, &bgp_notify, "sending");
892 if (bgp_notify.data)
893 XFREE (MTYPE_TMP, bgp_notify.data);
894 }
895
896 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000897 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000898 peer->host, BGP_MSG_NOTIFY, length);
899
hassoe0701b72004-05-20 09:19:34 +0000900 /* peer reset cause */
901 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
902 {
903 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
904 peer->last_reset = PEER_DOWN_USER_RESET;
905 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
906 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
907 else
908 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
909 }
910
paul718e3742002-12-13 20:15:29 +0000911 /* Call imidiately. */
912 BGP_WRITE_OFF (peer->t_write);
913
914 bgp_write_notify (peer);
915}
916
917/* Send BGP notify packet. */
918void
919bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
920{
921 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
922}
923
paul718e3742002-12-13 20:15:29 +0000924/* Send route refresh message to the peer. */
925void
926bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
927 u_char orf_type, u_char when_to_refresh, int remove)
928{
929 struct stream *s;
930 struct stream *packet;
931 int length;
932 struct bgp_filter *filter;
933 int orf_refresh = 0;
934
Paul Jakma750e8142008-07-22 21:11:48 +0000935 if (DISABLE_BGP_ANNOUNCE)
936 return;
paul718e3742002-12-13 20:15:29 +0000937
938 filter = &peer->filter[afi][safi];
939
940 /* Adjust safi code. */
941 if (safi == SAFI_MPLS_VPN)
942 safi = BGP_SAFI_VPNV4;
943
944 s = stream_new (BGP_MAX_PACKET_SIZE);
945
946 /* Make BGP update packet. */
947 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
948 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
949 else
950 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
951
952 /* Encode Route Refresh message. */
953 stream_putw (s, afi);
954 stream_putc (s, 0);
955 stream_putc (s, safi);
956
957 if (orf_type == ORF_TYPE_PREFIX
958 || orf_type == ORF_TYPE_PREFIX_OLD)
959 if (remove || filter->plist[FILTER_IN].plist)
960 {
961 u_int16_t orf_len;
962 unsigned long orfp;
963
964 orf_refresh = 1;
965 stream_putc (s, when_to_refresh);
966 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000967 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000968 stream_putw (s, 0);
969
970 if (remove)
971 {
972 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
973 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
974 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000975 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000976 peer->host, orf_type,
977 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
978 afi, safi);
979 }
980 else
981 {
982 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
983 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
984 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
985 ORF_COMMON_PART_DENY);
986 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000987 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000988 peer->host, orf_type,
989 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
990 afi, safi);
991 }
992
993 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +0000994 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +0000995 stream_putw_at (s, orfp, orf_len);
996 }
997
998 /* Set packet size. */
999 length = bgp_packet_set_size (s);
1000
1001 if (BGP_DEBUG (normal, NORMAL))
1002 {
1003 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001004 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001005 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001006 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001007 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1008 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1009 }
1010
1011 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001012 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001013 stream_free (s);
1014
1015 /* Add packet to the peer. */
1016 bgp_packet_add (peer, packet);
1017
pauleb821182004-05-01 08:44:08 +00001018 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001019}
1020
1021/* Send capability message to the peer. */
1022void
1023bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1024 int capability_code, int action)
1025{
1026 struct stream *s;
1027 struct stream *packet;
1028 int length;
1029
1030 /* Adjust safi code. */
1031 if (safi == SAFI_MPLS_VPN)
1032 safi = BGP_SAFI_VPNV4;
1033
1034 s = stream_new (BGP_MAX_PACKET_SIZE);
1035
1036 /* Make BGP update packet. */
1037 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1038
1039 /* Encode MP_EXT capability. */
1040 if (capability_code == CAPABILITY_CODE_MP)
1041 {
1042 stream_putc (s, action);
1043 stream_putc (s, CAPABILITY_CODE_MP);
1044 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1045 stream_putw (s, afi);
1046 stream_putc (s, 0);
1047 stream_putc (s, safi);
1048
1049 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001050 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001051 peer->host, action == CAPABILITY_ACTION_SET ?
1052 "Advertising" : "Removing", afi, safi);
1053 }
1054
paul718e3742002-12-13 20:15:29 +00001055 /* Set packet size. */
1056 length = bgp_packet_set_size (s);
1057
1058 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001059 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001060 stream_free (s);
1061
1062 /* Add packet to the peer. */
1063 bgp_packet_add (peer, packet);
1064
1065 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001066 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001067 peer->host, BGP_MSG_CAPABILITY, length);
1068
pauleb821182004-05-01 08:44:08 +00001069 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001070}
1071
1072/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001073static int
pauleb821182004-05-01 08:44:08 +00001074bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001075{
pauleb821182004-05-01 08:44:08 +00001076 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001077 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001078 struct bgp *bgp;
1079
1080 bgp = bgp_get_default ();
1081 if (! bgp)
1082 return 0;
1083
1084 /* Upon receipt of an OPEN message, the local system must examine
1085 all of its connections that are in the OpenConfirm state. A BGP
1086 speaker may also examine connections in an OpenSent state if it
1087 knows the BGP Identifier of the peer by means outside of the
1088 protocol. If among these connections there is a connection to a
1089 remote BGP speaker whose BGP Identifier equals the one in the
1090 OPEN message, then the local system performs the following
1091 collision resolution procedure: */
1092
paul1eb8ef22005-04-07 07:30:20 +00001093 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001094 {
1095 /* Under OpenConfirm status, local peer structure already hold
1096 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001097
1098 if (peer != new
1099 && (peer->status == OpenConfirm || peer->status == OpenSent)
1100 && sockunion_same (&peer->su, &new->su))
1101 {
paul718e3742002-12-13 20:15:29 +00001102 /* 1. The BGP Identifier of the local system is compared to
1103 the BGP Identifier of the remote system (as specified in
1104 the OPEN message). */
1105
1106 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1107 {
1108 /* 2. If the value of the local BGP Identifier is less
1109 than the remote one, the local system closes BGP
1110 connection that already exists (the one that is
1111 already in the OpenConfirm state), and accepts BGP
1112 connection initiated by the remote system. */
1113
pauleb821182004-05-01 08:44:08 +00001114 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001115 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001116 return 1;
1117 }
1118 else
1119 {
1120 /* 3. Otherwise, the local system closes newly created
1121 BGP connection (the one associated with the newly
1122 received OPEN message), and continues to use the
1123 existing one (the one that is already in the
1124 OpenConfirm state). */
1125
pauleb821182004-05-01 08:44:08 +00001126 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001127 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1128 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001129 return -1;
1130 }
pauleb821182004-05-01 08:44:08 +00001131 }
1132 }
paul718e3742002-12-13 20:15:29 +00001133 return 0;
1134}
1135
paul94f2b392005-06-28 12:44:16 +00001136static int
paul718e3742002-12-13 20:15:29 +00001137bgp_open_receive (struct peer *peer, bgp_size_t size)
1138{
1139 int ret;
1140 u_char version;
1141 u_char optlen;
1142 u_int16_t holdtime;
1143 u_int16_t send_holdtime;
1144 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001145 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001146 struct peer *realpeer;
1147 struct in_addr remote_id;
1148 int capability;
paul5228ad22004-06-04 17:58:18 +00001149 u_int8_t notify_data_remote_as[2];
1150 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001151
1152 realpeer = NULL;
1153
1154 /* Parse open packet. */
1155 version = stream_getc (peer->ibuf);
1156 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1157 remote_as = stream_getw (peer->ibuf);
1158 holdtime = stream_getw (peer->ibuf);
1159 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1160 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1161
1162 /* Receive OPEN message log */
1163 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001164 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001165 " holdtime %d, id %s",
1166 peer->host, version, remote_as, holdtime,
1167 inet_ntoa (remote_id));
1168
1169 /* BEGIN to read the capability here, but dont do it yet */
1170 capability = 0;
1171 optlen = stream_getc (peer->ibuf);
1172
1173 if (optlen != 0)
1174 {
1175 /* We need the as4 capability value *right now* because
1176 * if it is there, we have not got the remote_as yet, and without
1177 * that we do not know which peer is connecting to us now.
1178 */
1179 as4 = peek_for_as4_capability (peer, optlen);
1180 }
1181
1182 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1183 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1184 {
1185 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1186 peer->host);
1187 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1188 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1189 return -1;
1190 }
1191
1192 if (remote_as == BGP_AS_TRANS)
1193 {
1194 /* Take the AS4 from the capability. We must have received the
1195 * capability now! Otherwise we have a asn16 peer who uses
1196 * BGP_AS_TRANS, for some unknown reason.
1197 */
1198 if (as4 == BGP_AS_TRANS)
1199 {
1200 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1201 peer->host);
1202 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1203 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1204 return -1;
1205 }
1206
1207 if (!as4 && BGP_DEBUG (as4, AS4))
1208 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1209 " Odd, but proceeding.", peer->host);
1210 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001211 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001212 "in 2-bytes, very odd peer.", peer->host, as4);
1213 if (as4)
1214 remote_as = as4;
1215 }
1216 else
1217 {
1218 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1219 /* If we have got the capability, peer->as4cap must match remote_as */
1220 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1221 && as4 != remote_as)
1222 {
1223 /* raise error, log this, close session */
1224 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1225 " mismatch with 16bit 'myasn' %u in open",
1226 peer->host, as4, remote_as);
1227 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1228 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1229 return -1;
1230 }
1231 }
1232
paul718e3742002-12-13 20:15:29 +00001233 /* Lookup peer from Open packet. */
1234 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1235 {
1236 int as = 0;
1237
1238 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1239
1240 if (! realpeer)
1241 {
1242 /* Peer's source IP address is check in bgp_accept(), so this
1243 must be AS number mismatch or remote-id configuration
1244 mismatch. */
1245 if (as)
1246 {
1247 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001248 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1249 peer->host, inet_ntoa (remote_id));
1250 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1251 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1252 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001253 }
1254 else
1255 {
1256 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001257 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001258 peer->host, remote_as, peer->as);
1259 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1260 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1261 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001262 }
1263 return -1;
1264 }
1265 }
1266
1267 /* When collision is detected and this peer is closed. Retrun
1268 immidiately. */
1269 ret = bgp_collision_detect (peer, remote_id);
1270 if (ret < 0)
1271 return ret;
1272
pauleb821182004-05-01 08:44:08 +00001273 /* Hack part. */
1274 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1275 {
hasso93406d82005-02-02 14:40:33 +00001276 if (realpeer->status == Established
1277 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1278 {
1279 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1280 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1281 }
1282 else if (ret == 0 && realpeer->status != Active
1283 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001284 && realpeer->status != OpenConfirm
1285 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001286 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001287 /* XXX: This is an awful problem..
1288 *
1289 * According to the RFC we should just let this connection (of the
1290 * accepted 'peer') continue on to Established if the other
1291 * connection (the 'realpeer' one) is in state Connect, and deal
1292 * with the more larval FSM as/when it gets far enough to receive
1293 * an Open. We don't do that though, we instead close the (more
1294 * developed) accepted connection.
1295 *
1296 * This means there's a race, which if hit, can loop:
1297 *
1298 * FSM for A FSM for B
1299 * realpeer accept-peer realpeer accept-peer
1300 *
1301 * Connect Connect
1302 * Active
1303 * OpenSent OpenSent
1304 * <arrive here,
1305 * Notify, delete>
1306 * Idle Active
1307 * OpenSent OpenSent
1308 * <arrive here,
1309 * Notify, delete>
1310 * Idle
1311 * <wait> <wait>
1312 * Connect Connect
1313 *
1314 *
1315 * If both sides are Quagga, they're almost certain to wait for
1316 * the same amount of time of course (which doesn't preclude other
1317 * implementations also waiting for same time). The race is
1318 * exacerbated by high-latency (in bgpd and/or the network).
1319 *
1320 * The reason we do this is because our FSM is tied to our peer
1321 * structure, which carries our configuration information, etc.
1322 * I.e. we can't let the accepted-peer FSM continue on as it is,
1323 * cause it's not associated with any actual peer configuration -
1324 * it's just a dummy.
1325 *
1326 * It's possible we could hack-fix this by just bgp_stop'ing the
1327 * realpeer and continueing on with the 'transfer FSM' below.
1328 * Ideally, we need to seperate FSMs from struct peer.
1329 *
1330 * Setting one side to passive avoids the race, as a workaround.
1331 */
pauleb821182004-05-01 08:44:08 +00001332 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001333 zlog_debug ("%s peer status is %s close connection",
1334 realpeer->host, LOOKUP (bgp_status_msg,
1335 realpeer->status));
1336 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1337 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1338
pauleb821182004-05-01 08:44:08 +00001339 return -1;
1340 }
1341
1342 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001343 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1344 peer->host,
1345 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001346
1347 bgp_stop (realpeer);
1348
1349 /* Transfer file descriptor. */
1350 realpeer->fd = peer->fd;
1351 peer->fd = -1;
1352
1353 /* Transfer input buffer. */
1354 stream_free (realpeer->ibuf);
1355 realpeer->ibuf = peer->ibuf;
1356 realpeer->packet_size = peer->packet_size;
1357 peer->ibuf = NULL;
1358
1359 /* Transfer status. */
1360 realpeer->status = peer->status;
1361 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001362
pauleb821182004-05-01 08:44:08 +00001363 /* peer pointer change. Open packet send to neighbor. */
1364 peer = realpeer;
1365 bgp_open_send (peer);
1366 if (peer->fd < 0)
1367 {
1368 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1369 peer->fd);
1370 return -1;
1371 }
1372 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1373 }
1374
paul718e3742002-12-13 20:15:29 +00001375 /* remote router-id check. */
1376 if (remote_id.s_addr == 0
1377 || ntohl (remote_id.s_addr) >= 0xe0000000
1378 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1379 {
1380 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001381 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001382 peer->host, inet_ntoa (remote_id));
1383 bgp_notify_send_with_data (peer,
1384 BGP_NOTIFY_OPEN_ERR,
1385 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1386 notify_data_remote_id, 4);
1387 return -1;
1388 }
1389
1390 /* Set remote router-id */
1391 peer->remote_id = remote_id;
1392
1393 /* Peer BGP version check. */
1394 if (version != BGP_VERSION_4)
1395 {
paul5228ad22004-06-04 17:58:18 +00001396 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001397 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001398 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001399 peer->host, version, BGP_VERSION_4);
1400 bgp_notify_send_with_data (peer,
1401 BGP_NOTIFY_OPEN_ERR,
1402 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001403 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001404 return -1;
1405 }
1406
1407 /* Check neighbor as number. */
1408 if (remote_as != peer->as)
1409 {
1410 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001411 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001412 peer->host, remote_as, peer->as);
1413 bgp_notify_send_with_data (peer,
1414 BGP_NOTIFY_OPEN_ERR,
1415 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1416 notify_data_remote_as, 2);
1417 return -1;
1418 }
1419
1420 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1421 calculate the value of the Hold Timer by using the smaller of its
1422 configured Hold Time and the Hold Time received in the OPEN message.
1423 The Hold Time MUST be either zero or at least three seconds. An
1424 implementation may reject connections on the basis of the Hold Time. */
1425
1426 if (holdtime < 3 && holdtime != 0)
1427 {
1428 bgp_notify_send (peer,
1429 BGP_NOTIFY_OPEN_ERR,
1430 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1431 return -1;
1432 }
1433
1434 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1435 would be one third of the Hold Time interval. KEEPALIVE messages
1436 MUST NOT be sent more frequently than one per second. An
1437 implementation MAY adjust the rate at which it sends KEEPALIVE
1438 messages as a function of the Hold Time interval. */
1439
1440 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1441 send_holdtime = peer->holdtime;
1442 else
1443 send_holdtime = peer->bgp->default_holdtime;
1444
1445 if (holdtime < send_holdtime)
1446 peer->v_holdtime = holdtime;
1447 else
1448 peer->v_holdtime = send_holdtime;
1449
1450 peer->v_keepalive = peer->v_holdtime / 3;
1451
1452 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001453 if (optlen != 0)
1454 {
1455 ret = bgp_open_option_parse (peer, optlen, &capability);
1456 if (ret < 0)
1457 return ret;
paul718e3742002-12-13 20:15:29 +00001458 }
1459 else
1460 {
1461 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001462 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001463 peer->host);
1464 }
1465
1466 /* Override capability. */
1467 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1468 {
1469 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1470 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1471 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1472 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1473 }
1474
1475 /* Get sockname. */
1476 bgp_getsockname (peer);
1477
1478 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1479
1480 peer->packet_size = 0;
1481 if (peer->ibuf)
1482 stream_reset (peer->ibuf);
1483
1484 return 0;
1485}
1486
1487/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001488static int
paul718e3742002-12-13 20:15:29 +00001489bgp_update_receive (struct peer *peer, bgp_size_t size)
1490{
1491 int ret;
1492 u_char *end;
1493 struct stream *s;
1494 struct attr attr;
1495 bgp_size_t attribute_len;
1496 bgp_size_t update_len;
1497 bgp_size_t withdraw_len;
1498 struct bgp_nlri update;
1499 struct bgp_nlri withdraw;
1500 struct bgp_nlri mp_update;
1501 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001502 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001503
1504 /* Status must be Established. */
1505 if (peer->status != Established)
1506 {
1507 zlog_err ("%s [FSM] Update packet received under status %s",
1508 peer->host, LOOKUP (bgp_status_msg, peer->status));
1509 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1510 return -1;
1511 }
1512
1513 /* Set initial values. */
1514 memset (&attr, 0, sizeof (struct attr));
1515 memset (&update, 0, sizeof (struct bgp_nlri));
1516 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1517 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1518 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1519
1520 s = peer->ibuf;
1521 end = stream_pnt (s) + size;
1522
1523 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1524 Length is too large (i.e., if Unfeasible Routes Length + Total
1525 Attribute Length + 23 exceeds the message Length), then the Error
1526 Subcode is set to Malformed Attribute List. */
1527 if (stream_pnt (s) + 2 > end)
1528 {
1529 zlog_err ("%s [Error] Update packet error"
1530 " (packet length is short for unfeasible length)",
1531 peer->host);
1532 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1533 BGP_NOTIFY_UPDATE_MAL_ATTR);
1534 return -1;
1535 }
1536
1537 /* Unfeasible Route Length. */
1538 withdraw_len = stream_getw (s);
1539
1540 /* Unfeasible Route Length check. */
1541 if (stream_pnt (s) + withdraw_len > end)
1542 {
1543 zlog_err ("%s [Error] Update packet error"
1544 " (packet unfeasible length overflow %d)",
1545 peer->host, withdraw_len);
1546 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1547 BGP_NOTIFY_UPDATE_MAL_ATTR);
1548 return -1;
1549 }
1550
1551 /* Unfeasible Route packet format check. */
1552 if (withdraw_len > 0)
1553 {
1554 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1555 if (ret < 0)
1556 return -1;
1557
1558 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001559 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001560
1561 withdraw.afi = AFI_IP;
1562 withdraw.safi = SAFI_UNICAST;
1563 withdraw.nlri = stream_pnt (s);
1564 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001565 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001566 }
1567
1568 /* Attribute total length check. */
1569 if (stream_pnt (s) + 2 > end)
1570 {
1571 zlog_warn ("%s [Error] Packet Error"
1572 " (update packet is short for attribute length)",
1573 peer->host);
1574 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1575 BGP_NOTIFY_UPDATE_MAL_ATTR);
1576 return -1;
1577 }
1578
1579 /* Fetch attribute total length. */
1580 attribute_len = stream_getw (s);
1581
1582 /* Attribute length check. */
1583 if (stream_pnt (s) + attribute_len > end)
1584 {
1585 zlog_warn ("%s [Error] Packet Error"
1586 " (update packet attribute length overflow %d)",
1587 peer->host, attribute_len);
1588 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1589 BGP_NOTIFY_UPDATE_MAL_ATTR);
1590 return -1;
1591 }
Paul Jakmab881c702010-11-23 16:35:42 +00001592
1593 /* Certain attribute parsing errors should not be considered bad enough
1594 * to reset the session for, most particularly any partial/optional
1595 * attributes that have 'tunneled' over speakers that don't understand
1596 * them. Instead we withdraw only the prefix concerned.
1597 *
1598 * Complicates the flow a little though..
1599 */
1600 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1601 /* This define morphs the update case into a withdraw when lower levels
1602 * have signalled an error condition where this is best.
1603 */
1604#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001605
1606 /* Parse attribute when it exists. */
1607 if (attribute_len)
1608 {
Paul Jakmab881c702010-11-23 16:35:42 +00001609 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
paul718e3742002-12-13 20:15:29 +00001610 &mp_update, &mp_withdraw);
Paul Jakmab881c702010-11-23 16:35:42 +00001611 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
paul718e3742002-12-13 20:15:29 +00001612 return -1;
1613 }
Paul Jakmab881c702010-11-23 16:35:42 +00001614
paul718e3742002-12-13 20:15:29 +00001615 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001616 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1617 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001618 {
paule01f9cb2004-07-09 17:48:53 +00001619 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001620 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1621 ? LOG_ERR : LOG_DEBUG;
1622
1623 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1624 zlog (peer->log, LOG_ERR,
1625 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1626 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001627
1628 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001629 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001630 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001631 }
Paul Jakmab881c702010-11-23 16:35:42 +00001632
paul718e3742002-12-13 20:15:29 +00001633 /* Network Layer Reachability Information. */
1634 update_len = end - stream_pnt (s);
1635
1636 if (update_len)
1637 {
1638 /* Check NLRI packet format and prefix length. */
1639 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1640 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001641 {
1642 bgp_attr_unintern_sub (&attr);
1643 if (attr.extra)
1644 bgp_attr_extra_free (&attr);
1645 return -1;
1646 }
paul718e3742002-12-13 20:15:29 +00001647
1648 /* Set NLRI portion to structure. */
1649 update.afi = AFI_IP;
1650 update.safi = SAFI_UNICAST;
1651 update.nlri = stream_pnt (s);
1652 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001653 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001654 }
1655
1656 /* NLRI is processed only when the peer is configured specific
1657 Address Family and Subsequent Address Family. */
1658 if (peer->afc[AFI_IP][SAFI_UNICAST])
1659 {
1660 if (withdraw.length)
1661 bgp_nlri_parse (peer, NULL, &withdraw);
1662
1663 if (update.length)
1664 {
1665 /* We check well-known attribute only for IPv4 unicast
1666 update. */
1667 ret = bgp_attr_check (peer, &attr);
1668 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001669 {
1670 bgp_attr_unintern_sub (&attr);
1671 if (attr.extra)
1672 bgp_attr_extra_free (&attr);
1673 return -1;
1674 }
paul718e3742002-12-13 20:15:29 +00001675
Paul Jakmab881c702010-11-23 16:35:42 +00001676 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
paul718e3742002-12-13 20:15:29 +00001677 }
paule01f9cb2004-07-09 17:48:53 +00001678
hassof4184462005-02-01 20:13:16 +00001679 if (mp_update.length
1680 && mp_update.afi == AFI_IP
1681 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001682 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
hassof4184462005-02-01 20:13:16 +00001683
1684 if (mp_withdraw.length
1685 && mp_withdraw.afi == AFI_IP
1686 && mp_withdraw.safi == SAFI_UNICAST)
1687 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1688
paule01f9cb2004-07-09 17:48:53 +00001689 if (! attribute_len && ! withdraw_len)
1690 {
1691 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001692 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1693 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001694
hasso93406d82005-02-02 14:40:33 +00001695 /* NSF delete stale route */
1696 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1697 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1698
1699 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001700 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001701 peer->host);
1702 }
paul718e3742002-12-13 20:15:29 +00001703 }
1704 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1705 {
1706 if (mp_update.length
1707 && mp_update.afi == AFI_IP
1708 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001709 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001710
1711 if (mp_withdraw.length
1712 && mp_withdraw.afi == AFI_IP
1713 && mp_withdraw.safi == SAFI_MULTICAST)
1714 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001715
hasso93406d82005-02-02 14:40:33 +00001716 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001717 && mp_withdraw.afi == AFI_IP
1718 && mp_withdraw.safi == SAFI_MULTICAST
1719 && mp_withdraw.length == 0)
1720 {
1721 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001722 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1723 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001724
hasso93406d82005-02-02 14:40:33 +00001725 /* NSF delete stale route */
1726 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1727 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1728
1729 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001730 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001731 peer->host);
1732 }
paul718e3742002-12-13 20:15:29 +00001733 }
1734 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1735 {
1736 if (mp_update.length
1737 && mp_update.afi == AFI_IP6
1738 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001739 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001740
1741 if (mp_withdraw.length
1742 && mp_withdraw.afi == AFI_IP6
1743 && mp_withdraw.safi == SAFI_UNICAST)
1744 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001745
hasso93406d82005-02-02 14:40:33 +00001746 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001747 && mp_withdraw.afi == AFI_IP6
1748 && mp_withdraw.safi == SAFI_UNICAST
1749 && mp_withdraw.length == 0)
1750 {
1751 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001752 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001753
hasso93406d82005-02-02 14:40:33 +00001754 /* NSF delete stale route */
1755 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1756 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1757
1758 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001759 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001760 peer->host);
1761 }
paul718e3742002-12-13 20:15:29 +00001762 }
1763 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1764 {
1765 if (mp_update.length
1766 && mp_update.afi == AFI_IP6
1767 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001768 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001769
1770 if (mp_withdraw.length
1771 && mp_withdraw.afi == AFI_IP6
1772 && mp_withdraw.safi == SAFI_MULTICAST)
1773 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001774
hasso93406d82005-02-02 14:40:33 +00001775 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001776 && mp_withdraw.afi == AFI_IP6
1777 && mp_withdraw.safi == SAFI_MULTICAST
1778 && mp_withdraw.length == 0)
1779 {
1780 /* End-of-RIB received */
1781
hasso93406d82005-02-02 14:40:33 +00001782 /* NSF delete stale route */
1783 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1784 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1785
paule01f9cb2004-07-09 17:48:53 +00001786 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001787 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001788 peer->host);
1789 }
paul718e3742002-12-13 20:15:29 +00001790 }
1791 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1792 {
1793 if (mp_update.length
1794 && mp_update.afi == AFI_IP
1795 && mp_update.safi == BGP_SAFI_VPNV4)
Paul Jakmab881c702010-11-23 16:35:42 +00001796 bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001797
1798 if (mp_withdraw.length
1799 && mp_withdraw.afi == AFI_IP
1800 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1801 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001802
hasso93406d82005-02-02 14:40:33 +00001803 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001804 && mp_withdraw.afi == AFI_IP
1805 && mp_withdraw.safi == BGP_SAFI_VPNV4
1806 && mp_withdraw.length == 0)
1807 {
1808 /* End-of-RIB received */
1809
1810 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001811 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001812 peer->host);
1813 }
paul718e3742002-12-13 20:15:29 +00001814 }
1815
1816 /* Everything is done. We unintern temporary structures which
1817 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001818 bgp_attr_unintern_sub (&attr);
Paul Jakmafb982c22007-05-04 20:15:47 +00001819 if (attr.extra)
Paul Jakmab881c702010-11-23 16:35:42 +00001820 bgp_attr_extra_free (&attr);
1821
paul718e3742002-12-13 20:15:29 +00001822 /* If peering is stopped due to some reason, do not generate BGP
1823 event. */
1824 if (peer->status != Established)
1825 return 0;
1826
1827 /* Increment packet counter. */
1828 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001829 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001830
1831 /* Generate BGP event. */
1832 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1833
1834 return 0;
1835}
1836
1837/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001838static void
paul718e3742002-12-13 20:15:29 +00001839bgp_notify_receive (struct peer *peer, bgp_size_t size)
1840{
1841 struct bgp_notify bgp_notify;
1842
1843 if (peer->notify.data)
1844 {
1845 XFREE (MTYPE_TMP, peer->notify.data);
1846 peer->notify.data = NULL;
1847 peer->notify.length = 0;
1848 }
1849
1850 bgp_notify.code = stream_getc (peer->ibuf);
1851 bgp_notify.subcode = stream_getc (peer->ibuf);
1852 bgp_notify.length = size - 2;
1853 bgp_notify.data = NULL;
1854
1855 /* Preserv notify code and sub code. */
1856 peer->notify.code = bgp_notify.code;
1857 peer->notify.subcode = bgp_notify.subcode;
1858 /* For further diagnostic record returned Data. */
1859 if (bgp_notify.length)
1860 {
1861 peer->notify.length = size - 2;
1862 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1863 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1864 }
1865
1866 /* For debug */
1867 {
1868 int i;
1869 int first = 0;
1870 char c[4];
1871
1872 if (bgp_notify.length)
1873 {
1874 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1875 for (i = 0; i < bgp_notify.length; i++)
1876 if (first)
1877 {
1878 sprintf (c, " %02x", stream_getc (peer->ibuf));
1879 strcat (bgp_notify.data, c);
1880 }
1881 else
1882 {
1883 first = 1;
1884 sprintf (c, "%02x", stream_getc (peer->ibuf));
1885 strcpy (bgp_notify.data, c);
1886 }
1887 }
1888
1889 bgp_notify_print(peer, &bgp_notify, "received");
1890 if (bgp_notify.data)
1891 XFREE (MTYPE_TMP, bgp_notify.data);
1892 }
1893
1894 /* peer count update */
1895 peer->notify_in++;
1896
hassoe0701b72004-05-20 09:19:34 +00001897 if (peer->status == Established)
1898 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1899
paul718e3742002-12-13 20:15:29 +00001900 /* We have to check for Notify with Unsupported Optional Parameter.
1901 in that case we fallback to open without the capability option.
1902 But this done in bgp_stop. We just mark it here to avoid changing
1903 the fsm tables. */
1904 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1905 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1906 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1907
paul718e3742002-12-13 20:15:29 +00001908 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1909}
1910
1911/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001912static void
paul718e3742002-12-13 20:15:29 +00001913bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1914{
1915 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001916 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001917
1918 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1919}
1920
1921/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001922static void
paul718e3742002-12-13 20:15:29 +00001923bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1924{
1925 afi_t afi;
1926 safi_t safi;
1927 u_char reserved;
1928 struct stream *s;
1929
1930 /* If peer does not have the capability, send notification. */
1931 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1932 {
1933 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1934 peer->host);
1935 bgp_notify_send (peer,
1936 BGP_NOTIFY_HEADER_ERR,
1937 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1938 return;
1939 }
1940
1941 /* Status must be Established. */
1942 if (peer->status != Established)
1943 {
1944 plog_err (peer->log,
1945 "%s [Error] Route refresh packet received under status %s",
1946 peer->host, LOOKUP (bgp_status_msg, peer->status));
1947 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1948 return;
1949 }
1950
1951 s = peer->ibuf;
1952
1953 /* Parse packet. */
1954 afi = stream_getw (s);
1955 reserved = stream_getc (s);
1956 safi = stream_getc (s);
1957
1958 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001959 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001960 peer->host, afi, safi);
1961
1962 /* Check AFI and SAFI. */
1963 if ((afi != AFI_IP && afi != AFI_IP6)
1964 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1965 && safi != BGP_SAFI_VPNV4))
1966 {
1967 if (BGP_DEBUG (normal, NORMAL))
1968 {
ajs6b514742004-12-08 21:03:23 +00001969 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001970 peer->host, afi, safi);
1971 }
1972 return;
1973 }
1974
1975 /* Adjust safi code. */
1976 if (safi == BGP_SAFI_VPNV4)
1977 safi = SAFI_MPLS_VPN;
1978
1979 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1980 {
1981 u_char *end;
1982 u_char when_to_refresh;
1983 u_char orf_type;
1984 u_int16_t orf_len;
1985
1986 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1987 {
1988 zlog_info ("%s ORF route refresh length error", peer->host);
1989 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1990 return;
1991 }
1992
1993 when_to_refresh = stream_getc (s);
1994 end = stream_pnt (s) + (size - 5);
1995
Paul Jakma370b64a2007-12-22 16:49:52 +00001996 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00001997 {
1998 orf_type = stream_getc (s);
1999 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002000
2001 /* orf_len in bounds? */
2002 if ((stream_pnt (s) + orf_len) > end)
2003 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002004 if (orf_type == ORF_TYPE_PREFIX
2005 || orf_type == ORF_TYPE_PREFIX_OLD)
2006 {
2007 u_char *p_pnt = stream_pnt (s);
2008 u_char *p_end = stream_pnt (s) + orf_len;
2009 struct orf_prefix orfp;
2010 u_char common = 0;
2011 u_int32_t seq;
2012 int psize;
2013 char name[BUFSIZ];
2014 char buf[BUFSIZ];
2015 int ret;
2016
2017 if (BGP_DEBUG (normal, NORMAL))
2018 {
ajs6b514742004-12-08 21:03:23 +00002019 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002020 peer->host, orf_type, orf_len);
2021 }
2022
Paul Jakma370b64a2007-12-22 16:49:52 +00002023 /* we're going to read at least 1 byte of common ORF header,
2024 * and 7 bytes of ORF Address-filter entry from the stream
2025 */
2026 if (orf_len < 7)
2027 break;
2028
paul718e3742002-12-13 20:15:29 +00002029 /* ORF prefix-list name */
2030 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2031
2032 while (p_pnt < p_end)
2033 {
Chris Halld64379e2010-05-14 16:38:39 +04002034 /* If the ORF entry is malformed, want to read as much of it
2035 * as possible without going beyond the bounds of the entry,
2036 * to maximise debug information.
2037 */
2038 int ok ;
paul718e3742002-12-13 20:15:29 +00002039 memset (&orfp, 0, sizeof (struct orf_prefix));
2040 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002041 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002042 if (common & ORF_COMMON_PART_REMOVE_ALL)
2043 {
2044 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002045 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00002046 prefix_bgp_orf_remove_all (name);
2047 break;
2048 }
Chris Halld64379e2010-05-14 16:38:39 +04002049 ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
2050 if (ok)
2051 {
paul718e3742002-12-13 20:15:29 +00002052 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2053 p_pnt += sizeof (u_int32_t);
2054 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002055 }
2056 else
2057 p_pnt = p_end ;
2058
2059 if ((ok = (p_pnt < p_end)))
2060 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2061 if ((ok = (p_pnt < p_end)))
2062 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2063 if ((ok = (p_pnt < p_end)))
2064 orfp.p.prefixlen = *p_pnt++ ;
2065 orfp.p.family = afi2family (afi); /* afi checked already */
2066
2067 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2068 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2069 {
2070 ok = 0 ;
2071 psize = prefix_blen(&orfp.p) ;
2072 }
2073 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2074 {
2075 ok = 0 ;
2076 psize = p_end - p_pnt ;
2077 }
2078
2079 if (psize > 0)
2080 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002081 p_pnt += psize;
2082
2083 if (BGP_DEBUG (normal, NORMAL))
Chris Halld64379e2010-05-14 16:38:39 +04002084 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
paul718e3742002-12-13 20:15:29 +00002085 peer->host,
2086 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2087 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2088 orfp.seq,
2089 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
Chris Halld64379e2010-05-14 16:38:39 +04002090 orfp.p.prefixlen, orfp.ge, orfp.le,
2091 ok ? "" : " MALFORMED");
paul718e3742002-12-13 20:15:29 +00002092
Chris Halld64379e2010-05-14 16:38:39 +04002093 if (ok)
paul718e3742002-12-13 20:15:29 +00002094 ret = prefix_bgp_orf_set (name, afi, &orfp,
2095 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2096 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
2097
Chris Halld64379e2010-05-14 16:38:39 +04002098 if (!ok || (ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002099 {
2100 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002101 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00002102 prefix_bgp_orf_remove_all (name);
2103 break;
2104 }
2105 }
2106 peer->orf_plist[afi][safi] =
2107 prefix_list_lookup (AFI_ORF_PREFIX, name);
2108 }
paul9985f832005-02-09 15:51:56 +00002109 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002110 }
2111 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002112 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002113 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2114 if (when_to_refresh == REFRESH_DEFER)
2115 return;
2116 }
2117
2118 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2119 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2120 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2121
2122 /* Perform route refreshment to the peer */
2123 bgp_announce_route (peer, afi, safi);
2124}
2125
paul94f2b392005-06-28 12:44:16 +00002126static int
paul718e3742002-12-13 20:15:29 +00002127bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2128{
2129 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002130 struct capability_mp_data mpc;
2131 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002132 u_char action;
2133 struct bgp *bgp;
2134 afi_t afi;
2135 safi_t safi;
2136
2137 bgp = peer->bgp;
2138 end = pnt + length;
2139
2140 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002141 {
paul718e3742002-12-13 20:15:29 +00002142 /* We need at least action, capability code and capability length. */
2143 if (pnt + 3 > end)
2144 {
2145 zlog_info ("%s Capability length error", peer->host);
2146 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2147 return -1;
2148 }
paul718e3742002-12-13 20:15:29 +00002149 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002150 hdr = (struct capability_header *)(pnt + 1);
2151
paul718e3742002-12-13 20:15:29 +00002152 /* Action value check. */
2153 if (action != CAPABILITY_ACTION_SET
2154 && action != CAPABILITY_ACTION_UNSET)
2155 {
2156 zlog_info ("%s Capability Action Value error %d",
2157 peer->host, action);
2158 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2159 return -1;
2160 }
2161
2162 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002163 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002164 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002165
2166 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002167 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002168 {
2169 zlog_info ("%s Capability length error", peer->host);
2170 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2171 return -1;
2172 }
2173
Paul Jakma6d582722007-08-06 15:21:45 +00002174 /* Fetch structure to the byte stream. */
2175 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2176
paul718e3742002-12-13 20:15:29 +00002177 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002178 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002179 {
Paul Jakma6d582722007-08-06 15:21:45 +00002180 afi = ntohs (mpc.afi);
2181 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002182
2183 /* Ignore capability when override-capability is set. */
2184 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2185 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002186
2187 if (!bgp_afi_safi_valid_indices (afi, &safi))
2188 {
2189 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002190 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2191 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002192 continue;
2193 }
2194
paul718e3742002-12-13 20:15:29 +00002195 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002196 if (BGP_DEBUG (normal, NORMAL))
2197 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2198 peer->host,
2199 action == CAPABILITY_ACTION_SET
2200 ? "Advertising" : "Removing",
2201 ntohs(mpc.afi) , mpc.safi);
2202
2203 if (action == CAPABILITY_ACTION_SET)
2204 {
2205 peer->afc_recv[afi][safi] = 1;
2206 if (peer->afc[afi][safi])
2207 {
2208 peer->afc_nego[afi][safi] = 1;
2209 bgp_announce_route (peer, afi, safi);
2210 }
2211 }
2212 else
2213 {
2214 peer->afc_recv[afi][safi] = 0;
2215 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002216
Paul Jakma6d582722007-08-06 15:21:45 +00002217 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002218 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002219 else
2220 BGP_EVENT_ADD (peer, BGP_Stop);
2221 }
paul718e3742002-12-13 20:15:29 +00002222 }
paul718e3742002-12-13 20:15:29 +00002223 else
2224 {
2225 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002226 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002227 }
Paul Jakma6d582722007-08-06 15:21:45 +00002228 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002229 }
2230 return 0;
2231}
2232
Paul Jakma01b7ce22009-06-18 12:34:43 +01002233/* Dynamic Capability is received.
2234 *
2235 * This is exported for unit-test purposes
2236 */
Paul Jakma6d582722007-08-06 15:21:45 +00002237int
paul718e3742002-12-13 20:15:29 +00002238bgp_capability_receive (struct peer *peer, bgp_size_t size)
2239{
2240 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002241
2242 /* Fetch pointer. */
2243 pnt = stream_pnt (peer->ibuf);
2244
2245 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002246 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002247
2248 /* If peer does not have the capability, send notification. */
2249 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2250 {
2251 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2252 peer->host);
2253 bgp_notify_send (peer,
2254 BGP_NOTIFY_HEADER_ERR,
2255 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002256 return -1;
paul718e3742002-12-13 20:15:29 +00002257 }
2258
2259 /* Status must be Established. */
2260 if (peer->status != Established)
2261 {
2262 plog_err (peer->log,
2263 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2264 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002265 return -1;
paul718e3742002-12-13 20:15:29 +00002266 }
2267
2268 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002269 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002270}
2271
2272/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002273static int
paul718e3742002-12-13 20:15:29 +00002274bgp_read_packet (struct peer *peer)
2275{
2276 int nbytes;
2277 int readsize;
2278
paul9985f832005-02-09 15:51:56 +00002279 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002280
2281 /* If size is zero then return. */
2282 if (! readsize)
2283 return 0;
2284
2285 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002286 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002287
2288 /* If read byte is smaller than zero then error occured. */
2289 if (nbytes < 0)
2290 {
2291 if (errno == EAGAIN)
2292 return -1;
2293
2294 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002295 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002296
2297 if (peer->status == Established)
2298 {
2299 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2300 {
2301 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2302 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2303 }
2304 else
2305 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2306 }
2307
paul718e3742002-12-13 20:15:29 +00002308 BGP_EVENT_ADD (peer, TCP_fatal_error);
2309 return -1;
2310 }
2311
2312 /* When read byte is zero : clear bgp peer and return */
2313 if (nbytes == 0)
2314 {
2315 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002316 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002317 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002318
2319 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002320 {
2321 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2322 {
2323 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2324 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2325 }
2326 else
2327 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2328 }
hassoe0701b72004-05-20 09:19:34 +00002329
paul718e3742002-12-13 20:15:29 +00002330 BGP_EVENT_ADD (peer, TCP_connection_closed);
2331 return -1;
2332 }
2333
2334 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002335 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002336 return -1;
2337
2338 return 0;
2339}
2340
2341/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002342static int
paul718e3742002-12-13 20:15:29 +00002343bgp_marker_all_one (struct stream *s, int length)
2344{
2345 int i;
2346
2347 for (i = 0; i < length; i++)
2348 if (s->data[i] != 0xff)
2349 return 0;
2350
2351 return 1;
2352}
2353
2354/* Starting point of packet process function. */
2355int
2356bgp_read (struct thread *thread)
2357{
2358 int ret;
2359 u_char type = 0;
2360 struct peer *peer;
2361 bgp_size_t size;
2362 char notify_data_length[2];
2363
2364 /* Yes first of all get peer pointer. */
2365 peer = THREAD_ARG (thread);
2366 peer->t_read = NULL;
2367
2368 /* For non-blocking IO check. */
2369 if (peer->status == Connect)
2370 {
2371 bgp_connect_check (peer);
2372 goto done;
2373 }
2374 else
2375 {
pauleb821182004-05-01 08:44:08 +00002376 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002377 {
pauleb821182004-05-01 08:44:08 +00002378 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002379 return -1;
2380 }
pauleb821182004-05-01 08:44:08 +00002381 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002382 }
2383
2384 /* Read packet header to determine type of the packet */
2385 if (peer->packet_size == 0)
2386 peer->packet_size = BGP_HEADER_SIZE;
2387
paul9985f832005-02-09 15:51:56 +00002388 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002389 {
2390 ret = bgp_read_packet (peer);
2391
2392 /* Header read error or partial read packet. */
2393 if (ret < 0)
2394 goto done;
2395
2396 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002397 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002398 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2399 size = stream_getw (peer->ibuf);
2400 type = stream_getc (peer->ibuf);
2401
2402 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002403 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002404 peer->host, type, size - BGP_HEADER_SIZE);
2405
2406 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002407 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002408 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2409 {
2410 bgp_notify_send (peer,
2411 BGP_NOTIFY_HEADER_ERR,
2412 BGP_NOTIFY_HEADER_NOT_SYNC);
2413 goto done;
2414 }
2415
2416 /* BGP type check. */
2417 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2418 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2419 && type != BGP_MSG_ROUTE_REFRESH_NEW
2420 && type != BGP_MSG_ROUTE_REFRESH_OLD
2421 && type != BGP_MSG_CAPABILITY)
2422 {
2423 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002424 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002425 "%s unknown message type 0x%02x",
2426 peer->host, type);
2427 bgp_notify_send_with_data (peer,
2428 BGP_NOTIFY_HEADER_ERR,
2429 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2430 &type, 1);
2431 goto done;
2432 }
2433 /* Mimimum packet length check. */
2434 if ((size < BGP_HEADER_SIZE)
2435 || (size > BGP_MAX_PACKET_SIZE)
2436 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2437 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2438 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2439 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2440 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2441 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2442 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2443 {
2444 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002445 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002446 "%s bad message length - %d for %s",
2447 peer->host, size,
2448 type == 128 ? "ROUTE-REFRESH" :
2449 bgp_type_str[(int) type]);
2450 bgp_notify_send_with_data (peer,
2451 BGP_NOTIFY_HEADER_ERR,
2452 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002453 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002454 goto done;
2455 }
2456
2457 /* Adjust size to message length. */
2458 peer->packet_size = size;
2459 }
2460
2461 ret = bgp_read_packet (peer);
2462 if (ret < 0)
2463 goto done;
2464
2465 /* Get size and type again. */
2466 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2467 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2468
2469 /* BGP packet dump function. */
2470 bgp_dump_packet (peer, type, peer->ibuf);
2471
2472 size = (peer->packet_size - BGP_HEADER_SIZE);
2473
2474 /* Read rest of the packet and call each sort of packet routine */
2475 switch (type)
2476 {
2477 case BGP_MSG_OPEN:
2478 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002479 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002480 break;
2481 case BGP_MSG_UPDATE:
2482 peer->readtime = time(NULL); /* Last read timer reset */
2483 bgp_update_receive (peer, size);
2484 break;
2485 case BGP_MSG_NOTIFY:
2486 bgp_notify_receive (peer, size);
2487 break;
2488 case BGP_MSG_KEEPALIVE:
2489 peer->readtime = time(NULL); /* Last read timer reset */
2490 bgp_keepalive_receive (peer, size);
2491 break;
2492 case BGP_MSG_ROUTE_REFRESH_NEW:
2493 case BGP_MSG_ROUTE_REFRESH_OLD:
2494 peer->refresh_in++;
2495 bgp_route_refresh_receive (peer, size);
2496 break;
2497 case BGP_MSG_CAPABILITY:
2498 peer->dynamic_cap_in++;
2499 bgp_capability_receive (peer, size);
2500 break;
2501 }
2502
2503 /* Clear input buffer. */
2504 peer->packet_size = 0;
2505 if (peer->ibuf)
2506 stream_reset (peer->ibuf);
2507
2508 done:
2509 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2510 {
2511 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002512 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002513 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002514 }
2515 return 0;
2516}