blob: 2653201172a594d1d063ac5e59419de6c9b34214 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
31#include "linklist.h"
32#include "plist.h"
33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_table.h"
36#include "bgpd/bgp_dump.h"
37#include "bgpd/bgp_attr.h"
38#include "bgpd/bgp_debug.h"
39#include "bgpd/bgp_fsm.h"
40#include "bgpd/bgp_route.h"
41#include "bgpd/bgp_packet.h"
42#include "bgpd/bgp_open.h"
43#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_community.h"
45#include "bgpd/bgp_ecommunity.h"
46#include "bgpd/bgp_network.h"
47#include "bgpd/bgp_mplsvpn.h"
48#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000049#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000050
51int stream_put_prefix (struct stream *, struct prefix *);
52
53/* Set up BGP packet marker and packet type. */
54static int
55bgp_packet_set_marker (struct stream *s, u_char type)
56{
57 int i;
58
59 /* Fill in marker. */
60 for (i = 0; i < BGP_MARKER_SIZE; i++)
61 stream_putc (s, 0xff);
62
63 /* Dummy total length. This field is should be filled in later on. */
64 stream_putw (s, 0);
65
66 /* BGP packet type. */
67 stream_putc (s, type);
68
69 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000070 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000071}
72
73/* Set BGP packet header size entry. If size is zero then use current
74 stream size. */
75static int
76bgp_packet_set_size (struct stream *s)
77{
78 int cp;
79
80 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000081 cp = stream_get_endp (s);
82 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000083
84 return cp;
85}
86
87/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000088static void
paul718e3742002-12-13 20:15:29 +000089bgp_packet_add (struct peer *peer, struct stream *s)
90{
91 /* Add packet to the end of list. */
92 stream_fifo_push (peer->obuf, s);
93}
94
95/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000096static void
paul718e3742002-12-13 20:15:29 +000097bgp_packet_delete (struct peer *peer)
98{
99 stream_free (stream_fifo_pop (peer->obuf));
100}
101
paul718e3742002-12-13 20:15:29 +0000102/* Check file descriptor whether connect is established. */
103static void
104bgp_connect_check (struct peer *peer)
105{
106 int status;
paul5228ad22004-06-04 17:58:18 +0000107 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000108 int ret;
109
110 /* Anyway I have to reset read and write thread. */
111 BGP_READ_OFF (peer->t_read);
112 BGP_WRITE_OFF (peer->t_write);
113
114 /* Check file descriptor. */
115 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000116 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000117
118 /* If getsockopt is fail, this is fatal error. */
119 if (ret < 0)
120 {
121 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
122 BGP_EVENT_ADD (peer, TCP_fatal_error);
123 return;
124 }
125
126 /* When status is 0 then TCP connection is established. */
127 if (status == 0)
128 {
129 BGP_EVENT_ADD (peer, TCP_connection_open);
130 }
131 else
132 {
133 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000134 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000135 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000136 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
137 }
138}
139
140/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000141static struct stream *
paul718e3742002-12-13 20:15:29 +0000142bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
143{
144 struct stream *s;
145 struct bgp_adj_out *adj;
146 struct bgp_advertise *adv;
147 struct stream *packet;
148 struct bgp_node *rn = NULL;
149 struct bgp_info *binfo = NULL;
150 bgp_size_t total_attr_len = 0;
151 unsigned long pos;
152 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000153
154 s = peer->work;
155 stream_reset (s);
156
157 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
158
159 while (adv)
160 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000161 assert (adv->rn);
162 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000163 adj = adv->adj;
164 if (adv->binfo)
165 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000166
167 /* When remaining space can't include NLRI and it's length. */
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000168 if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
paul718e3742002-12-13 20:15:29 +0000169 break;
170
171 /* If packet is empty, set attribute. */
172 if (stream_empty (s))
173 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000174 struct prefix_rd *prd = NULL;
175 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000176 struct peer *from = NULL;
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000177
178 if (rn->prn)
179 prd = (struct prefix_rd *) &rn->prn->p;
Paul Jakmafb982c22007-05-04 20:15:47 +0000180 if (binfo && binfo->extra)
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 {
Paul Jakmafb982c22007-05-04 20:15:47 +0000182 tag = binfo->extra->tag;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000183 from = binfo->peer;
184 }
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000185
paul718e3742002-12-13 20:15:29 +0000186 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
187 stream_putw (s, 0);
paul9985f832005-02-09 15:51:56 +0000188 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000189 stream_putw (s, 0);
paul5228ad22004-06-04 17:58:18 +0000190 total_attr_len = bgp_packet_attribute (NULL, peer, s,
191 adv->baa->attr,
192 &rn->p, afi, safi,
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000193 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000194 stream_putw_at (s, pos, total_attr_len);
195 }
196
197 if (afi == AFI_IP && safi == SAFI_UNICAST)
198 stream_put_prefix (s, &rn->p);
199
200 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000201 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
paul718e3742002-12-13 20:15:29 +0000202 peer->host,
203 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
204 rn->p.prefixlen);
205
206 /* Synchnorize attribute. */
207 if (adj->attr)
208 bgp_attr_unintern (adj->attr);
209 else
210 peer->scount[afi][safi]++;
211
212 adj->attr = bgp_attr_intern (adv->baa->attr);
213
214 adv = bgp_advertise_clean (peer, adj, afi, safi);
215
216 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
217 break;
218 }
219
220 if (! stream_empty (s))
221 {
222 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000223 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000224 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000225 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000226 stream_reset (s);
227 return packet;
228 }
229 return NULL;
hasso93406d82005-02-02 14:40:33 +0000230}
paul718e3742002-12-13 20:15:29 +0000231
paul94f2b392005-06-28 12:44:16 +0000232static struct stream *
hasso93406d82005-02-02 14:40:33 +0000233bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
234{
235 struct stream *s;
236 struct stream *packet;
237
238#ifdef DISABLE_BGP_ANNOUNCE
239 return;
240#endif /* DISABLE_BGP_ANNOUNCE */
241
242 if (BGP_DEBUG (normal, NORMAL))
243 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
244
245 s = stream_new (BGP_MAX_PACKET_SIZE);
246
247 /* Make BGP update packet. */
248 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
249
250 /* Unfeasible Routes Length */
251 stream_putw (s, 0);
252
253 if (afi == AFI_IP && safi == SAFI_UNICAST)
254 {
255 /* Total Path Attribute Length */
256 stream_putw (s, 0);
257 }
258 else
259 {
260 /* Total Path Attribute Length */
261 stream_putw (s, 6);
262 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
263 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
264 stream_putc (s, 3);
265 stream_putw (s, afi);
266 stream_putc (s, safi);
267 }
268
269 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000270 packet = stream_dup (s);
hasso93406d82005-02-02 14:40:33 +0000271 bgp_packet_add (peer, packet);
272 stream_free (s);
273 return packet;
paul718e3742002-12-13 20:15:29 +0000274}
275
276/* Make BGP withdraw packet. */
paul94f2b392005-06-28 12:44:16 +0000277static struct stream *
paul718e3742002-12-13 20:15:29 +0000278bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
279{
280 struct stream *s;
281 struct stream *packet;
282 struct bgp_adj_out *adj;
283 struct bgp_advertise *adv;
284 struct bgp_node *rn;
285 unsigned long pos;
286 bgp_size_t unfeasible_len;
287 bgp_size_t total_attr_len;
288 char buf[BUFSIZ];
paul718e3742002-12-13 20:15:29 +0000289
290 s = peer->work;
291 stream_reset (s);
292
293 while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
294 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000295 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000296 adj = adv->adj;
297 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000298
299 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000300 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000301 break;
302
303 if (stream_empty (s))
304 {
305 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
306 stream_putw (s, 0);
307 }
308
309 if (afi == AFI_IP && safi == SAFI_UNICAST)
310 stream_put_prefix (s, &rn->p);
311 else
312 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000313 struct prefix_rd *prd = NULL;
314
315 if (rn->prn)
316 prd = (struct prefix_rd *) &rn->prn->p;
paul9985f832005-02-09 15:51:56 +0000317 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000318 stream_putw (s, 0);
319 total_attr_len
320 = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
321
322 /* Set total path attribute length. */
323 stream_putw_at (s, pos, total_attr_len);
324 }
325
326 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000327 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000328 peer->host,
329 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
330 rn->p.prefixlen);
331
332 peer->scount[afi][safi]--;
333
334 bgp_adj_out_remove (rn, adj, peer, afi, safi);
335 bgp_unlock_node (rn);
336
337 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
338 break;
339 }
340
341 if (! stream_empty (s))
342 {
343 if (afi == AFI_IP && safi == SAFI_UNICAST)
344 {
345 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000346 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000347 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
348 stream_putw (s, 0);
349 }
350 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000351 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000352 bgp_packet_add (peer, packet);
353 stream_reset (s);
354 return packet;
355 }
356
357 return NULL;
358}
359
360void
361bgp_default_update_send (struct peer *peer, struct attr *attr,
362 afi_t afi, safi_t safi, struct peer *from)
363{
364 struct stream *s;
365 struct stream *packet;
366 struct prefix p;
367 unsigned long pos;
368 bgp_size_t total_attr_len;
369 char attrstr[BUFSIZ];
370 char buf[BUFSIZ];
371
372#ifdef DISABLE_BGP_ANNOUNCE
373 return;
374#endif /* DISABLE_BGP_ANNOUNCE */
375
376 if (afi == AFI_IP)
377 str2prefix ("0.0.0.0/0", &p);
378#ifdef HAVE_IPV6
379 else
380 str2prefix ("::/0", &p);
381#endif /* HAVE_IPV6 */
382
383 /* Logging the attribute. */
384 if (BGP_DEBUG (update, UPDATE_OUT))
385 {
386 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000387 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
paul718e3742002-12-13 20:15:29 +0000388 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
389 p.prefixlen, attrstr);
390 }
391
392 s = stream_new (BGP_MAX_PACKET_SIZE);
393
394 /* Make BGP update packet. */
395 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
396
397 /* Unfeasible Routes Length. */
398 stream_putw (s, 0);
399
400 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000401 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000402 stream_putw (s, 0);
403 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
404
405 /* Set Total Path Attribute Length. */
406 stream_putw_at (s, pos, total_attr_len);
407
408 /* NLRI set. */
409 if (p.family == AF_INET && safi == SAFI_UNICAST)
410 stream_put_prefix (s, &p);
411
412 /* Set size. */
413 bgp_packet_set_size (s);
414
paule83e2082005-05-19 02:12:25 +0000415 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000416 stream_free (s);
417
418 /* Dump packet if debug option is set. */
419#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000420 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000421#endif /* DEBUG */
422
423 /* Add packet to the peer. */
424 bgp_packet_add (peer, packet);
425
pauleb821182004-05-01 08:44:08 +0000426 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000427}
428
429void
430bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
431{
432 struct stream *s;
433 struct stream *packet;
434 struct prefix p;
435 unsigned long pos;
436 unsigned long cp;
437 bgp_size_t unfeasible_len;
438 bgp_size_t total_attr_len;
439 char buf[BUFSIZ];
440
441#ifdef DISABLE_BGP_ANNOUNCE
442 return;
443#endif /* DISABLE_BGP_ANNOUNCE */
444
445 if (afi == AFI_IP)
446 str2prefix ("0.0.0.0/0", &p);
447#ifdef HAVE_IPV6
448 else
449 str2prefix ("::/0", &p);
450#endif /* HAVE_IPV6 */
451
452 total_attr_len = 0;
453 pos = 0;
454
455 if (BGP_DEBUG (update, UPDATE_OUT))
ajs6b514742004-12-08 21:03:23 +0000456 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
paul718e3742002-12-13 20:15:29 +0000457 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
458 p.prefixlen);
459
460 s = stream_new (BGP_MAX_PACKET_SIZE);
461
462 /* Make BGP update packet. */
463 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
464
465 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000466 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000467 stream_putw (s, 0);
468
469 /* Withdrawn Routes. */
470 if (p.family == AF_INET && safi == SAFI_UNICAST)
471 {
472 stream_put_prefix (s, &p);
473
paul9985f832005-02-09 15:51:56 +0000474 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000475
476 /* Set unfeasible len. */
477 stream_putw_at (s, cp, unfeasible_len);
478
479 /* Set total path attribute length. */
480 stream_putw (s, 0);
481 }
482 else
483 {
paul9985f832005-02-09 15:51:56 +0000484 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000485 stream_putw (s, 0);
486 total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
487
488 /* Set total path attribute length. */
489 stream_putw_at (s, pos, total_attr_len);
490 }
491
492 bgp_packet_set_size (s);
493
paule83e2082005-05-19 02:12:25 +0000494 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000495 stream_free (s);
496
497 /* Add packet to the peer. */
498 bgp_packet_add (peer, packet);
499
pauleb821182004-05-01 08:44:08 +0000500 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000501}
502
503/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000504static struct stream *
paul718e3742002-12-13 20:15:29 +0000505bgp_write_packet (struct peer *peer)
506{
507 afi_t afi;
508 safi_t safi;
509 struct stream *s = NULL;
510 struct bgp_advertise *adv;
511
512 s = stream_fifo_head (peer->obuf);
513 if (s)
514 return s;
515
516 for (afi = AFI_IP; afi < AFI_MAX; afi++)
517 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
518 {
519 adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
520 if (adv)
521 {
522 s = bgp_withdraw_packet (peer, afi, safi);
523 if (s)
524 return s;
525 }
526 }
527
528 for (afi = AFI_IP; afi < AFI_MAX; afi++)
529 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
530 {
531 adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
532 if (adv)
533 {
534 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000535 {
536 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
537 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
538 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
539 && safi != SAFI_MPLS_VPN)
540 {
541 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
542 PEER_STATUS_EOR_RECEIVED))
543 s = bgp_update_packet (peer, afi, safi);
544 }
545 else
546 s = bgp_update_packet (peer, afi, safi);
547 }
paul718e3742002-12-13 20:15:29 +0000548
549 if (s)
550 return s;
551 }
hasso93406d82005-02-02 14:40:33 +0000552
553 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
554 {
555 if (peer->afc_nego[afi][safi] && peer->synctime
556 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
557 && safi != SAFI_MPLS_VPN)
558 {
559 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
560 return bgp_update_packet_eor (peer, afi, safi);
561 }
562 }
paul718e3742002-12-13 20:15:29 +0000563 }
564
565 return NULL;
566}
567
568/* Is there partially written packet or updates we can send right
569 now. */
paul94f2b392005-06-28 12:44:16 +0000570static int
paul718e3742002-12-13 20:15:29 +0000571bgp_write_proceed (struct peer *peer)
572{
573 afi_t afi;
574 safi_t safi;
575 struct bgp_advertise *adv;
576
577 if (stream_fifo_head (peer->obuf))
578 return 1;
579
580 for (afi = AFI_IP; afi < AFI_MAX; afi++)
581 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
582 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
583 return 1;
584
585 for (afi = AFI_IP; afi < AFI_MAX; afi++)
586 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
587 if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
588 if (adv->binfo->uptime < peer->synctime)
589 return 1;
590
591 return 0;
592}
593
594/* Write packet to the peer. */
595int
596bgp_write (struct thread *thread)
597{
598 struct peer *peer;
599 u_char type;
600 struct stream *s;
601 int num;
paulfd79ac92004-10-13 05:06:08 +0000602 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000603 int write_errno;
604
605 /* Yes first of all get peer pointer. */
606 peer = THREAD_ARG (thread);
607 peer->t_write = NULL;
608
609 /* For non-blocking IO check. */
610 if (peer->status == Connect)
611 {
612 bgp_connect_check (peer);
613 return 0;
614 }
615
616 /* Nonblocking write until TCP output buffer is full. */
617 while (1)
618 {
619 int writenum;
paula24a7e12005-01-05 08:14:13 +0000620 int val;
paul718e3742002-12-13 20:15:29 +0000621
622 s = bgp_write_packet (peer);
623 if (! s)
624 return 0;
paula24a7e12005-01-05 08:14:13 +0000625
626 /* XXX: FIXME, the socket should be NONBLOCK from the start
627 * status shouldnt need to be toggled on each write
628 */
629 val = fcntl (peer->fd, F_GETFL, 0);
630 fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
paul718e3742002-12-13 20:15:29 +0000631
632 /* Number of bytes to be sent. */
633 writenum = stream_get_endp (s) - stream_get_getp (s);
634
635 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000636 num = write (peer->fd, STREAM_PNT (s), writenum);
paul718e3742002-12-13 20:15:29 +0000637 write_errno = errno;
paula24a7e12005-01-05 08:14:13 +0000638 fcntl (peer->fd, F_SETFL, val);
paul718e3742002-12-13 20:15:29 +0000639 if (num <= 0)
640 {
641 /* Partial write. */
642 if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
643 break;
644
Paul Jakmadcdf3992006-10-15 23:39:59 +0000645 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000646 return 0;
647 }
648 if (num != writenum)
649 {
paul9985f832005-02-09 15:51:56 +0000650 stream_forward_getp (s, num);
paul718e3742002-12-13 20:15:29 +0000651
652 if (write_errno == EAGAIN)
653 break;
654
655 continue;
656 }
657
658 /* Retrieve BGP packet type. */
659 stream_set_getp (s, BGP_MARKER_SIZE + 2);
660 type = stream_getc (s);
661
662 switch (type)
663 {
664 case BGP_MSG_OPEN:
665 peer->open_out++;
666 break;
667 case BGP_MSG_UPDATE:
668 peer->update_out++;
669 break;
670 case BGP_MSG_NOTIFY:
671 peer->notify_out++;
672 /* Double start timer. */
673 peer->v_start *= 2;
674
675 /* Overflow check. */
676 if (peer->v_start >= (60 * 2))
677 peer->v_start = (60 * 2);
678
Paul Jakmaca058a32006-09-14 02:58:49 +0000679 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000680 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000681 return 0;
paul718e3742002-12-13 20:15:29 +0000682 case BGP_MSG_KEEPALIVE:
683 peer->keepalive_out++;
684 break;
685 case BGP_MSG_ROUTE_REFRESH_NEW:
686 case BGP_MSG_ROUTE_REFRESH_OLD:
687 peer->refresh_out++;
688 break;
689 case BGP_MSG_CAPABILITY:
690 peer->dynamic_cap_out++;
691 break;
692 }
693
694 /* OK we send packet so delete it. */
695 bgp_packet_delete (peer);
696
697 if (++count >= BGP_WRITE_PACKET_MAX)
698 break;
699 }
700
701 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000702 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000703
704 return 0;
705}
706
707/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000708static int
paul718e3742002-12-13 20:15:29 +0000709bgp_write_notify (struct peer *peer)
710{
711 int ret;
712 u_char type;
713 struct stream *s;
714
715 /* There should be at least one packet. */
716 s = stream_fifo_head (peer->obuf);
717 if (!s)
718 return 0;
719 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
720
721 /* I'm not sure fd is writable. */
pauleb821182004-05-01 08:44:08 +0000722 ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +0000723 if (ret <= 0)
724 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000725 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000726 return 0;
727 }
728
729 /* Retrieve BGP packet type. */
730 stream_set_getp (s, BGP_MARKER_SIZE + 2);
731 type = stream_getc (s);
732
733 assert (type == BGP_MSG_NOTIFY);
734
735 /* Type should be notify. */
736 peer->notify_out++;
737
738 /* Double start timer. */
739 peer->v_start *= 2;
740
741 /* Overflow check. */
742 if (peer->v_start >= (60 * 2))
743 peer->v_start = (60 * 2);
744
Paul Jakmadcdf3992006-10-15 23:39:59 +0000745 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000746
747 return 0;
748}
749
750/* Make keepalive packet and send it to the peer. */
751void
752bgp_keepalive_send (struct peer *peer)
753{
754 struct stream *s;
755 int length;
756
757 s = stream_new (BGP_MAX_PACKET_SIZE);
758
759 /* Make keepalive packet. */
760 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
761
762 /* Set packet size. */
763 length = bgp_packet_set_size (s);
764
765 /* Dump packet if debug option is set. */
766 /* bgp_packet_dump (s); */
767
768 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000769 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000770 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000771 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000772 peer->host, BGP_MSG_KEEPALIVE, length);
773
774 /* Add packet to the peer. */
775 bgp_packet_add (peer, s);
776
pauleb821182004-05-01 08:44:08 +0000777 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000778}
779
780/* Make open packet and send it to the peer. */
781void
782bgp_open_send (struct peer *peer)
783{
784 struct stream *s;
785 int length;
786 u_int16_t send_holdtime;
787 as_t local_as;
788
789 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
790 send_holdtime = peer->holdtime;
791 else
792 send_holdtime = peer->bgp->default_holdtime;
793
794 /* local-as Change */
795 if (peer->change_local_as)
796 local_as = peer->change_local_as;
797 else
798 local_as = peer->local_as;
799
800 s = stream_new (BGP_MAX_PACKET_SIZE);
801
802 /* Make open packet. */
803 bgp_packet_set_marker (s, BGP_MSG_OPEN);
804
805 /* Set open packet values. */
806 stream_putc (s, BGP_VERSION_4); /* BGP version */
807 stream_putw (s, local_as); /* My Autonomous System*/
808 stream_putw (s, send_holdtime); /* Hold Time */
809 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
810
811 /* Set capability code. */
812 bgp_open_capability (s, peer);
813
814 /* Set BGP packet length. */
815 length = bgp_packet_set_size (s);
816
817 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000818 zlog_debug ("%s sending OPEN, version %d, my as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000819 peer->host, BGP_VERSION_4, local_as,
820 send_holdtime, inet_ntoa (peer->local_id));
821
822 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000823 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000824 peer->host, BGP_MSG_OPEN, length);
825
826 /* Dump packet if debug option is set. */
827 /* bgp_packet_dump (s); */
828
829 /* Add packet to the peer. */
830 bgp_packet_add (peer, s);
831
pauleb821182004-05-01 08:44:08 +0000832 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000833}
834
835/* Send BGP notify packet with data potion. */
836void
837bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
838 u_char *data, size_t datalen)
839{
840 struct stream *s;
841 int length;
842
843 /* Allocate new stream. */
844 s = stream_new (BGP_MAX_PACKET_SIZE);
845
846 /* Make nitify packet. */
847 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
848
849 /* Set notify packet values. */
850 stream_putc (s, code); /* BGP notify code */
851 stream_putc (s, sub_code); /* BGP notify sub_code */
852
853 /* If notify data is present. */
854 if (data)
855 stream_write (s, data, datalen);
856
857 /* Set BGP packet length. */
858 length = bgp_packet_set_size (s);
859
860 /* Add packet to the peer. */
861 stream_fifo_clean (peer->obuf);
862 bgp_packet_add (peer, s);
863
864 /* For debug */
865 {
866 struct bgp_notify bgp_notify;
867 int first = 0;
868 int i;
869 char c[4];
870
871 bgp_notify.code = code;
872 bgp_notify.subcode = sub_code;
873 bgp_notify.data = NULL;
874 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
875
876 if (bgp_notify.length)
877 {
878 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
879 for (i = 0; i < bgp_notify.length; i++)
880 if (first)
881 {
882 sprintf (c, " %02x", data[i]);
883 strcat (bgp_notify.data, c);
884 }
885 else
886 {
887 first = 1;
888 sprintf (c, "%02x", data[i]);
889 strcpy (bgp_notify.data, c);
890 }
891 }
892 bgp_notify_print (peer, &bgp_notify, "sending");
893 if (bgp_notify.data)
894 XFREE (MTYPE_TMP, bgp_notify.data);
895 }
896
897 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000898 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000899 peer->host, BGP_MSG_NOTIFY, length);
900
hassoe0701b72004-05-20 09:19:34 +0000901 /* peer reset cause */
902 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
903 {
904 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
905 peer->last_reset = PEER_DOWN_USER_RESET;
906 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
907 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
908 else
909 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
910 }
911
paul718e3742002-12-13 20:15:29 +0000912 /* Call imidiately. */
913 BGP_WRITE_OFF (peer->t_write);
914
915 bgp_write_notify (peer);
916}
917
918/* Send BGP notify packet. */
919void
920bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
921{
922 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
923}
924
paul94f2b392005-06-28 12:44:16 +0000925static const char *
paul718e3742002-12-13 20:15:29 +0000926afi2str (afi_t afi)
927{
928 if (afi == AFI_IP)
929 return "AFI_IP";
930 else if (afi == AFI_IP6)
931 return "AFI_IP6";
932 else
933 return "Unknown AFI";
934}
935
paul94f2b392005-06-28 12:44:16 +0000936static const char *
paul718e3742002-12-13 20:15:29 +0000937safi2str (safi_t safi)
938{
939 if (safi == SAFI_UNICAST)
940 return "SAFI_UNICAST";
941 else if (safi == SAFI_MULTICAST)
942 return "SAFI_MULTICAST";
943 else if (safi == SAFI_MPLS_VPN || safi == BGP_SAFI_VPNV4)
944 return "SAFI_MPLS_VPN";
945 else
946 return "Unknown SAFI";
947}
948
949/* Send route refresh message to the peer. */
950void
951bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
952 u_char orf_type, u_char when_to_refresh, int remove)
953{
954 struct stream *s;
955 struct stream *packet;
956 int length;
957 struct bgp_filter *filter;
958 int orf_refresh = 0;
959
960#ifdef DISABLE_BGP_ANNOUNCE
961 return;
962#endif /* DISABLE_BGP_ANNOUNCE */
963
964 filter = &peer->filter[afi][safi];
965
966 /* Adjust safi code. */
967 if (safi == SAFI_MPLS_VPN)
968 safi = BGP_SAFI_VPNV4;
969
970 s = stream_new (BGP_MAX_PACKET_SIZE);
971
972 /* Make BGP update packet. */
973 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
974 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
975 else
976 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
977
978 /* Encode Route Refresh message. */
979 stream_putw (s, afi);
980 stream_putc (s, 0);
981 stream_putc (s, safi);
982
983 if (orf_type == ORF_TYPE_PREFIX
984 || orf_type == ORF_TYPE_PREFIX_OLD)
985 if (remove || filter->plist[FILTER_IN].plist)
986 {
987 u_int16_t orf_len;
988 unsigned long orfp;
989
990 orf_refresh = 1;
991 stream_putc (s, when_to_refresh);
992 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +0000993 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000994 stream_putw (s, 0);
995
996 if (remove)
997 {
998 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
999 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1000 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001001 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001002 peer->host, orf_type,
1003 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1004 afi, safi);
1005 }
1006 else
1007 {
1008 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1009 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1010 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1011 ORF_COMMON_PART_DENY);
1012 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001013 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001014 peer->host, orf_type,
1015 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1016 afi, safi);
1017 }
1018
1019 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001020 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001021 stream_putw_at (s, orfp, orf_len);
1022 }
1023
1024 /* Set packet size. */
1025 length = bgp_packet_set_size (s);
1026
1027 if (BGP_DEBUG (normal, NORMAL))
1028 {
1029 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001030 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001031 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001032 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001033 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1034 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1035 }
1036
1037 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001038 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001039 stream_free (s);
1040
1041 /* Add packet to the peer. */
1042 bgp_packet_add (peer, packet);
1043
pauleb821182004-05-01 08:44:08 +00001044 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001045}
1046
1047/* Send capability message to the peer. */
1048void
1049bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1050 int capability_code, int action)
1051{
1052 struct stream *s;
1053 struct stream *packet;
1054 int length;
1055
1056 /* Adjust safi code. */
1057 if (safi == SAFI_MPLS_VPN)
1058 safi = BGP_SAFI_VPNV4;
1059
1060 s = stream_new (BGP_MAX_PACKET_SIZE);
1061
1062 /* Make BGP update packet. */
1063 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1064
1065 /* Encode MP_EXT capability. */
1066 if (capability_code == CAPABILITY_CODE_MP)
1067 {
1068 stream_putc (s, action);
1069 stream_putc (s, CAPABILITY_CODE_MP);
1070 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1071 stream_putw (s, afi);
1072 stream_putc (s, 0);
1073 stream_putc (s, safi);
1074
1075 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001076 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001077 peer->host, action == CAPABILITY_ACTION_SET ?
1078 "Advertising" : "Removing", afi, safi);
1079 }
1080
paul718e3742002-12-13 20:15:29 +00001081 /* Set packet size. */
1082 length = bgp_packet_set_size (s);
1083
1084 /* Make real packet. */
paule83e2082005-05-19 02:12:25 +00001085 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +00001086 stream_free (s);
1087
1088 /* Add packet to the peer. */
1089 bgp_packet_add (peer, packet);
1090
1091 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001092 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001093 peer->host, BGP_MSG_CAPABILITY, length);
1094
pauleb821182004-05-01 08:44:08 +00001095 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001096}
1097
1098/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001099static int
pauleb821182004-05-01 08:44:08 +00001100bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001101{
pauleb821182004-05-01 08:44:08 +00001102 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001103 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001104 struct bgp *bgp;
1105
1106 bgp = bgp_get_default ();
1107 if (! bgp)
1108 return 0;
1109
1110 /* Upon receipt of an OPEN message, the local system must examine
1111 all of its connections that are in the OpenConfirm state. A BGP
1112 speaker may also examine connections in an OpenSent state if it
1113 knows the BGP Identifier of the peer by means outside of the
1114 protocol. If among these connections there is a connection to a
1115 remote BGP speaker whose BGP Identifier equals the one in the
1116 OPEN message, then the local system performs the following
1117 collision resolution procedure: */
1118
paul1eb8ef22005-04-07 07:30:20 +00001119 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001120 {
1121 /* Under OpenConfirm status, local peer structure already hold
1122 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001123
1124 if (peer != new
1125 && (peer->status == OpenConfirm || peer->status == OpenSent)
1126 && sockunion_same (&peer->su, &new->su))
1127 {
paul718e3742002-12-13 20:15:29 +00001128 /* 1. The BGP Identifier of the local system is compared to
1129 the BGP Identifier of the remote system (as specified in
1130 the OPEN message). */
1131
1132 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1133 {
1134 /* 2. If the value of the local BGP Identifier is less
1135 than the remote one, the local system closes BGP
1136 connection that already exists (the one that is
1137 already in the OpenConfirm state), and accepts BGP
1138 connection initiated by the remote system. */
1139
pauleb821182004-05-01 08:44:08 +00001140 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001141 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001142 return 1;
1143 }
1144 else
1145 {
1146 /* 3. Otherwise, the local system closes newly created
1147 BGP connection (the one associated with the newly
1148 received OPEN message), and continues to use the
1149 existing one (the one that is already in the
1150 OpenConfirm state). */
1151
pauleb821182004-05-01 08:44:08 +00001152 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001153 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1154 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001155 return -1;
1156 }
pauleb821182004-05-01 08:44:08 +00001157 }
1158 }
paul718e3742002-12-13 20:15:29 +00001159 return 0;
1160}
1161
paul94f2b392005-06-28 12:44:16 +00001162static int
paul718e3742002-12-13 20:15:29 +00001163bgp_open_receive (struct peer *peer, bgp_size_t size)
1164{
1165 int ret;
1166 u_char version;
1167 u_char optlen;
1168 u_int16_t holdtime;
1169 u_int16_t send_holdtime;
1170 as_t remote_as;
1171 struct peer *realpeer;
1172 struct in_addr remote_id;
1173 int capability;
paul5228ad22004-06-04 17:58:18 +00001174 u_int8_t notify_data_remote_as[2];
1175 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001176
1177 realpeer = NULL;
1178
1179 /* Parse open packet. */
1180 version = stream_getc (peer->ibuf);
1181 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1182 remote_as = stream_getw (peer->ibuf);
1183 holdtime = stream_getw (peer->ibuf);
1184 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1185 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1186
1187 /* Receive OPEN message log */
1188 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001189 zlog_debug ("%s rcv OPEN, version %d, remote-as %d, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +00001190 peer->host, version, remote_as, holdtime,
1191 inet_ntoa (remote_id));
1192
1193 /* Lookup peer from Open packet. */
1194 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1195 {
1196 int as = 0;
1197
1198 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1199
1200 if (! realpeer)
1201 {
1202 /* Peer's source IP address is check in bgp_accept(), so this
1203 must be AS number mismatch or remote-id configuration
1204 mismatch. */
1205 if (as)
1206 {
1207 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001208 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1209 peer->host, inet_ntoa (remote_id));
1210 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1211 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1212 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001213 }
1214 else
1215 {
1216 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001217 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
1218 peer->host, remote_as, peer->as);
1219 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1220 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1221 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001222 }
1223 return -1;
1224 }
1225 }
1226
1227 /* When collision is detected and this peer is closed. Retrun
1228 immidiately. */
1229 ret = bgp_collision_detect (peer, remote_id);
1230 if (ret < 0)
1231 return ret;
1232
pauleb821182004-05-01 08:44:08 +00001233 /* Hack part. */
1234 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1235 {
hasso93406d82005-02-02 14:40:33 +00001236 if (realpeer->status == Established
1237 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1238 {
1239 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1240 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1241 }
1242 else if (ret == 0 && realpeer->status != Active
1243 && realpeer->status != OpenSent
1244 && realpeer->status != OpenConfirm)
1245
pauleb821182004-05-01 08:44:08 +00001246 {
1247 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001248 zlog_debug ("%s peer status is %s close connection",
1249 realpeer->host, LOOKUP (bgp_status_msg,
1250 realpeer->status));
1251 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1252 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1253
pauleb821182004-05-01 08:44:08 +00001254 return -1;
1255 }
1256
1257 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00001258 zlog_debug ("%s [Event] Transfer temporary BGP peer to existing one",
pauleb821182004-05-01 08:44:08 +00001259 peer->host);
1260
1261 bgp_stop (realpeer);
1262
1263 /* Transfer file descriptor. */
1264 realpeer->fd = peer->fd;
1265 peer->fd = -1;
1266
1267 /* Transfer input buffer. */
1268 stream_free (realpeer->ibuf);
1269 realpeer->ibuf = peer->ibuf;
1270 realpeer->packet_size = peer->packet_size;
1271 peer->ibuf = NULL;
1272
1273 /* Transfer status. */
1274 realpeer->status = peer->status;
1275 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001276
pauleb821182004-05-01 08:44:08 +00001277 /* peer pointer change. Open packet send to neighbor. */
1278 peer = realpeer;
1279 bgp_open_send (peer);
1280 if (peer->fd < 0)
1281 {
1282 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1283 peer->fd);
1284 return -1;
1285 }
1286 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1287 }
1288
paul718e3742002-12-13 20:15:29 +00001289 /* remote router-id check. */
1290 if (remote_id.s_addr == 0
1291 || ntohl (remote_id.s_addr) >= 0xe0000000
1292 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1293 {
1294 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001295 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001296 peer->host, inet_ntoa (remote_id));
1297 bgp_notify_send_with_data (peer,
1298 BGP_NOTIFY_OPEN_ERR,
1299 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1300 notify_data_remote_id, 4);
1301 return -1;
1302 }
1303
1304 /* Set remote router-id */
1305 peer->remote_id = remote_id;
1306
1307 /* Peer BGP version check. */
1308 if (version != BGP_VERSION_4)
1309 {
paul5228ad22004-06-04 17:58:18 +00001310 u_int8_t maxver = BGP_VERSION_4;
paul718e3742002-12-13 20:15:29 +00001311 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001312 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001313 peer->host, version, BGP_VERSION_4);
1314 bgp_notify_send_with_data (peer,
1315 BGP_NOTIFY_OPEN_ERR,
1316 BGP_NOTIFY_OPEN_UNSUP_VERSION,
paul5228ad22004-06-04 17:58:18 +00001317 &maxver, 1);
paul718e3742002-12-13 20:15:29 +00001318 return -1;
1319 }
1320
1321 /* Check neighbor as number. */
1322 if (remote_as != peer->as)
1323 {
1324 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001325 zlog_debug ("%s bad OPEN, remote AS is %d, expected %d",
paul718e3742002-12-13 20:15:29 +00001326 peer->host, remote_as, peer->as);
1327 bgp_notify_send_with_data (peer,
1328 BGP_NOTIFY_OPEN_ERR,
1329 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1330 notify_data_remote_as, 2);
1331 return -1;
1332 }
1333
1334 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1335 calculate the value of the Hold Timer by using the smaller of its
1336 configured Hold Time and the Hold Time received in the OPEN message.
1337 The Hold Time MUST be either zero or at least three seconds. An
1338 implementation may reject connections on the basis of the Hold Time. */
1339
1340 if (holdtime < 3 && holdtime != 0)
1341 {
1342 bgp_notify_send (peer,
1343 BGP_NOTIFY_OPEN_ERR,
1344 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1345 return -1;
1346 }
1347
1348 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1349 would be one third of the Hold Time interval. KEEPALIVE messages
1350 MUST NOT be sent more frequently than one per second. An
1351 implementation MAY adjust the rate at which it sends KEEPALIVE
1352 messages as a function of the Hold Time interval. */
1353
1354 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1355 send_holdtime = peer->holdtime;
1356 else
1357 send_holdtime = peer->bgp->default_holdtime;
1358
1359 if (holdtime < send_holdtime)
1360 peer->v_holdtime = holdtime;
1361 else
1362 peer->v_holdtime = send_holdtime;
1363
1364 peer->v_keepalive = peer->v_holdtime / 3;
1365
1366 /* Open option part parse. */
1367 capability = 0;
1368 optlen = stream_getc (peer->ibuf);
1369 if (optlen != 0)
1370 {
1371 ret = bgp_open_option_parse (peer, optlen, &capability);
1372 if (ret < 0)
1373 return ret;
1374
paul9985f832005-02-09 15:51:56 +00001375 stream_forward_getp (peer->ibuf, optlen);
paul718e3742002-12-13 20:15:29 +00001376 }
1377 else
1378 {
1379 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001380 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001381 peer->host);
1382 }
1383
1384 /* Override capability. */
1385 if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1386 {
1387 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1388 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1389 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1390 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1391 }
1392
1393 /* Get sockname. */
1394 bgp_getsockname (peer);
1395
1396 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1397
1398 peer->packet_size = 0;
1399 if (peer->ibuf)
1400 stream_reset (peer->ibuf);
1401
1402 return 0;
1403}
1404
1405/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001406static int
paul718e3742002-12-13 20:15:29 +00001407bgp_update_receive (struct peer *peer, bgp_size_t size)
1408{
1409 int ret;
1410 u_char *end;
1411 struct stream *s;
1412 struct attr attr;
1413 bgp_size_t attribute_len;
1414 bgp_size_t update_len;
1415 bgp_size_t withdraw_len;
1416 struct bgp_nlri update;
1417 struct bgp_nlri withdraw;
1418 struct bgp_nlri mp_update;
1419 struct bgp_nlri mp_withdraw;
paule01f9cb2004-07-09 17:48:53 +00001420 char attrstr[BUFSIZ] = "";
paul718e3742002-12-13 20:15:29 +00001421
1422 /* Status must be Established. */
1423 if (peer->status != Established)
1424 {
1425 zlog_err ("%s [FSM] Update packet received under status %s",
1426 peer->host, LOOKUP (bgp_status_msg, peer->status));
1427 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1428 return -1;
1429 }
1430
1431 /* Set initial values. */
1432 memset (&attr, 0, sizeof (struct attr));
1433 memset (&update, 0, sizeof (struct bgp_nlri));
1434 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1435 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1436 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
1437
1438 s = peer->ibuf;
1439 end = stream_pnt (s) + size;
1440
1441 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1442 Length is too large (i.e., if Unfeasible Routes Length + Total
1443 Attribute Length + 23 exceeds the message Length), then the Error
1444 Subcode is set to Malformed Attribute List. */
1445 if (stream_pnt (s) + 2 > end)
1446 {
1447 zlog_err ("%s [Error] Update packet error"
1448 " (packet length is short for unfeasible length)",
1449 peer->host);
1450 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1451 BGP_NOTIFY_UPDATE_MAL_ATTR);
1452 return -1;
1453 }
1454
1455 /* Unfeasible Route Length. */
1456 withdraw_len = stream_getw (s);
1457
1458 /* Unfeasible Route Length check. */
1459 if (stream_pnt (s) + withdraw_len > end)
1460 {
1461 zlog_err ("%s [Error] Update packet error"
1462 " (packet unfeasible length overflow %d)",
1463 peer->host, withdraw_len);
1464 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1465 BGP_NOTIFY_UPDATE_MAL_ATTR);
1466 return -1;
1467 }
1468
1469 /* Unfeasible Route packet format check. */
1470 if (withdraw_len > 0)
1471 {
1472 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1473 if (ret < 0)
1474 return -1;
1475
1476 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001477 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001478
1479 withdraw.afi = AFI_IP;
1480 withdraw.safi = SAFI_UNICAST;
1481 withdraw.nlri = stream_pnt (s);
1482 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001483 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001484 }
1485
1486 /* Attribute total length check. */
1487 if (stream_pnt (s) + 2 > end)
1488 {
1489 zlog_warn ("%s [Error] Packet Error"
1490 " (update packet is short for attribute length)",
1491 peer->host);
1492 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1493 BGP_NOTIFY_UPDATE_MAL_ATTR);
1494 return -1;
1495 }
1496
1497 /* Fetch attribute total length. */
1498 attribute_len = stream_getw (s);
1499
1500 /* Attribute length check. */
1501 if (stream_pnt (s) + attribute_len > end)
1502 {
1503 zlog_warn ("%s [Error] Packet Error"
1504 " (update packet attribute length overflow %d)",
1505 peer->host, attribute_len);
1506 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1507 BGP_NOTIFY_UPDATE_MAL_ATTR);
1508 return -1;
1509 }
1510
1511 /* Parse attribute when it exists. */
1512 if (attribute_len)
1513 {
1514 ret = bgp_attr_parse (peer, &attr, attribute_len,
1515 &mp_update, &mp_withdraw);
1516 if (ret < 0)
1517 return -1;
1518 }
1519
1520 /* Logging the attribute. */
1521 if (BGP_DEBUG (update, UPDATE_IN))
1522 {
paule01f9cb2004-07-09 17:48:53 +00001523 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1524
1525 if (ret)
ajs6b514742004-12-08 21:03:23 +00001526 zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001527 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001528 }
1529
1530 /* Network Layer Reachability Information. */
1531 update_len = end - stream_pnt (s);
1532
1533 if (update_len)
1534 {
1535 /* Check NLRI packet format and prefix length. */
1536 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1537 if (ret < 0)
1538 return -1;
1539
1540 /* Set NLRI portion to structure. */
1541 update.afi = AFI_IP;
1542 update.safi = SAFI_UNICAST;
1543 update.nlri = stream_pnt (s);
1544 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001545 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001546 }
1547
1548 /* NLRI is processed only when the peer is configured specific
1549 Address Family and Subsequent Address Family. */
1550 if (peer->afc[AFI_IP][SAFI_UNICAST])
1551 {
1552 if (withdraw.length)
1553 bgp_nlri_parse (peer, NULL, &withdraw);
1554
1555 if (update.length)
1556 {
1557 /* We check well-known attribute only for IPv4 unicast
1558 update. */
1559 ret = bgp_attr_check (peer, &attr);
1560 if (ret < 0)
1561 return -1;
1562
1563 bgp_nlri_parse (peer, &attr, &update);
1564 }
paule01f9cb2004-07-09 17:48:53 +00001565
hassof4184462005-02-01 20:13:16 +00001566 if (mp_update.length
1567 && mp_update.afi == AFI_IP
1568 && mp_update.safi == SAFI_UNICAST)
1569 bgp_nlri_parse (peer, &attr, &mp_update);
1570
1571 if (mp_withdraw.length
1572 && mp_withdraw.afi == AFI_IP
1573 && mp_withdraw.safi == SAFI_UNICAST)
1574 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1575
paule01f9cb2004-07-09 17:48:53 +00001576 if (! attribute_len && ! withdraw_len)
1577 {
1578 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001579 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1580 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001581
hasso93406d82005-02-02 14:40:33 +00001582 /* NSF delete stale route */
1583 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1584 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1585
1586 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001587 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001588 peer->host);
1589 }
paul718e3742002-12-13 20:15:29 +00001590 }
1591 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1592 {
1593 if (mp_update.length
1594 && mp_update.afi == AFI_IP
1595 && mp_update.safi == SAFI_MULTICAST)
1596 bgp_nlri_parse (peer, &attr, &mp_update);
1597
1598 if (mp_withdraw.length
1599 && mp_withdraw.afi == AFI_IP
1600 && mp_withdraw.safi == SAFI_MULTICAST)
1601 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001602
hasso93406d82005-02-02 14:40:33 +00001603 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001604 && mp_withdraw.afi == AFI_IP
1605 && mp_withdraw.safi == SAFI_MULTICAST
1606 && mp_withdraw.length == 0)
1607 {
1608 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001609 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1610 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001611
hasso93406d82005-02-02 14:40:33 +00001612 /* NSF delete stale route */
1613 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1614 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1615
1616 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001617 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001618 peer->host);
1619 }
paul718e3742002-12-13 20:15:29 +00001620 }
1621 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1622 {
1623 if (mp_update.length
1624 && mp_update.afi == AFI_IP6
1625 && mp_update.safi == SAFI_UNICAST)
1626 bgp_nlri_parse (peer, &attr, &mp_update);
1627
1628 if (mp_withdraw.length
1629 && mp_withdraw.afi == AFI_IP6
1630 && mp_withdraw.safi == SAFI_UNICAST)
1631 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001632
hasso93406d82005-02-02 14:40:33 +00001633 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001634 && mp_withdraw.afi == AFI_IP6
1635 && mp_withdraw.safi == SAFI_UNICAST
1636 && mp_withdraw.length == 0)
1637 {
1638 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001639 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001640
hasso93406d82005-02-02 14:40:33 +00001641 /* NSF delete stale route */
1642 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1643 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1644
1645 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001646 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001647 peer->host);
1648 }
paul718e3742002-12-13 20:15:29 +00001649 }
1650 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1651 {
1652 if (mp_update.length
1653 && mp_update.afi == AFI_IP6
1654 && mp_update.safi == SAFI_MULTICAST)
1655 bgp_nlri_parse (peer, &attr, &mp_update);
1656
1657 if (mp_withdraw.length
1658 && mp_withdraw.afi == AFI_IP6
1659 && mp_withdraw.safi == SAFI_MULTICAST)
1660 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001661
hasso93406d82005-02-02 14:40:33 +00001662 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001663 && mp_withdraw.afi == AFI_IP6
1664 && mp_withdraw.safi == SAFI_MULTICAST
1665 && mp_withdraw.length == 0)
1666 {
1667 /* End-of-RIB received */
1668
hasso93406d82005-02-02 14:40:33 +00001669 /* NSF delete stale route */
1670 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1671 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1672
paule01f9cb2004-07-09 17:48:53 +00001673 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001674 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001675 peer->host);
1676 }
paul718e3742002-12-13 20:15:29 +00001677 }
1678 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1679 {
1680 if (mp_update.length
1681 && mp_update.afi == AFI_IP
1682 && mp_update.safi == BGP_SAFI_VPNV4)
1683 bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);
1684
1685 if (mp_withdraw.length
1686 && mp_withdraw.afi == AFI_IP
1687 && mp_withdraw.safi == BGP_SAFI_VPNV4)
1688 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001689
hasso93406d82005-02-02 14:40:33 +00001690 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001691 && mp_withdraw.afi == AFI_IP
1692 && mp_withdraw.safi == BGP_SAFI_VPNV4
1693 && mp_withdraw.length == 0)
1694 {
1695 /* End-of-RIB received */
1696
1697 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001698 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001699 peer->host);
1700 }
paul718e3742002-12-13 20:15:29 +00001701 }
1702
1703 /* Everything is done. We unintern temporary structures which
1704 interned in bgp_attr_parse(). */
1705 if (attr.aspath)
1706 aspath_unintern (attr.aspath);
1707 if (attr.community)
1708 community_unintern (attr.community);
Paul Jakmafb982c22007-05-04 20:15:47 +00001709 if (attr.extra)
1710 {
1711 if (attr.extra->ecommunity)
1712 ecommunity_unintern (attr.extra->ecommunity);
1713 if (attr.extra->cluster)
1714 cluster_unintern (attr.extra->cluster);
1715 if (attr.extra->transit)
1716 transit_unintern (attr.extra->transit);
1717 bgp_attr_extra_free (&attr);
1718 }
paul718e3742002-12-13 20:15:29 +00001719
1720 /* If peering is stopped due to some reason, do not generate BGP
1721 event. */
1722 if (peer->status != Established)
1723 return 0;
1724
1725 /* Increment packet counter. */
1726 peer->update_in++;
1727 peer->update_time = time (NULL);
1728
1729 /* Generate BGP event. */
1730 BGP_EVENT_ADD (peer, Receive_UPDATE_message);
1731
1732 return 0;
1733}
1734
1735/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001736static void
paul718e3742002-12-13 20:15:29 +00001737bgp_notify_receive (struct peer *peer, bgp_size_t size)
1738{
1739 struct bgp_notify bgp_notify;
1740
1741 if (peer->notify.data)
1742 {
1743 XFREE (MTYPE_TMP, peer->notify.data);
1744 peer->notify.data = NULL;
1745 peer->notify.length = 0;
1746 }
1747
1748 bgp_notify.code = stream_getc (peer->ibuf);
1749 bgp_notify.subcode = stream_getc (peer->ibuf);
1750 bgp_notify.length = size - 2;
1751 bgp_notify.data = NULL;
1752
1753 /* Preserv notify code and sub code. */
1754 peer->notify.code = bgp_notify.code;
1755 peer->notify.subcode = bgp_notify.subcode;
1756 /* For further diagnostic record returned Data. */
1757 if (bgp_notify.length)
1758 {
1759 peer->notify.length = size - 2;
1760 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1761 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1762 }
1763
1764 /* For debug */
1765 {
1766 int i;
1767 int first = 0;
1768 char c[4];
1769
1770 if (bgp_notify.length)
1771 {
1772 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1773 for (i = 0; i < bgp_notify.length; i++)
1774 if (first)
1775 {
1776 sprintf (c, " %02x", stream_getc (peer->ibuf));
1777 strcat (bgp_notify.data, c);
1778 }
1779 else
1780 {
1781 first = 1;
1782 sprintf (c, "%02x", stream_getc (peer->ibuf));
1783 strcpy (bgp_notify.data, c);
1784 }
1785 }
1786
1787 bgp_notify_print(peer, &bgp_notify, "received");
1788 if (bgp_notify.data)
1789 XFREE (MTYPE_TMP, bgp_notify.data);
1790 }
1791
1792 /* peer count update */
1793 peer->notify_in++;
1794
hassoe0701b72004-05-20 09:19:34 +00001795 if (peer->status == Established)
1796 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1797
paul718e3742002-12-13 20:15:29 +00001798 /* We have to check for Notify with Unsupported Optional Parameter.
1799 in that case we fallback to open without the capability option.
1800 But this done in bgp_stop. We just mark it here to avoid changing
1801 the fsm tables. */
1802 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1803 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1804 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1805
1806 /* Also apply to Unsupported Capability until remote router support
1807 capability. */
1808 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1809 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
1810 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1811
1812 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1813}
1814
1815/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001816static void
paul718e3742002-12-13 20:15:29 +00001817bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1818{
1819 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001820 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001821
1822 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1823}
1824
1825/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00001826static void
paul718e3742002-12-13 20:15:29 +00001827bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
1828{
1829 afi_t afi;
1830 safi_t safi;
1831 u_char reserved;
1832 struct stream *s;
1833
1834 /* If peer does not have the capability, send notification. */
1835 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
1836 {
1837 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
1838 peer->host);
1839 bgp_notify_send (peer,
1840 BGP_NOTIFY_HEADER_ERR,
1841 BGP_NOTIFY_HEADER_BAD_MESTYPE);
1842 return;
1843 }
1844
1845 /* Status must be Established. */
1846 if (peer->status != Established)
1847 {
1848 plog_err (peer->log,
1849 "%s [Error] Route refresh packet received under status %s",
1850 peer->host, LOOKUP (bgp_status_msg, peer->status));
1851 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1852 return;
1853 }
1854
1855 s = peer->ibuf;
1856
1857 /* Parse packet. */
1858 afi = stream_getw (s);
1859 reserved = stream_getc (s);
1860 safi = stream_getc (s);
1861
1862 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001863 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001864 peer->host, afi, safi);
1865
1866 /* Check AFI and SAFI. */
1867 if ((afi != AFI_IP && afi != AFI_IP6)
1868 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1869 && safi != BGP_SAFI_VPNV4))
1870 {
1871 if (BGP_DEBUG (normal, NORMAL))
1872 {
ajs6b514742004-12-08 21:03:23 +00001873 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00001874 peer->host, afi, safi);
1875 }
1876 return;
1877 }
1878
1879 /* Adjust safi code. */
1880 if (safi == BGP_SAFI_VPNV4)
1881 safi = SAFI_MPLS_VPN;
1882
1883 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
1884 {
1885 u_char *end;
1886 u_char when_to_refresh;
1887 u_char orf_type;
1888 u_int16_t orf_len;
1889
1890 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
1891 {
1892 zlog_info ("%s ORF route refresh length error", peer->host);
1893 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
1894 return;
1895 }
1896
1897 when_to_refresh = stream_getc (s);
1898 end = stream_pnt (s) + (size - 5);
1899
1900 while (stream_pnt (s) < end)
1901 {
1902 orf_type = stream_getc (s);
1903 orf_len = stream_getw (s);
1904
1905 if (orf_type == ORF_TYPE_PREFIX
1906 || orf_type == ORF_TYPE_PREFIX_OLD)
1907 {
1908 u_char *p_pnt = stream_pnt (s);
1909 u_char *p_end = stream_pnt (s) + orf_len;
1910 struct orf_prefix orfp;
1911 u_char common = 0;
1912 u_int32_t seq;
1913 int psize;
1914 char name[BUFSIZ];
1915 char buf[BUFSIZ];
1916 int ret;
1917
1918 if (BGP_DEBUG (normal, NORMAL))
1919 {
ajs6b514742004-12-08 21:03:23 +00001920 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00001921 peer->host, orf_type, orf_len);
1922 }
1923
1924 /* ORF prefix-list name */
1925 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
1926
1927 while (p_pnt < p_end)
1928 {
1929 memset (&orfp, 0, sizeof (struct orf_prefix));
1930 common = *p_pnt++;
1931 if (common & ORF_COMMON_PART_REMOVE_ALL)
1932 {
1933 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001934 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
paul718e3742002-12-13 20:15:29 +00001935 prefix_bgp_orf_remove_all (name);
1936 break;
1937 }
1938 memcpy (&seq, p_pnt, sizeof (u_int32_t));
1939 p_pnt += sizeof (u_int32_t);
1940 orfp.seq = ntohl (seq);
1941 orfp.ge = *p_pnt++;
1942 orfp.le = *p_pnt++;
1943 orfp.p.prefixlen = *p_pnt++;
1944 orfp.p.family = afi2family (afi);
1945 psize = PSIZE (orfp.p.prefixlen);
1946 memcpy (&orfp.p.u.prefix, p_pnt, psize);
1947 p_pnt += psize;
1948
1949 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001950 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
paul718e3742002-12-13 20:15:29 +00001951 peer->host,
1952 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
1953 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
1954 orfp.seq,
1955 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
1956 orfp.p.prefixlen, orfp.ge, orfp.le);
1957
1958 ret = prefix_bgp_orf_set (name, afi, &orfp,
1959 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
1960 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
1961
1962 if (ret != CMD_SUCCESS)
1963 {
1964 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001965 zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
paul718e3742002-12-13 20:15:29 +00001966 prefix_bgp_orf_remove_all (name);
1967 break;
1968 }
1969 }
1970 peer->orf_plist[afi][safi] =
1971 prefix_list_lookup (AFI_ORF_PREFIX, name);
1972 }
paul9985f832005-02-09 15:51:56 +00001973 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00001974 }
1975 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001976 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00001977 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
1978 if (when_to_refresh == REFRESH_DEFER)
1979 return;
1980 }
1981
1982 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1983 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
1984 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
1985
1986 /* Perform route refreshment to the peer */
1987 bgp_announce_route (peer, afi, safi);
1988}
1989
paul94f2b392005-06-28 12:44:16 +00001990static int
paul718e3742002-12-13 20:15:29 +00001991bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
1992{
1993 u_char *end;
1994 struct capability cap;
1995 u_char action;
1996 struct bgp *bgp;
1997 afi_t afi;
1998 safi_t safi;
1999
2000 bgp = peer->bgp;
2001 end = pnt + length;
2002
2003 while (pnt < end)
2004 {
2005 /* We need at least action, capability code and capability length. */
2006 if (pnt + 3 > end)
2007 {
2008 zlog_info ("%s Capability length error", peer->host);
2009 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2010 return -1;
2011 }
2012
2013 action = *pnt;
2014
2015 /* Fetch structure to the byte stream. */
2016 memcpy (&cap, pnt + 1, sizeof (struct capability));
2017
2018 /* Action value check. */
2019 if (action != CAPABILITY_ACTION_SET
2020 && action != CAPABILITY_ACTION_UNSET)
2021 {
2022 zlog_info ("%s Capability Action Value error %d",
2023 peer->host, action);
2024 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2025 return -1;
2026 }
2027
2028 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002029 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
paul718e3742002-12-13 20:15:29 +00002030 peer->host, action, cap.code, cap.length);
2031
2032 /* Capability length check. */
2033 if (pnt + (cap.length + 3) > end)
2034 {
2035 zlog_info ("%s Capability length error", peer->host);
2036 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2037 return -1;
2038 }
2039
2040 /* We know MP Capability Code. */
2041 if (cap.code == CAPABILITY_CODE_MP)
2042 {
2043 afi = ntohs (cap.mpc.afi);
2044 safi = cap.mpc.safi;
2045
2046 /* Ignore capability when override-capability is set. */
2047 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2048 continue;
2049
2050 /* Address family check. */
2051 if ((afi == AFI_IP
2052 || afi == AFI_IP6)
2053 && (safi == SAFI_UNICAST
2054 || safi == SAFI_MULTICAST
2055 || safi == BGP_SAFI_VPNV4))
2056 {
2057 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002058 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
paul718e3742002-12-13 20:15:29 +00002059 peer->host,
2060 action == CAPABILITY_ACTION_SET
2061 ? "Advertising" : "Removing",
2062 ntohs(cap.mpc.afi) , cap.mpc.safi);
2063
2064 /* Adjust safi code. */
2065 if (safi == BGP_SAFI_VPNV4)
2066 safi = SAFI_MPLS_VPN;
2067
2068 if (action == CAPABILITY_ACTION_SET)
2069 {
2070 peer->afc_recv[afi][safi] = 1;
2071 if (peer->afc[afi][safi])
2072 {
2073 peer->afc_nego[afi][safi] = 1;
2074 bgp_announce_route (peer, afi, safi);
2075 }
2076 }
2077 else
2078 {
2079 peer->afc_recv[afi][safi] = 0;
2080 peer->afc_nego[afi][safi] = 0;
2081
2082 if (peer_active_nego (peer))
2083 bgp_clear_route (peer, afi, safi);
2084 else
2085 BGP_EVENT_ADD (peer, BGP_Stop);
2086 }
2087 }
2088 }
paul718e3742002-12-13 20:15:29 +00002089 else
2090 {
2091 zlog_warn ("%s unrecognized capability code: %d - ignored",
2092 peer->host, cap.code);
2093 }
2094 pnt += cap.length + 3;
2095 }
2096 return 0;
2097}
2098
2099/* Dynamic Capability is received. */
paul94f2b392005-06-28 12:44:16 +00002100static void
paul718e3742002-12-13 20:15:29 +00002101bgp_capability_receive (struct peer *peer, bgp_size_t size)
2102{
2103 u_char *pnt;
2104 int ret;
2105
2106 /* Fetch pointer. */
2107 pnt = stream_pnt (peer->ibuf);
2108
2109 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002110 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002111
2112 /* If peer does not have the capability, send notification. */
2113 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2114 {
2115 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2116 peer->host);
2117 bgp_notify_send (peer,
2118 BGP_NOTIFY_HEADER_ERR,
2119 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2120 return;
2121 }
2122
2123 /* Status must be Established. */
2124 if (peer->status != Established)
2125 {
2126 plog_err (peer->log,
2127 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2128 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2129 return;
2130 }
2131
2132 /* Parse packet. */
2133 ret = bgp_capability_msg_parse (peer, pnt, size);
2134}
2135
2136/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002137static int
paul718e3742002-12-13 20:15:29 +00002138bgp_read_packet (struct peer *peer)
2139{
2140 int nbytes;
2141 int readsize;
2142
paul9985f832005-02-09 15:51:56 +00002143 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002144
2145 /* If size is zero then return. */
2146 if (! readsize)
2147 return 0;
2148
2149 /* Read packet from fd. */
pauleb821182004-05-01 08:44:08 +00002150 nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002151
2152 /* If read byte is smaller than zero then error occured. */
2153 if (nbytes < 0)
2154 {
2155 if (errno == EAGAIN)
2156 return -1;
2157
2158 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002159 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002160
2161 if (peer->status == Established)
2162 {
2163 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2164 {
2165 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2166 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2167 }
2168 else
2169 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2170 }
2171
paul718e3742002-12-13 20:15:29 +00002172 BGP_EVENT_ADD (peer, TCP_fatal_error);
2173 return -1;
2174 }
2175
2176 /* When read byte is zero : clear bgp peer and return */
2177 if (nbytes == 0)
2178 {
2179 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002180 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002181 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002182
2183 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002184 {
2185 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2186 {
2187 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2188 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2189 }
2190 else
2191 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2192 }
hassoe0701b72004-05-20 09:19:34 +00002193
paul718e3742002-12-13 20:15:29 +00002194 BGP_EVENT_ADD (peer, TCP_connection_closed);
2195 return -1;
2196 }
2197
2198 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002199 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002200 return -1;
2201
2202 return 0;
2203}
2204
2205/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002206static int
paul718e3742002-12-13 20:15:29 +00002207bgp_marker_all_one (struct stream *s, int length)
2208{
2209 int i;
2210
2211 for (i = 0; i < length; i++)
2212 if (s->data[i] != 0xff)
2213 return 0;
2214
2215 return 1;
2216}
2217
2218/* Starting point of packet process function. */
2219int
2220bgp_read (struct thread *thread)
2221{
2222 int ret;
2223 u_char type = 0;
2224 struct peer *peer;
2225 bgp_size_t size;
2226 char notify_data_length[2];
2227
2228 /* Yes first of all get peer pointer. */
2229 peer = THREAD_ARG (thread);
2230 peer->t_read = NULL;
2231
2232 /* For non-blocking IO check. */
2233 if (peer->status == Connect)
2234 {
2235 bgp_connect_check (peer);
2236 goto done;
2237 }
2238 else
2239 {
pauleb821182004-05-01 08:44:08 +00002240 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002241 {
pauleb821182004-05-01 08:44:08 +00002242 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002243 return -1;
2244 }
pauleb821182004-05-01 08:44:08 +00002245 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002246 }
2247
2248 /* Read packet header to determine type of the packet */
2249 if (peer->packet_size == 0)
2250 peer->packet_size = BGP_HEADER_SIZE;
2251
paul9985f832005-02-09 15:51:56 +00002252 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002253 {
2254 ret = bgp_read_packet (peer);
2255
2256 /* Header read error or partial read packet. */
2257 if (ret < 0)
2258 goto done;
2259
2260 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002261 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002262 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2263 size = stream_getw (peer->ibuf);
2264 type = stream_getc (peer->ibuf);
2265
2266 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002267 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002268 peer->host, type, size - BGP_HEADER_SIZE);
2269
2270 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002271 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002272 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2273 {
2274 bgp_notify_send (peer,
2275 BGP_NOTIFY_HEADER_ERR,
2276 BGP_NOTIFY_HEADER_NOT_SYNC);
2277 goto done;
2278 }
2279
2280 /* BGP type check. */
2281 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2282 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2283 && type != BGP_MSG_ROUTE_REFRESH_NEW
2284 && type != BGP_MSG_ROUTE_REFRESH_OLD
2285 && type != BGP_MSG_CAPABILITY)
2286 {
2287 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002288 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002289 "%s unknown message type 0x%02x",
2290 peer->host, type);
2291 bgp_notify_send_with_data (peer,
2292 BGP_NOTIFY_HEADER_ERR,
2293 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2294 &type, 1);
2295 goto done;
2296 }
2297 /* Mimimum packet length check. */
2298 if ((size < BGP_HEADER_SIZE)
2299 || (size > BGP_MAX_PACKET_SIZE)
2300 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2301 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2302 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2303 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2304 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2305 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2306 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2307 {
2308 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002309 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002310 "%s bad message length - %d for %s",
2311 peer->host, size,
2312 type == 128 ? "ROUTE-REFRESH" :
2313 bgp_type_str[(int) type]);
2314 bgp_notify_send_with_data (peer,
2315 BGP_NOTIFY_HEADER_ERR,
2316 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002317 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002318 goto done;
2319 }
2320
2321 /* Adjust size to message length. */
2322 peer->packet_size = size;
2323 }
2324
2325 ret = bgp_read_packet (peer);
2326 if (ret < 0)
2327 goto done;
2328
2329 /* Get size and type again. */
2330 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2331 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2332
2333 /* BGP packet dump function. */
2334 bgp_dump_packet (peer, type, peer->ibuf);
2335
2336 size = (peer->packet_size - BGP_HEADER_SIZE);
2337
2338 /* Read rest of the packet and call each sort of packet routine */
2339 switch (type)
2340 {
2341 case BGP_MSG_OPEN:
2342 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002343 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002344 break;
2345 case BGP_MSG_UPDATE:
2346 peer->readtime = time(NULL); /* Last read timer reset */
2347 bgp_update_receive (peer, size);
2348 break;
2349 case BGP_MSG_NOTIFY:
2350 bgp_notify_receive (peer, size);
2351 break;
2352 case BGP_MSG_KEEPALIVE:
2353 peer->readtime = time(NULL); /* Last read timer reset */
2354 bgp_keepalive_receive (peer, size);
2355 break;
2356 case BGP_MSG_ROUTE_REFRESH_NEW:
2357 case BGP_MSG_ROUTE_REFRESH_OLD:
2358 peer->refresh_in++;
2359 bgp_route_refresh_receive (peer, size);
2360 break;
2361 case BGP_MSG_CAPABILITY:
2362 peer->dynamic_cap_in++;
2363 bgp_capability_receive (peer, size);
2364 break;
2365 }
2366
2367 /* Clear input buffer. */
2368 peer->packet_size = 0;
2369 if (peer->ibuf)
2370 stream_reset (peer->ibuf);
2371
2372 done:
2373 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2374 {
2375 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002376 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002377 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002378 }
2379 return 0;
2380}