blob: cf6d00f1ae1692295f3a65af20c204d49b0b174c [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
Paul Jakmadcdf3992006-10-15 23:39:59 +0000640 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000641 return 0;
642 }
643 if (num != writenum)
644 {
paul9985f832005-02-09 15:51:56 +0000645 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000646
647 if (write_errno == EAGAIN)
648 break;
649
650 continue;
651 }
652
653 /* Retrieve BGP packet type. */
654 stream_set_getp (s, BGP_MARKER_SIZE + 2);
655 type = stream_getc (s);
656
657 switch (type)
658 {
659 case BGP_MSG_OPEN:
660 peer->open_out++;
661 break;
662 case BGP_MSG_UPDATE:
663 peer->update_out++;
664 break;
665 case BGP_MSG_NOTIFY:
666 peer->notify_out++;
667 /* Double start timer. */
668 peer->v_start *= 2;
669
670 /* Overflow check. */
671 if (peer->v_start >= (60 * 2))
672 peer->v_start = (60 * 2);
673
Paul Jakmaca058a32006-09-14 02:58:49 +0000674 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000675 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000676 return 0;
paul718e3742002-12-13 20:15:29 +0000677 case BGP_MSG_KEEPALIVE:
678 peer->keepalive_out++;
679 break;
680 case BGP_MSG_ROUTE_REFRESH_NEW:
681 case BGP_MSG_ROUTE_REFRESH_OLD:
682 peer->refresh_out++;
683 break;
684 case BGP_MSG_CAPABILITY:
685 peer->dynamic_cap_out++;
686 break;
687 }
688
689 /* OK we send packet so delete it. */
690 bgp_packet_delete (peer);
691
692 if (++count >= BGP_WRITE_PACKET_MAX)
693 break;
694 }
695
696 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000697 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000698
699 return 0;
700}
701
702/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000703static int
paul718e3742002-12-13 20:15:29 +0000704bgp_write_notify (struct peer *peer)
705{
706 int ret;
707 u_char type;
708 struct stream *s;
709
710 /* There should be at least one packet. */
711 s = stream_fifo_head (peer->obuf);
712 if (!s)
713 return 0;
714 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
715
716 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000717 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000718 if (ret <= 0)
719 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000720 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000721 return 0;
722 }
723
724 /* Retrieve BGP packet type. */
725 stream_set_getp (s, BGP_MARKER_SIZE + 2);
726 type = stream_getc (s);
727
728 assert (type == BGP_MSG_NOTIFY);
729
730 /* Type should be notify. */
731 peer->notify_out++;
732
733 /* Double start timer. */
734 peer->v_start *= 2;
735
736 /* Overflow check. */
737 if (peer->v_start >= (60 * 2))
738 peer->v_start = (60 * 2);
739
Paul Jakmadcdf3992006-10-15 23:39:59 +0000740 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000741
742 return 0;
743}
744
745/* Make keepalive packet and send it to the peer. */
746void
747bgp_keepalive_send (struct peer *peer)
748{
749 struct stream *s;
750 int length;
751
752 s = stream_new (BGP_MAX_PACKET_SIZE);
753
754 /* Make keepalive packet. */
755 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
756
757 /* Set packet size. */
758 length = bgp_packet_set_size (s);
759
760 /* Dump packet if debug option is set. */
761 /* bgp_packet_dump (s); */
762
763 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000764 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000765 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000766 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000767 peer->host, BGP_MSG_KEEPALIVE, length);
768
769 /* Add packet to the peer. */
770 bgp_packet_add (peer, s);
771
pauleb821182004-05-01 08:44:08 +0000772 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000773}
774
775/* Make open packet and send it to the peer. */
776void
777bgp_open_send (struct peer *peer)
778{
779 struct stream *s;
780 int length;
781 u_int16_t send_holdtime;
782 as_t local_as;
783
784 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
785 send_holdtime = peer->holdtime;
786 else
787 send_holdtime = peer->bgp->default_holdtime;
788
789 /* local-as Change */
790 if (peer->change_local_as)
791 local_as = peer->change_local_as;
792 else
793 local_as = peer->local_as;
794
795 s = stream_new (BGP_MAX_PACKET_SIZE);
796
797 /* Make open packet. */
798 bgp_packet_set_marker (s, BGP_MSG_OPEN);
799
800 /* Set open packet values. */
801 stream_putc (s, BGP_VERSION_4); /* BGP version */
802 stream_putw (s, local_as); /* My Autonomous System*/
803 stream_putw (s, send_holdtime); /* Hold Time */
804 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
805
806 /* Set capability code. */
807 bgp_open_capability (s, peer);
808
809 /* Set BGP packet length. */
810 length = bgp_packet_set_size (s);
811
812 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000813 zlog_debug ("%s sending OPEN, version %d, my as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000814 peer->host, BGP_VERSION_4, local_as,
815 send_holdtime, inet_ntoa (peer->local_id));
816
817 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000818 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000819 peer->host, BGP_MSG_OPEN, length);
820
821 /* Dump packet if debug option is set. */
822 /* bgp_packet_dump (s); */
823
824 /* Add packet to the peer. */
825 bgp_packet_add (peer, s);
826
pauleb821182004-05-01 08:44:08 +0000827 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000828}
829
830/* Send BGP notify packet with data potion. */
831void
832bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
833 u_char *data, size_t datalen)
834{
835 struct stream *s;
836 int length;
837
838 /* Allocate new stream. */
839 s = stream_new (BGP_MAX_PACKET_SIZE);
840
841 /* Make nitify packet. */
842 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
843
844 /* Set notify packet values. */
845 stream_putc (s, code); /* BGP notify code */
846 stream_putc (s, sub_code); /* BGP notify sub_code */
847
848 /* If notify data is present. */
849 if (data)
850 stream_write (s, data, datalen);
851
852 /* Set BGP packet length. */
853 length = bgp_packet_set_size (s);
854
855 /* Add packet to the peer. */
856 stream_fifo_clean (peer->obuf);
857 bgp_packet_add (peer, s);
858
859 /* For debug */
860 {
861 struct bgp_notify bgp_notify;
862 int first = 0;
863 int i;
864 char c[4];
865
866 bgp_notify.code = code;
867 bgp_notify.subcode = sub_code;
868 bgp_notify.data = NULL;
869 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
870
871 if (bgp_notify.length)
872 {
873 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
874 for (i = 0; i < bgp_notify.length; i++)
875 if (first)
876 {
877 sprintf (c, " %02x", data[i]);
878 strcat (bgp_notify.data, c);
879 }
880 else
881 {
882 first = 1;
883 sprintf (c, "%02x", data[i]);
884 strcpy (bgp_notify.data, c);
885 }
886 }
887 bgp_notify_print (peer, &bgp_notify, "sending");
888 if (bgp_notify.data)
889 XFREE (MTYPE_TMP, bgp_notify.data);
890 }
891
892 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000893 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000894 peer->host, BGP_MSG_NOTIFY, length);
895
hassoe0701b72004-05-20 09:19:34 +0000896 /* peer reset cause */
897 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
898 {
899 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
900 peer->last_reset = PEER_DOWN_USER_RESET;
901 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
902 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
903 else
904 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
905 }
906
paul718e3742002-12-13 20:15:29 +0000907 /* Call imidiately. */
908 BGP_WRITE_OFF (peer->t_write);
909
910 bgp_write_notify (peer);
911}
912
913/* Send BGP notify packet. */
914void
915bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
916{
917 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
918}
919
paul94f2b392005-06-28 12:44:16 +0000920static const char *
paul718e3742002-12-13 20:15:29 +0000921afi2str (afi_t afi)
922{
923 if (afi == AFI_IP)
924 return "AFI_IP";
925 else if (afi == AFI_IP6)
926 return "AFI_IP6";
927 else
928 return "Unknown AFI";
929}
930
paul94f2b392005-06-28 12:44:16 +0000931static const char *
paul718e3742002-12-13 20:15:29 +0000932safi2str (safi_t safi)
933{
934 if (safi == SAFI_UNICAST)
935 return "SAFI_UNICAST";
936 else if (safi == SAFI_MULTICAST)
937 return "SAFI_MULTICAST";
938 else if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPNV4)
939 return "SAFI_MPLS_VPN";
940 else
941 return "Unknown SAFI";
942}
943
944/* Send route refresh message to the peer. */
945void
946bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
947 u_char orf_type, u_char when_to_refresh, int remove)
948{
949 struct stream *s;
950 struct stream *packet;
951 int length;
952 struct bgp_filter *filter;
953 int orf_refresh = 0;
954
955#ifdef DISABLE_BGP_ANNOUNCE
956 return;
957#endif /* DISABLE_BGP_ANNOUNCE */
958
959 filter = &peer->filter[afi][safi];
960
961 /* Adjust safi code. */
962 if (safi == SAFI_MPLS_VPN)
963 safi = BGP_SAFI_VPNV4;
964
965 s = stream_new (BGP_MAX_PACKET_SIZE);
966
967 /* Make BGP update packet. */
968 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
969 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
970 else
971 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
972
973 /* Encode Route Refresh message. */
974 stream_putw (s, afi);
975 stream_putc (s, 0);
976 stream_putc (s, safi);
977
978 if (orf_type == ORF_TYPE_PREFIX
979 || orf_type == ORF_TYPE_PREFIX_OLD)
980 if (remove || filter->plist[FILTER_IN].plist)
981 {
982 u_int16_t orf_len;
983 unsigned long orfp;
984
985 orf_refresh = 1;
986 stream_putc (s, when_to_refresh);
987 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000988 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000989 stream_putw (s, 0);
990
991 if (remove)
992 {
993 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
994 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
995 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000996 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000997 peer->host, orf_type,
998 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
999 afi, safi);
1000 }
1001 else
1002 {
1003 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1004 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1005 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1006 ORF_COMMON_PART_DENY);
1007 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001008 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001009 peer->host, orf_type,
1010 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1011 afi, safi);
1012 }
1013
1014 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001015 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001016 stream_putw_at (s, orfp, orf_len);
1017 }
1018
1019 /* Set packet size. */
1020 length = bgp_packet_set_size (s);
1021
1022 if (BGP_DEBUG (normal, NORMAL))
1023 {
1024 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001025 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001026 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001027 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001028 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1029 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1030 }
1031
1032 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001033 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001034 stream_free (s);
1035
1036 /* Add packet to the peer. */
1037 bgp_packet_add (peer, packet);
1038
pauleb821182004-05-01 08:44:08 +00001039 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001040}
1041
1042/* Send capability message to the peer. */
1043void
1044bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1045 int capability_code, int action)
1046{
1047 struct stream *s;
1048 struct stream *packet;
1049 int length;
1050
1051 /* Adjust safi code. */
1052 if (safi == SAFI_MPLS_VPN)
1053 safi = BGP_SAFI_VPNV4;
1054
1055 s = stream_new (BGP_MAX_PACKET_SIZE);
1056
1057 /* Make BGP update packet. */
1058 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1059
1060 /* Encode MP_EXT capability. */
1061 if (capability_code == CAPABILITY_CODE_MP)
1062 {
1063 stream_putc (s, action);
1064 stream_putc (s, CAPABILITY_CODE_MP);
1065 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1066 stream_putw (s, afi);
1067 stream_putc (s, 0);
1068 stream_putc (s, safi);
1069
1070 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001071 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001072 peer->host, action == CAPABILITY_ACTION_SET ?
1073 "Advertising" : "Removing", afi, safi);
1074 }
1075
paul718e3742002-12-13 20:15:29 +00001076 /* Set packet size. */
1077 length = bgp_packet_set_size (s);
1078
1079 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001080 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001081 stream_free (s);
1082
1083 /* Add packet to the peer. */
1084 bgp_packet_add (peer, packet);
1085
1086 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001087 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001088 peer->host, BGP_MSG_CAPABILITY, length);
1089
pauleb821182004-05-01 08:44:08 +00001090 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001091}
1092
1093/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001094static int
pauleb821182004-05-01 08:44:08 +00001095bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001096{
pauleb821182004-05-01 08:44:08 +00001097 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001098 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001099 struct bgp *bgp;
1100
1101 bgp = bgp_get_default ();
1102 if (! bgp)
1103 return 0;
1104
1105 /* Upon receipt of an OPEN message, the local system must examine
1106 all of its connections that are in the OpenConfirm state. A BGP
1107 speaker may also examine connections in an OpenSent state if it
1108 knows the BGP Identifier of the peer by means outside of the
1109 protocol. If among these connections there is a connection to a
1110 remote BGP speaker whose BGP Identifier equals the one in the
1111 OPEN message, then the local system performs the following
1112 collision resolution procedure: */
1113
paul1eb8ef22005-04-07 07:30:20 +00001114 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001115 {
1116 /* Under OpenConfirm status, local peer structure already hold
1117 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001118
1119 if (peer != new
1120 && (peer->status == OpenConfirm || peer->status == OpenSent)
1121 && sockunion_same (&peer->su, &new->su))
1122 {
paul718e3742002-12-13 20:15:29 +00001123 /* 1. The BGP Identifier of the local system is compared to
1124 the BGP Identifier of the remote system (as specified in
1125 the OPEN message). */
1126
1127 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1128 {
1129 /* 2. If the value of the local BGP Identifier is less
1130 than the remote one, the local system closes BGP
1131 connection that already exists (the one that is
1132 already in the OpenConfirm state), and accepts BGP
1133 connection initiated by the remote system. */
1134
pauleb821182004-05-01 08:44:08 +00001135 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001136 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001137 return 1;
1138 }
1139 else
1140 {
1141 /* 3. Otherwise, the local system closes newly created
1142 BGP connection (the one associated with the newly
1143 received OPEN message), and continues to use the
1144 existing one (the one that is already in the
1145 OpenConfirm state). */
1146
pauleb821182004-05-01 08:44:08 +00001147 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001148 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1149 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001150 return -1;
1151 }
pauleb821182004-05-01 08:44:08 +00001152 }
1153 }
paul718e3742002-12-13 20:15:29 +00001154 return 0;
1155}
1156
paul94f2b392005-06-28 12:44:16 +00001157static int
paul718e3742002-12-13 20:15:29 +00001158bgp_open_receive (struct peer *peer, bgp_size_t size)
1159{
1160 int ret;
1161 u_char version;
1162 u_char optlen;
1163 u_int16_t holdtime;
1164 u_int16_t send_holdtime;
1165 as_t remote_as;
1166 struct peer *realpeer;
1167 struct in_addr remote_id;
1168 int capability;
paul5228ad22004-06-04 17:58:18 +00001169 u_int8_t notify_data_remote_as[2];
1170 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001171
1172 realpeer = NULL;
1173
1174 /* Parse open packet. */
1175 version = stream_getc (peer->ibuf);
1176 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1177 remote_as = stream_getw (peer->ibuf);
1178 holdtime = stream_getw (peer->ibuf);
1179 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1180 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1181
1182 /* Receive OPEN message log */
1183 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001184 zlog_debug ("%s rcv OPEN, version %d, remote-as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +00001185 peer->host, version, remote_as, holdtime,
1186 inet_ntoa (remote_id));
1187
1188 /* Lookup peer from Open packet. */
1189 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1190 {
1191 int as = 0;
1192
1193 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1194
1195 if (! realpeer)
1196 {
1197 /* Peer's source IP address is check in bgp_accept(), so this
1198 must be AS number mismatch or remote-id configuration
1199 mismatch. */
1200 if (as)
1201 {
1202 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001203 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1204 peer->host, inet_ntoa (remote_id));
1205 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1206 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1207 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001208 }
1209 else
1210 {
1211 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001212 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
1213 peer->host, remote_as, peer->as);
1214 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1215 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1216 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001217 }
1218 return -1;
1219 }
1220 }
1221
1222 /* When collision is detected and this peer is closed. Retrun
1223 immidiately. */
1224 ret = bgp_collision_detect (peer, remote_id);
1225 if (ret < 0)
1226 return ret;
1227
pauleb821182004-05-01 08:44:08 +00001228 /* Hack part. */
1229 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1230 {
hasso93406d82005-02-02 14:40:33 +00001231 if (realpeer->status == Established
1232 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1233 {
1234 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1235 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1236 }
1237 else if (ret == 0 && realpeer->status != Active
1238 && realpeer->status != OpenSent
1239 && realpeer->status != OpenConfirm)
1240
pauleb821182004-05-01 08:44:08 +00001241 {
1242 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001243 zlog_debug ("%s peer status is %s close connection",
1244 realpeer->host, LOOKUP (bgp_status_msg,
1245 realpeer->status));
1246 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1247 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1248
pauleb821182004-05-01 08:44:08 +00001249 return -1;
1250 }
1251
1252 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00001253 zlog_debug ("%s [Event] Transfer temporary BGP peer to existing one",
pauleb821182004-05-01 08:44:08 +00001254 peer->host);
1255
1256 bgp_stop (realpeer);
1257
1258 /* Transfer file descriptor. */
1259 realpeer->fd = peer->fd;
1260 peer->fd = -1;
1261
1262 /* Transfer input buffer. */
1263 stream_free (realpeer->ibuf);
1264 realpeer->ibuf = peer->ibuf;
1265 realpeer->packet_size = peer->packet_size;
1266 peer->ibuf = NULL;
1267
1268 /* Transfer status. */
1269 realpeer->status = peer->status;
1270 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001271
pauleb821182004-05-01 08:44:08 +00001272 /* peer pointer change. Open packet send to neighbor. */
1273 peer = realpeer;
1274 bgp_open_send (peer);
1275 if (peer->fd < 0)
1276 {
1277 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1278 peer->fd);
1279 return -1;
1280 }
1281 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1282 }
1283
paul718e3742002-12-13 20:15:29 +00001284 /* remote router-id check. */
1285 if (remote_id.s_addr == 0
1286 || ntohl (remote_id.s_addr) >= 0xe0000000
1287 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1288 {
1289 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001290 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001291 peer->host, inet_ntoa (remote_id));
1292 bgp_notify_send_with_data (peer,
1293 BGP_NOTIFY_OPEN_ERR,
1294 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1295 notify_data_remote_id, 4);
1296 return -1;
1297 }
1298
1299 /* Set remote router-id */
1300 peer->remote_id = remote_id;
1301
1302 /* Peer BGP version check. */
1303 if (version != BGP_VERSION_4)
1304 {
paul5228ad22004-06-04 17:58:18 +00001305 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001306 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001307 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001308 peer->host, version, BGP_VERSION_4);
1309 bgp_notify_send_with_data (peer,
1310 BGP_NOTIFY_OPEN_ERR,
1311 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001312 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001313 return -1;
1314 }
1315
1316 /* Check neighbor as number. */
1317 if (remote_as != peer->as)
1318 {
1319 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001320 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
paul718e3742002-12-13 20:15:29 +00001321 peer->host, remote_as, peer->as);
1322 bgp_notify_send_with_data (peer,
1323 BGP_NOTIFY_OPEN_ERR,
1324 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1325 notify_data_remote_as, 2);
1326 return -1;
1327 }
1328
1329 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1330 calculate the value of the Hold Timer by using the smaller of its
1331 configured Hold Time and the Hold Time received in the OPEN message.
1332 The Hold Time MUST be either zero or at least three seconds. An
1333 implementation may reject connections on the basis of the Hold Time. */
1334
1335 if (holdtime < 3 && holdtime != 0)
1336 {
1337 bgp_notify_send (peer,
1338 BGP_NOTIFY_OPEN_ERR,
1339 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1340 return -1;
1341 }
1342
1343 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1344 would be one third of the Hold Time interval. KEEPALIVE messages
1345 MUST NOT be sent more frequently than one per second. An
1346 implementation MAY adjust the rate at which it sends KEEPALIVE
1347 messages as a function of the Hold Time interval. */
1348
1349 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1350 send_holdtime = peer->holdtime;
1351 else
1352 send_holdtime = peer->bgp->default_holdtime;
1353
1354 if (holdtime < send_holdtime)
1355 peer->v_holdtime = holdtime;
1356 else
1357 peer->v_holdtime = send_holdtime;
1358
1359 peer->v_keepalive = peer->v_holdtime / 3;
1360
1361 /* Open option part parse. */
1362 capability = 0;
1363 optlen = stream_getc (peer->ibuf);
1364 if (optlen != 0)
1365 {
1366 ret = bgp_open_option_parse (peer, optlen, &capability);
1367 if (ret < 0)
1368 return ret;
1369
paul9985f832005-02-09 15:51:56 +00001370 stream_forward_getp (peer->ibuf, optlen);
paul718e3742002-12-13 20:15:29 +00001371 }
1372 else
1373 {
1374 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001375 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001376 peer->host);
1377 }
1378
1379 /* Override capability. */
1380 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1381 {
1382 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1383 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1384 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1385 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1386 }
1387
1388 /* Get sockname. */
1389 bgp_getsockname (peer);
1390
1391 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1392
1393 peer->packet_size = 0;
1394 if (peer->ibuf)
1395 stream_reset (peer->ibuf);
1396
1397 return 0;
1398}
1399
1400/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001401static int
paul718e3742002-12-13 20:15:29 +00001402bgp_update_receive (struct peer *peer, bgp_size_t size)
1403{
1404 int ret;
1405 u_char *end;
1406 struct stream *s;
1407 struct attr attr;
1408 bgp_size_t attribute_len;
1409 bgp_size_t update_len;
1410 bgp_size_t withdraw_len;
1411 struct bgp_nlri update;
1412 struct bgp_nlri withdraw;
1413 struct bgp_nlri mp_update;
1414 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001415 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001416
1417 /* Status must be Established. */
1418 if (peer->status != Established)
1419 {
1420 zlog_err ("%s [FSM] Update packet received under status %s",
1421 peer->host, LOOKUP (bgp_status_msg, peer->status));
1422 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1423 return -1;
1424 }
1425
1426 /* Set initial values. */
1427 memset (&attr, 0, sizeof (struct attr));
1428 memset (&update, 0, sizeof (struct bgp_nlri));
1429 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1430 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1431 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1432
1433 s = peer->ibuf;
1434 end = stream_pnt (s) + size;
1435
1436 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1437 Length is too large (i.e., if Unfeasible Routes Length + Total
1438 Attribute Length + 23 exceeds the message Length), then the Error
1439 Subcode is set to Malformed Attribute List. */
1440 if (stream_pnt (s) + 2 > end)
1441 {
1442 zlog_err ("%s [Error] Update packet error"
1443 " (packet length is short for unfeasible length)",
1444 peer->host);
1445 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1446 BGP_NOTIFY_UPDATE_MAL_ATTR);
1447 return -1;
1448 }
1449
1450 /* Unfeasible Route Length. */
1451 withdraw_len = stream_getw (s);
1452
1453 /* Unfeasible Route Length check. */
1454 if (stream_pnt (s) + withdraw_len > end)
1455 {
1456 zlog_err ("%s [Error] Update packet error"
1457 " (packet unfeasible length overflow %d)",
1458 peer->host, withdraw_len);
1459 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1460 BGP_NOTIFY_UPDATE_MAL_ATTR);
1461 return -1;
1462 }
1463
1464 /* Unfeasible Route packet format check. */
1465 if (withdraw_len > 0)
1466 {
1467 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1468 if (ret < 0)
1469 return -1;
1470
1471 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001472 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001473
1474 withdraw.afi = AFI_IP;
1475 withdraw.safi = SAFI_UNICAST;
1476 withdraw.nlri = stream_pnt (s);
1477 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001478 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001479 }
1480
1481 /* Attribute total length check. */
1482 if (stream_pnt (s) + 2 > end)
1483 {
1484 zlog_warn ("%s [Error] Packet Error"
1485 " (update packet is short for attribute length)",
1486 peer->host);
1487 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1488 BGP_NOTIFY_UPDATE_MAL_ATTR);
1489 return -1;
1490 }
1491
1492 /* Fetch attribute total length. */
1493 attribute_len = stream_getw (s);
1494
1495 /* Attribute length check. */
1496 if (stream_pnt (s) + attribute_len > end)
1497 {
1498 zlog_warn ("%s [Error] Packet Error"
1499 " (update packet attribute length overflow %d)",
1500 peer->host, attribute_len);
1501 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1502 BGP_NOTIFY_UPDATE_MAL_ATTR);
1503 return -1;
1504 }
1505
1506 /* Parse attribute when it exists. */
1507 if (attribute_len)
1508 {
1509 ret = bgp_attr_parse (peer, &attr, attribute_len,
1510 &mp_update, &mp_withdraw);
1511 if (ret < 0)
1512 return -1;
1513 }
1514
1515 /* Logging the attribute. */
1516 if (BGP_DEBUG (update, UPDATE_IN))
1517 {
paule01f9cb2004-07-09 17:48:53 +00001518 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1519
1520 if (ret)
ajs6b514742004-12-08 21:03:23 +00001521 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001522 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001523 }
1524
1525 /* Network Layer Reachability Information. */
1526 update_len = end - stream_pnt (s);
1527
1528 if (update_len)
1529 {
1530 /* Check NLRI packet format and prefix length. */
1531 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1532 if (ret < 0)
1533 return -1;
1534
1535 /* Set NLRI portion to structure. */
1536 update.afi = AFI_IP;
1537 update.safi = SAFI_UNICAST;
1538 update.nlri = stream_pnt (s);
1539 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001540 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001541 }
1542
1543 /* NLRI is processed only when the peer is configured specific
1544 Address Family and Subsequent Address Family. */
1545 if (peer->afc[AFI_IP][SAFI_UNICAST])
1546 {
1547 if (withdraw.length)
1548 bgp_nlri_parse (peer, NULL, &withdraw);
1549
1550 if (update.length)
1551 {
1552 /* We check well-known attribute only for IPv4 unicast
1553 update. */
1554 ret = bgp_attr_check (peer, &attr);
1555 if (ret < 0)
1556 return -1;
1557
1558 bgp_nlri_parse (peer, &attr, &update);
1559 }
paule01f9cb2004-07-09 17:48:53 +00001560
hassof4184462005-02-01 20:13:16 +00001561 if (mp_update.length
1562 && mp_update.afi == AFI_IP
1563 && mp_update.safi == SAFI_UNICAST)
1564 bgp_nlri_parse (peer, &attr, &mp_update);
1565
1566 if (mp_withdraw.length
1567 && mp_withdraw.afi == AFI_IP
1568 && mp_withdraw.safi == SAFI_UNICAST)
1569 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1570
paule01f9cb2004-07-09 17:48:53 +00001571 if (! attribute_len && ! withdraw_len)
1572 {
1573 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001574 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1575 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001576
hasso93406d82005-02-02 14:40:33 +00001577 /* NSF delete stale route */
1578 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1579 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1580
1581 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001582 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001583 peer->host);
1584 }
paul718e3742002-12-13 20:15:29 +00001585 }
1586 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1587 {
1588 if (mp_update.length
1589 && mp_update.afi == AFI_IP
1590 && mp_update.safi == SAFI_MULTICAST)
1591 bgp_nlri_parse (peer, &attr, &mp_update);
1592
1593 if (mp_withdraw.length
1594 && mp_withdraw.afi == AFI_IP
1595 && mp_withdraw.safi == SAFI_MULTICAST)
1596 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001597
hasso93406d82005-02-02 14:40:33 +00001598 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001599 && mp_withdraw.afi == AFI_IP
1600 && mp_withdraw.safi == SAFI_MULTICAST
1601 && mp_withdraw.length == 0)
1602 {
1603 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001604 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1605 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001606
hasso93406d82005-02-02 14:40:33 +00001607 /* NSF delete stale route */
1608 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1609 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1610
1611 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001612 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001613 peer->host);
1614 }
paul718e3742002-12-13 20:15:29 +00001615 }
1616 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1617 {
1618 if (mp_update.length
1619 && mp_update.afi == AFI_IP6
1620 && mp_update.safi == SAFI_UNICAST)
1621 bgp_nlri_parse (peer, &attr, &mp_update);
1622
1623 if (mp_withdraw.length
1624 && mp_withdraw.afi == AFI_IP6
1625 && mp_withdraw.safi == SAFI_UNICAST)
1626 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001627
hasso93406d82005-02-02 14:40:33 +00001628 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001629 && mp_withdraw.afi == AFI_IP6
1630 && mp_withdraw.safi == SAFI_UNICAST
1631 && mp_withdraw.length == 0)
1632 {
1633 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001634 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001635
hasso93406d82005-02-02 14:40:33 +00001636 /* NSF delete stale route */
1637 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1638 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1639
1640 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001641 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001642 peer->host);
1643 }
paul718e3742002-12-13 20:15:29 +00001644 }
1645 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1646 {
1647 if (mp_update.length
1648 && mp_update.afi == AFI_IP6
1649 && mp_update.safi == SAFI_MULTICAST)
1650 bgp_nlri_parse (peer, &attr, &mp_update);
1651
1652 if (mp_withdraw.length
1653 && mp_withdraw.afi == AFI_IP6
1654 && mp_withdraw.safi == SAFI_MULTICAST)
1655 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001656
hasso93406d82005-02-02 14:40:33 +00001657 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001658 && mp_withdraw.afi == AFI_IP6
1659 && mp_withdraw.safi == SAFI_MULTICAST
1660 && mp_withdraw.length == 0)
1661 {
1662 /* End-of-RIB received */
1663
hasso93406d82005-02-02 14:40:33 +00001664 /* NSF delete stale route */
1665 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1666 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1667
paule01f9cb2004-07-09 17:48:53 +00001668 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001669 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001670 peer->host);
1671 }
paul718e3742002-12-13 20:15:29 +00001672 }
1673 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1674 {
1675 if (mp_update.length
1676 && mp_update.afi == AFI_IP
1677 && mp_update.safi == BGP_SAFI_VPNV4)
1678 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1679
1680 if (mp_withdraw.length
1681 && mp_withdraw.afi == AFI_IP
1682 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1683 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001684
hasso93406d82005-02-02 14:40:33 +00001685 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001686 && mp_withdraw.afi == AFI_IP
1687 && mp_withdraw.safi == BGP_SAFI_VPNV4
1688 && mp_withdraw.length == 0)
1689 {
1690 /* End-of-RIB received */
1691
1692 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001693 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001694 peer->host);
1695 }
paul718e3742002-12-13 20:15:29 +00001696 }
1697
1698 /* Everything is done. We unintern temporary structures which
1699 interned in bgp_attr_parse(). */
1700 if (attr.aspath)
1701 aspath_unintern (attr.aspath);
1702 if (attr.community)
1703 community_unintern (attr.community);
1704 if (attr.ecommunity)
1705 ecommunity_unintern (attr.ecommunity);
1706 if (attr.cluster)
1707 cluster_unintern (attr.cluster);
1708 if (attr.transit)
1709 transit_unintern (attr.transit);
1710
1711 /* If peering is stopped due to some reason, do not generate BGP
1712 event. */
1713 if (peer->status != Established)
1714 return 0;
1715
1716 /* Increment packet counter. */
1717 peer->update_in++;
1718 peer->update_time = time (NULL);
1719
1720 /* Generate BGP event. */
1721 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1722
1723 return 0;
1724}
1725
1726/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001727static void
paul718e3742002-12-13 20:15:29 +00001728bgp_notify_receive (struct peer *peer, bgp_size_t size)
1729{
1730 struct bgp_notify bgp_notify;
1731
1732 if (peer->notify.data)
1733 {
1734 XFREE (MTYPE_TMP, peer->notify.data);
1735 peer->notify.data = NULL;
1736 peer->notify.length = 0;
1737 }
1738
1739 bgp_notify.code = stream_getc (peer->ibuf);
1740 bgp_notify.subcode = stream_getc (peer->ibuf);
1741 bgp_notify.length = size - 2;
1742 bgp_notify.data = NULL;
1743
1744 /* Preserv notify code and sub code. */
1745 peer->notify.code = bgp_notify.code;
1746 peer->notify.subcode = bgp_notify.subcode;
1747 /* For further diagnostic record returned Data. */
1748 if (bgp_notify.length)
1749 {
1750 peer->notify.length = size - 2;
1751 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1752 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1753 }
1754
1755 /* For debug */
1756 {
1757 int i;
1758 int first = 0;
1759 char c[4];
1760
1761 if (bgp_notify.length)
1762 {
1763 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1764 for (i = 0; i < bgp_notify.length; i++)
1765 if (first)
1766 {
1767 sprintf (c, " %02x", stream_getc (peer->ibuf));
1768 strcat (bgp_notify.data, c);
1769 }
1770 else
1771 {
1772 first = 1;
1773 sprintf (c, "%02x", stream_getc (peer->ibuf));
1774 strcpy (bgp_notify.data, c);
1775 }
1776 }
1777
1778 bgp_notify_print(peer, &bgp_notify, "received");
1779 if (bgp_notify.data)
1780 XFREE (MTYPE_TMP, bgp_notify.data);
1781 }
1782
1783 /* peer count update */
1784 peer->notify_in++;
1785
hassoe0701b72004-05-20 09:19:34 +00001786 if (peer->status == Established)
1787 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1788
paul718e3742002-12-13 20:15:29 +00001789 /* We have to check for Notify with Unsupported Optional Parameter.
1790 in that case we fallback to open without the capability option.
1791 But this done in bgp_stop. We just mark it here to avoid changing
1792 the fsm tables. */
1793 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1794 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1795 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1796
1797 /* Also apply to Unsupported Capability until remote router support
1798 capability. */
1799 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1800 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
1801 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1802
1803 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1804}
1805
1806/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001807static void
paul718e3742002-12-13 20:15:29 +00001808bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1809{
1810 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001811 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001812
1813 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1814}
1815
1816/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001817static void
paul718e3742002-12-13 20:15:29 +00001818bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1819{
1820 afi_t afi;
1821 safi_t safi;
1822 u_char reserved;
1823 struct stream *s;
1824
1825 /* If peer does not have the capability, send notification. */
1826 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1827 {
1828 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1829 peer->host);
1830 bgp_notify_send (peer,
1831 BGP_NOTIFY_HEADER_ERR,
1832 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1833 return;
1834 }
1835
1836 /* Status must be Established. */
1837 if (peer->status != Established)
1838 {
1839 plog_err (peer->log,
1840 "%s [Error] Route refresh packet received under status %s",
1841 peer->host, LOOKUP (bgp_status_msg, peer->status));
1842 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1843 return;
1844 }
1845
1846 s = peer->ibuf;
1847
1848 /* Parse packet. */
1849 afi = stream_getw (s);
1850 reserved = stream_getc (s);
1851 safi = stream_getc (s);
1852
1853 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001854 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001855 peer->host, afi, safi);
1856
1857 /* Check AFI and SAFI. */
1858 if ((afi != AFI_IP && afi != AFI_IP6)
1859 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1860 && safi != BGP_SAFI_VPNV4))
1861 {
1862 if (BGP_DEBUG (normal, NORMAL))
1863 {
ajs6b514742004-12-08 21:03:23 +00001864 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001865 peer->host, afi, safi);
1866 }
1867 return;
1868 }
1869
1870 /* Adjust safi code. */
1871 if (safi == BGP_SAFI_VPNV4)
1872 safi = SAFI_MPLS_VPN;
1873
1874 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1875 {
1876 u_char *end;
1877 u_char when_to_refresh;
1878 u_char orf_type;
1879 u_int16_t orf_len;
1880
1881 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1882 {
1883 zlog_info ("%s ORF route refresh length error", peer->host);
1884 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1885 return;
1886 }
1887
1888 when_to_refresh = stream_getc (s);
1889 end = stream_pnt (s) + (size - 5);
1890
1891 while (stream_pnt (s) < end)
1892 {
1893 orf_type = stream_getc (s);
1894 orf_len = stream_getw (s);
1895
1896 if (orf_type == ORF_TYPE_PREFIX
1897 || orf_type == ORF_TYPE_PREFIX_OLD)
1898 {
1899 u_char *p_pnt = stream_pnt (s);
1900 u_char *p_end = stream_pnt (s) + orf_len;
1901 struct orf_prefix orfp;
1902 u_char common = 0;
1903 u_int32_t seq;
1904 int psize;
1905 char name[BUFSIZ];
1906 char buf[BUFSIZ];
1907 int ret;
1908
1909 if (BGP_DEBUG (normal, NORMAL))
1910 {
ajs6b514742004-12-08 21:03:23 +00001911 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00001912 peer->host, orf_type, orf_len);
1913 }
1914
1915 /* ORF prefix-list name */
1916 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
1917
1918 while (p_pnt < p_end)
1919 {
1920 memset (&orfp, 0, sizeof (struct orf_prefix));
1921 common = *p_pnt++;
1922 if (common & ORF_COMMON_PART_REMOVE_ALL)
1923 {
1924 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001925 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00001926 prefix_bgp_orf_remove_all (name);
1927 break;
1928 }
1929 memcpy (&seq, p_pnt, sizeof (u_int32_t));
1930 p_pnt += sizeof (u_int32_t);
1931 orfp.seq = ntohl (seq);
1932 orfp.ge = *p_pnt++;
1933 orfp.le = *p_pnt++;
1934 orfp.p.prefixlen = *p_pnt++;
1935 orfp.p.family = afi2family (afi);
1936 psize = PSIZE (orfp.p.prefixlen);
1937 memcpy (&orfp.p.u.prefix, p_pnt, psize);
1938 p_pnt += psize;
1939
1940 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001941 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
paul718e3742002-12-13 20:15:29 +00001942 peer->host,
1943 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
1944 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
1945 orfp.seq,
1946 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
1947 orfp.p.prefixlen, orfp.ge, orfp.le);
1948
1949 ret = prefix_bgp_orf_set (name, afi, &orfp,
1950 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
1951 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
1952
1953 if (ret != CMD_SUCCESS)
1954 {
1955 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001956 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00001957 prefix_bgp_orf_remove_all (name);
1958 break;
1959 }
1960 }
1961 peer->orf_plist[afi][safi] =
1962 prefix_list_lookup (AFI_ORF_PREFIX, name);
1963 }
paul9985f832005-02-09 15:51:56 +00001964 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00001965 }
1966 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001967 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00001968 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
1969 if (when_to_refresh == REFRESH_DEFER)
1970 return;
1971 }
1972
1973 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1974 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
1975 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
1976
1977 /* Perform route refreshment to the peer */
1978 bgp_announce_route (peer, afi, safi);
1979}
1980
paul94f2b392005-06-28 12:44:16 +00001981static int
paul718e3742002-12-13 20:15:29 +00001982bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
1983{
1984 u_char *end;
1985 struct capability cap;
1986 u_char action;
1987 struct bgp *bgp;
1988 afi_t afi;
1989 safi_t safi;
1990
1991 bgp = peer->bgp;
1992 end = pnt + length;
1993
1994 while (pnt < end)
1995 {
1996 /* We need at least action, capability code and capability length. */
1997 if (pnt + 3 > end)
1998 {
1999 zlog_info ("%s Capability length error", peer->host);
2000 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2001 return -1;
2002 }
2003
2004 action = *pnt;
2005
2006 /* Fetch structure to the byte stream. */
2007 memcpy (&cap, pnt + 1, sizeof (struct capability));
2008
2009 /* Action value check. */
2010 if (action != CAPABILITY_ACTION_SET
2011 && action != CAPABILITY_ACTION_UNSET)
2012 {
2013 zlog_info ("%s Capability Action Value error %d",
2014 peer->host, action);
2015 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2016 return -1;
2017 }
2018
2019 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002020 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
paul718e3742002-12-13 20:15:29 +00002021 peer->host, action, cap.code, cap.length);
2022
2023 /* Capability length check. */
2024 if (pnt + (cap.length + 3) > end)
2025 {
2026 zlog_info ("%s Capability length error", peer->host);
2027 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2028 return -1;
2029 }
2030
2031 /* We know MP Capability Code. */
2032 if (cap.code == CAPABILITY_CODE_MP)
2033 {
2034 afi = ntohs (cap.mpc.afi);
2035 safi = cap.mpc.safi;
2036
2037 /* Ignore capability when override-capability is set. */
2038 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2039 continue;
2040
2041 /* Address family check. */
2042 if ((afi == AFI_IP
2043 || afi == AFI_IP6)
2044 && (safi == SAFI_UNICAST
2045 || safi == SAFI_MULTICAST
2046 || safi == BGP_SAFI_VPNV4))
2047 {
2048 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002049 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
paul718e3742002-12-13 20:15:29 +00002050 peer->host,
2051 action == CAPABILITY_ACTION_SET
2052 ? "Advertising" : "Removing",
2053 ntohs(cap.mpc.afi) , cap.mpc.safi);
2054
2055 /* Adjust safi code. */
2056 if (safi == BGP_SAFI_VPNV4)
2057 safi = SAFI_MPLS_VPN;
2058
2059 if (action == CAPABILITY_ACTION_SET)
2060 {
2061 peer->afc_recv[afi][safi] = 1;
2062 if (peer->afc[afi][safi])
2063 {
2064 peer->afc_nego[afi][safi] = 1;
2065 bgp_announce_route (peer, afi, safi);
2066 }
2067 }
2068 else
2069 {
2070 peer->afc_recv[afi][safi] = 0;
2071 peer->afc_nego[afi][safi] = 0;
2072
2073 if (peer_active_nego (peer))
2074 bgp_clear_route (peer, afi, safi);
2075 else
2076 BGP_EVENT_ADD (peer, BGP_Stop);
2077 }
2078 }
2079 }
paul718e3742002-12-13 20:15:29 +00002080 else
2081 {
2082 zlog_warn ("%s unrecognized capability code: %d - ignored",
2083 peer->host, cap.code);
2084 }
2085 pnt += cap.length + 3;
2086 }
2087 return 0;
2088}
2089
2090/* Dynamic Capability is received. */
paul94f2b392005-06-28 12:44:16 +00002091static void
paul718e3742002-12-13 20:15:29 +00002092bgp_capability_receive (struct peer *peer, bgp_size_t size)
2093{
2094 u_char *pnt;
2095 int ret;
2096
2097 /* Fetch pointer. */
2098 pnt = stream_pnt (peer->ibuf);
2099
2100 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002101 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002102
2103 /* If peer does not have the capability, send notification. */
2104 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2105 {
2106 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2107 peer->host);
2108 bgp_notify_send (peer,
2109 BGP_NOTIFY_HEADER_ERR,
2110 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2111 return;
2112 }
2113
2114 /* Status must be Established. */
2115 if (peer->status != Established)
2116 {
2117 plog_err (peer->log,
2118 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2119 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2120 return;
2121 }
2122
2123 /* Parse packet. */
2124 ret = bgp_capability_msg_parse (peer, pnt, size);
2125}
2126
2127/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002128static int
paul718e3742002-12-13 20:15:29 +00002129bgp_read_packet (struct peer *peer)
2130{
2131 int nbytes;
2132 int readsize;
2133
paul9985f832005-02-09 15:51:56 +00002134 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002135
2136 /* If size is zero then return. */
2137 if (! readsize)
2138 return 0;
2139
2140 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002141 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002142
2143 /* If read byte is smaller than zero then error occured. */
2144 if (nbytes < 0)
2145 {
2146 if (errno == EAGAIN)
2147 return -1;
2148
2149 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002150 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002151
2152 if (peer->status == Established)
2153 {
2154 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2155 {
2156 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2157 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2158 }
2159 else
2160 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2161 }
2162
paul718e3742002-12-13 20:15:29 +00002163 BGP_EVENT_ADD (peer, TCP_fatal_error);
2164 return -1;
2165 }
2166
2167 /* When read byte is zero : clear bgp peer and return */
2168 if (nbytes == 0)
2169 {
2170 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002171 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002172 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002173
2174 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002175 {
2176 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2177 {
2178 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2179 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2180 }
2181 else
2182 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2183 }
hassoe0701b72004-05-20 09:19:34 +00002184
paul718e3742002-12-13 20:15:29 +00002185 BGP_EVENT_ADD (peer, TCP_connection_closed);
2186 return -1;
2187 }
2188
2189 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002190 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002191 return -1;
2192
2193 return 0;
2194}
2195
2196/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002197static int
paul718e3742002-12-13 20:15:29 +00002198bgp_marker_all_one (struct stream *s, int length)
2199{
2200 int i;
2201
2202 for (i = 0; i < length; i++)
2203 if (s->data[i] != 0xff)
2204 return 0;
2205
2206 return 1;
2207}
2208
2209/* Starting point of packet process function. */
2210int
2211bgp_read (struct thread *thread)
2212{
2213 int ret;
2214 u_char type = 0;
2215 struct peer *peer;
2216 bgp_size_t size;
2217 char notify_data_length[2];
2218
2219 /* Yes first of all get peer pointer. */
2220 peer = THREAD_ARG (thread);
2221 peer->t_read = NULL;
2222
2223 /* For non-blocking IO check. */
2224 if (peer->status == Connect)
2225 {
2226 bgp_connect_check (peer);
2227 goto done;
2228 }
2229 else
2230 {
pauleb821182004-05-01 08:44:08 +00002231 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002232 {
pauleb821182004-05-01 08:44:08 +00002233 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002234 return -1;
2235 }
pauleb821182004-05-01 08:44:08 +00002236 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002237 }
2238
2239 /* Read packet header to determine type of the packet */
2240 if (peer->packet_size == 0)
2241 peer->packet_size = BGP_HEADER_SIZE;
2242
paul9985f832005-02-09 15:51:56 +00002243 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002244 {
2245 ret = bgp_read_packet (peer);
2246
2247 /* Header read error or partial read packet. */
2248 if (ret < 0)
2249 goto done;
2250
2251 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002252 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002253 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2254 size = stream_getw (peer->ibuf);
2255 type = stream_getc (peer->ibuf);
2256
2257 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002258 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002259 peer->host, type, size - BGP_HEADER_SIZE);
2260
2261 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002262 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002263 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2264 {
2265 bgp_notify_send (peer,
2266 BGP_NOTIFY_HEADER_ERR,
2267 BGP_NOTIFY_HEADER_NOT_SYNC);
2268 goto done;
2269 }
2270
2271 /* BGP type check. */
2272 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2273 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2274 && type != BGP_MSG_ROUTE_REFRESH_NEW
2275 && type != BGP_MSG_ROUTE_REFRESH_OLD
2276 && type != BGP_MSG_CAPABILITY)
2277 {
2278 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002279 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002280 "%s unknown message type 0x%02x",
2281 peer->host, type);
2282 bgp_notify_send_with_data (peer,
2283 BGP_NOTIFY_HEADER_ERR,
2284 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2285 &type, 1);
2286 goto done;
2287 }
2288 /* Mimimum packet length check. */
2289 if ((size < BGP_HEADER_SIZE)
2290 || (size > BGP_MAX_PACKET_SIZE)
2291 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2292 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2293 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2294 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2295 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2296 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2297 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2298 {
2299 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002300 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002301 "%s bad message length - %d for %s",
2302 peer->host, size,
2303 type == 128 ? "ROUTE-REFRESH" :
2304 bgp_type_str[(int) type]);
2305 bgp_notify_send_with_data (peer,
2306 BGP_NOTIFY_HEADER_ERR,
2307 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002308 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002309 goto done;
2310 }
2311
2312 /* Adjust size to message length. */
2313 peer->packet_size = size;
2314 }
2315
2316 ret = bgp_read_packet (peer);
2317 if (ret < 0)
2318 goto done;
2319
2320 /* Get size and type again. */
2321 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2322 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2323
2324 /* BGP packet dump function. */
2325 bgp_dump_packet (peer, type, peer->ibuf);
2326
2327 size = (peer->packet_size - BGP_HEADER_SIZE);
2328
2329 /* Read rest of the packet and call each sort of packet routine */
2330 switch (type)
2331 {
2332 case BGP_MSG_OPEN:
2333 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002334 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002335 break;
2336 case BGP_MSG_UPDATE:
2337 peer->readtime = time(NULL); /* Last read timer reset */
2338 bgp_update_receive (peer, size);
2339 break;
2340 case BGP_MSG_NOTIFY:
2341 bgp_notify_receive (peer, size);
2342 break;
2343 case BGP_MSG_KEEPALIVE:
2344 peer->readtime = time(NULL); /* Last read timer reset */
2345 bgp_keepalive_receive (peer, size);
2346 break;
2347 case BGP_MSG_ROUTE_REFRESH_NEW:
2348 case BGP_MSG_ROUTE_REFRESH_OLD:
2349 peer->refresh_in++;
2350 bgp_route_refresh_receive (peer, size);
2351 break;
2352 case BGP_MSG_CAPABILITY:
2353 peer->dynamic_cap_in++;
2354 bgp_capability_receive (peer, size);
2355 break;
2356 }
2357
2358 /* Clear input buffer. */
2359 peer->packet_size = 0;
2360 if (peer->ibuf)
2361 stream_reset (peer->ibuf);
2362
2363 done:
2364 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2365 {
2366 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002367 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002368 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002369 }
2370 return 0;
2371}