blob: 8b024a1c0fd14c1350457cce07c6d18cc0cacacd [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 {
161 if (adv->rn)
162 rn = adv->rn;
163 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. */
168 if (rn && STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
169 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;
176
177 if (rn->prn)
178 prd = (struct prefix_rd *) &rn->prn->p;
179 if (binfo)
180 tag = binfo->tag;
181
paul718e3742002-12-13 20:15:29 +0000182 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
183 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000184 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000185 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000186 total_attr_len = bgp_packet_attribute (NULL, peer, s,
187 adv->baa->attr,
188 &rn->p, afi, safi,
189 binfo->peer, prd, tag);
paul718e3742002-12-13 20:15:29 +0000190 stream_putw_at (s, pos, total_attr_len);
191 }
192
193 if (afi == AFI_IP && safi == SAFI_UNICAST)
194 stream_put_prefix (s, &rn->p);
195
196 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000197 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000198 peer->host,
199 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
200 rn->p.prefixlen);
201
202 /* Synchnorize attribute. */
203 if (adj->attr)
204 bgp_attr_unintern (adj->attr);
205 else
206 peer->scount[afi][safi]++;
207
208 adj->attr = bgp_attr_intern (adv->baa->attr);
209
210 adv = bgp_advertise_clean (peer, adj, afi, safi);
211
212 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
213 break;
214 }
215
216 if (! stream_empty (s))
217 {
218 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000219 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000220 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000221 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000222 stream_reset (s);
223 return packet;
224 }
225 return NULL;
hasso93406d82005-02-02 14:40:33 +0000226}
paul718e3742002-12-13 20:15:29 +0000227
paul94f2b392005-06-28 12:44:16 +0000228static struct stream *
hasso93406d82005-02-02 14:40:33 +0000229bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
230{
231 struct stream *s;
232 struct stream *packet;
233
234#ifdef DISABLE_BGP_ANNOUNCE
235 return;
236#endif /* DISABLE_BGP_ANNOUNCE */
237
238 if (BGP_DEBUG (normal, NORMAL))
239 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
240
241 s = stream_new (BGP_MAX_PACKET_SIZE);
242
243 /* Make BGP update packet. */
244 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
245
246 /* Unfeasible Routes Length */
247 stream_putw (s, 0);
248
249 if (afi == AFI_IP && safi == SAFI_UNICAST)
250 {
251 /* Total Path Attribute Length */
252 stream_putw (s, 0);
253 }
254 else
255 {
256 /* Total Path Attribute Length */
257 stream_putw (s, 6);
258 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
259 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
260 stream_putc (s, 3);
261 stream_putw (s, afi);
262 stream_putc (s, safi);
263 }
264
265 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000266 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000267 bgp_packet_add (peer, packet);
268 stream_free (s);
269 return packet;
paul718e3742002-12-13 20:15:29 +0000270}
271
272/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000273static struct stream *
paul718e3742002-12-13 20:15:29 +0000274bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
275{
276 struct stream *s;
277 struct stream *packet;
278 struct bgp_adj_out *adj;
279 struct bgp_advertise *adv;
280 struct bgp_node *rn;
281 unsigned long pos;
282 bgp_size_t unfeasible_len;
283 bgp_size_t total_attr_len;
284 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000285
286 s = peer->work;
287 stream_reset (s);
288
289 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
290 {
291 adj = adv->adj;
292 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000293
294 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000295 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000296 break;
297
298 if (stream_empty (s))
299 {
300 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
301 stream_putw (s, 0);
302 }
303
304 if (afi == AFI_IP && safi == SAFI_UNICAST)
305 stream_put_prefix (s, &rn->p);
306 else
307 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000308 struct prefix_rd *prd = NULL;
309
310 if (rn->prn)
311 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000312 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000313 stream_putw (s, 0);
314 total_attr_len
315 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
316
317 /* Set total path attribute length. */
318 stream_putw_at (s, pos, total_attr_len);
319 }
320
321 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000322 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000323 peer->host,
324 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
325 rn->p.prefixlen);
326
327 peer->scount[afi][safi]--;
328
329 bgp_adj_out_remove (rn, adj, peer, afi, safi);
330 bgp_unlock_node (rn);
331
332 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
333 break;
334 }
335
336 if (! stream_empty (s))
337 {
338 if (afi == AFI_IP && safi == SAFI_UNICAST)
339 {
340 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000341 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000342 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
343 stream_putw (s, 0);
344 }
345 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000346 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000347 bgp_packet_add (peer, packet);
348 stream_reset (s);
349 return packet;
350 }
351
352 return NULL;
353}
354
355void
356bgp_default_update_send (struct peer *peer, struct attr *attr,
357 afi_t afi, safi_t safi, struct peer *from)
358{
359 struct stream *s;
360 struct stream *packet;
361 struct prefix p;
362 unsigned long pos;
363 bgp_size_t total_attr_len;
364 char attrstr[BUFSIZ];
365 char buf[BUFSIZ];
366
367#ifdef DISABLE_BGP_ANNOUNCE
368 return;
369#endif /* DISABLE_BGP_ANNOUNCE */
370
371 if (afi == AFI_IP)
372 str2prefix ("0.0.0.0/0", &p);
373#ifdef HAVE_IPV6
374 else
375 str2prefix ("::/0", &p);
376#endif /* HAVE_IPV6 */
377
378 /* Logging the attribute. */
379 if (BGP_DEBUG (update, UPDATE_OUT))
380 {
381 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000382 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000383 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
384 p.prefixlen, attrstr);
385 }
386
387 s = stream_new (BGP_MAX_PACKET_SIZE);
388
389 /* Make BGP update packet. */
390 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
391
392 /* Unfeasible Routes Length. */
393 stream_putw (s, 0);
394
395 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000396 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000397 stream_putw (s, 0);
398 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
399
400 /* Set Total Path Attribute Length. */
401 stream_putw_at (s, pos, total_attr_len);
402
403 /* NLRI set. */
404 if (p.family == AF_INET && safi == SAFI_UNICAST)
405 stream_put_prefix (s, &p);
406
407 /* Set size. */
408 bgp_packet_set_size (s);
409
paule83e2082005-05-19 02:12:25 +0000410 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000411 stream_free (s);
412
413 /* Dump packet if debug option is set. */
414#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000415 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000416#endif /* DEBUG */
417
418 /* Add packet to the peer. */
419 bgp_packet_add (peer, packet);
420
pauleb821182004-05-01 08:44:08 +0000421 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000422}
423
424void
425bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
426{
427 struct stream *s;
428 struct stream *packet;
429 struct prefix p;
430 unsigned long pos;
431 unsigned long cp;
432 bgp_size_t unfeasible_len;
433 bgp_size_t total_attr_len;
434 char buf[BUFSIZ];
435
436#ifdef DISABLE_BGP_ANNOUNCE
437 return;
438#endif /* DISABLE_BGP_ANNOUNCE */
439
440 if (afi == AFI_IP)
441 str2prefix ("0.0.0.0/0", &p);
442#ifdef HAVE_IPV6
443 else
444 str2prefix ("::/0", &p);
445#endif /* HAVE_IPV6 */
446
447 total_attr_len = 0;
448 pos = 0;
449
450 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000451 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000452 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
453 p.prefixlen);
454
455 s = stream_new (BGP_MAX_PACKET_SIZE);
456
457 /* Make BGP update packet. */
458 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
459
460 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000461 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000462 stream_putw (s, 0);
463
464 /* Withdrawn Routes. */
465 if (p.family == AF_INET && safi == SAFI_UNICAST)
466 {
467 stream_put_prefix (s, &p);
468
paul9985f832005-02-09 15:51:56 +0000469 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000470
471 /* Set unfeasible len. */
472 stream_putw_at (s, cp, unfeasible_len);
473
474 /* Set total path attribute length. */
475 stream_putw (s, 0);
476 }
477 else
478 {
paul9985f832005-02-09 15:51:56 +0000479 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000480 stream_putw (s, 0);
481 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
482
483 /* Set total path attribute length. */
484 stream_putw_at (s, pos, total_attr_len);
485 }
486
487 bgp_packet_set_size (s);
488
paule83e2082005-05-19 02:12:25 +0000489 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000490 stream_free (s);
491
492 /* Add packet to the peer. */
493 bgp_packet_add (peer, packet);
494
pauleb821182004-05-01 08:44:08 +0000495 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000496}
497
498/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000499static struct stream *
paul718e3742002-12-13 20:15:29 +0000500bgp_write_packet (struct peer *peer)
501{
502 afi_t afi;
503 safi_t safi;
504 struct stream *s = NULL;
505 struct bgp_advertise *adv;
506
507 s = stream_fifo_head (peer->obuf);
508 if (s)
509 return s;
510
511 for (afi = AFI_IP; afi < AFI_MAX; afi++)
512 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
513 {
514 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
515 if (adv)
516 {
517 s = bgp_withdraw_packet (peer, afi, safi);
518 if (s)
519 return s;
520 }
521 }
522
523 for (afi = AFI_IP; afi < AFI_MAX; afi++)
524 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
525 {
526 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
527 if (adv)
528 {
529 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000530 {
531 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
532 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
533 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
534 && safi != SAFI_MPLS_VPN)
535 {
536 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
537 PEER_STATUS_EOR_RECEIVED))
538 s = bgp_update_packet (peer, afi, safi);
539 }
540 else
541 s = bgp_update_packet (peer, afi, safi);
542 }
paul718e3742002-12-13 20:15:29 +0000543
544 if (s)
545 return s;
546 }
hasso93406d82005-02-02 14:40:33 +0000547
548 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
549 {
550 if (peer->afc_nego[afi][safi] && peer->synctime
551 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
552 && safi != SAFI_MPLS_VPN)
553 {
554 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
555 return bgp_update_packet_eor (peer, afi, safi);
556 }
557 }
paul718e3742002-12-13 20:15:29 +0000558 }
559
560 return NULL;
561}
562
563/* Is there partially written packet or updates we can send right
564 now. */
paul94f2b392005-06-28 12:44:16 +0000565static int
paul718e3742002-12-13 20:15:29 +0000566bgp_write_proceed (struct peer *peer)
567{
568 afi_t afi;
569 safi_t safi;
570 struct bgp_advertise *adv;
571
572 if (stream_fifo_head (peer->obuf))
573 return 1;
574
575 for (afi = AFI_IP; afi < AFI_MAX; afi++)
576 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
577 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
578 return 1;
579
580 for (afi = AFI_IP; afi < AFI_MAX; afi++)
581 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
582 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
583 if (adv->binfo->uptime < peer->synctime)
584 return 1;
585
586 return 0;
587}
588
589/* Write packet to the peer. */
590int
591bgp_write (struct thread *thread)
592{
593 struct peer *peer;
594 u_char type;
595 struct stream *s;
596 int num;
paulfd79ac92004-10-13 05:06:08 +0000597 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000598 int write_errno;
599
600 /* Yes first of all get peer pointer. */
601 peer = THREAD_ARG (thread);
602 peer->t_write = NULL;
603
604 /* For non-blocking IO check. */
605 if (peer->status == Connect)
606 {
607 bgp_connect_check (peer);
608 return 0;
609 }
610
611 /* Nonblocking write until TCP output buffer is full. */
612 while (1)
613 {
614 int writenum;
paula24a7e12005-01-05 08:14:13 +0000615 int val;
paul718e3742002-12-13 20:15:29 +0000616
617 s = bgp_write_packet (peer);
618 if (! s)
619 return 0;
paula24a7e12005-01-05 08:14:13 +0000620
621 /* XXX: FIXME, the socket should be NONBLOCK from the start
622 * status shouldnt need to be toggled on each write
623 */
624 val = fcntl (peer->fd, F_GETFL, 0);
625 fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
paul718e3742002-12-13 20:15:29 +0000626
627 /* Number of bytes to be sent. */
628 writenum = stream_get_endp (s) - stream_get_getp (s);
629
630 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000631 num = write (peer->fd, STREAM_PNT (s), writenum);
paul718e3742002-12-13 20:15:29 +0000632 write_errno = errno;
paula24a7e12005-01-05 08:14:13 +0000633 fcntl (peer->fd, F_SETFL, val);
paul718e3742002-12-13 20:15:29 +0000634 if (num <= 0)
635 {
636 /* Partial write. */
637 if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
638 break;
639
paul200df112005-06-01 11:17:05 +0000640 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000641 peer->status = Idle;
642 bgp_timer_set (peer);
643 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
paul200df112005-06-01 11:17:05 +0000676 BGP_EVENT_ADD (peer, BGP_Stop);
677 /*bgp_stop (peer);*/
paul718e3742002-12-13 20:15:29 +0000678 peer->status = Idle;
679 bgp_timer_set (peer);
680 return 0;
paul718e3742002-12-13 20:15:29 +0000681 case BGP_MSG_KEEPALIVE:
682 peer->keepalive_out++;
683 break;
684 case BGP_MSG_ROUTE_REFRESH_NEW:
685 case BGP_MSG_ROUTE_REFRESH_OLD:
686 peer->refresh_out++;
687 break;
688 case BGP_MSG_CAPABILITY:
689 peer->dynamic_cap_out++;
690 break;
691 }
692
693 /* OK we send packet so delete it. */
694 bgp_packet_delete (peer);
695
696 if (++count >= BGP_WRITE_PACKET_MAX)
697 break;
698 }
699
700 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000701 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000702
703 return 0;
704}
705
706/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000707static int
paul718e3742002-12-13 20:15:29 +0000708bgp_write_notify (struct peer *peer)
709{
710 int ret;
711 u_char type;
712 struct stream *s;
713
714 /* There should be at least one packet. */
715 s = stream_fifo_head (peer->obuf);
716 if (!s)
717 return 0;
718 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
719
720 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000721 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000722 if (ret <= 0)
723 {
paul200df112005-06-01 11:17:05 +0000724 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000725 peer->status = Idle;
726 bgp_timer_set (peer);
727 return 0;
728 }
729
730 /* Retrieve BGP packet type. */
731 stream_set_getp (s, BGP_MARKER_SIZE + 2);
732 type = stream_getc (s);
733
734 assert (type == BGP_MSG_NOTIFY);
735
736 /* Type should be notify. */
737 peer->notify_out++;
738
739 /* Double start timer. */
740 peer->v_start *= 2;
741
742 /* Overflow check. */
743 if (peer->v_start >= (60 * 2))
744 peer->v_start = (60 * 2);
745
746 /* We don't call event manager at here for avoiding other events. */
747 bgp_stop (peer);
748 peer->status = Idle;
749 bgp_timer_set (peer);
750
751 return 0;
752}
753
754/* Make keepalive packet and send it to the peer. */
755void
756bgp_keepalive_send (struct peer *peer)
757{
758 struct stream *s;
759 int length;
760
761 s = stream_new (BGP_MAX_PACKET_SIZE);
762
763 /* Make keepalive packet. */
764 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
765
766 /* Set packet size. */
767 length = bgp_packet_set_size (s);
768
769 /* Dump packet if debug option is set. */
770 /* bgp_packet_dump (s); */
771
772 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000773 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000774 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000775 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000776 peer->host, BGP_MSG_KEEPALIVE, length);
777
778 /* Add packet to the peer. */
779 bgp_packet_add (peer, s);
780
pauleb821182004-05-01 08:44:08 +0000781 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000782}
783
784/* Make open packet and send it to the peer. */
785void
786bgp_open_send (struct peer *peer)
787{
788 struct stream *s;
789 int length;
790 u_int16_t send_holdtime;
791 as_t local_as;
792
793 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
794 send_holdtime = peer->holdtime;
795 else
796 send_holdtime = peer->bgp->default_holdtime;
797
798 /* local-as Change */
799 if (peer->change_local_as)
800 local_as = peer->change_local_as;
801 else
802 local_as = peer->local_as;
803
804 s = stream_new (BGP_MAX_PACKET_SIZE);
805
806 /* Make open packet. */
807 bgp_packet_set_marker (s, BGP_MSG_OPEN);
808
809 /* Set open packet values. */
810 stream_putc (s, BGP_VERSION_4); /* BGP version */
811 stream_putw (s, local_as); /* My Autonomous System*/
812 stream_putw (s, send_holdtime); /* Hold Time */
813 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
814
815 /* Set capability code. */
816 bgp_open_capability (s, peer);
817
818 /* Set BGP packet length. */
819 length = bgp_packet_set_size (s);
820
821 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000822 zlog_debug ("%s sending OPEN, version %d, my as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000823 peer->host, BGP_VERSION_4, local_as,
824 send_holdtime, inet_ntoa (peer->local_id));
825
826 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000827 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000828 peer->host, BGP_MSG_OPEN, length);
829
830 /* Dump packet if debug option is set. */
831 /* bgp_packet_dump (s); */
832
833 /* Add packet to the peer. */
834 bgp_packet_add (peer, s);
835
pauleb821182004-05-01 08:44:08 +0000836 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000837}
838
839/* Send BGP notify packet with data potion. */
840void
841bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
842 u_char *data, size_t datalen)
843{
844 struct stream *s;
845 int length;
846
847 /* Allocate new stream. */
848 s = stream_new (BGP_MAX_PACKET_SIZE);
849
850 /* Make nitify packet. */
851 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
852
853 /* Set notify packet values. */
854 stream_putc (s, code); /* BGP notify code */
855 stream_putc (s, sub_code); /* BGP notify sub_code */
856
857 /* If notify data is present. */
858 if (data)
859 stream_write (s, data, datalen);
860
861 /* Set BGP packet length. */
862 length = bgp_packet_set_size (s);
863
864 /* Add packet to the peer. */
865 stream_fifo_clean (peer->obuf);
866 bgp_packet_add (peer, s);
867
868 /* For debug */
869 {
870 struct bgp_notify bgp_notify;
871 int first = 0;
872 int i;
873 char c[4];
874
875 bgp_notify.code = code;
876 bgp_notify.subcode = sub_code;
877 bgp_notify.data = NULL;
878 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
879
880 if (bgp_notify.length)
881 {
882 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
883 for (i = 0; i < bgp_notify.length; i++)
884 if (first)
885 {
886 sprintf (c, " %02x", data[i]);
887 strcat (bgp_notify.data, c);
888 }
889 else
890 {
891 first = 1;
892 sprintf (c, "%02x", data[i]);
893 strcpy (bgp_notify.data, c);
894 }
895 }
896 bgp_notify_print (peer, &bgp_notify, "sending");
897 if (bgp_notify.data)
898 XFREE (MTYPE_TMP, bgp_notify.data);
899 }
900
901 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000902 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000903 peer->host, BGP_MSG_NOTIFY, length);
904
hassoe0701b72004-05-20 09:19:34 +0000905 /* peer reset cause */
906 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
907 {
908 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
909 peer->last_reset = PEER_DOWN_USER_RESET;
910 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
911 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
912 else
913 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
914 }
915
paul718e3742002-12-13 20:15:29 +0000916 /* Call imidiately. */
917 BGP_WRITE_OFF (peer->t_write);
918
919 bgp_write_notify (peer);
920}
921
922/* Send BGP notify packet. */
923void
924bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
925{
926 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
927}
928
paul94f2b392005-06-28 12:44:16 +0000929static const char *
paul718e3742002-12-13 20:15:29 +0000930afi2str (afi_t afi)
931{
932 if (afi == AFI_IP)
933 return "AFI_IP";
934 else if (afi == AFI_IP6)
935 return "AFI_IP6";
936 else
937 return "Unknown AFI";
938}
939
paul94f2b392005-06-28 12:44:16 +0000940static const char *
paul718e3742002-12-13 20:15:29 +0000941safi2str (safi_t safi)
942{
943 if (safi == SAFI_UNICAST)
944 return "SAFI_UNICAST";
945 else if (safi == SAFI_MULTICAST)
946 return "SAFI_MULTICAST";
947 else if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPNV4)
948 return "SAFI_MPLS_VPN";
949 else
950 return "Unknown SAFI";
951}
952
953/* Send route refresh message to the peer. */
954void
955bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
956 u_char orf_type, u_char when_to_refresh, int remove)
957{
958 struct stream *s;
959 struct stream *packet;
960 int length;
961 struct bgp_filter *filter;
962 int orf_refresh = 0;
963
964#ifdef DISABLE_BGP_ANNOUNCE
965 return;
966#endif /* DISABLE_BGP_ANNOUNCE */
967
968 filter = &peer->filter[afi][safi];
969
970 /* Adjust safi code. */
971 if (safi == SAFI_MPLS_VPN)
972 safi = BGP_SAFI_VPNV4;
973
974 s = stream_new (BGP_MAX_PACKET_SIZE);
975
976 /* Make BGP update packet. */
977 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
978 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
979 else
980 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
981
982 /* Encode Route Refresh message. */
983 stream_putw (s, afi);
984 stream_putc (s, 0);
985 stream_putc (s, safi);
986
987 if (orf_type == ORF_TYPE_PREFIX
988 || orf_type == ORF_TYPE_PREFIX_OLD)
989 if (remove || filter->plist[FILTER_IN].plist)
990 {
991 u_int16_t orf_len;
992 unsigned long orfp;
993
994 orf_refresh = 1;
995 stream_putc (s, when_to_refresh);
996 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000997 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000998 stream_putw (s, 0);
999
1000 if (remove)
1001 {
1002 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1003 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1004 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001005 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001006 peer->host, orf_type,
1007 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1008 afi, safi);
1009 }
1010 else
1011 {
1012 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1013 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1014 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1015 ORF_COMMON_PART_DENY);
1016 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001017 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001018 peer->host, orf_type,
1019 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1020 afi, safi);
1021 }
1022
1023 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001024 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001025 stream_putw_at (s, orfp, orf_len);
1026 }
1027
1028 /* Set packet size. */
1029 length = bgp_packet_set_size (s);
1030
1031 if (BGP_DEBUG (normal, NORMAL))
1032 {
1033 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001034 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001035 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001036 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001037 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1038 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1039 }
1040
1041 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001042 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001043 stream_free (s);
1044
1045 /* Add packet to the peer. */
1046 bgp_packet_add (peer, packet);
1047
pauleb821182004-05-01 08:44:08 +00001048 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001049}
1050
1051/* Send capability message to the peer. */
1052void
1053bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1054 int capability_code, int action)
1055{
1056 struct stream *s;
1057 struct stream *packet;
1058 int length;
1059
1060 /* Adjust safi code. */
1061 if (safi == SAFI_MPLS_VPN)
1062 safi = BGP_SAFI_VPNV4;
1063
1064 s = stream_new (BGP_MAX_PACKET_SIZE);
1065
1066 /* Make BGP update packet. */
1067 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1068
1069 /* Encode MP_EXT capability. */
1070 if (capability_code == CAPABILITY_CODE_MP)
1071 {
1072 stream_putc (s, action);
1073 stream_putc (s, CAPABILITY_CODE_MP);
1074 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1075 stream_putw (s, afi);
1076 stream_putc (s, 0);
1077 stream_putc (s, safi);
1078
1079 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001080 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001081 peer->host, action == CAPABILITY_ACTION_SET ?
1082 "Advertising" : "Removing", afi, safi);
1083 }
1084
paul718e3742002-12-13 20:15:29 +00001085 /* Set packet size. */
1086 length = bgp_packet_set_size (s);
1087
1088 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001089 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001090 stream_free (s);
1091
1092 /* Add packet to the peer. */
1093 bgp_packet_add (peer, packet);
1094
1095 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001096 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001097 peer->host, BGP_MSG_CAPABILITY, length);
1098
pauleb821182004-05-01 08:44:08 +00001099 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001100}
1101
1102/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001103static int
pauleb821182004-05-01 08:44:08 +00001104bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001105{
pauleb821182004-05-01 08:44:08 +00001106 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001107 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001108 struct bgp *bgp;
1109
1110 bgp = bgp_get_default ();
1111 if (! bgp)
1112 return 0;
1113
1114 /* Upon receipt of an OPEN message, the local system must examine
1115 all of its connections that are in the OpenConfirm state. A BGP
1116 speaker may also examine connections in an OpenSent state if it
1117 knows the BGP Identifier of the peer by means outside of the
1118 protocol. If among these connections there is a connection to a
1119 remote BGP speaker whose BGP Identifier equals the one in the
1120 OPEN message, then the local system performs the following
1121 collision resolution procedure: */
1122
paul1eb8ef22005-04-07 07:30:20 +00001123 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001124 {
1125 /* Under OpenConfirm status, local peer structure already hold
1126 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001127
1128 if (peer != new
1129 && (peer->status == OpenConfirm || peer->status == OpenSent)
1130 && sockunion_same (&peer->su, &new->su))
1131 {
paul718e3742002-12-13 20:15:29 +00001132 /* 1. The BGP Identifier of the local system is compared to
1133 the BGP Identifier of the remote system (as specified in
1134 the OPEN message). */
1135
1136 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1137 {
1138 /* 2. If the value of the local BGP Identifier is less
1139 than the remote one, the local system closes BGP
1140 connection that already exists (the one that is
1141 already in the OpenConfirm state), and accepts BGP
1142 connection initiated by the remote system. */
1143
pauleb821182004-05-01 08:44:08 +00001144 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001145 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001146 return 1;
1147 }
1148 else
1149 {
1150 /* 3. Otherwise, the local system closes newly created
1151 BGP connection (the one associated with the newly
1152 received OPEN message), and continues to use the
1153 existing one (the one that is already in the
1154 OpenConfirm state). */
1155
pauleb821182004-05-01 08:44:08 +00001156 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001157 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1158 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001159 return -1;
1160 }
pauleb821182004-05-01 08:44:08 +00001161 }
1162 }
paul718e3742002-12-13 20:15:29 +00001163 return 0;
1164}
1165
paul94f2b392005-06-28 12:44:16 +00001166static int
paul718e3742002-12-13 20:15:29 +00001167bgp_open_receive (struct peer *peer, bgp_size_t size)
1168{
1169 int ret;
1170 u_char version;
1171 u_char optlen;
1172 u_int16_t holdtime;
1173 u_int16_t send_holdtime;
1174 as_t remote_as;
1175 struct peer *realpeer;
1176 struct in_addr remote_id;
1177 int capability;
paul5228ad22004-06-04 17:58:18 +00001178 u_int8_t notify_data_remote_as[2];
1179 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001180
1181 realpeer = NULL;
1182
1183 /* Parse open packet. */
1184 version = stream_getc (peer->ibuf);
1185 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1186 remote_as = stream_getw (peer->ibuf);
1187 holdtime = stream_getw (peer->ibuf);
1188 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1189 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1190
1191 /* Receive OPEN message log */
1192 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001193 zlog_debug ("%s rcv OPEN, version %d, remote-as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +00001194 peer->host, version, remote_as, holdtime,
1195 inet_ntoa (remote_id));
1196
1197 /* Lookup peer from Open packet. */
1198 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1199 {
1200 int as = 0;
1201
1202 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1203
1204 if (! realpeer)
1205 {
1206 /* Peer's source IP address is check in bgp_accept(), so this
1207 must be AS number mismatch or remote-id configuration
1208 mismatch. */
1209 if (as)
1210 {
1211 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001212 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1213 peer->host, inet_ntoa (remote_id));
1214 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1215 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1216 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001217 }
1218 else
1219 {
1220 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001221 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
1222 peer->host, remote_as, peer->as);
1223 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1224 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1225 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001226 }
1227 return -1;
1228 }
1229 }
1230
1231 /* When collision is detected and this peer is closed. Retrun
1232 immidiately. */
1233 ret = bgp_collision_detect (peer, remote_id);
1234 if (ret < 0)
1235 return ret;
1236
pauleb821182004-05-01 08:44:08 +00001237 /* Hack part. */
1238 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1239 {
hasso93406d82005-02-02 14:40:33 +00001240 if (realpeer->status == Established
1241 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1242 {
1243 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1244 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1245 }
1246 else if (ret == 0 && realpeer->status != Active
1247 && realpeer->status != OpenSent
1248 && realpeer->status != OpenConfirm)
1249
pauleb821182004-05-01 08:44:08 +00001250 {
1251 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001252 zlog_debug ("%s peer status is %s close connection",
1253 realpeer->host, LOOKUP (bgp_status_msg,
1254 realpeer->status));
1255 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1256 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1257
pauleb821182004-05-01 08:44:08 +00001258 return -1;
1259 }
1260
1261 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00001262 zlog_debug ("%s [Event] Transfer temporary BGP peer to existing one",
pauleb821182004-05-01 08:44:08 +00001263 peer->host);
1264
1265 bgp_stop (realpeer);
1266
1267 /* Transfer file descriptor. */
1268 realpeer->fd = peer->fd;
1269 peer->fd = -1;
1270
1271 /* Transfer input buffer. */
1272 stream_free (realpeer->ibuf);
1273 realpeer->ibuf = peer->ibuf;
1274 realpeer->packet_size = peer->packet_size;
1275 peer->ibuf = NULL;
1276
1277 /* Transfer status. */
1278 realpeer->status = peer->status;
1279 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001280
pauleb821182004-05-01 08:44:08 +00001281 /* peer pointer change. Open packet send to neighbor. */
1282 peer = realpeer;
1283 bgp_open_send (peer);
1284 if (peer->fd < 0)
1285 {
1286 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1287 peer->fd);
1288 return -1;
1289 }
1290 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1291 }
1292
paul718e3742002-12-13 20:15:29 +00001293 /* remote router-id check. */
1294 if (remote_id.s_addr == 0
1295 || ntohl (remote_id.s_addr) >= 0xe0000000
1296 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1297 {
1298 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001299 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001300 peer->host, inet_ntoa (remote_id));
1301 bgp_notify_send_with_data (peer,
1302 BGP_NOTIFY_OPEN_ERR,
1303 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1304 notify_data_remote_id, 4);
1305 return -1;
1306 }
1307
1308 /* Set remote router-id */
1309 peer->remote_id = remote_id;
1310
1311 /* Peer BGP version check. */
1312 if (version != BGP_VERSION_4)
1313 {
paul5228ad22004-06-04 17:58:18 +00001314 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001315 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001316 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001317 peer->host, version, BGP_VERSION_4);
1318 bgp_notify_send_with_data (peer,
1319 BGP_NOTIFY_OPEN_ERR,
1320 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001321 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001322 return -1;
1323 }
1324
1325 /* Check neighbor as number. */
1326 if (remote_as != peer->as)
1327 {
1328 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001329 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
paul718e3742002-12-13 20:15:29 +00001330 peer->host, remote_as, peer->as);
1331 bgp_notify_send_with_data (peer,
1332 BGP_NOTIFY_OPEN_ERR,
1333 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1334 notify_data_remote_as, 2);
1335 return -1;
1336 }
1337
1338 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1339 calculate the value of the Hold Timer by using the smaller of its
1340 configured Hold Time and the Hold Time received in the OPEN message.
1341 The Hold Time MUST be either zero or at least three seconds. An
1342 implementation may reject connections on the basis of the Hold Time. */
1343
1344 if (holdtime < 3 && holdtime != 0)
1345 {
1346 bgp_notify_send (peer,
1347 BGP_NOTIFY_OPEN_ERR,
1348 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1349 return -1;
1350 }
1351
1352 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1353 would be one third of the Hold Time interval. KEEPALIVE messages
1354 MUST NOT be sent more frequently than one per second. An
1355 implementation MAY adjust the rate at which it sends KEEPALIVE
1356 messages as a function of the Hold Time interval. */
1357
1358 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1359 send_holdtime = peer->holdtime;
1360 else
1361 send_holdtime = peer->bgp->default_holdtime;
1362
1363 if (holdtime < send_holdtime)
1364 peer->v_holdtime = holdtime;
1365 else
1366 peer->v_holdtime = send_holdtime;
1367
1368 peer->v_keepalive = peer->v_holdtime / 3;
1369
1370 /* Open option part parse. */
1371 capability = 0;
1372 optlen = stream_getc (peer->ibuf);
1373 if (optlen != 0)
1374 {
1375 ret = bgp_open_option_parse (peer, optlen, &capability);
1376 if (ret < 0)
1377 return ret;
1378
paul9985f832005-02-09 15:51:56 +00001379 stream_forward_getp (peer->ibuf, optlen);
paul718e3742002-12-13 20:15:29 +00001380 }
1381 else
1382 {
1383 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001384 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001385 peer->host);
1386 }
1387
1388 /* Override capability. */
1389 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1390 {
1391 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1392 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1393 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1394 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1395 }
1396
1397 /* Get sockname. */
1398 bgp_getsockname (peer);
1399
1400 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1401
1402 peer->packet_size = 0;
1403 if (peer->ibuf)
1404 stream_reset (peer->ibuf);
1405
1406 return 0;
1407}
1408
1409/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001410static int
paul718e3742002-12-13 20:15:29 +00001411bgp_update_receive (struct peer *peer, bgp_size_t size)
1412{
1413 int ret;
1414 u_char *end;
1415 struct stream *s;
1416 struct attr attr;
1417 bgp_size_t attribute_len;
1418 bgp_size_t update_len;
1419 bgp_size_t withdraw_len;
1420 struct bgp_nlri update;
1421 struct bgp_nlri withdraw;
1422 struct bgp_nlri mp_update;
1423 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001424 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001425
1426 /* Status must be Established. */
1427 if (peer->status != Established)
1428 {
1429 zlog_err ("%s [FSM] Update packet received under status %s",
1430 peer->host, LOOKUP (bgp_status_msg, peer->status));
1431 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1432 return -1;
1433 }
1434
1435 /* Set initial values. */
1436 memset (&attr, 0, sizeof (struct attr));
1437 memset (&update, 0, sizeof (struct bgp_nlri));
1438 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1439 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1440 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1441
1442 s = peer->ibuf;
1443 end = stream_pnt (s) + size;
1444
1445 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1446 Length is too large (i.e., if Unfeasible Routes Length + Total
1447 Attribute Length + 23 exceeds the message Length), then the Error
1448 Subcode is set to Malformed Attribute List. */
1449 if (stream_pnt (s) + 2 > end)
1450 {
1451 zlog_err ("%s [Error] Update packet error"
1452 " (packet length is short for unfeasible length)",
1453 peer->host);
1454 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1455 BGP_NOTIFY_UPDATE_MAL_ATTR);
1456 return -1;
1457 }
1458
1459 /* Unfeasible Route Length. */
1460 withdraw_len = stream_getw (s);
1461
1462 /* Unfeasible Route Length check. */
1463 if (stream_pnt (s) + withdraw_len > end)
1464 {
1465 zlog_err ("%s [Error] Update packet error"
1466 " (packet unfeasible length overflow %d)",
1467 peer->host, withdraw_len);
1468 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1469 BGP_NOTIFY_UPDATE_MAL_ATTR);
1470 return -1;
1471 }
1472
1473 /* Unfeasible Route packet format check. */
1474 if (withdraw_len > 0)
1475 {
1476 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1477 if (ret < 0)
1478 return -1;
1479
1480 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001481 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001482
1483 withdraw.afi = AFI_IP;
1484 withdraw.safi = SAFI_UNICAST;
1485 withdraw.nlri = stream_pnt (s);
1486 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001487 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001488 }
1489
1490 /* Attribute total length check. */
1491 if (stream_pnt (s) + 2 > end)
1492 {
1493 zlog_warn ("%s [Error] Packet Error"
1494 " (update packet is short for attribute length)",
1495 peer->host);
1496 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1497 BGP_NOTIFY_UPDATE_MAL_ATTR);
1498 return -1;
1499 }
1500
1501 /* Fetch attribute total length. */
1502 attribute_len = stream_getw (s);
1503
1504 /* Attribute length check. */
1505 if (stream_pnt (s) + attribute_len > end)
1506 {
1507 zlog_warn ("%s [Error] Packet Error"
1508 " (update packet attribute length overflow %d)",
1509 peer->host, attribute_len);
1510 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1511 BGP_NOTIFY_UPDATE_MAL_ATTR);
1512 return -1;
1513 }
1514
1515 /* Parse attribute when it exists. */
1516 if (attribute_len)
1517 {
1518 ret = bgp_attr_parse (peer, &attr, attribute_len,
1519 &mp_update, &mp_withdraw);
1520 if (ret < 0)
1521 return -1;
1522 }
1523
1524 /* Logging the attribute. */
1525 if (BGP_DEBUG (update, UPDATE_IN))
1526 {
paule01f9cb2004-07-09 17:48:53 +00001527 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1528
1529 if (ret)
ajs6b514742004-12-08 21:03:23 +00001530 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001531 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001532 }
1533
1534 /* Network Layer Reachability Information. */
1535 update_len = end - stream_pnt (s);
1536
1537 if (update_len)
1538 {
1539 /* Check NLRI packet format and prefix length. */
1540 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1541 if (ret < 0)
1542 return -1;
1543
1544 /* Set NLRI portion to structure. */
1545 update.afi = AFI_IP;
1546 update.safi = SAFI_UNICAST;
1547 update.nlri = stream_pnt (s);
1548 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001549 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001550 }
1551
1552 /* NLRI is processed only when the peer is configured specific
1553 Address Family and Subsequent Address Family. */
1554 if (peer->afc[AFI_IP][SAFI_UNICAST])
1555 {
1556 if (withdraw.length)
1557 bgp_nlri_parse (peer, NULL, &withdraw);
1558
1559 if (update.length)
1560 {
1561 /* We check well-known attribute only for IPv4 unicast
1562 update. */
1563 ret = bgp_attr_check (peer, &attr);
1564 if (ret < 0)
1565 return -1;
1566
1567 bgp_nlri_parse (peer, &attr, &update);
1568 }
paule01f9cb2004-07-09 17:48:53 +00001569
hassof4184462005-02-01 20:13:16 +00001570 if (mp_update.length
1571 && mp_update.afi == AFI_IP
1572 && mp_update.safi == SAFI_UNICAST)
1573 bgp_nlri_parse (peer, &attr, &mp_update);
1574
1575 if (mp_withdraw.length
1576 && mp_withdraw.afi == AFI_IP
1577 && mp_withdraw.safi == SAFI_UNICAST)
1578 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1579
paule01f9cb2004-07-09 17:48:53 +00001580 if (! attribute_len && ! withdraw_len)
1581 {
1582 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001583 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1584 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001585
hasso93406d82005-02-02 14:40:33 +00001586 /* NSF delete stale route */
1587 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1588 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1589
1590 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001591 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001592 peer->host);
1593 }
paul718e3742002-12-13 20:15:29 +00001594 }
1595 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1596 {
1597 if (mp_update.length
1598 && mp_update.afi == AFI_IP
1599 && mp_update.safi == SAFI_MULTICAST)
1600 bgp_nlri_parse (peer, &attr, &mp_update);
1601
1602 if (mp_withdraw.length
1603 && mp_withdraw.afi == AFI_IP
1604 && mp_withdraw.safi == SAFI_MULTICAST)
1605 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001606
hasso93406d82005-02-02 14:40:33 +00001607 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001608 && mp_withdraw.afi == AFI_IP
1609 && mp_withdraw.safi == SAFI_MULTICAST
1610 && mp_withdraw.length == 0)
1611 {
1612 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001613 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1614 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001615
hasso93406d82005-02-02 14:40:33 +00001616 /* NSF delete stale route */
1617 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1618 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1619
1620 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001621 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001622 peer->host);
1623 }
paul718e3742002-12-13 20:15:29 +00001624 }
1625 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1626 {
1627 if (mp_update.length
1628 && mp_update.afi == AFI_IP6
1629 && mp_update.safi == SAFI_UNICAST)
1630 bgp_nlri_parse (peer, &attr, &mp_update);
1631
1632 if (mp_withdraw.length
1633 && mp_withdraw.afi == AFI_IP6
1634 && mp_withdraw.safi == SAFI_UNICAST)
1635 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001636
hasso93406d82005-02-02 14:40:33 +00001637 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001638 && mp_withdraw.afi == AFI_IP6
1639 && mp_withdraw.safi == SAFI_UNICAST
1640 && mp_withdraw.length == 0)
1641 {
1642 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001643 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001644
hasso93406d82005-02-02 14:40:33 +00001645 /* NSF delete stale route */
1646 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1647 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1648
1649 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001650 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001651 peer->host);
1652 }
paul718e3742002-12-13 20:15:29 +00001653 }
1654 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1655 {
1656 if (mp_update.length
1657 && mp_update.afi == AFI_IP6
1658 && mp_update.safi == SAFI_MULTICAST)
1659 bgp_nlri_parse (peer, &attr, &mp_update);
1660
1661 if (mp_withdraw.length
1662 && mp_withdraw.afi == AFI_IP6
1663 && mp_withdraw.safi == SAFI_MULTICAST)
1664 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001665
hasso93406d82005-02-02 14:40:33 +00001666 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001667 && mp_withdraw.afi == AFI_IP6
1668 && mp_withdraw.safi == SAFI_MULTICAST
1669 && mp_withdraw.length == 0)
1670 {
1671 /* End-of-RIB received */
1672
hasso93406d82005-02-02 14:40:33 +00001673 /* NSF delete stale route */
1674 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1675 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1676
paule01f9cb2004-07-09 17:48:53 +00001677 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001678 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001679 peer->host);
1680 }
paul718e3742002-12-13 20:15:29 +00001681 }
1682 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1683 {
1684 if (mp_update.length
1685 && mp_update.afi == AFI_IP
1686 && mp_update.safi == BGP_SAFI_VPNV4)
1687 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1688
1689 if (mp_withdraw.length
1690 && mp_withdraw.afi == AFI_IP
1691 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1692 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001693
hasso93406d82005-02-02 14:40:33 +00001694 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001695 && mp_withdraw.afi == AFI_IP
1696 && mp_withdraw.safi == BGP_SAFI_VPNV4
1697 && mp_withdraw.length == 0)
1698 {
1699 /* End-of-RIB received */
1700
1701 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001702 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001703 peer->host);
1704 }
paul718e3742002-12-13 20:15:29 +00001705 }
1706
1707 /* Everything is done. We unintern temporary structures which
1708 interned in bgp_attr_parse(). */
1709 if (attr.aspath)
1710 aspath_unintern (attr.aspath);
1711 if (attr.community)
1712 community_unintern (attr.community);
1713 if (attr.ecommunity)
1714 ecommunity_unintern (attr.ecommunity);
1715 if (attr.cluster)
1716 cluster_unintern (attr.cluster);
1717 if (attr.transit)
1718 transit_unintern (attr.transit);
1719
1720 /* If peering is stopped due to some reason, do not generate BGP
1721 event. */
1722 if (peer->status != Established)
1723 return 0;
1724
1725 /* Increment packet counter. */
1726 peer->update_in++;
1727 peer->update_time = time (NULL);
1728
1729 /* Generate BGP event. */
1730 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1731
1732 return 0;
1733}
1734
1735/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001736static void
paul718e3742002-12-13 20:15:29 +00001737bgp_notify_receive (struct peer *peer, bgp_size_t size)
1738{
1739 struct bgp_notify bgp_notify;
1740
1741 if (peer->notify.data)
1742 {
1743 XFREE (MTYPE_TMP, peer->notify.data);
1744 peer->notify.data = NULL;
1745 peer->notify.length = 0;
1746 }
1747
1748 bgp_notify.code = stream_getc (peer->ibuf);
1749 bgp_notify.subcode = stream_getc (peer->ibuf);
1750 bgp_notify.length = size - 2;
1751 bgp_notify.data = NULL;
1752
1753 /* Preserv notify code and sub code. */
1754 peer->notify.code = bgp_notify.code;
1755 peer->notify.subcode = bgp_notify.subcode;
1756 /* For further diagnostic record returned Data. */
1757 if (bgp_notify.length)
1758 {
1759 peer->notify.length = size - 2;
1760 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1761 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1762 }
1763
1764 /* For debug */
1765 {
1766 int i;
1767 int first = 0;
1768 char c[4];
1769
1770 if (bgp_notify.length)
1771 {
1772 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1773 for (i = 0; i < bgp_notify.length; i++)
1774 if (first)
1775 {
1776 sprintf (c, " %02x", stream_getc (peer->ibuf));
1777 strcat (bgp_notify.data, c);
1778 }
1779 else
1780 {
1781 first = 1;
1782 sprintf (c, "%02x", stream_getc (peer->ibuf));
1783 strcpy (bgp_notify.data, c);
1784 }
1785 }
1786
1787 bgp_notify_print(peer, &bgp_notify, "received");
1788 if (bgp_notify.data)
1789 XFREE (MTYPE_TMP, bgp_notify.data);
1790 }
1791
1792 /* peer count update */
1793 peer->notify_in++;
1794
hassoe0701b72004-05-20 09:19:34 +00001795 if (peer->status == Established)
1796 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1797
paul718e3742002-12-13 20:15:29 +00001798 /* We have to check for Notify with Unsupported Optional Parameter.
1799 in that case we fallback to open without the capability option.
1800 But this done in bgp_stop. We just mark it here to avoid changing
1801 the fsm tables. */
1802 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1803 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1804 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1805
1806 /* Also apply to Unsupported Capability until remote router support
1807 capability. */
1808 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1809 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
1810 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1811
1812 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1813}
1814
1815/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001816static void
paul718e3742002-12-13 20:15:29 +00001817bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1818{
1819 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001820 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001821
1822 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1823}
1824
1825/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001826static void
paul718e3742002-12-13 20:15:29 +00001827bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1828{
1829 afi_t afi;
1830 safi_t safi;
1831 u_char reserved;
1832 struct stream *s;
1833
1834 /* If peer does not have the capability, send notification. */
1835 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1836 {
1837 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1838 peer->host);
1839 bgp_notify_send (peer,
1840 BGP_NOTIFY_HEADER_ERR,
1841 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1842 return;
1843 }
1844
1845 /* Status must be Established. */
1846 if (peer->status != Established)
1847 {
1848 plog_err (peer->log,
1849 "%s [Error] Route refresh packet received under status %s",
1850 peer->host, LOOKUP (bgp_status_msg, peer->status));
1851 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1852 return;
1853 }
1854
1855 s = peer->ibuf;
1856
1857 /* Parse packet. */
1858 afi = stream_getw (s);
1859 reserved = stream_getc (s);
1860 safi = stream_getc (s);
1861
1862 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001863 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001864 peer->host, afi, safi);
1865
1866 /* Check AFI and SAFI. */
1867 if ((afi != AFI_IP && afi != AFI_IP6)
1868 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1869 && safi != BGP_SAFI_VPNV4))
1870 {
1871 if (BGP_DEBUG (normal, NORMAL))
1872 {
ajs6b514742004-12-08 21:03:23 +00001873 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001874 peer->host, afi, safi);
1875 }
1876 return;
1877 }
1878
1879 /* Adjust safi code. */
1880 if (safi == BGP_SAFI_VPNV4)
1881 safi = SAFI_MPLS_VPN;
1882
1883 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1884 {
1885 u_char *end;
1886 u_char when_to_refresh;
1887 u_char orf_type;
1888 u_int16_t orf_len;
1889
1890 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1891 {
1892 zlog_info ("%s ORF route refresh length error", peer->host);
1893 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1894 return;
1895 }
1896
1897 when_to_refresh = stream_getc (s);
1898 end = stream_pnt (s) + (size - 5);
1899
1900 while (stream_pnt (s) < end)
1901 {
1902 orf_type = stream_getc (s);
1903 orf_len = stream_getw (s);
1904
1905 if (orf_type == ORF_TYPE_PREFIX
1906 || orf_type == ORF_TYPE_PREFIX_OLD)
1907 {
1908 u_char *p_pnt = stream_pnt (s);
1909 u_char *p_end = stream_pnt (s) + orf_len;
1910 struct orf_prefix orfp;
1911 u_char common = 0;
1912 u_int32_t seq;
1913 int psize;
1914 char name[BUFSIZ];
1915 char buf[BUFSIZ];
1916 int ret;
1917
1918 if (BGP_DEBUG (normal, NORMAL))
1919 {
ajs6b514742004-12-08 21:03:23 +00001920 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00001921 peer->host, orf_type, orf_len);
1922 }
1923
1924 /* ORF prefix-list name */
1925 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
1926
1927 while (p_pnt < p_end)
1928 {
1929 memset (&orfp, 0, sizeof (struct orf_prefix));
1930 common = *p_pnt++;
1931 if (common & ORF_COMMON_PART_REMOVE_ALL)
1932 {
1933 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001934 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00001935 prefix_bgp_orf_remove_all (name);
1936 break;
1937 }
1938 memcpy (&seq, p_pnt, sizeof (u_int32_t));
1939 p_pnt += sizeof (u_int32_t);
1940 orfp.seq = ntohl (seq);
1941 orfp.ge = *p_pnt++;
1942 orfp.le = *p_pnt++;
1943 orfp.p.prefixlen = *p_pnt++;
1944 orfp.p.family = afi2family (afi);
1945 psize = PSIZE (orfp.p.prefixlen);
1946 memcpy (&orfp.p.u.prefix, p_pnt, psize);
1947 p_pnt += psize;
1948
1949 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001950 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
paul718e3742002-12-13 20:15:29 +00001951 peer->host,
1952 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
1953 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
1954 orfp.seq,
1955 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
1956 orfp.p.prefixlen, orfp.ge, orfp.le);
1957
1958 ret = prefix_bgp_orf_set (name, afi, &orfp,
1959 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
1960 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
1961
1962 if (ret != CMD_SUCCESS)
1963 {
1964 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001965 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00001966 prefix_bgp_orf_remove_all (name);
1967 break;
1968 }
1969 }
1970 peer->orf_plist[afi][safi] =
1971 prefix_list_lookup (AFI_ORF_PREFIX, name);
1972 }
paul9985f832005-02-09 15:51:56 +00001973 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00001974 }
1975 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001976 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00001977 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
1978 if (when_to_refresh == REFRESH_DEFER)
1979 return;
1980 }
1981
1982 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1983 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
1984 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
1985
1986 /* Perform route refreshment to the peer */
1987 bgp_announce_route (peer, afi, safi);
1988}
1989
paul94f2b392005-06-28 12:44:16 +00001990static int
paul718e3742002-12-13 20:15:29 +00001991bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
1992{
1993 u_char *end;
1994 struct capability cap;
1995 u_char action;
1996 struct bgp *bgp;
1997 afi_t afi;
1998 safi_t safi;
1999
2000 bgp = peer->bgp;
2001 end = pnt + length;
2002
2003 while (pnt < end)
2004 {
2005 /* We need at least action, capability code and capability length. */
2006 if (pnt + 3 > end)
2007 {
2008 zlog_info ("%s Capability length error", peer->host);
2009 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2010 return -1;
2011 }
2012
2013 action = *pnt;
2014
2015 /* Fetch structure to the byte stream. */
2016 memcpy (&cap, pnt + 1, sizeof (struct capability));
2017
2018 /* Action value check. */
2019 if (action != CAPABILITY_ACTION_SET
2020 && action != CAPABILITY_ACTION_UNSET)
2021 {
2022 zlog_info ("%s Capability Action Value error %d",
2023 peer->host, action);
2024 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2025 return -1;
2026 }
2027
2028 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002029 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
paul718e3742002-12-13 20:15:29 +00002030 peer->host, action, cap.code, cap.length);
2031
2032 /* Capability length check. */
2033 if (pnt + (cap.length + 3) > end)
2034 {
2035 zlog_info ("%s Capability length error", peer->host);
2036 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2037 return -1;
2038 }
2039
2040 /* We know MP Capability Code. */
2041 if (cap.code == CAPABILITY_CODE_MP)
2042 {
2043 afi = ntohs (cap.mpc.afi);
2044 safi = cap.mpc.safi;
2045
2046 /* Ignore capability when override-capability is set. */
2047 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2048 continue;
2049
2050 /* Address family check. */
2051 if ((afi == AFI_IP
2052 || afi == AFI_IP6)
2053 && (safi == SAFI_UNICAST
2054 || safi == SAFI_MULTICAST
2055 || safi == BGP_SAFI_VPNV4))
2056 {
2057 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002058 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
paul718e3742002-12-13 20:15:29 +00002059 peer->host,
2060 action == CAPABILITY_ACTION_SET
2061 ? "Advertising" : "Removing",
2062 ntohs(cap.mpc.afi) , cap.mpc.safi);
2063
2064 /* Adjust safi code. */
2065 if (safi == BGP_SAFI_VPNV4)
2066 safi = SAFI_MPLS_VPN;
2067
2068 if (action == CAPABILITY_ACTION_SET)
2069 {
2070 peer->afc_recv[afi][safi] = 1;
2071 if (peer->afc[afi][safi])
2072 {
2073 peer->afc_nego[afi][safi] = 1;
2074 bgp_announce_route (peer, afi, safi);
2075 }
2076 }
2077 else
2078 {
2079 peer->afc_recv[afi][safi] = 0;
2080 peer->afc_nego[afi][safi] = 0;
2081
2082 if (peer_active_nego (peer))
2083 bgp_clear_route (peer, afi, safi);
2084 else
2085 BGP_EVENT_ADD (peer, BGP_Stop);
2086 }
2087 }
2088 }
paul718e3742002-12-13 20:15:29 +00002089 else
2090 {
2091 zlog_warn ("%s unrecognized capability code: %d - ignored",
2092 peer->host, cap.code);
2093 }
2094 pnt += cap.length + 3;
2095 }
2096 return 0;
2097}
2098
2099/* Dynamic Capability is received. */
paul94f2b392005-06-28 12:44:16 +00002100static void
paul718e3742002-12-13 20:15:29 +00002101bgp_capability_receive (struct peer *peer, bgp_size_t size)
2102{
2103 u_char *pnt;
2104 int ret;
2105
2106 /* Fetch pointer. */
2107 pnt = stream_pnt (peer->ibuf);
2108
2109 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002110 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002111
2112 /* If peer does not have the capability, send notification. */
2113 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2114 {
2115 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2116 peer->host);
2117 bgp_notify_send (peer,
2118 BGP_NOTIFY_HEADER_ERR,
2119 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2120 return;
2121 }
2122
2123 /* Status must be Established. */
2124 if (peer->status != Established)
2125 {
2126 plog_err (peer->log,
2127 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2128 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2129 return;
2130 }
2131
2132 /* Parse packet. */
2133 ret = bgp_capability_msg_parse (peer, pnt, size);
2134}
2135
2136/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002137static int
paul718e3742002-12-13 20:15:29 +00002138bgp_read_packet (struct peer *peer)
2139{
2140 int nbytes;
2141 int readsize;
2142
paul9985f832005-02-09 15:51:56 +00002143 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002144
2145 /* If size is zero then return. */
2146 if (! readsize)
2147 return 0;
2148
2149 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002150 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002151
2152 /* If read byte is smaller than zero then error occured. */
2153 if (nbytes < 0)
2154 {
2155 if (errno == EAGAIN)
2156 return -1;
2157
2158 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002159 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002160
2161 if (peer->status == Established)
2162 {
2163 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2164 {
2165 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2166 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2167 }
2168 else
2169 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2170 }
2171
paul718e3742002-12-13 20:15:29 +00002172 BGP_EVENT_ADD (peer, TCP_fatal_error);
2173 return -1;
2174 }
2175
2176 /* When read byte is zero : clear bgp peer and return */
2177 if (nbytes == 0)
2178 {
2179 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002180 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002181 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002182
2183 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002184 {
2185 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2186 {
2187 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2188 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2189 }
2190 else
2191 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2192 }
hassoe0701b72004-05-20 09:19:34 +00002193
paul718e3742002-12-13 20:15:29 +00002194 BGP_EVENT_ADD (peer, TCP_connection_closed);
2195 return -1;
2196 }
2197
2198 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002199 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002200 return -1;
2201
2202 return 0;
2203}
2204
2205/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002206static int
paul718e3742002-12-13 20:15:29 +00002207bgp_marker_all_one (struct stream *s, int length)
2208{
2209 int i;
2210
2211 for (i = 0; i < length; i++)
2212 if (s->data[i] != 0xff)
2213 return 0;
2214
2215 return 1;
2216}
2217
2218/* Starting point of packet process function. */
2219int
2220bgp_read (struct thread *thread)
2221{
2222 int ret;
2223 u_char type = 0;
2224 struct peer *peer;
2225 bgp_size_t size;
2226 char notify_data_length[2];
2227
2228 /* Yes first of all get peer pointer. */
2229 peer = THREAD_ARG (thread);
2230 peer->t_read = NULL;
2231
2232 /* For non-blocking IO check. */
2233 if (peer->status == Connect)
2234 {
2235 bgp_connect_check (peer);
2236 goto done;
2237 }
2238 else
2239 {
pauleb821182004-05-01 08:44:08 +00002240 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002241 {
pauleb821182004-05-01 08:44:08 +00002242 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002243 return -1;
2244 }
pauleb821182004-05-01 08:44:08 +00002245 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002246 }
2247
2248 /* Read packet header to determine type of the packet */
2249 if (peer->packet_size == 0)
2250 peer->packet_size = BGP_HEADER_SIZE;
2251
paul9985f832005-02-09 15:51:56 +00002252 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002253 {
2254 ret = bgp_read_packet (peer);
2255
2256 /* Header read error or partial read packet. */
2257 if (ret < 0)
2258 goto done;
2259
2260 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002261 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002262 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2263 size = stream_getw (peer->ibuf);
2264 type = stream_getc (peer->ibuf);
2265
2266 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002267 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002268 peer->host, type, size - BGP_HEADER_SIZE);
2269
2270 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002271 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002272 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2273 {
2274 bgp_notify_send (peer,
2275 BGP_NOTIFY_HEADER_ERR,
2276 BGP_NOTIFY_HEADER_NOT_SYNC);
2277 goto done;
2278 }
2279
2280 /* BGP type check. */
2281 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2282 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2283 && type != BGP_MSG_ROUTE_REFRESH_NEW
2284 && type != BGP_MSG_ROUTE_REFRESH_OLD
2285 && type != BGP_MSG_CAPABILITY)
2286 {
2287 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002288 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002289 "%s unknown message type 0x%02x",
2290 peer->host, type);
2291 bgp_notify_send_with_data (peer,
2292 BGP_NOTIFY_HEADER_ERR,
2293 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2294 &type, 1);
2295 goto done;
2296 }
2297 /* Mimimum packet length check. */
2298 if ((size < BGP_HEADER_SIZE)
2299 || (size > BGP_MAX_PACKET_SIZE)
2300 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2301 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2302 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2303 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2304 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2305 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2306 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2307 {
2308 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002309 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002310 "%s bad message length - %d for %s",
2311 peer->host, size,
2312 type == 128 ? "ROUTE-REFRESH" :
2313 bgp_type_str[(int) type]);
2314 bgp_notify_send_with_data (peer,
2315 BGP_NOTIFY_HEADER_ERR,
2316 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002317 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002318 goto done;
2319 }
2320
2321 /* Adjust size to message length. */
2322 peer->packet_size = size;
2323 }
2324
2325 ret = bgp_read_packet (peer);
2326 if (ret < 0)
2327 goto done;
2328
2329 /* Get size and type again. */
2330 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2331 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2332
2333 /* BGP packet dump function. */
2334 bgp_dump_packet (peer, type, peer->ibuf);
2335
2336 size = (peer->packet_size - BGP_HEADER_SIZE);
2337
2338 /* Read rest of the packet and call each sort of packet routine */
2339 switch (type)
2340 {
2341 case BGP_MSG_OPEN:
2342 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002343 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002344 break;
2345 case BGP_MSG_UPDATE:
2346 peer->readtime = time(NULL); /* Last read timer reset */
2347 bgp_update_receive (peer, size);
2348 break;
2349 case BGP_MSG_NOTIFY:
2350 bgp_notify_receive (peer, size);
2351 break;
2352 case BGP_MSG_KEEPALIVE:
2353 peer->readtime = time(NULL); /* Last read timer reset */
2354 bgp_keepalive_receive (peer, size);
2355 break;
2356 case BGP_MSG_ROUTE_REFRESH_NEW:
2357 case BGP_MSG_ROUTE_REFRESH_OLD:
2358 peer->refresh_in++;
2359 bgp_route_refresh_receive (peer, size);
2360 break;
2361 case BGP_MSG_CAPABILITY:
2362 peer->dynamic_cap_in++;
2363 bgp_capability_receive (peer, size);
2364 break;
2365 }
2366
2367 /* Clear input buffer. */
2368 peer->packet_size = 0;
2369 if (peer->ibuf)
2370 stream_reset (peer->ibuf);
2371
2372 done:
2373 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2374 {
2375 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002376 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002377 peer_delete (peer);
paul200df112005-06-01 11:17:05 +00002378 /* we've lost track of a reference to ACCEPT_PEER somehow. It doesnt
2379 * _seem_ to be the 'update realpeer with accept peer' hack, yet it
2380 * *must* be.. Very very odd, but I give up trying to
2381 * root cause this - ACCEPT_PEER is a dirty hack, it should be fixed
2382 * instead, which would make root-causing this a moot point..
2383 * A hack because of a hack, appropriate.
2384 */
2385 peer_unlock (peer); /* god knows what reference... ACCEPT_PEER sucks */
paul718e3742002-12-13 20:15:29 +00002386 }
2387 return 0;
2388}