blob: 0971c5ca603407279068b84eacffd72f97bf7e7f [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];
153 struct prefix_rd *prd = NULL;
154 char *tag = NULL;
155
156 s = peer->work;
157 stream_reset (s);
158
159 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
160
161 while (adv)
162 {
163 if (adv->rn)
164 rn = adv->rn;
165 adj = adv->adj;
166 if (adv->binfo)
167 binfo = adv->binfo;
168#ifdef MPLS_VPN
169 if (rn)
170 prd = (struct prefix_rd *) &rn->prn->p;
171 if (binfo)
172 tag = binfo->tag;
173#endif /* MPLS_VPN */
174
175 /* When remaining space can't include NLRI and it's length. */
176 if (rn && STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
177 break;
178
179 /* If packet is empty, set attribute. */
180 if (stream_empty (s))
181 {
182 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];
285 struct prefix_rd *prd = NULL;
286
287 s = peer->work;
288 stream_reset (s);
289
290 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
291 {
292 adj = adv->adj;
293 rn = adv->rn;
294#ifdef MPLS_VPN
295 prd = (struct prefix_rd *) &rn->prn->p;
296#endif /* MPLS_VPN */
297
298 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000299 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000300 break;
301
302 if (stream_empty (s))
303 {
304 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
305 stream_putw (s, 0);
306 }
307
308 if (afi == AFI_IP && safi == SAFI_UNICAST)
309 stream_put_prefix (s, &rn->p);
310 else
311 {
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
415 bgp_packet_dump (packet);
416#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;
681 break;
682 case BGP_MSG_KEEPALIVE:
683 peer->keepalive_out++;
684 break;
685 case BGP_MSG_ROUTE_REFRESH_NEW:
686 case BGP_MSG_ROUTE_REFRESH_OLD:
687 peer->refresh_out++;
688 break;
689 case BGP_MSG_CAPABILITY:
690 peer->dynamic_cap_out++;
691 break;
692 }
693
694 /* OK we send packet so delete it. */
695 bgp_packet_delete (peer);
696
697 if (++count >= BGP_WRITE_PACKET_MAX)
698 break;
699 }
700
701 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000702 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000703
704 return 0;
705}
706
707/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000708static int
paul718e3742002-12-13 20:15:29 +0000709bgp_write_notify (struct peer *peer)
710{
711 int ret;
712 u_char type;
713 struct stream *s;
714
715 /* There should be at least one packet. */
716 s = stream_fifo_head (peer->obuf);
717 if (!s)
718 return 0;
719 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
720
721 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000722 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000723 if (ret <= 0)
724 {
paul200df112005-06-01 11:17:05 +0000725 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000726 peer->status = Idle;
727 bgp_timer_set (peer);
728 return 0;
729 }
730
731 /* Retrieve BGP packet type. */
732 stream_set_getp (s, BGP_MARKER_SIZE + 2);
733 type = stream_getc (s);
734
735 assert (type == BGP_MSG_NOTIFY);
736
737 /* Type should be notify. */
738 peer->notify_out++;
739
740 /* Double start timer. */
741 peer->v_start *= 2;
742
743 /* Overflow check. */
744 if (peer->v_start >= (60 * 2))
745 peer->v_start = (60 * 2);
746
747 /* We don't call event manager at here for avoiding other events. */
748 bgp_stop (peer);
749 peer->status = Idle;
750 bgp_timer_set (peer);
751
752 return 0;
753}
754
755/* Make keepalive packet and send it to the peer. */
756void
757bgp_keepalive_send (struct peer *peer)
758{
759 struct stream *s;
760 int length;
761
762 s = stream_new (BGP_MAX_PACKET_SIZE);
763
764 /* Make keepalive packet. */
765 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
766
767 /* Set packet size. */
768 length = bgp_packet_set_size (s);
769
770 /* Dump packet if debug option is set. */
771 /* bgp_packet_dump (s); */
772
773 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000774 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000775 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000776 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000777 peer->host, BGP_MSG_KEEPALIVE, length);
778
779 /* Add packet to the peer. */
780 bgp_packet_add (peer, s);
781
pauleb821182004-05-01 08:44:08 +0000782 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000783}
784
785/* Make open packet and send it to the peer. */
786void
787bgp_open_send (struct peer *peer)
788{
789 struct stream *s;
790 int length;
791 u_int16_t send_holdtime;
792 as_t local_as;
793
794 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
795 send_holdtime = peer->holdtime;
796 else
797 send_holdtime = peer->bgp->default_holdtime;
798
799 /* local-as Change */
800 if (peer->change_local_as)
801 local_as = peer->change_local_as;
802 else
803 local_as = peer->local_as;
804
805 s = stream_new (BGP_MAX_PACKET_SIZE);
806
807 /* Make open packet. */
808 bgp_packet_set_marker (s, BGP_MSG_OPEN);
809
810 /* Set open packet values. */
811 stream_putc (s, BGP_VERSION_4); /* BGP version */
812 stream_putw (s, local_as); /* My Autonomous System*/
813 stream_putw (s, send_holdtime); /* Hold Time */
814 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
815
816 /* Set capability code. */
817 bgp_open_capability (s, peer);
818
819 /* Set BGP packet length. */
820 length = bgp_packet_set_size (s);
821
822 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000823 zlog_debug ("%s sending OPEN, version %d, my as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000824 peer->host, BGP_VERSION_4, local_as,
825 send_holdtime, inet_ntoa (peer->local_id));
826
827 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000828 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000829 peer->host, BGP_MSG_OPEN, length);
830
831 /* Dump packet if debug option is set. */
832 /* bgp_packet_dump (s); */
833
834 /* Add packet to the peer. */
835 bgp_packet_add (peer, s);
836
pauleb821182004-05-01 08:44:08 +0000837 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000838}
839
840/* Send BGP notify packet with data potion. */
841void
842bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
843 u_char *data, size_t datalen)
844{
845 struct stream *s;
846 int length;
847
848 /* Allocate new stream. */
849 s = stream_new (BGP_MAX_PACKET_SIZE);
850
851 /* Make nitify packet. */
852 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
853
854 /* Set notify packet values. */
855 stream_putc (s, code); /* BGP notify code */
856 stream_putc (s, sub_code); /* BGP notify sub_code */
857
858 /* If notify data is present. */
859 if (data)
860 stream_write (s, data, datalen);
861
862 /* Set BGP packet length. */
863 length = bgp_packet_set_size (s);
864
865 /* Add packet to the peer. */
866 stream_fifo_clean (peer->obuf);
867 bgp_packet_add (peer, s);
868
869 /* For debug */
870 {
871 struct bgp_notify bgp_notify;
872 int first = 0;
873 int i;
874 char c[4];
875
876 bgp_notify.code = code;
877 bgp_notify.subcode = sub_code;
878 bgp_notify.data = NULL;
879 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
880
881 if (bgp_notify.length)
882 {
883 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
884 for (i = 0; i < bgp_notify.length; i++)
885 if (first)
886 {
887 sprintf (c, " %02x", data[i]);
888 strcat (bgp_notify.data, c);
889 }
890 else
891 {
892 first = 1;
893 sprintf (c, "%02x", data[i]);
894 strcpy (bgp_notify.data, c);
895 }
896 }
897 bgp_notify_print (peer, &bgp_notify, "sending");
898 if (bgp_notify.data)
899 XFREE (MTYPE_TMP, bgp_notify.data);
900 }
901
902 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000903 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000904 peer->host, BGP_MSG_NOTIFY, length);
905
hassoe0701b72004-05-20 09:19:34 +0000906 /* peer reset cause */
907 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
908 {
909 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
910 peer->last_reset = PEER_DOWN_USER_RESET;
911 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
912 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
913 else
914 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
915 }
916
paul718e3742002-12-13 20:15:29 +0000917 /* Call imidiately. */
918 BGP_WRITE_OFF (peer->t_write);
919
920 bgp_write_notify (peer);
921}
922
923/* Send BGP notify packet. */
924void
925bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
926{
927 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
928}
929
paul94f2b392005-06-28 12:44:16 +0000930static const char *
paul718e3742002-12-13 20:15:29 +0000931afi2str (afi_t afi)
932{
933 if (afi == AFI_IP)
934 return "AFI_IP";
935 else if (afi == AFI_IP6)
936 return "AFI_IP6";
937 else
938 return "Unknown AFI";
939}
940
paul94f2b392005-06-28 12:44:16 +0000941static const char *
paul718e3742002-12-13 20:15:29 +0000942safi2str (safi_t safi)
943{
944 if (safi == SAFI_UNICAST)
945 return "SAFI_UNICAST";
946 else if (safi == SAFI_MULTICAST)
947 return "SAFI_MULTICAST";
948 else if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPNV4)
949 return "SAFI_MPLS_VPN";
950 else
951 return "Unknown SAFI";
952}
953
954/* Send route refresh message to the peer. */
955void
956bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
957 u_char orf_type, u_char when_to_refresh, int remove)
958{
959 struct stream *s;
960 struct stream *packet;
961 int length;
962 struct bgp_filter *filter;
963 int orf_refresh = 0;
964
965#ifdef DISABLE_BGP_ANNOUNCE
966 return;
967#endif /* DISABLE_BGP_ANNOUNCE */
968
969 filter = &peer->filter[afi][safi];
970
971 /* Adjust safi code. */
972 if (safi == SAFI_MPLS_VPN)
973 safi = BGP_SAFI_VPNV4;
974
975 s = stream_new (BGP_MAX_PACKET_SIZE);
976
977 /* Make BGP update packet. */
978 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
979 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
980 else
981 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
982
983 /* Encode Route Refresh message. */
984 stream_putw (s, afi);
985 stream_putc (s, 0);
986 stream_putc (s, safi);
987
988 if (orf_type == ORF_TYPE_PREFIX
989 || orf_type == ORF_TYPE_PREFIX_OLD)
990 if (remove || filter->plist[FILTER_IN].plist)
991 {
992 u_int16_t orf_len;
993 unsigned long orfp;
994
995 orf_refresh = 1;
996 stream_putc (s, when_to_refresh);
997 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000998 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000999 stream_putw (s, 0);
1000
1001 if (remove)
1002 {
1003 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1004 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1005 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001006 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001007 peer->host, orf_type,
1008 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1009 afi, safi);
1010 }
1011 else
1012 {
1013 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1014 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1015 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1016 ORF_COMMON_PART_DENY);
1017 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001018 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001019 peer->host, orf_type,
1020 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1021 afi, safi);
1022 }
1023
1024 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001025 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001026 stream_putw_at (s, orfp, orf_len);
1027 }
1028
1029 /* Set packet size. */
1030 length = bgp_packet_set_size (s);
1031
1032 if (BGP_DEBUG (normal, NORMAL))
1033 {
1034 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001035 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001036 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001037 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001038 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1039 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1040 }
1041
1042 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001043 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001044 stream_free (s);
1045
1046 /* Add packet to the peer. */
1047 bgp_packet_add (peer, packet);
1048
pauleb821182004-05-01 08:44:08 +00001049 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001050}
1051
1052/* Send capability message to the peer. */
1053void
1054bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1055 int capability_code, int action)
1056{
1057 struct stream *s;
1058 struct stream *packet;
1059 int length;
1060
1061 /* Adjust safi code. */
1062 if (safi == SAFI_MPLS_VPN)
1063 safi = BGP_SAFI_VPNV4;
1064
1065 s = stream_new (BGP_MAX_PACKET_SIZE);
1066
1067 /* Make BGP update packet. */
1068 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1069
1070 /* Encode MP_EXT capability. */
1071 if (capability_code == CAPABILITY_CODE_MP)
1072 {
1073 stream_putc (s, action);
1074 stream_putc (s, CAPABILITY_CODE_MP);
1075 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1076 stream_putw (s, afi);
1077 stream_putc (s, 0);
1078 stream_putc (s, safi);
1079
1080 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001081 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001082 peer->host, action == CAPABILITY_ACTION_SET ?
1083 "Advertising" : "Removing", afi, safi);
1084 }
1085
paul718e3742002-12-13 20:15:29 +00001086 /* Set packet size. */
1087 length = bgp_packet_set_size (s);
1088
1089 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001090 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001091 stream_free (s);
1092
1093 /* Add packet to the peer. */
1094 bgp_packet_add (peer, packet);
1095
1096 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001097 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001098 peer->host, BGP_MSG_CAPABILITY, length);
1099
pauleb821182004-05-01 08:44:08 +00001100 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001101}
1102
1103/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001104static int
pauleb821182004-05-01 08:44:08 +00001105bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001106{
pauleb821182004-05-01 08:44:08 +00001107 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001108 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001109 struct bgp *bgp;
1110
1111 bgp = bgp_get_default ();
1112 if (! bgp)
1113 return 0;
1114
1115 /* Upon receipt of an OPEN message, the local system must examine
1116 all of its connections that are in the OpenConfirm state. A BGP
1117 speaker may also examine connections in an OpenSent state if it
1118 knows the BGP Identifier of the peer by means outside of the
1119 protocol. If among these connections there is a connection to a
1120 remote BGP speaker whose BGP Identifier equals the one in the
1121 OPEN message, then the local system performs the following
1122 collision resolution procedure: */
1123
paul1eb8ef22005-04-07 07:30:20 +00001124 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001125 {
1126 /* Under OpenConfirm status, local peer structure already hold
1127 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001128
1129 if (peer != new
1130 && (peer->status == OpenConfirm || peer->status == OpenSent)
1131 && sockunion_same (&peer->su, &new->su))
1132 {
paul718e3742002-12-13 20:15:29 +00001133 /* 1. The BGP Identifier of the local system is compared to
1134 the BGP Identifier of the remote system (as specified in
1135 the OPEN message). */
1136
1137 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1138 {
1139 /* 2. If the value of the local BGP Identifier is less
1140 than the remote one, the local system closes BGP
1141 connection that already exists (the one that is
1142 already in the OpenConfirm state), and accepts BGP
1143 connection initiated by the remote system. */
1144
pauleb821182004-05-01 08:44:08 +00001145 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001146 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001147 return 1;
1148 }
1149 else
1150 {
1151 /* 3. Otherwise, the local system closes newly created
1152 BGP connection (the one associated with the newly
1153 received OPEN message), and continues to use the
1154 existing one (the one that is already in the
1155 OpenConfirm state). */
1156
pauleb821182004-05-01 08:44:08 +00001157 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001158 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1159 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001160 return -1;
1161 }
pauleb821182004-05-01 08:44:08 +00001162 }
1163 }
paul718e3742002-12-13 20:15:29 +00001164 return 0;
1165}
1166
paul94f2b392005-06-28 12:44:16 +00001167static int
paul718e3742002-12-13 20:15:29 +00001168bgp_open_receive (struct peer *peer, bgp_size_t size)
1169{
1170 int ret;
1171 u_char version;
1172 u_char optlen;
1173 u_int16_t holdtime;
1174 u_int16_t send_holdtime;
1175 as_t remote_as;
1176 struct peer *realpeer;
1177 struct in_addr remote_id;
1178 int capability;
paul5228ad22004-06-04 17:58:18 +00001179 u_int8_t notify_data_remote_as[2];
1180 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001181
1182 realpeer = NULL;
1183
1184 /* Parse open packet. */
1185 version = stream_getc (peer->ibuf);
1186 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1187 remote_as = stream_getw (peer->ibuf);
1188 holdtime = stream_getw (peer->ibuf);
1189 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1190 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1191
1192 /* Receive OPEN message log */
1193 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001194 zlog_debug ("%s rcv OPEN, version %d, remote-as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +00001195 peer->host, version, remote_as, holdtime,
1196 inet_ntoa (remote_id));
1197
1198 /* Lookup peer from Open packet. */
1199 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1200 {
1201 int as = 0;
1202
1203 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1204
1205 if (! realpeer)
1206 {
1207 /* Peer's source IP address is check in bgp_accept(), so this
1208 must be AS number mismatch or remote-id configuration
1209 mismatch. */
1210 if (as)
1211 {
1212 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001213 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1214 peer->host, inet_ntoa (remote_id));
1215 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1216 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1217 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001218 }
1219 else
1220 {
1221 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001222 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
1223 peer->host, remote_as, peer->as);
1224 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1225 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1226 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001227 }
1228 return -1;
1229 }
1230 }
1231
1232 /* When collision is detected and this peer is closed. Retrun
1233 immidiately. */
1234 ret = bgp_collision_detect (peer, remote_id);
1235 if (ret < 0)
1236 return ret;
1237
pauleb821182004-05-01 08:44:08 +00001238 /* Hack part. */
1239 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1240 {
hasso93406d82005-02-02 14:40:33 +00001241 if (realpeer->status == Established
1242 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1243 {
1244 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1245 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1246 }
1247 else if (ret == 0 && realpeer->status != Active
1248 && realpeer->status != OpenSent
1249 && realpeer->status != OpenConfirm)
1250
pauleb821182004-05-01 08:44:08 +00001251 {
1252 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001253 zlog_debug ("%s peer status is %s close connection",
1254 realpeer->host, LOOKUP (bgp_status_msg,
1255 realpeer->status));
1256 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1257 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1258
pauleb821182004-05-01 08:44:08 +00001259 return -1;
1260 }
1261
1262 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00001263 zlog_debug ("%s [Event] Transfer temporary BGP peer to existing one",
pauleb821182004-05-01 08:44:08 +00001264 peer->host);
1265
1266 bgp_stop (realpeer);
1267
1268 /* Transfer file descriptor. */
1269 realpeer->fd = peer->fd;
1270 peer->fd = -1;
1271
1272 /* Transfer input buffer. */
1273 stream_free (realpeer->ibuf);
1274 realpeer->ibuf = peer->ibuf;
1275 realpeer->packet_size = peer->packet_size;
1276 peer->ibuf = NULL;
1277
1278 /* Transfer status. */
1279 realpeer->status = peer->status;
1280 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001281
pauleb821182004-05-01 08:44:08 +00001282 /* peer pointer change. Open packet send to neighbor. */
1283 peer = realpeer;
1284 bgp_open_send (peer);
1285 if (peer->fd < 0)
1286 {
1287 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1288 peer->fd);
1289 return -1;
1290 }
1291 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1292 }
1293
paul718e3742002-12-13 20:15:29 +00001294 /* remote router-id check. */
1295 if (remote_id.s_addr == 0
1296 || ntohl (remote_id.s_addr) >= 0xe0000000
1297 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1298 {
1299 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001300 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001301 peer->host, inet_ntoa (remote_id));
1302 bgp_notify_send_with_data (peer,
1303 BGP_NOTIFY_OPEN_ERR,
1304 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1305 notify_data_remote_id, 4);
1306 return -1;
1307 }
1308
1309 /* Set remote router-id */
1310 peer->remote_id = remote_id;
1311
1312 /* Peer BGP version check. */
1313 if (version != BGP_VERSION_4)
1314 {
paul5228ad22004-06-04 17:58:18 +00001315 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001316 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001317 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001318 peer->host, version, BGP_VERSION_4);
1319 bgp_notify_send_with_data (peer,
1320 BGP_NOTIFY_OPEN_ERR,
1321 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001322 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001323 return -1;
1324 }
1325
1326 /* Check neighbor as number. */
1327 if (remote_as != peer->as)
1328 {
1329 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001330 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
paul718e3742002-12-13 20:15:29 +00001331 peer->host, remote_as, peer->as);
1332 bgp_notify_send_with_data (peer,
1333 BGP_NOTIFY_OPEN_ERR,
1334 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1335 notify_data_remote_as, 2);
1336 return -1;
1337 }
1338
1339 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1340 calculate the value of the Hold Timer by using the smaller of its
1341 configured Hold Time and the Hold Time received in the OPEN message.
1342 The Hold Time MUST be either zero or at least three seconds. An
1343 implementation may reject connections on the basis of the Hold Time. */
1344
1345 if (holdtime < 3 && holdtime != 0)
1346 {
1347 bgp_notify_send (peer,
1348 BGP_NOTIFY_OPEN_ERR,
1349 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1350 return -1;
1351 }
1352
1353 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1354 would be one third of the Hold Time interval. KEEPALIVE messages
1355 MUST NOT be sent more frequently than one per second. An
1356 implementation MAY adjust the rate at which it sends KEEPALIVE
1357 messages as a function of the Hold Time interval. */
1358
1359 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1360 send_holdtime = peer->holdtime;
1361 else
1362 send_holdtime = peer->bgp->default_holdtime;
1363
1364 if (holdtime < send_holdtime)
1365 peer->v_holdtime = holdtime;
1366 else
1367 peer->v_holdtime = send_holdtime;
1368
1369 peer->v_keepalive = peer->v_holdtime / 3;
1370
1371 /* Open option part parse. */
1372 capability = 0;
1373 optlen = stream_getc (peer->ibuf);
1374 if (optlen != 0)
1375 {
1376 ret = bgp_open_option_parse (peer, optlen, &capability);
1377 if (ret < 0)
1378 return ret;
1379
paul9985f832005-02-09 15:51:56 +00001380 stream_forward_getp (peer->ibuf, optlen);
paul718e3742002-12-13 20:15:29 +00001381 }
1382 else
1383 {
1384 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001385 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001386 peer->host);
1387 }
1388
1389 /* Override capability. */
1390 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1391 {
1392 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1393 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1394 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1395 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1396 }
1397
1398 /* Get sockname. */
1399 bgp_getsockname (peer);
1400
1401 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1402
1403 peer->packet_size = 0;
1404 if (peer->ibuf)
1405 stream_reset (peer->ibuf);
1406
1407 return 0;
1408}
1409
1410/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001411static int
paul718e3742002-12-13 20:15:29 +00001412bgp_update_receive (struct peer *peer, bgp_size_t size)
1413{
1414 int ret;
1415 u_char *end;
1416 struct stream *s;
1417 struct attr attr;
1418 bgp_size_t attribute_len;
1419 bgp_size_t update_len;
1420 bgp_size_t withdraw_len;
1421 struct bgp_nlri update;
1422 struct bgp_nlri withdraw;
1423 struct bgp_nlri mp_update;
1424 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001425 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001426
1427 /* Status must be Established. */
1428 if (peer->status != Established)
1429 {
1430 zlog_err ("%s [FSM] Update packet received under status %s",
1431 peer->host, LOOKUP (bgp_status_msg, peer->status));
1432 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1433 return -1;
1434 }
1435
1436 /* Set initial values. */
1437 memset (&attr, 0, sizeof (struct attr));
1438 memset (&update, 0, sizeof (struct bgp_nlri));
1439 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1440 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1441 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1442
1443 s = peer->ibuf;
1444 end = stream_pnt (s) + size;
1445
1446 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1447 Length is too large (i.e., if Unfeasible Routes Length + Total
1448 Attribute Length + 23 exceeds the message Length), then the Error
1449 Subcode is set to Malformed Attribute List. */
1450 if (stream_pnt (s) + 2 > end)
1451 {
1452 zlog_err ("%s [Error] Update packet error"
1453 " (packet length is short for unfeasible length)",
1454 peer->host);
1455 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1456 BGP_NOTIFY_UPDATE_MAL_ATTR);
1457 return -1;
1458 }
1459
1460 /* Unfeasible Route Length. */
1461 withdraw_len = stream_getw (s);
1462
1463 /* Unfeasible Route Length check. */
1464 if (stream_pnt (s) + withdraw_len > end)
1465 {
1466 zlog_err ("%s [Error] Update packet error"
1467 " (packet unfeasible length overflow %d)",
1468 peer->host, withdraw_len);
1469 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1470 BGP_NOTIFY_UPDATE_MAL_ATTR);
1471 return -1;
1472 }
1473
1474 /* Unfeasible Route packet format check. */
1475 if (withdraw_len > 0)
1476 {
1477 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1478 if (ret < 0)
1479 return -1;
1480
1481 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001482 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001483
1484 withdraw.afi = AFI_IP;
1485 withdraw.safi = SAFI_UNICAST;
1486 withdraw.nlri = stream_pnt (s);
1487 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001488 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001489 }
1490
1491 /* Attribute total length check. */
1492 if (stream_pnt (s) + 2 > end)
1493 {
1494 zlog_warn ("%s [Error] Packet Error"
1495 " (update packet is short for attribute length)",
1496 peer->host);
1497 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1498 BGP_NOTIFY_UPDATE_MAL_ATTR);
1499 return -1;
1500 }
1501
1502 /* Fetch attribute total length. */
1503 attribute_len = stream_getw (s);
1504
1505 /* Attribute length check. */
1506 if (stream_pnt (s) + attribute_len > end)
1507 {
1508 zlog_warn ("%s [Error] Packet Error"
1509 " (update packet attribute length overflow %d)",
1510 peer->host, attribute_len);
1511 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1512 BGP_NOTIFY_UPDATE_MAL_ATTR);
1513 return -1;
1514 }
1515
1516 /* Parse attribute when it exists. */
1517 if (attribute_len)
1518 {
1519 ret = bgp_attr_parse (peer, &attr, attribute_len,
1520 &mp_update, &mp_withdraw);
1521 if (ret < 0)
1522 return -1;
1523 }
1524
1525 /* Logging the attribute. */
1526 if (BGP_DEBUG (update, UPDATE_IN))
1527 {
paule01f9cb2004-07-09 17:48:53 +00001528 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1529
1530 if (ret)
ajs6b514742004-12-08 21:03:23 +00001531 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001532 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001533 }
1534
1535 /* Network Layer Reachability Information. */
1536 update_len = end - stream_pnt (s);
1537
1538 if (update_len)
1539 {
1540 /* Check NLRI packet format and prefix length. */
1541 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1542 if (ret < 0)
1543 return -1;
1544
1545 /* Set NLRI portion to structure. */
1546 update.afi = AFI_IP;
1547 update.safi = SAFI_UNICAST;
1548 update.nlri = stream_pnt (s);
1549 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001550 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001551 }
1552
1553 /* NLRI is processed only when the peer is configured specific
1554 Address Family and Subsequent Address Family. */
1555 if (peer->afc[AFI_IP][SAFI_UNICAST])
1556 {
1557 if (withdraw.length)
1558 bgp_nlri_parse (peer, NULL, &withdraw);
1559
1560 if (update.length)
1561 {
1562 /* We check well-known attribute only for IPv4 unicast
1563 update. */
1564 ret = bgp_attr_check (peer, &attr);
1565 if (ret < 0)
1566 return -1;
1567
1568 bgp_nlri_parse (peer, &attr, &update);
1569 }
paule01f9cb2004-07-09 17:48:53 +00001570
hassof4184462005-02-01 20:13:16 +00001571 if (mp_update.length
1572 && mp_update.afi == AFI_IP
1573 && mp_update.safi == SAFI_UNICAST)
1574 bgp_nlri_parse (peer, &attr, &mp_update);
1575
1576 if (mp_withdraw.length
1577 && mp_withdraw.afi == AFI_IP
1578 && mp_withdraw.safi == SAFI_UNICAST)
1579 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1580
paule01f9cb2004-07-09 17:48:53 +00001581 if (! attribute_len && ! withdraw_len)
1582 {
1583 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001584 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1585 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001586
hasso93406d82005-02-02 14:40:33 +00001587 /* NSF delete stale route */
1588 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1589 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1590
1591 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001592 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001593 peer->host);
1594 }
paul718e3742002-12-13 20:15:29 +00001595 }
1596 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1597 {
1598 if (mp_update.length
1599 && mp_update.afi == AFI_IP
1600 && mp_update.safi == SAFI_MULTICAST)
1601 bgp_nlri_parse (peer, &attr, &mp_update);
1602
1603 if (mp_withdraw.length
1604 && mp_withdraw.afi == AFI_IP
1605 && mp_withdraw.safi == SAFI_MULTICAST)
1606 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001607
hasso93406d82005-02-02 14:40:33 +00001608 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001609 && mp_withdraw.afi == AFI_IP
1610 && mp_withdraw.safi == SAFI_MULTICAST
1611 && mp_withdraw.length == 0)
1612 {
1613 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001614 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1615 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001616
hasso93406d82005-02-02 14:40:33 +00001617 /* NSF delete stale route */
1618 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1619 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1620
1621 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001622 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001623 peer->host);
1624 }
paul718e3742002-12-13 20:15:29 +00001625 }
1626 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1627 {
1628 if (mp_update.length
1629 && mp_update.afi == AFI_IP6
1630 && mp_update.safi == SAFI_UNICAST)
1631 bgp_nlri_parse (peer, &attr, &mp_update);
1632
1633 if (mp_withdraw.length
1634 && mp_withdraw.afi == AFI_IP6
1635 && mp_withdraw.safi == SAFI_UNICAST)
1636 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001637
hasso93406d82005-02-02 14:40:33 +00001638 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001639 && mp_withdraw.afi == AFI_IP6
1640 && mp_withdraw.safi == SAFI_UNICAST
1641 && mp_withdraw.length == 0)
1642 {
1643 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001644 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001645
hasso93406d82005-02-02 14:40:33 +00001646 /* NSF delete stale route */
1647 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1648 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1649
1650 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001651 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001652 peer->host);
1653 }
paul718e3742002-12-13 20:15:29 +00001654 }
1655 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1656 {
1657 if (mp_update.length
1658 && mp_update.afi == AFI_IP6
1659 && mp_update.safi == SAFI_MULTICAST)
1660 bgp_nlri_parse (peer, &attr, &mp_update);
1661
1662 if (mp_withdraw.length
1663 && mp_withdraw.afi == AFI_IP6
1664 && mp_withdraw.safi == SAFI_MULTICAST)
1665 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001666
hasso93406d82005-02-02 14:40:33 +00001667 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001668 && mp_withdraw.afi == AFI_IP6
1669 && mp_withdraw.safi == SAFI_MULTICAST
1670 && mp_withdraw.length == 0)
1671 {
1672 /* End-of-RIB received */
1673
hasso93406d82005-02-02 14:40:33 +00001674 /* NSF delete stale route */
1675 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1676 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1677
paule01f9cb2004-07-09 17:48:53 +00001678 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001679 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001680 peer->host);
1681 }
paul718e3742002-12-13 20:15:29 +00001682 }
1683 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1684 {
1685 if (mp_update.length
1686 && mp_update.afi == AFI_IP
1687 && mp_update.safi == BGP_SAFI_VPNV4)
1688 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1689
1690 if (mp_withdraw.length
1691 && mp_withdraw.afi == AFI_IP
1692 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1693 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001694
hasso93406d82005-02-02 14:40:33 +00001695 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001696 && mp_withdraw.afi == AFI_IP
1697 && mp_withdraw.safi == BGP_SAFI_VPNV4
1698 && mp_withdraw.length == 0)
1699 {
1700 /* End-of-RIB received */
1701
1702 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001703 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001704 peer->host);
1705 }
paul718e3742002-12-13 20:15:29 +00001706 }
1707
1708 /* Everything is done. We unintern temporary structures which
1709 interned in bgp_attr_parse(). */
1710 if (attr.aspath)
1711 aspath_unintern (attr.aspath);
1712 if (attr.community)
1713 community_unintern (attr.community);
1714 if (attr.ecommunity)
1715 ecommunity_unintern (attr.ecommunity);
1716 if (attr.cluster)
1717 cluster_unintern (attr.cluster);
1718 if (attr.transit)
1719 transit_unintern (attr.transit);
1720
1721 /* If peering is stopped due to some reason, do not generate BGP
1722 event. */
1723 if (peer->status != Established)
1724 return 0;
1725
1726 /* Increment packet counter. */
1727 peer->update_in++;
1728 peer->update_time = time (NULL);
1729
1730 /* Generate BGP event. */
1731 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1732
1733 return 0;
1734}
1735
1736/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001737static void
paul718e3742002-12-13 20:15:29 +00001738bgp_notify_receive (struct peer *peer, bgp_size_t size)
1739{
1740 struct bgp_notify bgp_notify;
1741
1742 if (peer->notify.data)
1743 {
1744 XFREE (MTYPE_TMP, peer->notify.data);
1745 peer->notify.data = NULL;
1746 peer->notify.length = 0;
1747 }
1748
1749 bgp_notify.code = stream_getc (peer->ibuf);
1750 bgp_notify.subcode = stream_getc (peer->ibuf);
1751 bgp_notify.length = size - 2;
1752 bgp_notify.data = NULL;
1753
1754 /* Preserv notify code and sub code. */
1755 peer->notify.code = bgp_notify.code;
1756 peer->notify.subcode = bgp_notify.subcode;
1757 /* For further diagnostic record returned Data. */
1758 if (bgp_notify.length)
1759 {
1760 peer->notify.length = size - 2;
1761 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1762 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1763 }
1764
1765 /* For debug */
1766 {
1767 int i;
1768 int first = 0;
1769 char c[4];
1770
1771 if (bgp_notify.length)
1772 {
1773 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1774 for (i = 0; i < bgp_notify.length; i++)
1775 if (first)
1776 {
1777 sprintf (c, " %02x", stream_getc (peer->ibuf));
1778 strcat (bgp_notify.data, c);
1779 }
1780 else
1781 {
1782 first = 1;
1783 sprintf (c, "%02x", stream_getc (peer->ibuf));
1784 strcpy (bgp_notify.data, c);
1785 }
1786 }
1787
1788 bgp_notify_print(peer, &bgp_notify, "received");
1789 if (bgp_notify.data)
1790 XFREE (MTYPE_TMP, bgp_notify.data);
1791 }
1792
1793 /* peer count update */
1794 peer->notify_in++;
1795
hassoe0701b72004-05-20 09:19:34 +00001796 if (peer->status == Established)
1797 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1798
paul718e3742002-12-13 20:15:29 +00001799 /* We have to check for Notify with Unsupported Optional Parameter.
1800 in that case we fallback to open without the capability option.
1801 But this done in bgp_stop. We just mark it here to avoid changing
1802 the fsm tables. */
1803 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1804 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1805 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1806
1807 /* Also apply to Unsupported Capability until remote router support
1808 capability. */
1809 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1810 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
1811 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1812
1813 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1814}
1815
1816/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001817static void
paul718e3742002-12-13 20:15:29 +00001818bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1819{
1820 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001821 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001822
1823 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1824}
1825
1826/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001827static void
paul718e3742002-12-13 20:15:29 +00001828bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1829{
1830 afi_t afi;
1831 safi_t safi;
1832 u_char reserved;
1833 struct stream *s;
1834
1835 /* If peer does not have the capability, send notification. */
1836 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1837 {
1838 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1839 peer->host);
1840 bgp_notify_send (peer,
1841 BGP_NOTIFY_HEADER_ERR,
1842 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1843 return;
1844 }
1845
1846 /* Status must be Established. */
1847 if (peer->status != Established)
1848 {
1849 plog_err (peer->log,
1850 "%s [Error] Route refresh packet received under status %s",
1851 peer->host, LOOKUP (bgp_status_msg, peer->status));
1852 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1853 return;
1854 }
1855
1856 s = peer->ibuf;
1857
1858 /* Parse packet. */
1859 afi = stream_getw (s);
1860 reserved = stream_getc (s);
1861 safi = stream_getc (s);
1862
1863 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001864 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001865 peer->host, afi, safi);
1866
1867 /* Check AFI and SAFI. */
1868 if ((afi != AFI_IP && afi != AFI_IP6)
1869 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1870 && safi != BGP_SAFI_VPNV4))
1871 {
1872 if (BGP_DEBUG (normal, NORMAL))
1873 {
ajs6b514742004-12-08 21:03:23 +00001874 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001875 peer->host, afi, safi);
1876 }
1877 return;
1878 }
1879
1880 /* Adjust safi code. */
1881 if (safi == BGP_SAFI_VPNV4)
1882 safi = SAFI_MPLS_VPN;
1883
1884 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1885 {
1886 u_char *end;
1887 u_char when_to_refresh;
1888 u_char orf_type;
1889 u_int16_t orf_len;
1890
1891 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1892 {
1893 zlog_info ("%s ORF route refresh length error", peer->host);
1894 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1895 return;
1896 }
1897
1898 when_to_refresh = stream_getc (s);
1899 end = stream_pnt (s) + (size - 5);
1900
1901 while (stream_pnt (s) < end)
1902 {
1903 orf_type = stream_getc (s);
1904 orf_len = stream_getw (s);
1905
1906 if (orf_type == ORF_TYPE_PREFIX
1907 || orf_type == ORF_TYPE_PREFIX_OLD)
1908 {
1909 u_char *p_pnt = stream_pnt (s);
1910 u_char *p_end = stream_pnt (s) + orf_len;
1911 struct orf_prefix orfp;
1912 u_char common = 0;
1913 u_int32_t seq;
1914 int psize;
1915 char name[BUFSIZ];
1916 char buf[BUFSIZ];
1917 int ret;
1918
1919 if (BGP_DEBUG (normal, NORMAL))
1920 {
ajs6b514742004-12-08 21:03:23 +00001921 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00001922 peer->host, orf_type, orf_len);
1923 }
1924
1925 /* ORF prefix-list name */
1926 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
1927
1928 while (p_pnt < p_end)
1929 {
1930 memset (&orfp, 0, sizeof (struct orf_prefix));
1931 common = *p_pnt++;
1932 if (common & ORF_COMMON_PART_REMOVE_ALL)
1933 {
1934 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001935 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00001936 prefix_bgp_orf_remove_all (name);
1937 break;
1938 }
1939 memcpy (&seq, p_pnt, sizeof (u_int32_t));
1940 p_pnt += sizeof (u_int32_t);
1941 orfp.seq = ntohl (seq);
1942 orfp.ge = *p_pnt++;
1943 orfp.le = *p_pnt++;
1944 orfp.p.prefixlen = *p_pnt++;
1945 orfp.p.family = afi2family (afi);
1946 psize = PSIZE (orfp.p.prefixlen);
1947 memcpy (&orfp.p.u.prefix, p_pnt, psize);
1948 p_pnt += psize;
1949
1950 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001951 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
paul718e3742002-12-13 20:15:29 +00001952 peer->host,
1953 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
1954 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
1955 orfp.seq,
1956 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
1957 orfp.p.prefixlen, orfp.ge, orfp.le);
1958
1959 ret = prefix_bgp_orf_set (name, afi, &orfp,
1960 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
1961 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
1962
1963 if (ret != CMD_SUCCESS)
1964 {
1965 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001966 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00001967 prefix_bgp_orf_remove_all (name);
1968 break;
1969 }
1970 }
1971 peer->orf_plist[afi][safi] =
1972 prefix_list_lookup (AFI_ORF_PREFIX, name);
1973 }
paul9985f832005-02-09 15:51:56 +00001974 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00001975 }
1976 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001977 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00001978 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
1979 if (when_to_refresh == REFRESH_DEFER)
1980 return;
1981 }
1982
1983 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1984 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
1985 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
1986
1987 /* Perform route refreshment to the peer */
1988 bgp_announce_route (peer, afi, safi);
1989}
1990
paul94f2b392005-06-28 12:44:16 +00001991static int
paul718e3742002-12-13 20:15:29 +00001992bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
1993{
1994 u_char *end;
1995 struct capability cap;
1996 u_char action;
1997 struct bgp *bgp;
1998 afi_t afi;
1999 safi_t safi;
2000
2001 bgp = peer->bgp;
2002 end = pnt + length;
2003
2004 while (pnt < end)
2005 {
2006 /* We need at least action, capability code and capability length. */
2007 if (pnt + 3 > end)
2008 {
2009 zlog_info ("%s Capability length error", peer->host);
2010 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2011 return -1;
2012 }
2013
2014 action = *pnt;
2015
2016 /* Fetch structure to the byte stream. */
2017 memcpy (&cap, pnt + 1, sizeof (struct capability));
2018
2019 /* Action value check. */
2020 if (action != CAPABILITY_ACTION_SET
2021 && action != CAPABILITY_ACTION_UNSET)
2022 {
2023 zlog_info ("%s Capability Action Value error %d",
2024 peer->host, action);
2025 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2026 return -1;
2027 }
2028
2029 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002030 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
paul718e3742002-12-13 20:15:29 +00002031 peer->host, action, cap.code, cap.length);
2032
2033 /* Capability length check. */
2034 if (pnt + (cap.length + 3) > end)
2035 {
2036 zlog_info ("%s Capability length error", peer->host);
2037 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2038 return -1;
2039 }
2040
2041 /* We know MP Capability Code. */
2042 if (cap.code == CAPABILITY_CODE_MP)
2043 {
2044 afi = ntohs (cap.mpc.afi);
2045 safi = cap.mpc.safi;
2046
2047 /* Ignore capability when override-capability is set. */
2048 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2049 continue;
2050
2051 /* Address family check. */
2052 if ((afi == AFI_IP
2053 || afi == AFI_IP6)
2054 && (safi == SAFI_UNICAST
2055 || safi == SAFI_MULTICAST
2056 || safi == BGP_SAFI_VPNV4))
2057 {
2058 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002059 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
paul718e3742002-12-13 20:15:29 +00002060 peer->host,
2061 action == CAPABILITY_ACTION_SET
2062 ? "Advertising" : "Removing",
2063 ntohs(cap.mpc.afi) , cap.mpc.safi);
2064
2065 /* Adjust safi code. */
2066 if (safi == BGP_SAFI_VPNV4)
2067 safi = SAFI_MPLS_VPN;
2068
2069 if (action == CAPABILITY_ACTION_SET)
2070 {
2071 peer->afc_recv[afi][safi] = 1;
2072 if (peer->afc[afi][safi])
2073 {
2074 peer->afc_nego[afi][safi] = 1;
2075 bgp_announce_route (peer, afi, safi);
2076 }
2077 }
2078 else
2079 {
2080 peer->afc_recv[afi][safi] = 0;
2081 peer->afc_nego[afi][safi] = 0;
2082
2083 if (peer_active_nego (peer))
2084 bgp_clear_route (peer, afi, safi);
2085 else
2086 BGP_EVENT_ADD (peer, BGP_Stop);
2087 }
2088 }
2089 }
paul718e3742002-12-13 20:15:29 +00002090 else
2091 {
2092 zlog_warn ("%s unrecognized capability code: %d - ignored",
2093 peer->host, cap.code);
2094 }
2095 pnt += cap.length + 3;
2096 }
2097 return 0;
2098}
2099
2100/* Dynamic Capability is received. */
paul94f2b392005-06-28 12:44:16 +00002101static void
paul718e3742002-12-13 20:15:29 +00002102bgp_capability_receive (struct peer *peer, bgp_size_t size)
2103{
2104 u_char *pnt;
2105 int ret;
2106
2107 /* Fetch pointer. */
2108 pnt = stream_pnt (peer->ibuf);
2109
2110 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002111 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002112
2113 /* If peer does not have the capability, send notification. */
2114 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2115 {
2116 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2117 peer->host);
2118 bgp_notify_send (peer,
2119 BGP_NOTIFY_HEADER_ERR,
2120 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2121 return;
2122 }
2123
2124 /* Status must be Established. */
2125 if (peer->status != Established)
2126 {
2127 plog_err (peer->log,
2128 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2129 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2130 return;
2131 }
2132
2133 /* Parse packet. */
2134 ret = bgp_capability_msg_parse (peer, pnt, size);
2135}
2136
2137/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002138static int
paul718e3742002-12-13 20:15:29 +00002139bgp_read_packet (struct peer *peer)
2140{
2141 int nbytes;
2142 int readsize;
2143
paul9985f832005-02-09 15:51:56 +00002144 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002145
2146 /* If size is zero then return. */
2147 if (! readsize)
2148 return 0;
2149
2150 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002151 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002152
2153 /* If read byte is smaller than zero then error occured. */
2154 if (nbytes < 0)
2155 {
2156 if (errno == EAGAIN)
2157 return -1;
2158
2159 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002160 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002161
2162 if (peer->status == Established)
2163 {
2164 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2165 {
2166 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2167 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2168 }
2169 else
2170 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2171 }
2172
paul718e3742002-12-13 20:15:29 +00002173 BGP_EVENT_ADD (peer, TCP_fatal_error);
2174 return -1;
2175 }
2176
2177 /* When read byte is zero : clear bgp peer and return */
2178 if (nbytes == 0)
2179 {
2180 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002181 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002182 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002183
2184 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002185 {
2186 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2187 {
2188 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2189 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2190 }
2191 else
2192 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2193 }
hassoe0701b72004-05-20 09:19:34 +00002194
paul718e3742002-12-13 20:15:29 +00002195 BGP_EVENT_ADD (peer, TCP_connection_closed);
2196 return -1;
2197 }
2198
2199 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002200 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002201 return -1;
2202
2203 return 0;
2204}
2205
2206/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002207static int
paul718e3742002-12-13 20:15:29 +00002208bgp_marker_all_one (struct stream *s, int length)
2209{
2210 int i;
2211
2212 for (i = 0; i < length; i++)
2213 if (s->data[i] != 0xff)
2214 return 0;
2215
2216 return 1;
2217}
2218
2219/* Starting point of packet process function. */
2220int
2221bgp_read (struct thread *thread)
2222{
2223 int ret;
2224 u_char type = 0;
2225 struct peer *peer;
2226 bgp_size_t size;
2227 char notify_data_length[2];
2228
2229 /* Yes first of all get peer pointer. */
2230 peer = THREAD_ARG (thread);
2231 peer->t_read = NULL;
2232
2233 /* For non-blocking IO check. */
2234 if (peer->status == Connect)
2235 {
2236 bgp_connect_check (peer);
2237 goto done;
2238 }
2239 else
2240 {
pauleb821182004-05-01 08:44:08 +00002241 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002242 {
pauleb821182004-05-01 08:44:08 +00002243 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002244 return -1;
2245 }
pauleb821182004-05-01 08:44:08 +00002246 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002247 }
2248
2249 /* Read packet header to determine type of the packet */
2250 if (peer->packet_size == 0)
2251 peer->packet_size = BGP_HEADER_SIZE;
2252
paul9985f832005-02-09 15:51:56 +00002253 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002254 {
2255 ret = bgp_read_packet (peer);
2256
2257 /* Header read error or partial read packet. */
2258 if (ret < 0)
2259 goto done;
2260
2261 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002262 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002263 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2264 size = stream_getw (peer->ibuf);
2265 type = stream_getc (peer->ibuf);
2266
2267 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002268 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002269 peer->host, type, size - BGP_HEADER_SIZE);
2270
2271 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002272 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002273 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2274 {
2275 bgp_notify_send (peer,
2276 BGP_NOTIFY_HEADER_ERR,
2277 BGP_NOTIFY_HEADER_NOT_SYNC);
2278 goto done;
2279 }
2280
2281 /* BGP type check. */
2282 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2283 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2284 && type != BGP_MSG_ROUTE_REFRESH_NEW
2285 && type != BGP_MSG_ROUTE_REFRESH_OLD
2286 && type != BGP_MSG_CAPABILITY)
2287 {
2288 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002289 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002290 "%s unknown message type 0x%02x",
2291 peer->host, type);
2292 bgp_notify_send_with_data (peer,
2293 BGP_NOTIFY_HEADER_ERR,
2294 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2295 &type, 1);
2296 goto done;
2297 }
2298 /* Mimimum packet length check. */
2299 if ((size < BGP_HEADER_SIZE)
2300 || (size > BGP_MAX_PACKET_SIZE)
2301 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2302 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2303 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2304 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2305 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2306 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2307 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2308 {
2309 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002310 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002311 "%s bad message length - %d for %s",
2312 peer->host, size,
2313 type == 128 ? "ROUTE-REFRESH" :
2314 bgp_type_str[(int) type]);
2315 bgp_notify_send_with_data (peer,
2316 BGP_NOTIFY_HEADER_ERR,
2317 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002318 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002319 goto done;
2320 }
2321
2322 /* Adjust size to message length. */
2323 peer->packet_size = size;
2324 }
2325
2326 ret = bgp_read_packet (peer);
2327 if (ret < 0)
2328 goto done;
2329
2330 /* Get size and type again. */
2331 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2332 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2333
2334 /* BGP packet dump function. */
2335 bgp_dump_packet (peer, type, peer->ibuf);
2336
2337 size = (peer->packet_size - BGP_HEADER_SIZE);
2338
2339 /* Read rest of the packet and call each sort of packet routine */
2340 switch (type)
2341 {
2342 case BGP_MSG_OPEN:
2343 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002344 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002345 break;
2346 case BGP_MSG_UPDATE:
2347 peer->readtime = time(NULL); /* Last read timer reset */
2348 bgp_update_receive (peer, size);
2349 break;
2350 case BGP_MSG_NOTIFY:
2351 bgp_notify_receive (peer, size);
2352 break;
2353 case BGP_MSG_KEEPALIVE:
2354 peer->readtime = time(NULL); /* Last read timer reset */
2355 bgp_keepalive_receive (peer, size);
2356 break;
2357 case BGP_MSG_ROUTE_REFRESH_NEW:
2358 case BGP_MSG_ROUTE_REFRESH_OLD:
2359 peer->refresh_in++;
2360 bgp_route_refresh_receive (peer, size);
2361 break;
2362 case BGP_MSG_CAPABILITY:
2363 peer->dynamic_cap_in++;
2364 bgp_capability_receive (peer, size);
2365 break;
2366 }
2367
2368 /* Clear input buffer. */
2369 peer->packet_size = 0;
2370 if (peer->ibuf)
2371 stream_reset (peer->ibuf);
2372
2373 done:
2374 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2375 {
2376 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002377 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002378 peer_delete (peer);
paul200df112005-06-01 11:17:05 +00002379 /* we've lost track of a reference to ACCEPT_PEER somehow. It doesnt
2380 * _seem_ to be the 'update realpeer with accept peer' hack, yet it
2381 * *must* be.. Very very odd, but I give up trying to
2382 * root cause this - ACCEPT_PEER is a dirty hack, it should be fixed
2383 * instead, which would make root-causing this a moot point..
2384 * A hack because of a hack, appropriate.
2385 */
2386 peer_unlock (peer); /* god knows what reference... ACCEPT_PEER sucks */
paul718e3742002-12-13 20:15:29 +00002387 }
2388 return 0;
2389}