blob: 9fa23e52ffb7c5beacd3256dc3ae854a9de11c13 [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. */
88void
89bgp_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. */
96void
97bgp_packet_delete (struct peer *peer)
98{
99 stream_free (stream_fifo_pop (peer->obuf));
100}
101
102/* Duplicate packet. */
103struct stream *
104bgp_packet_dup (struct stream *s)
105{
106 struct stream *new;
107
108 new = stream_new (stream_get_endp (s));
109
110 new->endp = s->endp;
paul718e3742002-12-13 20:15:29 +0000111 new->getp = s->getp;
112
113 memcpy (new->data, s->data, stream_get_endp (s));
114
115 return new;
116}
117
118/* Check file descriptor whether connect is established. */
119static void
120bgp_connect_check (struct peer *peer)
121{
122 int status;
paul5228ad22004-06-04 17:58:18 +0000123 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000124 int ret;
125
126 /* Anyway I have to reset read and write thread. */
127 BGP_READ_OFF (peer->t_read);
128 BGP_WRITE_OFF (peer->t_write);
129
130 /* Check file descriptor. */
131 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000132 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000133
134 /* If getsockopt is fail, this is fatal error. */
135 if (ret < 0)
136 {
137 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
138 BGP_EVENT_ADD (peer, TCP_fatal_error);
139 return;
140 }
141
142 /* When status is 0 then TCP connection is established. */
143 if (status == 0)
144 {
145 BGP_EVENT_ADD (peer, TCP_connection_open);
146 }
147 else
148 {
149 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000150 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000151 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000152 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
153 }
154}
155
156/* Make BGP update packet. */
157struct stream *
158bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
159{
160 struct stream *s;
161 struct bgp_adj_out *adj;
162 struct bgp_advertise *adv;
163 struct stream *packet;
164 struct bgp_node *rn = NULL;
165 struct bgp_info *binfo = NULL;
166 bgp_size_t total_attr_len = 0;
167 unsigned long pos;
168 char buf[BUFSIZ];
169 struct prefix_rd *prd = NULL;
170 char *tag = NULL;
171
172 s = peer->work;
173 stream_reset (s);
174
175 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
176
177 while (adv)
178 {
179 if (adv->rn)
180 rn = adv->rn;
181 adj = adv->adj;
182 if (adv->binfo)
183 binfo = adv->binfo;
184#ifdef MPLS_VPN
185 if (rn)
186 prd = (struct prefix_rd *) &rn->prn->p;
187 if (binfo)
188 tag = binfo->tag;
189#endif /* MPLS_VPN */
190
191 /* When remaining space can't include NLRI and it's length. */
192 if (rn && STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
193 break;
194
195 /* If packet is empty, set attribute. */
196 if (stream_empty (s))
197 {
198 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
199 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000200 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000201 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000202 total_attr_len = bgp_packet_attribute (NULL, peer, s,
203 adv->baa->attr,
204 &rn->p, afi, safi,
205 binfo->peer, prd, tag);
paul718e3742002-12-13 20:15:29 +0000206 stream_putw_at (s, pos, total_attr_len);
207 }
208
209 if (afi == AFI_IP && safi == SAFI_UNICAST)
210 stream_put_prefix (s, &rn->p);
211
212 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000213 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000214 peer->host,
215 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
216 rn->p.prefixlen);
217
218 /* Synchnorize attribute. */
219 if (adj->attr)
220 bgp_attr_unintern (adj->attr);
221 else
222 peer->scount[afi][safi]++;
223
224 adj->attr = bgp_attr_intern (adv->baa->attr);
225
226 adv = bgp_advertise_clean (peer, adj, afi, safi);
227
228 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
229 break;
230 }
231
232 if (! stream_empty (s))
233 {
234 bgp_packet_set_size (s);
235 packet = bgp_packet_dup (s);
236 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000237 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000238 stream_reset (s);
239 return packet;
240 }
241 return NULL;
hasso93406d82005-02-02 14:40:33 +0000242}
paul718e3742002-12-13 20:15:29 +0000243
hasso93406d82005-02-02 14:40:33 +0000244struct stream *
245bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
246{
247 struct stream *s;
248 struct stream *packet;
249
250#ifdef DISABLE_BGP_ANNOUNCE
251 return;
252#endif /* DISABLE_BGP_ANNOUNCE */
253
254 if (BGP_DEBUG (normal, NORMAL))
255 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
256
257 s = stream_new (BGP_MAX_PACKET_SIZE);
258
259 /* Make BGP update packet. */
260 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
261
262 /* Unfeasible Routes Length */
263 stream_putw (s, 0);
264
265 if (afi == AFI_IP && safi == SAFI_UNICAST)
266 {
267 /* Total Path Attribute Length */
268 stream_putw (s, 0);
269 }
270 else
271 {
272 /* Total Path Attribute Length */
273 stream_putw (s, 6);
274 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
275 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
276 stream_putc (s, 3);
277 stream_putw (s, afi);
278 stream_putc (s, safi);
279 }
280
281 bgp_packet_set_size (s);
282 packet = bgp_packet_dup (s);
283 bgp_packet_add (peer, packet);
284 stream_free (s);
285 return packet;
paul718e3742002-12-13 20:15:29 +0000286}
287
288/* Make BGP withdraw packet. */
289struct stream *
290bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
291{
292 struct stream *s;
293 struct stream *packet;
294 struct bgp_adj_out *adj;
295 struct bgp_advertise *adv;
296 struct bgp_node *rn;
297 unsigned long pos;
298 bgp_size_t unfeasible_len;
299 bgp_size_t total_attr_len;
300 char buf[BUFSIZ];
301 struct prefix_rd *prd = NULL;
302
303 s = peer->work;
304 stream_reset (s);
305
306 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
307 {
308 adj = adv->adj;
309 rn = adv->rn;
310#ifdef MPLS_VPN
311 prd = (struct prefix_rd *) &rn->prn->p;
312#endif /* MPLS_VPN */
313
314 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000315 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000316 break;
317
318 if (stream_empty (s))
319 {
320 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
321 stream_putw (s, 0);
322 }
323
324 if (afi == AFI_IP && safi == SAFI_UNICAST)
325 stream_put_prefix (s, &rn->p);
326 else
327 {
paul9985f832005-02-09 15:51:56 +0000328 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000329 stream_putw (s, 0);
330 total_attr_len
331 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
332
333 /* Set total path attribute length. */
334 stream_putw_at (s, pos, total_attr_len);
335 }
336
337 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000338 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000339 peer->host,
340 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
341 rn->p.prefixlen);
342
343 peer->scount[afi][safi]--;
344
345 bgp_adj_out_remove (rn, adj, peer, afi, safi);
346 bgp_unlock_node (rn);
347
348 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
349 break;
350 }
351
352 if (! stream_empty (s))
353 {
354 if (afi == AFI_IP && safi == SAFI_UNICAST)
355 {
356 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000357 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000358 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
359 stream_putw (s, 0);
360 }
361 bgp_packet_set_size (s);
362 packet = bgp_packet_dup (s);
363 bgp_packet_add (peer, packet);
364 stream_reset (s);
365 return packet;
366 }
367
368 return NULL;
369}
370
371void
372bgp_default_update_send (struct peer *peer, struct attr *attr,
373 afi_t afi, safi_t safi, struct peer *from)
374{
375 struct stream *s;
376 struct stream *packet;
377 struct prefix p;
378 unsigned long pos;
379 bgp_size_t total_attr_len;
380 char attrstr[BUFSIZ];
381 char buf[BUFSIZ];
382
383#ifdef DISABLE_BGP_ANNOUNCE
384 return;
385#endif /* DISABLE_BGP_ANNOUNCE */
386
387 if (afi == AFI_IP)
388 str2prefix ("0.0.0.0/0", &p);
389#ifdef HAVE_IPV6
390 else
391 str2prefix ("::/0", &p);
392#endif /* HAVE_IPV6 */
393
394 /* Logging the attribute. */
395 if (BGP_DEBUG (update, UPDATE_OUT))
396 {
397 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000398 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000399 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
400 p.prefixlen, attrstr);
401 }
402
403 s = stream_new (BGP_MAX_PACKET_SIZE);
404
405 /* Make BGP update packet. */
406 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
407
408 /* Unfeasible Routes Length. */
409 stream_putw (s, 0);
410
411 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000412 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000413 stream_putw (s, 0);
414 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
415
416 /* Set Total Path Attribute Length. */
417 stream_putw_at (s, pos, total_attr_len);
418
419 /* NLRI set. */
420 if (p.family == AF_INET && safi == SAFI_UNICAST)
421 stream_put_prefix (s, &p);
422
423 /* Set size. */
424 bgp_packet_set_size (s);
425
426 packet = bgp_packet_dup (s);
427 stream_free (s);
428
429 /* Dump packet if debug option is set. */
430#ifdef DEBUG
431 bgp_packet_dump (packet);
432#endif /* DEBUG */
433
434 /* Add packet to the peer. */
435 bgp_packet_add (peer, packet);
436
pauleb821182004-05-01 08:44:08 +0000437 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000438}
439
440void
441bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
442{
443 struct stream *s;
444 struct stream *packet;
445 struct prefix p;
446 unsigned long pos;
447 unsigned long cp;
448 bgp_size_t unfeasible_len;
449 bgp_size_t total_attr_len;
450 char buf[BUFSIZ];
451
452#ifdef DISABLE_BGP_ANNOUNCE
453 return;
454#endif /* DISABLE_BGP_ANNOUNCE */
455
456 if (afi == AFI_IP)
457 str2prefix ("0.0.0.0/0", &p);
458#ifdef HAVE_IPV6
459 else
460 str2prefix ("::/0", &p);
461#endif /* HAVE_IPV6 */
462
463 total_attr_len = 0;
464 pos = 0;
465
466 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000467 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000468 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
469 p.prefixlen);
470
471 s = stream_new (BGP_MAX_PACKET_SIZE);
472
473 /* Make BGP update packet. */
474 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
475
476 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000477 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000478 stream_putw (s, 0);
479
480 /* Withdrawn Routes. */
481 if (p.family == AF_INET && safi == SAFI_UNICAST)
482 {
483 stream_put_prefix (s, &p);
484
paul9985f832005-02-09 15:51:56 +0000485 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000486
487 /* Set unfeasible len. */
488 stream_putw_at (s, cp, unfeasible_len);
489
490 /* Set total path attribute length. */
491 stream_putw (s, 0);
492 }
493 else
494 {
paul9985f832005-02-09 15:51:56 +0000495 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000496 stream_putw (s, 0);
497 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
498
499 /* Set total path attribute length. */
500 stream_putw_at (s, pos, total_attr_len);
501 }
502
503 bgp_packet_set_size (s);
504
505 packet = bgp_packet_dup (s);
506 stream_free (s);
507
508 /* Add packet to the peer. */
509 bgp_packet_add (peer, packet);
510
pauleb821182004-05-01 08:44:08 +0000511 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000512}
513
514/* Get next packet to be written. */
515struct stream *
516bgp_write_packet (struct peer *peer)
517{
518 afi_t afi;
519 safi_t safi;
520 struct stream *s = NULL;
521 struct bgp_advertise *adv;
522
523 s = stream_fifo_head (peer->obuf);
524 if (s)
525 return s;
526
527 for (afi = AFI_IP; afi < AFI_MAX; afi++)
528 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
529 {
530 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
531 if (adv)
532 {
533 s = bgp_withdraw_packet (peer, afi, safi);
534 if (s)
535 return s;
536 }
537 }
538
539 for (afi = AFI_IP; afi < AFI_MAX; afi++)
540 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
541 {
542 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
543 if (adv)
544 {
545 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000546 {
547 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
548 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
549 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
550 && safi != SAFI_MPLS_VPN)
551 {
552 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
553 PEER_STATUS_EOR_RECEIVED))
554 s = bgp_update_packet (peer, afi, safi);
555 }
556 else
557 s = bgp_update_packet (peer, afi, safi);
558 }
paul718e3742002-12-13 20:15:29 +0000559
560 if (s)
561 return s;
562 }
hasso93406d82005-02-02 14:40:33 +0000563
564 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
565 {
566 if (peer->afc_nego[afi][safi] && peer->synctime
567 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
568 && safi != SAFI_MPLS_VPN)
569 {
570 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
571 return bgp_update_packet_eor (peer, afi, safi);
572 }
573 }
paul718e3742002-12-13 20:15:29 +0000574 }
575
576 return NULL;
577}
578
579/* Is there partially written packet or updates we can send right
580 now. */
581int
582bgp_write_proceed (struct peer *peer)
583{
584 afi_t afi;
585 safi_t safi;
586 struct bgp_advertise *adv;
587
588 if (stream_fifo_head (peer->obuf))
589 return 1;
590
591 for (afi = AFI_IP; afi < AFI_MAX; afi++)
592 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
593 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
594 return 1;
595
596 for (afi = AFI_IP; afi < AFI_MAX; afi++)
597 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
598 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
599 if (adv->binfo->uptime < peer->synctime)
600 return 1;
601
602 return 0;
603}
604
605/* Write packet to the peer. */
606int
607bgp_write (struct thread *thread)
608{
609 struct peer *peer;
610 u_char type;
611 struct stream *s;
612 int num;
paulfd79ac92004-10-13 05:06:08 +0000613 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000614 int write_errno;
615
616 /* Yes first of all get peer pointer. */
617 peer = THREAD_ARG (thread);
618 peer->t_write = NULL;
619
620 /* For non-blocking IO check. */
621 if (peer->status == Connect)
622 {
623 bgp_connect_check (peer);
624 return 0;
625 }
626
627 /* Nonblocking write until TCP output buffer is full. */
628 while (1)
629 {
630 int writenum;
paula24a7e12005-01-05 08:14:13 +0000631 int val;
paul718e3742002-12-13 20:15:29 +0000632
633 s = bgp_write_packet (peer);
634 if (! s)
635 return 0;
paula24a7e12005-01-05 08:14:13 +0000636
637 /* XXX: FIXME, the socket should be NONBLOCK from the start
638 * status shouldnt need to be toggled on each write
639 */
640 val = fcntl (peer->fd, F_GETFL, 0);
641 fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
paul718e3742002-12-13 20:15:29 +0000642
643 /* Number of bytes to be sent. */
644 writenum = stream_get_endp (s) - stream_get_getp (s);
645
646 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000647 num = write (peer->fd, STREAM_PNT (s), writenum);
paul718e3742002-12-13 20:15:29 +0000648 write_errno = errno;
paula24a7e12005-01-05 08:14:13 +0000649 fcntl (peer->fd, F_SETFL, val);
paul718e3742002-12-13 20:15:29 +0000650 if (num <= 0)
651 {
652 /* Partial write. */
653 if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
654 break;
655
656 bgp_stop (peer);
657 peer->status = Idle;
658 bgp_timer_set (peer);
659 return 0;
660 }
661 if (num != writenum)
662 {
paul9985f832005-02-09 15:51:56 +0000663 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000664
665 if (write_errno == EAGAIN)
666 break;
667
668 continue;
669 }
670
671 /* Retrieve BGP packet type. */
672 stream_set_getp (s, BGP_MARKER_SIZE + 2);
673 type = stream_getc (s);
674
675 switch (type)
676 {
677 case BGP_MSG_OPEN:
678 peer->open_out++;
679 break;
680 case BGP_MSG_UPDATE:
681 peer->update_out++;
682 break;
683 case BGP_MSG_NOTIFY:
684 peer->notify_out++;
685 /* Double start timer. */
686 peer->v_start *= 2;
687
688 /* Overflow check. */
689 if (peer->v_start >= (60 * 2))
690 peer->v_start = (60 * 2);
691
692 /* BGP_EVENT_ADD (peer, BGP_Stop); */
693 bgp_stop (peer);
694 peer->status = Idle;
695 bgp_timer_set (peer);
696 return 0;
697 break;
698 case BGP_MSG_KEEPALIVE:
699 peer->keepalive_out++;
700 break;
701 case BGP_MSG_ROUTE_REFRESH_NEW:
702 case BGP_MSG_ROUTE_REFRESH_OLD:
703 peer->refresh_out++;
704 break;
705 case BGP_MSG_CAPABILITY:
706 peer->dynamic_cap_out++;
707 break;
708 }
709
710 /* OK we send packet so delete it. */
711 bgp_packet_delete (peer);
712
713 if (++count >= BGP_WRITE_PACKET_MAX)
714 break;
715 }
716
717 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000718 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000719
720 return 0;
721}
722
723/* This is only for sending NOTIFICATION message to neighbor. */
724int
725bgp_write_notify (struct peer *peer)
726{
727 int ret;
728 u_char type;
729 struct stream *s;
730
731 /* There should be at least one packet. */
732 s = stream_fifo_head (peer->obuf);
733 if (!s)
734 return 0;
735 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
736
737 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000738 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000739 if (ret <= 0)
740 {
741 bgp_stop (peer);
742 peer->status = Idle;
743 bgp_timer_set (peer);
744 return 0;
745 }
746
747 /* Retrieve BGP packet type. */
748 stream_set_getp (s, BGP_MARKER_SIZE + 2);
749 type = stream_getc (s);
750
751 assert (type == BGP_MSG_NOTIFY);
752
753 /* Type should be notify. */
754 peer->notify_out++;
755
756 /* Double start timer. */
757 peer->v_start *= 2;
758
759 /* Overflow check. */
760 if (peer->v_start >= (60 * 2))
761 peer->v_start = (60 * 2);
762
763 /* We don't call event manager at here for avoiding other events. */
764 bgp_stop (peer);
765 peer->status = Idle;
766 bgp_timer_set (peer);
767
768 return 0;
769}
770
771/* Make keepalive packet and send it to the peer. */
772void
773bgp_keepalive_send (struct peer *peer)
774{
775 struct stream *s;
776 int length;
777
778 s = stream_new (BGP_MAX_PACKET_SIZE);
779
780 /* Make keepalive packet. */
781 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
782
783 /* Set packet size. */
784 length = bgp_packet_set_size (s);
785
786 /* Dump packet if debug option is set. */
787 /* bgp_packet_dump (s); */
788
789 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000790 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000791 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000792 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000793 peer->host, BGP_MSG_KEEPALIVE, length);
794
795 /* Add packet to the peer. */
796 bgp_packet_add (peer, s);
797
pauleb821182004-05-01 08:44:08 +0000798 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000799}
800
801/* Make open packet and send it to the peer. */
802void
803bgp_open_send (struct peer *peer)
804{
805 struct stream *s;
806 int length;
807 u_int16_t send_holdtime;
808 as_t local_as;
809
810 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
811 send_holdtime = peer->holdtime;
812 else
813 send_holdtime = peer->bgp->default_holdtime;
814
815 /* local-as Change */
816 if (peer->change_local_as)
817 local_as = peer->change_local_as;
818 else
819 local_as = peer->local_as;
820
821 s = stream_new (BGP_MAX_PACKET_SIZE);
822
823 /* Make open packet. */
824 bgp_packet_set_marker (s, BGP_MSG_OPEN);
825
826 /* Set open packet values. */
827 stream_putc (s, BGP_VERSION_4); /* BGP version */
828 stream_putw (s, local_as); /* My Autonomous System*/
829 stream_putw (s, send_holdtime); /* Hold Time */
830 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
831
832 /* Set capability code. */
833 bgp_open_capability (s, peer);
834
835 /* Set BGP packet length. */
836 length = bgp_packet_set_size (s);
837
838 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000839 zlog_debug ("%s sending OPEN, version %d, my as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000840 peer->host, BGP_VERSION_4, local_as,
841 send_holdtime, inet_ntoa (peer->local_id));
842
843 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000844 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000845 peer->host, BGP_MSG_OPEN, length);
846
847 /* Dump packet if debug option is set. */
848 /* bgp_packet_dump (s); */
849
850 /* Add packet to the peer. */
851 bgp_packet_add (peer, s);
852
pauleb821182004-05-01 08:44:08 +0000853 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000854}
855
856/* Send BGP notify packet with data potion. */
857void
858bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
859 u_char *data, size_t datalen)
860{
861 struct stream *s;
862 int length;
863
864 /* Allocate new stream. */
865 s = stream_new (BGP_MAX_PACKET_SIZE);
866
867 /* Make nitify packet. */
868 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
869
870 /* Set notify packet values. */
871 stream_putc (s, code); /* BGP notify code */
872 stream_putc (s, sub_code); /* BGP notify sub_code */
873
874 /* If notify data is present. */
875 if (data)
876 stream_write (s, data, datalen);
877
878 /* Set BGP packet length. */
879 length = bgp_packet_set_size (s);
880
881 /* Add packet to the peer. */
882 stream_fifo_clean (peer->obuf);
883 bgp_packet_add (peer, s);
884
885 /* For debug */
886 {
887 struct bgp_notify bgp_notify;
888 int first = 0;
889 int i;
890 char c[4];
891
892 bgp_notify.code = code;
893 bgp_notify.subcode = sub_code;
894 bgp_notify.data = NULL;
895 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
896
897 if (bgp_notify.length)
898 {
899 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
900 for (i = 0; i < bgp_notify.length; i++)
901 if (first)
902 {
903 sprintf (c, " %02x", data[i]);
904 strcat (bgp_notify.data, c);
905 }
906 else
907 {
908 first = 1;
909 sprintf (c, "%02x", data[i]);
910 strcpy (bgp_notify.data, c);
911 }
912 }
913 bgp_notify_print (peer, &bgp_notify, "sending");
914 if (bgp_notify.data)
915 XFREE (MTYPE_TMP, bgp_notify.data);
916 }
917
918 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000919 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000920 peer->host, BGP_MSG_NOTIFY, length);
921
hassoe0701b72004-05-20 09:19:34 +0000922 /* peer reset cause */
923 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
924 {
925 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
926 peer->last_reset = PEER_DOWN_USER_RESET;
927 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
928 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
929 else
930 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
931 }
932
paul718e3742002-12-13 20:15:29 +0000933 /* Call imidiately. */
934 BGP_WRITE_OFF (peer->t_write);
935
936 bgp_write_notify (peer);
937}
938
939/* Send BGP notify packet. */
940void
941bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
942{
943 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
944}
945
paulfd79ac92004-10-13 05:06:08 +0000946const char *
paul718e3742002-12-13 20:15:29 +0000947afi2str (afi_t afi)
948{
949 if (afi == AFI_IP)
950 return "AFI_IP";
951 else if (afi == AFI_IP6)
952 return "AFI_IP6";
953 else
954 return "Unknown AFI";
955}
956
paulfd79ac92004-10-13 05:06:08 +0000957const char *
paul718e3742002-12-13 20:15:29 +0000958safi2str (safi_t safi)
959{
960 if (safi == SAFI_UNICAST)
961 return "SAFI_UNICAST";
962 else if (safi == SAFI_MULTICAST)
963 return "SAFI_MULTICAST";
964 else if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPNV4)
965 return "SAFI_MPLS_VPN";
966 else
967 return "Unknown SAFI";
968}
969
970/* Send route refresh message to the peer. */
971void
972bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
973 u_char orf_type, u_char when_to_refresh, int remove)
974{
975 struct stream *s;
976 struct stream *packet;
977 int length;
978 struct bgp_filter *filter;
979 int orf_refresh = 0;
980
981#ifdef DISABLE_BGP_ANNOUNCE
982 return;
983#endif /* DISABLE_BGP_ANNOUNCE */
984
985 filter = &peer->filter[afi][safi];
986
987 /* Adjust safi code. */
988 if (safi == SAFI_MPLS_VPN)
989 safi = BGP_SAFI_VPNV4;
990
991 s = stream_new (BGP_MAX_PACKET_SIZE);
992
993 /* Make BGP update packet. */
994 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
995 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
996 else
997 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
998
999 /* Encode Route Refresh message. */
1000 stream_putw (s, afi);
1001 stream_putc (s, 0);
1002 stream_putc (s, safi);
1003
1004 if (orf_type == ORF_TYPE_PREFIX
1005 || orf_type == ORF_TYPE_PREFIX_OLD)
1006 if (remove || filter->plist[FILTER_IN].plist)
1007 {
1008 u_int16_t orf_len;
1009 unsigned long orfp;
1010
1011 orf_refresh = 1;
1012 stream_putc (s, when_to_refresh);
1013 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001014 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001015 stream_putw (s, 0);
1016
1017 if (remove)
1018 {
1019 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1020 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1021 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001022 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001023 peer->host, orf_type,
1024 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1025 afi, safi);
1026 }
1027 else
1028 {
1029 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1030 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1031 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1032 ORF_COMMON_PART_DENY);
1033 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001034 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001035 peer->host, orf_type,
1036 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1037 afi, safi);
1038 }
1039
1040 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001041 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001042 stream_putw_at (s, orfp, orf_len);
1043 }
1044
1045 /* Set packet size. */
1046 length = bgp_packet_set_size (s);
1047
1048 if (BGP_DEBUG (normal, NORMAL))
1049 {
1050 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001051 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001052 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001053 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001054 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1055 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1056 }
1057
1058 /* Make real packet. */
1059 packet = bgp_packet_dup (s);
1060 stream_free (s);
1061
1062 /* Add packet to the peer. */
1063 bgp_packet_add (peer, packet);
1064
pauleb821182004-05-01 08:44:08 +00001065 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001066}
1067
1068/* Send capability message to the peer. */
1069void
1070bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1071 int capability_code, int action)
1072{
1073 struct stream *s;
1074 struct stream *packet;
1075 int length;
1076
1077 /* Adjust safi code. */
1078 if (safi == SAFI_MPLS_VPN)
1079 safi = BGP_SAFI_VPNV4;
1080
1081 s = stream_new (BGP_MAX_PACKET_SIZE);
1082
1083 /* Make BGP update packet. */
1084 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1085
1086 /* Encode MP_EXT capability. */
1087 if (capability_code == CAPABILITY_CODE_MP)
1088 {
1089 stream_putc (s, action);
1090 stream_putc (s, CAPABILITY_CODE_MP);
1091 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1092 stream_putw (s, afi);
1093 stream_putc (s, 0);
1094 stream_putc (s, safi);
1095
1096 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001097 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001098 peer->host, action == CAPABILITY_ACTION_SET ?
1099 "Advertising" : "Removing", afi, safi);
1100 }
1101
paul718e3742002-12-13 20:15:29 +00001102 /* Set packet size. */
1103 length = bgp_packet_set_size (s);
1104
1105 /* Make real packet. */
1106 packet = bgp_packet_dup (s);
1107 stream_free (s);
1108
1109 /* Add packet to the peer. */
1110 bgp_packet_add (peer, packet);
1111
1112 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001113 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001114 peer->host, BGP_MSG_CAPABILITY, length);
1115
pauleb821182004-05-01 08:44:08 +00001116 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001117}
1118
1119/* RFC1771 6.8 Connection collision detection. */
1120int
pauleb821182004-05-01 08:44:08 +00001121bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001122{
pauleb821182004-05-01 08:44:08 +00001123 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001124 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001125 struct bgp *bgp;
1126
1127 bgp = bgp_get_default ();
1128 if (! bgp)
1129 return 0;
1130
1131 /* Upon receipt of an OPEN message, the local system must examine
1132 all of its connections that are in the OpenConfirm state. A BGP
1133 speaker may also examine connections in an OpenSent state if it
1134 knows the BGP Identifier of the peer by means outside of the
1135 protocol. If among these connections there is a connection to a
1136 remote BGP speaker whose BGP Identifier equals the one in the
1137 OPEN message, then the local system performs the following
1138 collision resolution procedure: */
1139
paul1eb8ef22005-04-07 07:30:20 +00001140 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001141 {
1142 /* Under OpenConfirm status, local peer structure already hold
1143 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001144
1145 if (peer != new
1146 && (peer->status == OpenConfirm || peer->status == OpenSent)
1147 && sockunion_same (&peer->su, &new->su))
1148 {
paul718e3742002-12-13 20:15:29 +00001149 /* 1. The BGP Identifier of the local system is compared to
1150 the BGP Identifier of the remote system (as specified in
1151 the OPEN message). */
1152
1153 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1154 {
1155 /* 2. If the value of the local BGP Identifier is less
1156 than the remote one, the local system closes BGP
1157 connection that already exists (the one that is
1158 already in the OpenConfirm state), and accepts BGP
1159 connection initiated by the remote system. */
1160
pauleb821182004-05-01 08:44:08 +00001161 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001162 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001163 return 1;
1164 }
1165 else
1166 {
1167 /* 3. Otherwise, the local system closes newly created
1168 BGP connection (the one associated with the newly
1169 received OPEN message), and continues to use the
1170 existing one (the one that is already in the
1171 OpenConfirm state). */
1172
pauleb821182004-05-01 08:44:08 +00001173 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001174 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1175 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001176 return -1;
1177 }
pauleb821182004-05-01 08:44:08 +00001178 }
1179 }
paul718e3742002-12-13 20:15:29 +00001180 return 0;
1181}
1182
1183int
1184bgp_open_receive (struct peer *peer, bgp_size_t size)
1185{
1186 int ret;
1187 u_char version;
1188 u_char optlen;
1189 u_int16_t holdtime;
1190 u_int16_t send_holdtime;
1191 as_t remote_as;
1192 struct peer *realpeer;
1193 struct in_addr remote_id;
1194 int capability;
paul5228ad22004-06-04 17:58:18 +00001195 u_int8_t notify_data_remote_as[2];
1196 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001197
1198 realpeer = NULL;
1199
1200 /* Parse open packet. */
1201 version = stream_getc (peer->ibuf);
1202 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1203 remote_as = stream_getw (peer->ibuf);
1204 holdtime = stream_getw (peer->ibuf);
1205 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1206 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1207
1208 /* Receive OPEN message log */
1209 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001210 zlog_debug ("%s rcv OPEN, version %d, remote-as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +00001211 peer->host, version, remote_as, holdtime,
1212 inet_ntoa (remote_id));
1213
1214 /* Lookup peer from Open packet. */
1215 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1216 {
1217 int as = 0;
1218
1219 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1220
1221 if (! realpeer)
1222 {
1223 /* Peer's source IP address is check in bgp_accept(), so this
1224 must be AS number mismatch or remote-id configuration
1225 mismatch. */
1226 if (as)
1227 {
1228 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001229 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1230 peer->host, inet_ntoa (remote_id));
1231 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1232 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1233 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001234 }
1235 else
1236 {
1237 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001238 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
1239 peer->host, remote_as, peer->as);
1240 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1241 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1242 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001243 }
1244 return -1;
1245 }
1246 }
1247
1248 /* When collision is detected and this peer is closed. Retrun
1249 immidiately. */
1250 ret = bgp_collision_detect (peer, remote_id);
1251 if (ret < 0)
1252 return ret;
1253
pauleb821182004-05-01 08:44:08 +00001254 /* Hack part. */
1255 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1256 {
hasso93406d82005-02-02 14:40:33 +00001257 if (realpeer->status == Established
1258 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1259 {
1260 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1261 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1262 }
1263 else if (ret == 0 && realpeer->status != Active
1264 && realpeer->status != OpenSent
1265 && realpeer->status != OpenConfirm)
1266
pauleb821182004-05-01 08:44:08 +00001267 {
1268 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001269 zlog_debug ("%s peer status is %s close connection",
1270 realpeer->host, LOOKUP (bgp_status_msg,
1271 realpeer->status));
1272 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1273 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1274
pauleb821182004-05-01 08:44:08 +00001275 return -1;
1276 }
1277
1278 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00001279 zlog_debug ("%s [Event] Transfer temporary BGP peer to existing one",
pauleb821182004-05-01 08:44:08 +00001280 peer->host);
1281
1282 bgp_stop (realpeer);
1283
1284 /* Transfer file descriptor. */
1285 realpeer->fd = peer->fd;
1286 peer->fd = -1;
1287
1288 /* Transfer input buffer. */
1289 stream_free (realpeer->ibuf);
1290 realpeer->ibuf = peer->ibuf;
1291 realpeer->packet_size = peer->packet_size;
1292 peer->ibuf = NULL;
1293
1294 /* Transfer status. */
1295 realpeer->status = peer->status;
1296 bgp_stop (peer);
1297
1298 /* peer pointer change. Open packet send to neighbor. */
1299 peer = realpeer;
1300 bgp_open_send (peer);
1301 if (peer->fd < 0)
1302 {
1303 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1304 peer->fd);
1305 return -1;
1306 }
1307 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1308 }
1309
paul718e3742002-12-13 20:15:29 +00001310 /* remote router-id check. */
1311 if (remote_id.s_addr == 0
1312 || ntohl (remote_id.s_addr) >= 0xe0000000
1313 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1314 {
1315 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001316 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001317 peer->host, inet_ntoa (remote_id));
1318 bgp_notify_send_with_data (peer,
1319 BGP_NOTIFY_OPEN_ERR,
1320 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1321 notify_data_remote_id, 4);
1322 return -1;
1323 }
1324
1325 /* Set remote router-id */
1326 peer->remote_id = remote_id;
1327
1328 /* Peer BGP version check. */
1329 if (version != BGP_VERSION_4)
1330 {
paul5228ad22004-06-04 17:58:18 +00001331 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001332 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001333 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001334 peer->host, version, BGP_VERSION_4);
1335 bgp_notify_send_with_data (peer,
1336 BGP_NOTIFY_OPEN_ERR,
1337 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001338 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001339 return -1;
1340 }
1341
1342 /* Check neighbor as number. */
1343 if (remote_as != peer->as)
1344 {
1345 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001346 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
paul718e3742002-12-13 20:15:29 +00001347 peer->host, remote_as, peer->as);
1348 bgp_notify_send_with_data (peer,
1349 BGP_NOTIFY_OPEN_ERR,
1350 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1351 notify_data_remote_as, 2);
1352 return -1;
1353 }
1354
1355 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1356 calculate the value of the Hold Timer by using the smaller of its
1357 configured Hold Time and the Hold Time received in the OPEN message.
1358 The Hold Time MUST be either zero or at least three seconds. An
1359 implementation may reject connections on the basis of the Hold Time. */
1360
1361 if (holdtime < 3 && holdtime != 0)
1362 {
1363 bgp_notify_send (peer,
1364 BGP_NOTIFY_OPEN_ERR,
1365 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1366 return -1;
1367 }
1368
1369 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1370 would be one third of the Hold Time interval. KEEPALIVE messages
1371 MUST NOT be sent more frequently than one per second. An
1372 implementation MAY adjust the rate at which it sends KEEPALIVE
1373 messages as a function of the Hold Time interval. */
1374
1375 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1376 send_holdtime = peer->holdtime;
1377 else
1378 send_holdtime = peer->bgp->default_holdtime;
1379
1380 if (holdtime < send_holdtime)
1381 peer->v_holdtime = holdtime;
1382 else
1383 peer->v_holdtime = send_holdtime;
1384
1385 peer->v_keepalive = peer->v_holdtime / 3;
1386
1387 /* Open option part parse. */
1388 capability = 0;
1389 optlen = stream_getc (peer->ibuf);
1390 if (optlen != 0)
1391 {
1392 ret = bgp_open_option_parse (peer, optlen, &capability);
1393 if (ret < 0)
1394 return ret;
1395
paul9985f832005-02-09 15:51:56 +00001396 stream_forward_getp (peer->ibuf, optlen);
paul718e3742002-12-13 20:15:29 +00001397 }
1398 else
1399 {
1400 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001401 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001402 peer->host);
1403 }
1404
1405 /* Override capability. */
1406 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1407 {
1408 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1409 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1410 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1411 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1412 }
1413
1414 /* Get sockname. */
1415 bgp_getsockname (peer);
1416
1417 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1418
1419 peer->packet_size = 0;
1420 if (peer->ibuf)
1421 stream_reset (peer->ibuf);
1422
1423 return 0;
1424}
1425
1426/* Parse BGP Update packet and make attribute object. */
1427int
1428bgp_update_receive (struct peer *peer, bgp_size_t size)
1429{
1430 int ret;
1431 u_char *end;
1432 struct stream *s;
1433 struct attr attr;
1434 bgp_size_t attribute_len;
1435 bgp_size_t update_len;
1436 bgp_size_t withdraw_len;
1437 struct bgp_nlri update;
1438 struct bgp_nlri withdraw;
1439 struct bgp_nlri mp_update;
1440 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001441 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001442
1443 /* Status must be Established. */
1444 if (peer->status != Established)
1445 {
1446 zlog_err ("%s [FSM] Update packet received under status %s",
1447 peer->host, LOOKUP (bgp_status_msg, peer->status));
1448 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1449 return -1;
1450 }
1451
1452 /* Set initial values. */
1453 memset (&attr, 0, sizeof (struct attr));
1454 memset (&update, 0, sizeof (struct bgp_nlri));
1455 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1456 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1457 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1458
1459 s = peer->ibuf;
1460 end = stream_pnt (s) + size;
1461
1462 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1463 Length is too large (i.e., if Unfeasible Routes Length + Total
1464 Attribute Length + 23 exceeds the message Length), then the Error
1465 Subcode is set to Malformed Attribute List. */
1466 if (stream_pnt (s) + 2 > end)
1467 {
1468 zlog_err ("%s [Error] Update packet error"
1469 " (packet length is short for unfeasible length)",
1470 peer->host);
1471 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1472 BGP_NOTIFY_UPDATE_MAL_ATTR);
1473 return -1;
1474 }
1475
1476 /* Unfeasible Route Length. */
1477 withdraw_len = stream_getw (s);
1478
1479 /* Unfeasible Route Length check. */
1480 if (stream_pnt (s) + withdraw_len > end)
1481 {
1482 zlog_err ("%s [Error] Update packet error"
1483 " (packet unfeasible length overflow %d)",
1484 peer->host, withdraw_len);
1485 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1486 BGP_NOTIFY_UPDATE_MAL_ATTR);
1487 return -1;
1488 }
1489
1490 /* Unfeasible Route packet format check. */
1491 if (withdraw_len > 0)
1492 {
1493 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1494 if (ret < 0)
1495 return -1;
1496
1497 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001498 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001499
1500 withdraw.afi = AFI_IP;
1501 withdraw.safi = SAFI_UNICAST;
1502 withdraw.nlri = stream_pnt (s);
1503 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001504 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001505 }
1506
1507 /* Attribute total length check. */
1508 if (stream_pnt (s) + 2 > end)
1509 {
1510 zlog_warn ("%s [Error] Packet Error"
1511 " (update packet is short for attribute length)",
1512 peer->host);
1513 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1514 BGP_NOTIFY_UPDATE_MAL_ATTR);
1515 return -1;
1516 }
1517
1518 /* Fetch attribute total length. */
1519 attribute_len = stream_getw (s);
1520
1521 /* Attribute length check. */
1522 if (stream_pnt (s) + attribute_len > end)
1523 {
1524 zlog_warn ("%s [Error] Packet Error"
1525 " (update packet attribute length overflow %d)",
1526 peer->host, attribute_len);
1527 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1528 BGP_NOTIFY_UPDATE_MAL_ATTR);
1529 return -1;
1530 }
1531
1532 /* Parse attribute when it exists. */
1533 if (attribute_len)
1534 {
1535 ret = bgp_attr_parse (peer, &attr, attribute_len,
1536 &mp_update, &mp_withdraw);
1537 if (ret < 0)
1538 return -1;
1539 }
1540
1541 /* Logging the attribute. */
1542 if (BGP_DEBUG (update, UPDATE_IN))
1543 {
paule01f9cb2004-07-09 17:48:53 +00001544 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1545
1546 if (ret)
ajs6b514742004-12-08 21:03:23 +00001547 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001548 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001549 }
1550
1551 /* Network Layer Reachability Information. */
1552 update_len = end - stream_pnt (s);
1553
1554 if (update_len)
1555 {
1556 /* Check NLRI packet format and prefix length. */
1557 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1558 if (ret < 0)
1559 return -1;
1560
1561 /* Set NLRI portion to structure. */
1562 update.afi = AFI_IP;
1563 update.safi = SAFI_UNICAST;
1564 update.nlri = stream_pnt (s);
1565 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001566 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001567 }
1568
1569 /* NLRI is processed only when the peer is configured specific
1570 Address Family and Subsequent Address Family. */
1571 if (peer->afc[AFI_IP][SAFI_UNICAST])
1572 {
1573 if (withdraw.length)
1574 bgp_nlri_parse (peer, NULL, &withdraw);
1575
1576 if (update.length)
1577 {
1578 /* We check well-known attribute only for IPv4 unicast
1579 update. */
1580 ret = bgp_attr_check (peer, &attr);
1581 if (ret < 0)
1582 return -1;
1583
1584 bgp_nlri_parse (peer, &attr, &update);
1585 }
paule01f9cb2004-07-09 17:48:53 +00001586
hassof4184462005-02-01 20:13:16 +00001587 if (mp_update.length
1588 && mp_update.afi == AFI_IP
1589 && mp_update.safi == SAFI_UNICAST)
1590 bgp_nlri_parse (peer, &attr, &mp_update);
1591
1592 if (mp_withdraw.length
1593 && mp_withdraw.afi == AFI_IP
1594 && mp_withdraw.safi == SAFI_UNICAST)
1595 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1596
paule01f9cb2004-07-09 17:48:53 +00001597 if (! attribute_len && ! withdraw_len)
1598 {
1599 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001600 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1601 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001602
hasso93406d82005-02-02 14:40:33 +00001603 /* NSF delete stale route */
1604 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1605 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1606
1607 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001608 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001609 peer->host);
1610 }
paul718e3742002-12-13 20:15:29 +00001611 }
1612 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1613 {
1614 if (mp_update.length
1615 && mp_update.afi == AFI_IP
1616 && mp_update.safi == SAFI_MULTICAST)
1617 bgp_nlri_parse (peer, &attr, &mp_update);
1618
1619 if (mp_withdraw.length
1620 && mp_withdraw.afi == AFI_IP
1621 && mp_withdraw.safi == SAFI_MULTICAST)
1622 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001623
hasso93406d82005-02-02 14:40:33 +00001624 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001625 && mp_withdraw.afi == AFI_IP
1626 && mp_withdraw.safi == SAFI_MULTICAST
1627 && mp_withdraw.length == 0)
1628 {
1629 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001630 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1631 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001632
hasso93406d82005-02-02 14:40:33 +00001633 /* NSF delete stale route */
1634 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1635 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1636
1637 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001638 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001639 peer->host);
1640 }
paul718e3742002-12-13 20:15:29 +00001641 }
1642 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1643 {
1644 if (mp_update.length
1645 && mp_update.afi == AFI_IP6
1646 && mp_update.safi == SAFI_UNICAST)
1647 bgp_nlri_parse (peer, &attr, &mp_update);
1648
1649 if (mp_withdraw.length
1650 && mp_withdraw.afi == AFI_IP6
1651 && mp_withdraw.safi == SAFI_UNICAST)
1652 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001653
hasso93406d82005-02-02 14:40:33 +00001654 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001655 && mp_withdraw.afi == AFI_IP6
1656 && mp_withdraw.safi == SAFI_UNICAST
1657 && mp_withdraw.length == 0)
1658 {
1659 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001660 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001661
hasso93406d82005-02-02 14:40:33 +00001662 /* NSF delete stale route */
1663 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1664 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1665
1666 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001667 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001668 peer->host);
1669 }
paul718e3742002-12-13 20:15:29 +00001670 }
1671 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1672 {
1673 if (mp_update.length
1674 && mp_update.afi == AFI_IP6
1675 && mp_update.safi == SAFI_MULTICAST)
1676 bgp_nlri_parse (peer, &attr, &mp_update);
1677
1678 if (mp_withdraw.length
1679 && mp_withdraw.afi == AFI_IP6
1680 && mp_withdraw.safi == SAFI_MULTICAST)
1681 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001682
hasso93406d82005-02-02 14:40:33 +00001683 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001684 && mp_withdraw.afi == AFI_IP6
1685 && mp_withdraw.safi == SAFI_MULTICAST
1686 && mp_withdraw.length == 0)
1687 {
1688 /* End-of-RIB received */
1689
hasso93406d82005-02-02 14:40:33 +00001690 /* NSF delete stale route */
1691 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1692 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1693
paule01f9cb2004-07-09 17:48:53 +00001694 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001695 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001696 peer->host);
1697 }
paul718e3742002-12-13 20:15:29 +00001698 }
1699 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1700 {
1701 if (mp_update.length
1702 && mp_update.afi == AFI_IP
1703 && mp_update.safi == BGP_SAFI_VPNV4)
1704 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1705
1706 if (mp_withdraw.length
1707 && mp_withdraw.afi == AFI_IP
1708 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1709 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001710
hasso93406d82005-02-02 14:40:33 +00001711 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001712 && mp_withdraw.afi == AFI_IP
1713 && mp_withdraw.safi == BGP_SAFI_VPNV4
1714 && mp_withdraw.length == 0)
1715 {
1716 /* End-of-RIB received */
1717
1718 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001719 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001720 peer->host);
1721 }
paul718e3742002-12-13 20:15:29 +00001722 }
1723
1724 /* Everything is done. We unintern temporary structures which
1725 interned in bgp_attr_parse(). */
1726 if (attr.aspath)
1727 aspath_unintern (attr.aspath);
1728 if (attr.community)
1729 community_unintern (attr.community);
1730 if (attr.ecommunity)
1731 ecommunity_unintern (attr.ecommunity);
1732 if (attr.cluster)
1733 cluster_unintern (attr.cluster);
1734 if (attr.transit)
1735 transit_unintern (attr.transit);
1736
1737 /* If peering is stopped due to some reason, do not generate BGP
1738 event. */
1739 if (peer->status != Established)
1740 return 0;
1741
1742 /* Increment packet counter. */
1743 peer->update_in++;
1744 peer->update_time = time (NULL);
1745
1746 /* Generate BGP event. */
1747 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1748
1749 return 0;
1750}
1751
1752/* Notify message treatment function. */
1753void
1754bgp_notify_receive (struct peer *peer, bgp_size_t size)
1755{
1756 struct bgp_notify bgp_notify;
1757
1758 if (peer->notify.data)
1759 {
1760 XFREE (MTYPE_TMP, peer->notify.data);
1761 peer->notify.data = NULL;
1762 peer->notify.length = 0;
1763 }
1764
1765 bgp_notify.code = stream_getc (peer->ibuf);
1766 bgp_notify.subcode = stream_getc (peer->ibuf);
1767 bgp_notify.length = size - 2;
1768 bgp_notify.data = NULL;
1769
1770 /* Preserv notify code and sub code. */
1771 peer->notify.code = bgp_notify.code;
1772 peer->notify.subcode = bgp_notify.subcode;
1773 /* For further diagnostic record returned Data. */
1774 if (bgp_notify.length)
1775 {
1776 peer->notify.length = size - 2;
1777 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1778 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1779 }
1780
1781 /* For debug */
1782 {
1783 int i;
1784 int first = 0;
1785 char c[4];
1786
1787 if (bgp_notify.length)
1788 {
1789 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1790 for (i = 0; i < bgp_notify.length; i++)
1791 if (first)
1792 {
1793 sprintf (c, " %02x", stream_getc (peer->ibuf));
1794 strcat (bgp_notify.data, c);
1795 }
1796 else
1797 {
1798 first = 1;
1799 sprintf (c, "%02x", stream_getc (peer->ibuf));
1800 strcpy (bgp_notify.data, c);
1801 }
1802 }
1803
1804 bgp_notify_print(peer, &bgp_notify, "received");
1805 if (bgp_notify.data)
1806 XFREE (MTYPE_TMP, bgp_notify.data);
1807 }
1808
1809 /* peer count update */
1810 peer->notify_in++;
1811
hassoe0701b72004-05-20 09:19:34 +00001812 if (peer->status == Established)
1813 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1814
paul718e3742002-12-13 20:15:29 +00001815 /* We have to check for Notify with Unsupported Optional Parameter.
1816 in that case we fallback to open without the capability option.
1817 But this done in bgp_stop. We just mark it here to avoid changing
1818 the fsm tables. */
1819 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1820 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1821 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1822
1823 /* Also apply to Unsupported Capability until remote router support
1824 capability. */
1825 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1826 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
1827 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1828
1829 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1830}
1831
1832/* Keepalive treatment function -- get keepalive send keepalive */
1833void
1834bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1835{
1836 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001837 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001838
1839 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1840}
1841
1842/* Route refresh message is received. */
1843void
1844bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1845{
1846 afi_t afi;
1847 safi_t safi;
1848 u_char reserved;
1849 struct stream *s;
1850
1851 /* If peer does not have the capability, send notification. */
1852 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1853 {
1854 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1855 peer->host);
1856 bgp_notify_send (peer,
1857 BGP_NOTIFY_HEADER_ERR,
1858 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1859 return;
1860 }
1861
1862 /* Status must be Established. */
1863 if (peer->status != Established)
1864 {
1865 plog_err (peer->log,
1866 "%s [Error] Route refresh packet received under status %s",
1867 peer->host, LOOKUP (bgp_status_msg, peer->status));
1868 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1869 return;
1870 }
1871
1872 s = peer->ibuf;
1873
1874 /* Parse packet. */
1875 afi = stream_getw (s);
1876 reserved = stream_getc (s);
1877 safi = stream_getc (s);
1878
1879 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001880 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001881 peer->host, afi, safi);
1882
1883 /* Check AFI and SAFI. */
1884 if ((afi != AFI_IP && afi != AFI_IP6)
1885 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1886 && safi != BGP_SAFI_VPNV4))
1887 {
1888 if (BGP_DEBUG (normal, NORMAL))
1889 {
ajs6b514742004-12-08 21:03:23 +00001890 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001891 peer->host, afi, safi);
1892 }
1893 return;
1894 }
1895
1896 /* Adjust safi code. */
1897 if (safi == BGP_SAFI_VPNV4)
1898 safi = SAFI_MPLS_VPN;
1899
1900 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1901 {
1902 u_char *end;
1903 u_char when_to_refresh;
1904 u_char orf_type;
1905 u_int16_t orf_len;
1906
1907 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1908 {
1909 zlog_info ("%s ORF route refresh length error", peer->host);
1910 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1911 return;
1912 }
1913
1914 when_to_refresh = stream_getc (s);
1915 end = stream_pnt (s) + (size - 5);
1916
1917 while (stream_pnt (s) < end)
1918 {
1919 orf_type = stream_getc (s);
1920 orf_len = stream_getw (s);
1921
1922 if (orf_type == ORF_TYPE_PREFIX
1923 || orf_type == ORF_TYPE_PREFIX_OLD)
1924 {
1925 u_char *p_pnt = stream_pnt (s);
1926 u_char *p_end = stream_pnt (s) + orf_len;
1927 struct orf_prefix orfp;
1928 u_char common = 0;
1929 u_int32_t seq;
1930 int psize;
1931 char name[BUFSIZ];
1932 char buf[BUFSIZ];
1933 int ret;
1934
1935 if (BGP_DEBUG (normal, NORMAL))
1936 {
ajs6b514742004-12-08 21:03:23 +00001937 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00001938 peer->host, orf_type, orf_len);
1939 }
1940
1941 /* ORF prefix-list name */
1942 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
1943
1944 while (p_pnt < p_end)
1945 {
1946 memset (&orfp, 0, sizeof (struct orf_prefix));
1947 common = *p_pnt++;
1948 if (common & ORF_COMMON_PART_REMOVE_ALL)
1949 {
1950 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001951 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00001952 prefix_bgp_orf_remove_all (name);
1953 break;
1954 }
1955 memcpy (&seq, p_pnt, sizeof (u_int32_t));
1956 p_pnt += sizeof (u_int32_t);
1957 orfp.seq = ntohl (seq);
1958 orfp.ge = *p_pnt++;
1959 orfp.le = *p_pnt++;
1960 orfp.p.prefixlen = *p_pnt++;
1961 orfp.p.family = afi2family (afi);
1962 psize = PSIZE (orfp.p.prefixlen);
1963 memcpy (&orfp.p.u.prefix, p_pnt, psize);
1964 p_pnt += psize;
1965
1966 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001967 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
paul718e3742002-12-13 20:15:29 +00001968 peer->host,
1969 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
1970 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
1971 orfp.seq,
1972 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
1973 orfp.p.prefixlen, orfp.ge, orfp.le);
1974
1975 ret = prefix_bgp_orf_set (name, afi, &orfp,
1976 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
1977 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
1978
1979 if (ret != CMD_SUCCESS)
1980 {
1981 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001982 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00001983 prefix_bgp_orf_remove_all (name);
1984 break;
1985 }
1986 }
1987 peer->orf_plist[afi][safi] =
1988 prefix_list_lookup (AFI_ORF_PREFIX, name);
1989 }
paul9985f832005-02-09 15:51:56 +00001990 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00001991 }
1992 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001993 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00001994 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
1995 if (when_to_refresh == REFRESH_DEFER)
1996 return;
1997 }
1998
1999 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2000 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2001 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2002
2003 /* Perform route refreshment to the peer */
2004 bgp_announce_route (peer, afi, safi);
2005}
2006
2007int
2008bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2009{
2010 u_char *end;
2011 struct capability cap;
2012 u_char action;
2013 struct bgp *bgp;
2014 afi_t afi;
2015 safi_t safi;
2016
2017 bgp = peer->bgp;
2018 end = pnt + length;
2019
2020 while (pnt < end)
2021 {
2022 /* We need at least action, capability code and capability length. */
2023 if (pnt + 3 > end)
2024 {
2025 zlog_info ("%s Capability length error", peer->host);
2026 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2027 return -1;
2028 }
2029
2030 action = *pnt;
2031
2032 /* Fetch structure to the byte stream. */
2033 memcpy (&cap, pnt + 1, sizeof (struct capability));
2034
2035 /* Action value check. */
2036 if (action != CAPABILITY_ACTION_SET
2037 && action != CAPABILITY_ACTION_UNSET)
2038 {
2039 zlog_info ("%s Capability Action Value error %d",
2040 peer->host, action);
2041 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2042 return -1;
2043 }
2044
2045 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002046 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
paul718e3742002-12-13 20:15:29 +00002047 peer->host, action, cap.code, cap.length);
2048
2049 /* Capability length check. */
2050 if (pnt + (cap.length + 3) > end)
2051 {
2052 zlog_info ("%s Capability length error", peer->host);
2053 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2054 return -1;
2055 }
2056
2057 /* We know MP Capability Code. */
2058 if (cap.code == CAPABILITY_CODE_MP)
2059 {
2060 afi = ntohs (cap.mpc.afi);
2061 safi = cap.mpc.safi;
2062
2063 /* Ignore capability when override-capability is set. */
2064 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2065 continue;
2066
2067 /* Address family check. */
2068 if ((afi == AFI_IP
2069 || afi == AFI_IP6)
2070 && (safi == SAFI_UNICAST
2071 || safi == SAFI_MULTICAST
2072 || safi == BGP_SAFI_VPNV4))
2073 {
2074 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002075 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
paul718e3742002-12-13 20:15:29 +00002076 peer->host,
2077 action == CAPABILITY_ACTION_SET
2078 ? "Advertising" : "Removing",
2079 ntohs(cap.mpc.afi) , cap.mpc.safi);
2080
2081 /* Adjust safi code. */
2082 if (safi == BGP_SAFI_VPNV4)
2083 safi = SAFI_MPLS_VPN;
2084
2085 if (action == CAPABILITY_ACTION_SET)
2086 {
2087 peer->afc_recv[afi][safi] = 1;
2088 if (peer->afc[afi][safi])
2089 {
2090 peer->afc_nego[afi][safi] = 1;
2091 bgp_announce_route (peer, afi, safi);
2092 }
2093 }
2094 else
2095 {
2096 peer->afc_recv[afi][safi] = 0;
2097 peer->afc_nego[afi][safi] = 0;
2098
2099 if (peer_active_nego (peer))
2100 bgp_clear_route (peer, afi, safi);
2101 else
2102 BGP_EVENT_ADD (peer, BGP_Stop);
2103 }
2104 }
2105 }
paul718e3742002-12-13 20:15:29 +00002106 else
2107 {
2108 zlog_warn ("%s unrecognized capability code: %d - ignored",
2109 peer->host, cap.code);
2110 }
2111 pnt += cap.length + 3;
2112 }
2113 return 0;
2114}
2115
2116/* Dynamic Capability is received. */
2117void
2118bgp_capability_receive (struct peer *peer, bgp_size_t size)
2119{
2120 u_char *pnt;
2121 int ret;
2122
2123 /* Fetch pointer. */
2124 pnt = stream_pnt (peer->ibuf);
2125
2126 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002127 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002128
2129 /* If peer does not have the capability, send notification. */
2130 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2131 {
2132 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2133 peer->host);
2134 bgp_notify_send (peer,
2135 BGP_NOTIFY_HEADER_ERR,
2136 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2137 return;
2138 }
2139
2140 /* Status must be Established. */
2141 if (peer->status != Established)
2142 {
2143 plog_err (peer->log,
2144 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2145 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2146 return;
2147 }
2148
2149 /* Parse packet. */
2150 ret = bgp_capability_msg_parse (peer, pnt, size);
2151}
2152
2153/* BGP read utility function. */
2154int
2155bgp_read_packet (struct peer *peer)
2156{
2157 int nbytes;
2158 int readsize;
2159
paul9985f832005-02-09 15:51:56 +00002160 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002161
2162 /* If size is zero then return. */
2163 if (! readsize)
2164 return 0;
2165
2166 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002167 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002168
2169 /* If read byte is smaller than zero then error occured. */
2170 if (nbytes < 0)
2171 {
2172 if (errno == EAGAIN)
2173 return -1;
2174
2175 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002176 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002177
2178 if (peer->status == Established)
2179 {
2180 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2181 {
2182 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2183 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2184 }
2185 else
2186 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2187 }
2188
paul718e3742002-12-13 20:15:29 +00002189 BGP_EVENT_ADD (peer, TCP_fatal_error);
2190 return -1;
2191 }
2192
2193 /* When read byte is zero : clear bgp peer and return */
2194 if (nbytes == 0)
2195 {
2196 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002197 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002198 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002199
2200 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002201 {
2202 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2203 {
2204 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2205 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2206 }
2207 else
2208 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2209 }
hassoe0701b72004-05-20 09:19:34 +00002210
paul718e3742002-12-13 20:15:29 +00002211 BGP_EVENT_ADD (peer, TCP_connection_closed);
2212 return -1;
2213 }
2214
2215 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002216 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002217 return -1;
2218
2219 return 0;
2220}
2221
2222/* Marker check. */
2223int
2224bgp_marker_all_one (struct stream *s, int length)
2225{
2226 int i;
2227
2228 for (i = 0; i < length; i++)
2229 if (s->data[i] != 0xff)
2230 return 0;
2231
2232 return 1;
2233}
2234
2235/* Starting point of packet process function. */
2236int
2237bgp_read (struct thread *thread)
2238{
2239 int ret;
2240 u_char type = 0;
2241 struct peer *peer;
2242 bgp_size_t size;
2243 char notify_data_length[2];
2244
2245 /* Yes first of all get peer pointer. */
2246 peer = THREAD_ARG (thread);
2247 peer->t_read = NULL;
2248
2249 /* For non-blocking IO check. */
2250 if (peer->status == Connect)
2251 {
2252 bgp_connect_check (peer);
2253 goto done;
2254 }
2255 else
2256 {
pauleb821182004-05-01 08:44:08 +00002257 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002258 {
pauleb821182004-05-01 08:44:08 +00002259 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002260 return -1;
2261 }
pauleb821182004-05-01 08:44:08 +00002262 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002263 }
2264
2265 /* Read packet header to determine type of the packet */
2266 if (peer->packet_size == 0)
2267 peer->packet_size = BGP_HEADER_SIZE;
2268
paul9985f832005-02-09 15:51:56 +00002269 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002270 {
2271 ret = bgp_read_packet (peer);
2272
2273 /* Header read error or partial read packet. */
2274 if (ret < 0)
2275 goto done;
2276
2277 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002278 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002279 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2280 size = stream_getw (peer->ibuf);
2281 type = stream_getc (peer->ibuf);
2282
2283 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002284 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002285 peer->host, type, size - BGP_HEADER_SIZE);
2286
2287 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002288 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002289 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2290 {
2291 bgp_notify_send (peer,
2292 BGP_NOTIFY_HEADER_ERR,
2293 BGP_NOTIFY_HEADER_NOT_SYNC);
2294 goto done;
2295 }
2296
2297 /* BGP type check. */
2298 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2299 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2300 && type != BGP_MSG_ROUTE_REFRESH_NEW
2301 && type != BGP_MSG_ROUTE_REFRESH_OLD
2302 && type != BGP_MSG_CAPABILITY)
2303 {
2304 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002305 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002306 "%s unknown message type 0x%02x",
2307 peer->host, type);
2308 bgp_notify_send_with_data (peer,
2309 BGP_NOTIFY_HEADER_ERR,
2310 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2311 &type, 1);
2312 goto done;
2313 }
2314 /* Mimimum packet length check. */
2315 if ((size < BGP_HEADER_SIZE)
2316 || (size > BGP_MAX_PACKET_SIZE)
2317 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2318 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2319 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2320 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2321 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2322 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2323 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2324 {
2325 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002326 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002327 "%s bad message length - %d for %s",
2328 peer->host, size,
2329 type == 128 ? "ROUTE-REFRESH" :
2330 bgp_type_str[(int) type]);
2331 bgp_notify_send_with_data (peer,
2332 BGP_NOTIFY_HEADER_ERR,
2333 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002334 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002335 goto done;
2336 }
2337
2338 /* Adjust size to message length. */
2339 peer->packet_size = size;
2340 }
2341
2342 ret = bgp_read_packet (peer);
2343 if (ret < 0)
2344 goto done;
2345
2346 /* Get size and type again. */
2347 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2348 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2349
2350 /* BGP packet dump function. */
2351 bgp_dump_packet (peer, type, peer->ibuf);
2352
2353 size = (peer->packet_size - BGP_HEADER_SIZE);
2354
2355 /* Read rest of the packet and call each sort of packet routine */
2356 switch (type)
2357 {
2358 case BGP_MSG_OPEN:
2359 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002360 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002361 break;
2362 case BGP_MSG_UPDATE:
2363 peer->readtime = time(NULL); /* Last read timer reset */
2364 bgp_update_receive (peer, size);
2365 break;
2366 case BGP_MSG_NOTIFY:
2367 bgp_notify_receive (peer, size);
2368 break;
2369 case BGP_MSG_KEEPALIVE:
2370 peer->readtime = time(NULL); /* Last read timer reset */
2371 bgp_keepalive_receive (peer, size);
2372 break;
2373 case BGP_MSG_ROUTE_REFRESH_NEW:
2374 case BGP_MSG_ROUTE_REFRESH_OLD:
2375 peer->refresh_in++;
2376 bgp_route_refresh_receive (peer, size);
2377 break;
2378 case BGP_MSG_CAPABILITY:
2379 peer->dynamic_cap_in++;
2380 bgp_capability_receive (peer, size);
2381 break;
2382 }
2383
2384 /* Clear input buffer. */
2385 peer->packet_size = 0;
2386 if (peer->ibuf)
2387 stream_reset (peer->ibuf);
2388
2389 done:
2390 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2391 {
2392 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002393 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002394 peer_delete (peer);
2395 }
2396 return 0;
2397}