Annotation of embedaddon/quagga/bgpd/bgp_packet.c, revision 1.1.1.5
1.1 misho 1: /* BGP packet management routine.
2: Copyright (C) 1999 Kunihiro Ishiguro
3:
4: This file is part of GNU Zebra.
5:
6: GNU Zebra is free software; you can redistribute it and/or modify it
7: under the terms of the GNU General Public License as published by the
8: Free Software Foundation; either version 2, or (at your option) any
9: later version.
10:
11: GNU Zebra is distributed in the hope that it will be useful, but
12: WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU Zebra; see the file COPYING. If not, write to the Free
18: Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19: 02111-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 () */
1.1.1.5 ! misho 31: #include "sockopt.h"
1.1 misho 32: #include "linklist.h"
33: #include "plist.h"
1.1.1.5 ! misho 34: #include "filter.h"
1.1 misho 35:
36: #include "bgpd/bgpd.h"
37: #include "bgpd/bgp_table.h"
38: #include "bgpd/bgp_dump.h"
39: #include "bgpd/bgp_attr.h"
40: #include "bgpd/bgp_debug.h"
41: #include "bgpd/bgp_fsm.h"
42: #include "bgpd/bgp_route.h"
43: #include "bgpd/bgp_packet.h"
44: #include "bgpd/bgp_open.h"
45: #include "bgpd/bgp_aspath.h"
46: #include "bgpd/bgp_community.h"
47: #include "bgpd/bgp_ecommunity.h"
48: #include "bgpd/bgp_network.h"
49: #include "bgpd/bgp_mplsvpn.h"
1.1.1.5 ! misho 50: #include "bgpd/bgp_encap.h"
1.1 misho 51: #include "bgpd/bgp_advertise.h"
52: #include "bgpd/bgp_vty.h"
53:
54: int stream_put_prefix (struct stream *, struct prefix *);
1.1.1.5 ! misho 55:
1.1 misho 56: /* Set up BGP packet marker and packet type. */
57: static int
58: bgp_packet_set_marker (struct stream *s, u_char type)
59: {
60: int i;
61:
62: /* Fill in marker. */
63: for (i = 0; i < BGP_MARKER_SIZE; i++)
64: stream_putc (s, 0xff);
65:
66: /* Dummy total length. This field is should be filled in later on. */
67: stream_putw (s, 0);
68:
69: /* BGP packet type. */
70: stream_putc (s, type);
71:
72: /* Return current stream size. */
73: return stream_get_endp (s);
74: }
75:
76: /* Set BGP packet header size entry. If size is zero then use current
77: stream size. */
78: static int
79: bgp_packet_set_size (struct stream *s)
80: {
81: int cp;
82:
83: /* Preserve current pointer. */
84: cp = stream_get_endp (s);
85: stream_putw_at (s, BGP_MARKER_SIZE, cp);
86:
87: return cp;
88: }
89:
90: /* Add new packet to the peer. */
91: static void
92: bgp_packet_add (struct peer *peer, struct stream *s)
93: {
94: /* Add packet to the end of list. */
95: stream_fifo_push (peer->obuf, s);
96: }
97:
98: /* Free first packet. */
99: static void
100: bgp_packet_delete (struct peer *peer)
101: {
102: stream_free (stream_fifo_pop (peer->obuf));
103: }
104:
105: /* Check file descriptor whether connect is established. */
106: static void
107: bgp_connect_check (struct peer *peer)
108: {
109: int status;
110: socklen_t slen;
111: int ret;
112:
113: /* Anyway I have to reset read and write thread. */
114: BGP_READ_OFF (peer->t_read);
115: BGP_WRITE_OFF (peer->t_write);
116:
117: /* Check file descriptor. */
118: slen = sizeof (status);
119: ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
120:
121: /* If getsockopt is fail, this is fatal error. */
122: if (ret < 0)
123: {
124: zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
125: BGP_EVENT_ADD (peer, TCP_fatal_error);
126: return;
127: }
128:
129: /* When status is 0 then TCP connection is established. */
130: if (status == 0)
131: {
132: BGP_EVENT_ADD (peer, TCP_connection_open);
133: }
134: else
135: {
136: if (BGP_DEBUG (events, EVENTS))
137: plog_debug (peer->log, "%s [Event] Connect failed (%s)",
138: peer->host, safe_strerror (errno));
139: BGP_EVENT_ADD (peer, TCP_connection_open_failed);
140: }
141: }
142:
143: /* Make BGP update packet. */
144: static struct stream *
145: bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
146: {
147: struct stream *s;
1.1.1.5 ! misho 148: struct stream *snlri;
1.1 misho 149: struct bgp_adj_out *adj;
150: struct bgp_advertise *adv;
151: struct stream *packet;
152: struct bgp_node *rn = NULL;
153: struct bgp_info *binfo = NULL;
154: bgp_size_t total_attr_len = 0;
1.1.1.5 ! misho 155: unsigned long attrlen_pos = 0;
! 156: size_t mpattrlen_pos = 0;
! 157: size_t mpattr_pos = 0;
1.1 misho 158:
159: s = peer->work;
160: stream_reset (s);
1.1.1.5 ! misho 161: snlri = peer->scratch;
! 162: stream_reset (snlri);
1.1 misho 163:
1.1.1.5 ! misho 164: adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
1.1 misho 165:
166: while (adv)
167: {
168: assert (adv->rn);
169: rn = adv->rn;
170: adj = adv->adj;
171: if (adv->binfo)
172: binfo = adv->binfo;
173:
174: /* When remaining space can't include NLRI and it's length. */
1.1.1.5 ! misho 175: if (STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) <=
! 176: (BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(afi,safi,&rn->p)))
1.1 misho 177: break;
178:
179: /* If packet is empty, set attribute. */
180: if (stream_empty (s))
181: {
182: struct prefix_rd *prd = NULL;
183: u_char *tag = NULL;
184: struct peer *from = NULL;
1.1.1.5 ! misho 185:
1.1 misho 186: if (rn->prn)
187: prd = (struct prefix_rd *) &rn->prn->p;
188: if (binfo)
189: {
190: from = binfo->peer;
191: if (binfo->extra)
192: tag = binfo->extra->tag;
193: }
1.1.1.5 ! misho 194:
! 195: /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
! 196: * one byte message type.
! 197: */
1.1 misho 198: bgp_packet_set_marker (s, BGP_MSG_UPDATE);
1.1.1.5 ! misho 199:
! 200: /* 2: withdrawn routes length */
1.1 misho 201: stream_putw (s, 0);
1.1.1.5 ! misho 202:
! 203: /* 3: total attributes length - attrlen_pos stores the position */
! 204: attrlen_pos = stream_get_endp (s);
! 205: stream_putw (s, 0);
! 206:
! 207: /* 4: if there is MP_REACH_NLRI attribute, that should be the first
! 208: * attribute, according to draft-ietf-idr-error-handling. Save the
! 209: * position.
! 210: */
! 211: mpattr_pos = stream_get_endp(s);
! 212:
! 213: /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
! 214: total_attr_len = bgp_packet_attribute (NULL, peer, s,
1.1 misho 215: adv->baa->attr,
1.1.1.5 ! misho 216: ((afi == AFI_IP && safi == SAFI_UNICAST) ?
! 217: &rn->p : NULL),
! 218: afi, safi,
1.1 misho 219: from, prd, tag);
220: }
221:
222: if (afi == AFI_IP && safi == SAFI_UNICAST)
223: stream_put_prefix (s, &rn->p);
1.1.1.5 ! misho 224: else
! 225: {
! 226: /* Encode the prefix in MP_REACH_NLRI attribute */
! 227: struct prefix_rd *prd = NULL;
! 228: u_char *tag = NULL;
! 229:
! 230: if (rn->prn)
! 231: prd = (struct prefix_rd *) &rn->prn->p;
! 232: if (binfo && binfo->extra)
! 233: tag = binfo->extra->tag;
! 234:
! 235: if (stream_empty(snlri))
! 236: mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
! 237: adv->baa->attr);
! 238: bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag);
! 239: }
1.1 misho 240: if (BGP_DEBUG (update, UPDATE_OUT))
1.1.1.4 misho 241: {
242: char buf[INET6_BUFSIZ];
243:
244: zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
245: peer->host,
246: inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
247: rn->p.prefixlen);
248: }
1.1 misho 249:
250: /* Synchnorize attribute. */
251: if (adj->attr)
252: bgp_attr_unintern (&adj->attr);
253: else
254: peer->scount[afi][safi]++;
255:
256: adj->attr = bgp_attr_intern (adv->baa->attr);
257:
258: adv = bgp_advertise_clean (peer, adj, afi, safi);
259: }
1.1.1.5 ! misho 260:
1.1 misho 261: if (! stream_empty (s))
262: {
1.1.1.5 ! misho 263: if (!stream_empty(snlri))
! 264: {
! 265: bgp_packet_mpattr_end(snlri, mpattrlen_pos);
! 266: total_attr_len += stream_get_endp(snlri);
! 267: }
! 268:
! 269: /* set the total attribute length correctly */
! 270: stream_putw_at (s, attrlen_pos, total_attr_len);
! 271:
! 272: if (!stream_empty(snlri))
! 273: packet = stream_dupcat(s, snlri, mpattr_pos);
! 274: else
! 275: packet = stream_dup (s);
! 276: bgp_packet_set_size (packet);
1.1 misho 277: bgp_packet_add (peer, packet);
278: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
279: stream_reset (s);
1.1.1.5 ! misho 280: stream_reset (snlri);
1.1 misho 281: return packet;
282: }
283: return NULL;
284: }
285:
286: static struct stream *
287: bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
288: {
289: struct stream *s;
290:
291: if (DISABLE_BGP_ANNOUNCE)
292: return NULL;
293:
294: if (BGP_DEBUG (normal, NORMAL))
295: zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
296:
297: s = stream_new (BGP_MAX_PACKET_SIZE);
298:
299: /* Make BGP update packet. */
300: bgp_packet_set_marker (s, BGP_MSG_UPDATE);
301:
302: /* Unfeasible Routes Length */
303: stream_putw (s, 0);
304:
305: if (afi == AFI_IP && safi == SAFI_UNICAST)
306: {
307: /* Total Path Attribute Length */
308: stream_putw (s, 0);
309: }
310: else
311: {
312: /* Total Path Attribute Length */
313: stream_putw (s, 6);
314: stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
315: stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
316: stream_putc (s, 3);
317: stream_putw (s, afi);
318: stream_putc (s, safi);
319: }
320:
321: bgp_packet_set_size (s);
1.1.1.5 ! misho 322: bgp_packet_add (peer, s);
! 323: return s;
1.1 misho 324: }
325:
326: /* Make BGP withdraw packet. */
1.1.1.5 ! misho 327: /* For ipv4 unicast:
! 328: 16-octet marker | 2-octet length | 1-octet type |
! 329: 2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
! 330: */
! 331: /* For other afi/safis:
! 332: 16-octet marker | 2-octet length | 1-octet type |
! 333: 2-octet withdrawn route length (=0) | 2-octet attrlen |
! 334: mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
! 335: */
1.1 misho 336: static struct stream *
337: bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
338: {
339: struct stream *s;
340: struct stream *packet;
341: struct bgp_adj_out *adj;
342: struct bgp_advertise *adv;
343: struct bgp_node *rn;
344: bgp_size_t unfeasible_len;
345: bgp_size_t total_attr_len;
1.1.1.5 ! misho 346: size_t mp_start = 0;
! 347: size_t attrlen_pos = 0;
! 348: size_t mplen_pos = 0;
! 349: u_char first_time = 1;
1.1 misho 350:
351: s = peer->work;
352: stream_reset (s);
353:
1.1.1.5 ! misho 354: while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
1.1 misho 355: {
356: assert (adv->rn);
357: adj = adv->adj;
358: rn = adv->rn;
359:
1.1.1.5 ! misho 360: if (STREAM_REMAIN (s)
1.1 misho 361: < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
362: break;
363:
364: if (stream_empty (s))
365: {
366: bgp_packet_set_marker (s, BGP_MSG_UPDATE);
1.1.1.5 ! misho 367: stream_putw (s, 0); /* unfeasible routes length */
1.1 misho 368: }
1.1.1.5 ! misho 369: else
! 370: first_time = 0;
1.1 misho 371:
372: if (afi == AFI_IP && safi == SAFI_UNICAST)
373: stream_put_prefix (s, &rn->p);
374: else
375: {
376: struct prefix_rd *prd = NULL;
1.1.1.5 ! misho 377:
1.1 misho 378: if (rn->prn)
379: prd = (struct prefix_rd *) &rn->prn->p;
1.1.1.5 ! misho 380:
! 381: /* If first time, format the MP_UNREACH header */
! 382: if (first_time)
! 383: {
! 384: attrlen_pos = stream_get_endp (s);
! 385: /* total attr length = 0 for now. reevaluate later */
! 386: stream_putw (s, 0);
! 387: mp_start = stream_get_endp (s);
! 388: mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
! 389: }
! 390:
! 391: bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL);
1.1 misho 392: }
393:
394: if (BGP_DEBUG (update, UPDATE_OUT))
1.1.1.4 misho 395: {
396: char buf[INET6_BUFSIZ];
397:
398: zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
399: peer->host,
400: inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
401: rn->p.prefixlen);
402: }
1.1 misho 403:
404: peer->scount[afi][safi]--;
405:
406: bgp_adj_out_remove (rn, adj, peer, afi, safi);
407: bgp_unlock_node (rn);
408: }
409:
410: if (! stream_empty (s))
411: {
412: if (afi == AFI_IP && safi == SAFI_UNICAST)
413: {
1.1.1.5 ! misho 414: unfeasible_len
1.1 misho 415: = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
416: stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
417: stream_putw (s, 0);
418: }
1.1.1.5 ! misho 419: else
! 420: {
! 421: /* Set the mp_unreach attr's length */
! 422: bgp_packet_mpunreach_end(s, mplen_pos);
! 423:
! 424: /* Set total path attribute length. */
! 425: total_attr_len = stream_get_endp(s) - mp_start;
! 426: stream_putw_at (s, attrlen_pos, total_attr_len);
! 427: }
1.1 misho 428: bgp_packet_set_size (s);
429: packet = stream_dup (s);
430: bgp_packet_add (peer, packet);
431: stream_reset (s);
432: return packet;
433: }
434:
435: return NULL;
436: }
437:
438: void
439: bgp_default_update_send (struct peer *peer, struct attr *attr,
440: afi_t afi, safi_t safi, struct peer *from)
441: {
442: struct stream *s;
443: struct prefix p;
444: unsigned long pos;
445: bgp_size_t total_attr_len;
446:
447: if (DISABLE_BGP_ANNOUNCE)
448: return;
449:
450: if (afi == AFI_IP)
451: str2prefix ("0.0.0.0/0", &p);
452: else
453: str2prefix ("::/0", &p);
454:
455: /* Logging the attribute. */
456: if (BGP_DEBUG (update, UPDATE_OUT))
457: {
1.1.1.4 misho 458: char attrstr[BUFSIZ];
459: char buf[INET6_BUFSIZ];
460: attrstr[0] = '\0';
461:
1.1 misho 462: bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
463: zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
1.1.1.4 misho 464: peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
1.1 misho 465: p.prefixlen, attrstr);
466: }
467:
468: s = stream_new (BGP_MAX_PACKET_SIZE);
469:
470: /* Make BGP update packet. */
471: bgp_packet_set_marker (s, BGP_MSG_UPDATE);
472:
473: /* Unfeasible Routes Length. */
474: stream_putw (s, 0);
475:
476: /* Make place for total attribute length. */
477: pos = stream_get_endp (s);
478: stream_putw (s, 0);
479: total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
480:
481: /* Set Total Path Attribute Length. */
482: stream_putw_at (s, pos, total_attr_len);
483:
484: /* NLRI set. */
485: if (p.family == AF_INET && safi == SAFI_UNICAST)
486: stream_put_prefix (s, &p);
487:
488: /* Set size. */
489: bgp_packet_set_size (s);
490:
491: /* Dump packet if debug option is set. */
492: #ifdef DEBUG
493: /* bgp_packet_dump (packet); */
494: #endif /* DEBUG */
495:
496: /* Add packet to the peer. */
1.1.1.5 ! misho 497: bgp_packet_add (peer, s);
1.1 misho 498:
499: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
500: }
501:
502: void
503: bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
504: {
505: struct stream *s;
506: struct prefix p;
1.1.1.5 ! misho 507: unsigned long attrlen_pos = 0;
1.1 misho 508: unsigned long cp;
509: bgp_size_t unfeasible_len;
510: bgp_size_t total_attr_len;
1.1.1.5 ! misho 511: size_t mp_start = 0;
! 512: size_t mplen_pos = 0;
1.1 misho 513:
514: if (DISABLE_BGP_ANNOUNCE)
515: return;
516:
517: if (afi == AFI_IP)
518: str2prefix ("0.0.0.0/0", &p);
519: else
520: str2prefix ("::/0", &p);
521:
522: total_attr_len = 0;
523:
524: if (BGP_DEBUG (update, UPDATE_OUT))
1.1.1.4 misho 525: {
526: char buf[INET6_BUFSIZ];
527:
528: zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
529: peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
530: p.prefixlen);
531: }
1.1 misho 532:
533: s = stream_new (BGP_MAX_PACKET_SIZE);
534:
535: /* Make BGP update packet. */
536: bgp_packet_set_marker (s, BGP_MSG_UPDATE);
537:
538: /* Unfeasible Routes Length. */;
539: cp = stream_get_endp (s);
540: stream_putw (s, 0);
541:
542: /* Withdrawn Routes. */
543: if (p.family == AF_INET && safi == SAFI_UNICAST)
544: {
545: stream_put_prefix (s, &p);
546:
547: unfeasible_len = stream_get_endp (s) - cp - 2;
548:
549: /* Set unfeasible len. */
550: stream_putw_at (s, cp, unfeasible_len);
551:
552: /* Set total path attribute length. */
553: stream_putw (s, 0);
554: }
555: else
556: {
1.1.1.5 ! misho 557: attrlen_pos = stream_get_endp (s);
1.1 misho 558: stream_putw (s, 0);
1.1.1.5 ! misho 559: mp_start = stream_get_endp (s);
! 560: mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
! 561: bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL);
! 562:
! 563: /* Set the mp_unreach attr's length */
! 564: bgp_packet_mpunreach_end(s, mplen_pos);
1.1 misho 565:
566: /* Set total path attribute length. */
1.1.1.5 ! misho 567: total_attr_len = stream_get_endp(s) - mp_start;
! 568: stream_putw_at (s, attrlen_pos, total_attr_len);
1.1 misho 569: }
570:
571: bgp_packet_set_size (s);
572:
573: /* Add packet to the peer. */
1.1.1.5 ! misho 574: bgp_packet_add (peer, s);
1.1 misho 575:
576: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
577: }
578:
579: /* Get next packet to be written. */
580: static struct stream *
581: bgp_write_packet (struct peer *peer)
582: {
583: afi_t afi;
584: safi_t safi;
585: struct stream *s = NULL;
586: struct bgp_advertise *adv;
587:
588: s = stream_fifo_head (peer->obuf);
589: if (s)
590: return s;
591:
592: for (afi = AFI_IP; afi < AFI_MAX; afi++)
593: for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
594: {
1.1.1.5 ! misho 595: adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
1.1 misho 596: if (adv)
597: {
598: s = bgp_withdraw_packet (peer, afi, safi);
599: if (s)
600: return s;
601: }
602: }
603:
604: for (afi = AFI_IP; afi < AFI_MAX; afi++)
605: for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
606: {
1.1.1.5 ! misho 607: adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
1.1 misho 608: if (adv)
609: {
610: if (adv->binfo && adv->binfo->uptime < peer->synctime)
611: {
612: if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
613: && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
1.1.1.5 ! misho 614: && ! (CHECK_FLAG (adv->binfo->peer->cap,
! 615: PEER_CAP_RESTART_BIT_RCV) &&
! 616: CHECK_FLAG (adv->binfo->peer->cap,
! 617: PEER_CAP_RESTART_BIT_ADV))
1.1 misho 618: && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
619: && safi != SAFI_MPLS_VPN)
620: {
621: if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
622: PEER_STATUS_EOR_RECEIVED))
623: s = bgp_update_packet (peer, afi, safi);
624: }
625: else
626: s = bgp_update_packet (peer, afi, safi);
627: }
628:
629: if (s)
630: return s;
631: }
632:
633: if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
634: {
635: if (peer->afc_nego[afi][safi] && peer->synctime
636: && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
637: && safi != SAFI_MPLS_VPN)
638: {
639: SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
640: return bgp_update_packet_eor (peer, afi, safi);
641: }
642: }
643: }
644:
645: return NULL;
646: }
647:
648: /* Is there partially written packet or updates we can send right
649: now. */
650: static int
651: bgp_write_proceed (struct peer *peer)
652: {
653: afi_t afi;
654: safi_t safi;
655: struct bgp_advertise *adv;
656:
657: if (stream_fifo_head (peer->obuf))
658: return 1;
659:
660: for (afi = AFI_IP; afi < AFI_MAX; afi++)
661: for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
662: if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
663: return 1;
664:
665: for (afi = AFI_IP; afi < AFI_MAX; afi++)
666: for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1.1.1.5 ! misho 667: if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
1.1 misho 668: if (adv->binfo->uptime < peer->synctime)
669: return 1;
670:
671: return 0;
672: }
673:
674: /* Write packet to the peer. */
675: int
676: bgp_write (struct thread *thread)
677: {
678: struct peer *peer;
679: u_char type;
680: struct stream *s;
681: int num;
682: unsigned int count = 0;
683:
684: /* Yes first of all get peer pointer. */
685: peer = THREAD_ARG (thread);
686: peer->t_write = NULL;
687:
688: /* For non-blocking IO check. */
689: if (peer->status == Connect)
690: {
691: bgp_connect_check (peer);
692: return 0;
693: }
694:
695: s = bgp_write_packet (peer);
696: if (!s)
697: return 0; /* nothing to send */
698:
699: sockopt_cork (peer->fd, 1);
700:
701: /* Nonblocking write until TCP output buffer is full. */
702: do
703: {
704: int writenum;
705:
706: /* Number of bytes to be sent. */
707: writenum = stream_get_endp (s) - stream_get_getp (s);
708:
709: /* Call write() system call. */
710: num = write (peer->fd, STREAM_PNT (s), writenum);
711: if (num < 0)
712: {
713: /* write failed either retry needed or error */
714: if (ERRNO_IO_RETRY(errno))
715: break;
716:
717: BGP_EVENT_ADD (peer, TCP_fatal_error);
718: return 0;
719: }
720:
721: if (num != writenum)
722: {
723: /* Partial write */
724: stream_forward_getp (s, num);
725: break;
726: }
727:
728: /* Retrieve BGP packet type. */
729: stream_set_getp (s, BGP_MARKER_SIZE + 2);
730: type = stream_getc (s);
731:
732: switch (type)
733: {
734: case BGP_MSG_OPEN:
735: peer->open_out++;
736: break;
737: case BGP_MSG_UPDATE:
738: peer->update_out++;
739: break;
740: case BGP_MSG_NOTIFY:
741: peer->notify_out++;
742: /* Double start timer. */
743: peer->v_start *= 2;
744:
745: /* Overflow check. */
746: if (peer->v_start >= (60 * 2))
747: peer->v_start = (60 * 2);
748:
749: /* Flush any existing events */
750: BGP_EVENT_ADD (peer, BGP_Stop);
1.1.1.4 misho 751: goto done;
752:
1.1 misho 753: case BGP_MSG_KEEPALIVE:
754: peer->keepalive_out++;
755: break;
756: case BGP_MSG_ROUTE_REFRESH_NEW:
757: case BGP_MSG_ROUTE_REFRESH_OLD:
758: peer->refresh_out++;
759: break;
760: case BGP_MSG_CAPABILITY:
761: peer->dynamic_cap_out++;
762: break;
763: }
764:
765: /* OK we send packet so delete it. */
766: bgp_packet_delete (peer);
767: }
768: while (++count < BGP_WRITE_PACKET_MAX &&
769: (s = bgp_write_packet (peer)) != NULL);
770:
771: if (bgp_write_proceed (peer))
772: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
1.1.1.4 misho 773:
774: done:
775: sockopt_cork (peer->fd, 0);
1.1 misho 776: return 0;
777: }
778:
779: /* This is only for sending NOTIFICATION message to neighbor. */
780: static int
781: bgp_write_notify (struct peer *peer)
782: {
783: int ret, val;
784: u_char type;
785: struct stream *s;
786:
787: /* There should be at least one packet. */
788: s = stream_fifo_head (peer->obuf);
789: if (!s)
790: return 0;
791: assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
792:
1.1.1.4 misho 793: /* Stop collecting data within the socket */
794: sockopt_cork (peer->fd, 0);
795:
1.1.1.5 ! misho 796: /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
! 797: * we only care about getting a clean shutdown at this point. */
1.1.1.4 misho 798: ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
1.1.1.5 ! misho 799:
! 800: /* only connection reset/close gets counted as TCP_fatal_error, failure
! 801: * to write the entire NOTIFY doesn't get different FSM treatment */
1.1 misho 802: if (ret <= 0)
803: {
804: BGP_EVENT_ADD (peer, TCP_fatal_error);
805: return 0;
806: }
807:
1.1.1.4 misho 808: /* Disable Nagle, make NOTIFY packet go out right away */
809: val = 1;
810: (void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
811: (char *) &val, sizeof (val));
812:
1.1 misho 813: /* Retrieve BGP packet type. */
814: stream_set_getp (s, BGP_MARKER_SIZE + 2);
815: type = stream_getc (s);
816:
817: assert (type == BGP_MSG_NOTIFY);
818:
819: /* Type should be notify. */
820: peer->notify_out++;
821:
822: /* Double start timer. */
823: peer->v_start *= 2;
824:
825: /* Overflow check. */
826: if (peer->v_start >= (60 * 2))
827: peer->v_start = (60 * 2);
828:
829: BGP_EVENT_ADD (peer, BGP_Stop);
830:
831: return 0;
832: }
833:
834: /* Make keepalive packet and send it to the peer. */
835: void
836: bgp_keepalive_send (struct peer *peer)
837: {
838: struct stream *s;
839: int length;
840:
841: s = stream_new (BGP_MAX_PACKET_SIZE);
842:
843: /* Make keepalive packet. */
844: bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
845:
846: /* Set packet size. */
847: length = bgp_packet_set_size (s);
848:
849: /* Dump packet if debug option is set. */
850: /* bgp_packet_dump (s); */
851:
852: if (BGP_DEBUG (keepalive, KEEPALIVE))
853: zlog_debug ("%s sending KEEPALIVE", peer->host);
854: if (BGP_DEBUG (normal, NORMAL))
855: zlog_debug ("%s send message type %d, length (incl. header) %d",
856: peer->host, BGP_MSG_KEEPALIVE, length);
857:
858: /* Add packet to the peer. */
859: bgp_packet_add (peer, s);
860:
861: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
862: }
863:
864: /* Make open packet and send it to the peer. */
865: void
866: bgp_open_send (struct peer *peer)
867: {
868: struct stream *s;
869: int length;
870: u_int16_t send_holdtime;
871: as_t local_as;
872:
873: if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
874: send_holdtime = peer->holdtime;
875: else
876: send_holdtime = peer->bgp->default_holdtime;
877:
878: /* local-as Change */
879: if (peer->change_local_as)
880: local_as = peer->change_local_as;
881: else
882: local_as = peer->local_as;
883:
884: s = stream_new (BGP_MAX_PACKET_SIZE);
885:
886: /* Make open packet. */
887: bgp_packet_set_marker (s, BGP_MSG_OPEN);
888:
889: /* Set open packet values. */
890: stream_putc (s, BGP_VERSION_4); /* BGP version */
891: stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
892: : BGP_AS_TRANS);
893: stream_putw (s, send_holdtime); /* Hold Time */
894: stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
895:
896: /* Set capability code. */
897: bgp_open_capability (s, peer);
898:
899: /* Set BGP packet length. */
900: length = bgp_packet_set_size (s);
901:
902: if (BGP_DEBUG (normal, NORMAL))
903: zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
904: peer->host, BGP_VERSION_4, local_as,
905: send_holdtime, inet_ntoa (peer->local_id));
906:
907: if (BGP_DEBUG (normal, NORMAL))
908: zlog_debug ("%s send message type %d, length (incl. header) %d",
909: peer->host, BGP_MSG_OPEN, length);
910:
911: /* Dump packet if debug option is set. */
912: /* bgp_packet_dump (s); */
913:
914: /* Add packet to the peer. */
915: bgp_packet_add (peer, s);
916:
917: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
918: }
919:
920: /* Send BGP notify packet with data potion. */
921: void
922: bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
923: u_char *data, size_t datalen)
924: {
925: struct stream *s;
926: int length;
927:
928: /* Allocate new stream. */
929: s = stream_new (BGP_MAX_PACKET_SIZE);
930:
931: /* Make nitify packet. */
932: bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
933:
934: /* Set notify packet values. */
935: stream_putc (s, code); /* BGP notify code */
936: stream_putc (s, sub_code); /* BGP notify sub_code */
937:
938: /* If notify data is present. */
939: if (data)
940: stream_write (s, data, datalen);
941:
942: /* Set BGP packet length. */
943: length = bgp_packet_set_size (s);
944:
945: /* Add packet to the peer. */
946: stream_fifo_clean (peer->obuf);
947: bgp_packet_add (peer, s);
948:
949: /* For debug */
950: {
951: struct bgp_notify bgp_notify;
952: int first = 0;
953: int i;
954: char c[4];
955:
956: bgp_notify.code = code;
957: bgp_notify.subcode = sub_code;
958: bgp_notify.data = NULL;
959: bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
960:
961: if (bgp_notify.length)
962: {
963: bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
964: for (i = 0; i < bgp_notify.length; i++)
965: if (first)
966: {
967: sprintf (c, " %02x", data[i]);
968: strcat (bgp_notify.data, c);
969: }
970: else
971: {
972: first = 1;
973: sprintf (c, "%02x", data[i]);
974: strcpy (bgp_notify.data, c);
975: }
976: }
977: bgp_notify_print (peer, &bgp_notify, "sending");
1.1.1.5 ! misho 978:
1.1 misho 979: if (bgp_notify.data)
1.1.1.5 ! misho 980: {
! 981: XFREE (MTYPE_TMP, bgp_notify.data);
! 982: bgp_notify.data = NULL;
! 983: bgp_notify.length = 0;
! 984: }
1.1 misho 985: }
986:
987: if (BGP_DEBUG (normal, NORMAL))
988: zlog_debug ("%s send message type %d, length (incl. header) %d",
989: peer->host, BGP_MSG_NOTIFY, length);
990:
991: /* peer reset cause */
992: if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
993: {
994: if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
995: {
996: peer->last_reset = PEER_DOWN_USER_RESET;
997: zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
998: }
999: else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
1000: {
1001: peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
1002: zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
1003: }
1004: else
1005: {
1006: peer->last_reset = PEER_DOWN_NOTIFY_SEND;
1007: zlog_info ("Notification sent to neighbor %s: type %u/%u",
1008: peer->host, code, sub_code);
1009: }
1010: }
1011: else
1012: zlog_info ("Notification sent to neighbor %s: configuration change",
1013: peer->host);
1014:
1015: /* Call immediately. */
1016: BGP_WRITE_OFF (peer->t_write);
1017:
1018: bgp_write_notify (peer);
1019: }
1020:
1021: /* Send BGP notify packet. */
1022: void
1023: bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1024: {
1025: bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1026: }
1027:
1028: /* Send route refresh message to the peer. */
1029: void
1030: bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1031: u_char orf_type, u_char when_to_refresh, int remove)
1032: {
1033: struct stream *s;
1034: int length;
1035: struct bgp_filter *filter;
1036: int orf_refresh = 0;
1037:
1038: if (DISABLE_BGP_ANNOUNCE)
1039: return;
1040:
1041: filter = &peer->filter[afi][safi];
1042:
1043: /* Adjust safi code. */
1044: if (safi == SAFI_MPLS_VPN)
1.1.1.3 misho 1045: safi = SAFI_MPLS_LABELED_VPN;
1.1 misho 1046:
1047: s = stream_new (BGP_MAX_PACKET_SIZE);
1048:
1049: /* Make BGP update packet. */
1050: if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1051: bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1052: else
1053: bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1054:
1055: /* Encode Route Refresh message. */
1056: stream_putw (s, afi);
1057: stream_putc (s, 0);
1058: stream_putc (s, safi);
1059:
1060: if (orf_type == ORF_TYPE_PREFIX
1061: || orf_type == ORF_TYPE_PREFIX_OLD)
1062: if (remove || filter->plist[FILTER_IN].plist)
1063: {
1064: u_int16_t orf_len;
1065: unsigned long orfp;
1066:
1067: orf_refresh = 1;
1068: stream_putc (s, when_to_refresh);
1069: stream_putc (s, orf_type);
1070: orfp = stream_get_endp (s);
1071: stream_putw (s, 0);
1072:
1073: if (remove)
1074: {
1075: UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1076: stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1077: if (BGP_DEBUG (normal, NORMAL))
1078: zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
1079: peer->host, orf_type,
1080: (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1081: afi, safi);
1082: }
1083: else
1084: {
1085: SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1086: prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1087: ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1088: ORF_COMMON_PART_DENY);
1089: if (BGP_DEBUG (normal, NORMAL))
1090: zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
1091: peer->host, orf_type,
1092: (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1093: afi, safi);
1094: }
1095:
1096: /* Total ORF Entry Len. */
1097: orf_len = stream_get_endp (s) - orfp - 2;
1098: stream_putw_at (s, orfp, orf_len);
1099: }
1100:
1101: /* Set packet size. */
1102: length = bgp_packet_set_size (s);
1103:
1104: if (BGP_DEBUG (normal, NORMAL))
1105: {
1106: if (! orf_refresh)
1107: zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
1108: peer->host, afi, safi);
1109: zlog_debug ("%s send message type %d, length (incl. header) %d",
1110: peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1111: BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1112: }
1113:
1114: /* Add packet to the peer. */
1.1.1.5 ! misho 1115: bgp_packet_add (peer, s);
1.1 misho 1116:
1117: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
1118: }
1119:
1120: /* Send capability message to the peer. */
1121: void
1122: bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1123: int capability_code, int action)
1124: {
1125: struct stream *s;
1126: int length;
1127:
1128: /* Adjust safi code. */
1129: if (safi == SAFI_MPLS_VPN)
1.1.1.3 misho 1130: safi = SAFI_MPLS_LABELED_VPN;
1.1 misho 1131:
1132: s = stream_new (BGP_MAX_PACKET_SIZE);
1133:
1134: /* Make BGP update packet. */
1135: bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1136:
1137: /* Encode MP_EXT capability. */
1138: if (capability_code == CAPABILITY_CODE_MP)
1139: {
1140: stream_putc (s, action);
1141: stream_putc (s, CAPABILITY_CODE_MP);
1142: stream_putc (s, CAPABILITY_CODE_MP_LEN);
1143: stream_putw (s, afi);
1144: stream_putc (s, 0);
1145: stream_putc (s, safi);
1146:
1147: if (BGP_DEBUG (normal, NORMAL))
1148: zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
1149: peer->host, action == CAPABILITY_ACTION_SET ?
1150: "Advertising" : "Removing", afi, safi);
1151: }
1152:
1153: /* Set packet size. */
1154: length = bgp_packet_set_size (s);
1155:
1156:
1157: /* Add packet to the peer. */
1.1.1.5 ! misho 1158: bgp_packet_add (peer, s);
1.1 misho 1159:
1160: if (BGP_DEBUG (normal, NORMAL))
1161: zlog_debug ("%s send message type %d, length (incl. header) %d",
1162: peer->host, BGP_MSG_CAPABILITY, length);
1163:
1164: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
1165: }
1.1.1.5 ! misho 1166:
1.1 misho 1167: /* RFC1771 6.8 Connection collision detection. */
1168: static int
1169: bgp_collision_detect (struct peer *new, struct in_addr remote_id)
1170: {
1171: struct peer *peer;
1172: struct listnode *node, *nnode;
1173: struct bgp *bgp;
1174:
1175: bgp = bgp_get_default ();
1176: if (! bgp)
1177: return 0;
1178:
1179: /* Upon receipt of an OPEN message, the local system must examine
1180: all of its connections that are in the OpenConfirm state. A BGP
1181: speaker may also examine connections in an OpenSent state if it
1182: knows the BGP Identifier of the peer by means outside of the
1183: protocol. If among these connections there is a connection to a
1184: remote BGP speaker whose BGP Identifier equals the one in the
1185: OPEN message, then the local system performs the following
1186: collision resolution procedure: */
1187:
1188: for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
1189: {
1190: /* Under OpenConfirm status, local peer structure already hold
1191: remote router ID. */
1192:
1193: if (peer != new
1194: && (peer->status == OpenConfirm || peer->status == OpenSent)
1195: && sockunion_same (&peer->su, &new->su))
1196: {
1197: /* 1. The BGP Identifier of the local system is compared to
1198: the BGP Identifier of the remote system (as specified in
1199: the OPEN message). */
1200:
1201: if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1202: {
1203: /* 2. If the value of the local BGP Identifier is less
1204: than the remote one, the local system closes BGP
1205: connection that already exists (the one that is
1206: already in the OpenConfirm state), and accepts BGP
1207: connection initiated by the remote system. */
1208:
1209: if (peer->fd >= 0)
1210: bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1211: return 1;
1212: }
1213: else
1214: {
1215: /* 3. Otherwise, the local system closes newly created
1216: BGP connection (the one associated with the newly
1217: received OPEN message), and continues to use the
1218: existing one (the one that is already in the
1219: OpenConfirm state). */
1220:
1221: if (new->fd >= 0)
1222: bgp_notify_send (new, BGP_NOTIFY_CEASE,
1223: BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1224: return -1;
1225: }
1226: }
1227: }
1228: return 0;
1229: }
1230:
1231: static int
1232: bgp_open_receive (struct peer *peer, bgp_size_t size)
1233: {
1234: int ret;
1235: u_char version;
1236: u_char optlen;
1237: u_int16_t holdtime;
1238: u_int16_t send_holdtime;
1239: as_t remote_as;
1240: as_t as4 = 0;
1241: struct peer *realpeer;
1242: struct in_addr remote_id;
1.1.1.3 misho 1243: int mp_capability;
1.1 misho 1244: u_int8_t notify_data_remote_as[2];
1245: u_int8_t notify_data_remote_id[4];
1246:
1247: realpeer = NULL;
1248:
1249: /* Parse open packet. */
1250: version = stream_getc (peer->ibuf);
1251: memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1252: remote_as = stream_getw (peer->ibuf);
1253: holdtime = stream_getw (peer->ibuf);
1254: memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1255: remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1256:
1257: /* Receive OPEN message log */
1258: if (BGP_DEBUG (normal, NORMAL))
1259: zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
1260: " holdtime %d, id %s",
1261: peer->host, version, remote_as, holdtime,
1262: inet_ntoa (remote_id));
1263:
1264: /* BEGIN to read the capability here, but dont do it yet */
1.1.1.3 misho 1265: mp_capability = 0;
1.1 misho 1266: optlen = stream_getc (peer->ibuf);
1267:
1268: if (optlen != 0)
1269: {
1270: /* We need the as4 capability value *right now* because
1271: * if it is there, we have not got the remote_as yet, and without
1272: * that we do not know which peer is connecting to us now.
1273: */
1274: as4 = peek_for_as4_capability (peer, optlen);
1275: }
1276:
1277: /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1278: if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1279: {
1280: zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1281: peer->host);
1282: bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1283: BGP_NOTIFY_OPEN_BAD_PEER_AS);
1284: return -1;
1285: }
1286:
1287: if (remote_as == BGP_AS_TRANS)
1288: {
1289: /* Take the AS4 from the capability. We must have received the
1290: * capability now! Otherwise we have a asn16 peer who uses
1291: * BGP_AS_TRANS, for some unknown reason.
1292: */
1293: if (as4 == BGP_AS_TRANS)
1294: {
1295: zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1296: peer->host);
1297: bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1298: BGP_NOTIFY_OPEN_BAD_PEER_AS);
1299: return -1;
1300: }
1301:
1302: if (!as4 && BGP_DEBUG (as4, AS4))
1303: zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1304: " Odd, but proceeding.", peer->host);
1305: else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
1306: zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
1307: "in 2-bytes, very odd peer.", peer->host, as4);
1308: if (as4)
1309: remote_as = as4;
1310: }
1311: else
1312: {
1313: /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1314: /* If we have got the capability, peer->as4cap must match remote_as */
1315: if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1316: && as4 != remote_as)
1317: {
1318: /* raise error, log this, close session */
1319: zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1320: " mismatch with 16bit 'myasn' %u in open",
1321: peer->host, as4, remote_as);
1322: bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1323: BGP_NOTIFY_OPEN_BAD_PEER_AS);
1324: return -1;
1325: }
1326: }
1327:
1328: /* Lookup peer from Open packet. */
1329: if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1330: {
1331: int as = 0;
1332:
1333: realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1334:
1335: if (! realpeer)
1336: {
1337: /* Peer's source IP address is check in bgp_accept(), so this
1338: must be AS number mismatch or remote-id configuration
1339: mismatch. */
1340: if (as)
1341: {
1342: if (BGP_DEBUG (normal, NORMAL))
1343: zlog_debug ("%s bad OPEN, wrong router identifier %s",
1344: peer->host, inet_ntoa (remote_id));
1345: bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1346: BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1347: notify_data_remote_id, 4);
1348: }
1349: else
1350: {
1351: if (BGP_DEBUG (normal, NORMAL))
1352: zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
1353: peer->host, remote_as, peer->as);
1354: bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1355: BGP_NOTIFY_OPEN_BAD_PEER_AS,
1356: notify_data_remote_as, 2);
1357: }
1358: return -1;
1359: }
1360: }
1361:
1362: /* When collision is detected and this peer is closed. Retrun
1363: immidiately. */
1364: ret = bgp_collision_detect (peer, remote_id);
1365: if (ret < 0)
1366: return ret;
1367:
1368: /* Hack part. */
1369: if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1370: {
1371: if (realpeer->status == Established
1372: && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1373: {
1374: realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1375: SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1376: }
1377: else if (ret == 0 && realpeer->status != Active
1378: && realpeer->status != OpenSent
1379: && realpeer->status != OpenConfirm
1380: && realpeer->status != Connect)
1381: {
1382: /* XXX: This is an awful problem..
1383: *
1384: * According to the RFC we should just let this connection (of the
1385: * accepted 'peer') continue on to Established if the other
1386: * connection (the 'realpeer' one) is in state Connect, and deal
1387: * with the more larval FSM as/when it gets far enough to receive
1388: * an Open. We don't do that though, we instead close the (more
1389: * developed) accepted connection.
1390: *
1391: * This means there's a race, which if hit, can loop:
1392: *
1393: * FSM for A FSM for B
1394: * realpeer accept-peer realpeer accept-peer
1395: *
1396: * Connect Connect
1397: * Active
1398: * OpenSent OpenSent
1399: * <arrive here,
1400: * Notify, delete>
1401: * Idle Active
1402: * OpenSent OpenSent
1403: * <arrive here,
1404: * Notify, delete>
1405: * Idle
1406: * <wait> <wait>
1407: * Connect Connect
1408: *
1409: *
1410: * If both sides are Quagga, they're almost certain to wait for
1411: * the same amount of time of course (which doesn't preclude other
1412: * implementations also waiting for same time). The race is
1413: * exacerbated by high-latency (in bgpd and/or the network).
1414: *
1415: * The reason we do this is because our FSM is tied to our peer
1416: * structure, which carries our configuration information, etc.
1417: * I.e. we can't let the accepted-peer FSM continue on as it is,
1418: * cause it's not associated with any actual peer configuration -
1419: * it's just a dummy.
1420: *
1421: * It's possible we could hack-fix this by just bgp_stop'ing the
1422: * realpeer and continueing on with the 'transfer FSM' below.
1423: * Ideally, we need to seperate FSMs from struct peer.
1424: *
1425: * Setting one side to passive avoids the race, as a workaround.
1426: */
1427: if (BGP_DEBUG (events, EVENTS))
1428: zlog_debug ("%s peer status is %s close connection",
1429: realpeer->host, LOOKUP (bgp_status_msg,
1430: realpeer->status));
1431: bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1432: BGP_NOTIFY_CEASE_CONNECT_REJECT);
1433:
1434: return -1;
1435: }
1436:
1437: if (BGP_DEBUG (events, EVENTS))
1438: zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1439: peer->host,
1440: LOOKUP (bgp_status_msg, realpeer->status));
1441:
1442: bgp_stop (realpeer);
1443:
1444: /* Transfer file descriptor. */
1445: realpeer->fd = peer->fd;
1446: peer->fd = -1;
1447:
1448: /* Transfer input buffer. */
1449: stream_free (realpeer->ibuf);
1450: realpeer->ibuf = peer->ibuf;
1451: realpeer->packet_size = peer->packet_size;
1452: peer->ibuf = NULL;
1453:
1454: /* Transfer status. */
1455: realpeer->status = peer->status;
1456: bgp_stop (peer);
1457:
1458: /* peer pointer change. Open packet send to neighbor. */
1459: peer = realpeer;
1460: bgp_open_send (peer);
1461: if (peer->fd < 0)
1462: {
1463: zlog_err ("bgp_open_receive peer's fd is negative value %d",
1464: peer->fd);
1465: return -1;
1466: }
1467: BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1468: }
1469:
1470: /* remote router-id check. */
1471: if (remote_id.s_addr == 0
1.1.1.3 misho 1472: || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
1.1 misho 1473: || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1474: {
1475: if (BGP_DEBUG (normal, NORMAL))
1476: zlog_debug ("%s bad OPEN, wrong router identifier %s",
1477: peer->host, inet_ntoa (remote_id));
1478: bgp_notify_send_with_data (peer,
1479: BGP_NOTIFY_OPEN_ERR,
1480: BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1481: notify_data_remote_id, 4);
1482: return -1;
1483: }
1484:
1485: /* Set remote router-id */
1486: peer->remote_id = remote_id;
1487:
1488: /* Peer BGP version check. */
1489: if (version != BGP_VERSION_4)
1490: {
1.1.1.4 misho 1491: u_int16_t maxver = htons(BGP_VERSION_4);
1492: /* XXX this reply may not be correct if version < 4 XXX */
1.1 misho 1493: if (BGP_DEBUG (normal, NORMAL))
1494: zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
1495: peer->host, version, BGP_VERSION_4);
1.1.1.4 misho 1496: /* Data must be in network byte order here */
1.1 misho 1497: bgp_notify_send_with_data (peer,
1498: BGP_NOTIFY_OPEN_ERR,
1499: BGP_NOTIFY_OPEN_UNSUP_VERSION,
1.1.1.4 misho 1500: (u_int8_t *) &maxver, 2);
1.1 misho 1501: return -1;
1502: }
1503:
1504: /* Check neighbor as number. */
1505: if (remote_as != peer->as)
1506: {
1507: if (BGP_DEBUG (normal, NORMAL))
1508: zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
1509: peer->host, remote_as, peer->as);
1510: bgp_notify_send_with_data (peer,
1511: BGP_NOTIFY_OPEN_ERR,
1512: BGP_NOTIFY_OPEN_BAD_PEER_AS,
1513: notify_data_remote_as, 2);
1514: return -1;
1515: }
1516:
1517: /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1518: calculate the value of the Hold Timer by using the smaller of its
1519: configured Hold Time and the Hold Time received in the OPEN message.
1520: The Hold Time MUST be either zero or at least three seconds. An
1521: implementation may reject connections on the basis of the Hold Time. */
1522:
1523: if (holdtime < 3 && holdtime != 0)
1524: {
1525: bgp_notify_send (peer,
1526: BGP_NOTIFY_OPEN_ERR,
1527: BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1528: return -1;
1529: }
1530:
1531: /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1532: would be one third of the Hold Time interval. KEEPALIVE messages
1533: MUST NOT be sent more frequently than one per second. An
1534: implementation MAY adjust the rate at which it sends KEEPALIVE
1535: messages as a function of the Hold Time interval. */
1536:
1537: if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1538: send_holdtime = peer->holdtime;
1539: else
1540: send_holdtime = peer->bgp->default_holdtime;
1541:
1542: if (holdtime < send_holdtime)
1543: peer->v_holdtime = holdtime;
1544: else
1545: peer->v_holdtime = send_holdtime;
1546:
1547: peer->v_keepalive = peer->v_holdtime / 3;
1548:
1549: /* Open option part parse. */
1550: if (optlen != 0)
1551: {
1.1.1.3 misho 1552: if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
1.1.1.2 misho 1553: {
1554: bgp_notify_send (peer,
1555: BGP_NOTIFY_OPEN_ERR,
1.1.1.5 ! misho 1556: BGP_NOTIFY_OPEN_UNSPECIFIC);
1.1.1.2 misho 1557: return ret;
1558: }
1.1 misho 1559: }
1560: else
1561: {
1562: if (BGP_DEBUG (normal, NORMAL))
1563: zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
1564: peer->host);
1565: }
1566:
1.1.1.3 misho 1567: /*
1568: * Assume that the peer supports the locally configured set of
1569: * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1570: * capabilities, or if 'override-capability' is configured.
1571: */
1572: if (! mp_capability ||
1573: CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
1.1 misho 1574: {
1575: peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1576: peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1577: peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1578: peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1579: }
1580:
1581: /* Get sockname. */
1582: bgp_getsockname (peer);
1.1.1.5 ! misho 1583: peer->rtt = sockopt_tcp_rtt (peer->fd);
1.1 misho 1584:
1585: BGP_EVENT_ADD (peer, Receive_OPEN_message);
1586:
1587: peer->packet_size = 0;
1588: if (peer->ibuf)
1589: stream_reset (peer->ibuf);
1590:
1591: return 0;
1592: }
1593:
1.1.1.5 ! misho 1594: /* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
! 1595: int
! 1596: bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
! 1597: {
! 1598: switch (packet->safi)
! 1599: {
! 1600: case SAFI_UNICAST:
! 1601: case SAFI_MULTICAST:
! 1602: return bgp_nlri_parse_ip (peer, attr, packet);
! 1603: case SAFI_MPLS_VPN:
! 1604: case SAFI_MPLS_LABELED_VPN:
! 1605: return bgp_nlri_parse_vpn (peer, attr, packet);
! 1606: case SAFI_ENCAP:
! 1607: return bgp_nlri_parse_encap (peer, attr, packet);
! 1608: }
! 1609: return -1;
! 1610: }
! 1611:
1.1 misho 1612: /* Parse BGP Update packet and make attribute object. */
1613: static int
1614: bgp_update_receive (struct peer *peer, bgp_size_t size)
1615: {
1.1.1.5 ! misho 1616: int ret, nlri_ret;
1.1 misho 1617: u_char *end;
1618: struct stream *s;
1619: struct attr attr;
1.1.1.4 misho 1620: struct attr_extra extra;
1.1 misho 1621: bgp_size_t attribute_len;
1622: bgp_size_t update_len;
1623: bgp_size_t withdraw_len;
1.1.1.5 ! misho 1624: int i;
! 1625:
! 1626: enum NLRI_TYPES {
! 1627: NLRI_UPDATE,
! 1628: NLRI_WITHDRAW,
! 1629: NLRI_MP_UPDATE,
! 1630: NLRI_MP_WITHDRAW,
! 1631: NLRI_TYPE_MAX,
! 1632: };
! 1633: struct bgp_nlri nlris[NLRI_TYPE_MAX];
1.1 misho 1634:
1635: /* Status must be Established. */
1636: if (peer->status != Established)
1637: {
1638: zlog_err ("%s [FSM] Update packet received under status %s",
1639: peer->host, LOOKUP (bgp_status_msg, peer->status));
1640: bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1641: return -1;
1642: }
1643:
1644: /* Set initial values. */
1645: memset (&attr, 0, sizeof (struct attr));
1.1.1.4 misho 1646: memset (&extra, 0, sizeof (struct attr_extra));
1.1.1.5 ! misho 1647: memset (&nlris, 0, sizeof nlris);
1.1.1.4 misho 1648: attr.extra = &extra;
1.1 misho 1649:
1650: s = peer->ibuf;
1651: end = stream_pnt (s) + size;
1652:
1653: /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1654: Length is too large (i.e., if Unfeasible Routes Length + Total
1655: Attribute Length + 23 exceeds the message Length), then the Error
1656: Subcode is set to Malformed Attribute List. */
1657: if (stream_pnt (s) + 2 > end)
1658: {
1659: zlog_err ("%s [Error] Update packet error"
1660: " (packet length is short for unfeasible length)",
1661: peer->host);
1662: bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1663: BGP_NOTIFY_UPDATE_MAL_ATTR);
1664: return -1;
1665: }
1666:
1667: /* Unfeasible Route Length. */
1668: withdraw_len = stream_getw (s);
1669:
1670: /* Unfeasible Route Length check. */
1671: if (stream_pnt (s) + withdraw_len > end)
1672: {
1673: zlog_err ("%s [Error] Update packet error"
1674: " (packet unfeasible length overflow %d)",
1675: peer->host, withdraw_len);
1676: bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1677: BGP_NOTIFY_UPDATE_MAL_ATTR);
1678: return -1;
1679: }
1680:
1681: /* Unfeasible Route packet format check. */
1682: if (withdraw_len > 0)
1683: {
1.1.1.5 ! misho 1684: nlris[NLRI_WITHDRAW].afi = AFI_IP;
! 1685: nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
! 1686: nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
! 1687: nlris[NLRI_WITHDRAW].length = withdraw_len;
! 1688:
1.1 misho 1689: if (BGP_DEBUG (packet, PACKET_RECV))
1690: zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
1691:
1692: stream_forward_getp (s, withdraw_len);
1693: }
1694:
1695: /* Attribute total length check. */
1696: if (stream_pnt (s) + 2 > end)
1697: {
1698: zlog_warn ("%s [Error] Packet Error"
1699: " (update packet is short for attribute length)",
1700: peer->host);
1701: bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1702: BGP_NOTIFY_UPDATE_MAL_ATTR);
1703: return -1;
1704: }
1705:
1706: /* Fetch attribute total length. */
1707: attribute_len = stream_getw (s);
1708:
1709: /* Attribute length check. */
1710: if (stream_pnt (s) + attribute_len > end)
1711: {
1712: zlog_warn ("%s [Error] Packet Error"
1713: " (update packet attribute length overflow %d)",
1714: peer->host, attribute_len);
1715: bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1716: BGP_NOTIFY_UPDATE_MAL_ATTR);
1717: return -1;
1718: }
1719:
1720: /* Certain attribute parsing errors should not be considered bad enough
1721: * to reset the session for, most particularly any partial/optional
1722: * attributes that have 'tunneled' over speakers that don't understand
1723: * them. Instead we withdraw only the prefix concerned.
1724: *
1725: * Complicates the flow a little though..
1726: */
1727: bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1728: /* This define morphs the update case into a withdraw when lower levels
1729: * have signalled an error condition where this is best.
1730: */
1731: #define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
1732:
1733: /* Parse attribute when it exists. */
1734: if (attribute_len)
1735: {
1736: attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
1.1.1.5 ! misho 1737: &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
1.1 misho 1738: if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
1.1.1.5 ! misho 1739: {
! 1740: bgp_attr_unintern_sub (&attr);
! 1741: bgp_attr_flush (&attr);
! 1742: return -1;
! 1743: }
1.1 misho 1744: }
1745:
1746: /* Logging the attribute. */
1747: if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1748: || BGP_DEBUG (update, UPDATE_IN))
1749: {
1.1.1.4 misho 1750: char attrstr[BUFSIZ];
1751: attrstr[0] = '\0';
1752:
1.1 misho 1753: ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
1754: int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1755: ? LOG_ERR : LOG_DEBUG;
1756:
1757: if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1758: zlog (peer->log, LOG_ERR,
1759: "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1760: peer->host);
1761:
1762: if (ret)
1763: zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
1764: peer->host, attrstr);
1765: }
1766:
1767: /* Network Layer Reachability Information. */
1768: update_len = end - stream_pnt (s);
1769:
1770: if (update_len)
1771: {
1772: /* Set NLRI portion to structure. */
1.1.1.5 ! misho 1773: nlris[NLRI_UPDATE].afi = AFI_IP;
! 1774: nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
! 1775: nlris[NLRI_UPDATE].nlri = stream_pnt (s);
! 1776: nlris[NLRI_UPDATE].length = update_len;
! 1777:
1.1 misho 1778: stream_forward_getp (s, update_len);
1779: }
1.1.1.5 ! misho 1780:
! 1781: /* Parse any given NLRIs */
! 1782: for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
1.1 misho 1783: {
1.1.1.5 ! misho 1784: /* We use afi and safi as indices into tables and what not. It would
! 1785: * be impossible, at this time, to support unknown afi/safis. And
! 1786: * anyway, the peer needs to be configured to enable the afi/safi
! 1787: * explicitly which requires UI support.
! 1788: *
! 1789: * Ignore unknown afi/safi NLRIs.
! 1790: *
! 1791: * Note: this means nlri[x].afi/safi still can not be trusted for
! 1792: * indexing later in this function!
! 1793: *
! 1794: * Note2: This will also remap the wire code-point for VPN safi to the
! 1795: * internal safi_t point, as needs be.
! 1796: */
! 1797: if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
! 1798: {
! 1799: plog_info (peer->log,
! 1800: "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
! 1801: peer->host, nlris[i].afi, nlris[i].safi);
! 1802: continue;
! 1803: }
! 1804:
! 1805: /* NLRI is processed only when the peer is configured specific
! 1806: Address Family and Subsequent Address Family. */
! 1807: if (!peer->afc[nlris[i].afi][nlris[i].safi])
! 1808: {
! 1809: plog_info (peer->log,
! 1810: "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
! 1811: peer->host, nlris[i].afi, nlris[i].safi);
! 1812: continue;
! 1813: }
! 1814:
! 1815: /* EoR handled later */
! 1816: if (nlris[i].length == 0)
! 1817: continue;
! 1818:
! 1819: switch (i)
! 1820: {
! 1821: case NLRI_UPDATE:
! 1822: case NLRI_MP_UPDATE:
! 1823: nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
! 1824: break;
! 1825: case NLRI_WITHDRAW:
! 1826: case NLRI_MP_WITHDRAW:
! 1827: nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
! 1828: }
! 1829:
! 1830: if (nlri_ret < 0)
! 1831: {
! 1832: plog_err (peer->log,
! 1833: "%s [Error] Error parsing NLRI", peer->host);
! 1834: if (peer->status == Established)
! 1835: bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
! 1836: i <= NLRI_WITHDRAW
! 1837: ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
! 1838: : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
! 1839: bgp_attr_unintern_sub (&attr);
! 1840: return -1;
! 1841: }
1.1 misho 1842: }
1.1.1.5 ! misho 1843:
! 1844: /* EoR checks.
! 1845: *
! 1846: * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
! 1847: * and MP EoR should have only an empty MP_UNREACH
! 1848: */
! 1849: if (!update_len && !withdraw_len
! 1850: && nlris[NLRI_MP_UPDATE].length == 0)
1.1 misho 1851: {
1.1.1.5 ! misho 1852: afi_t afi = 0;
! 1853: safi_t safi;
! 1854:
! 1855: /* Non-MP IPv4/Unicast is a completely empty UPDATE - already
! 1856: * checked update and withdraw NLRI lengths are 0.
! 1857: */
! 1858: if (!attribute_len)
! 1859: {
! 1860: afi = AFI_IP;
! 1861: safi = SAFI_UNICAST;
! 1862: }
! 1863: /* otherwise MP AFI/SAFI is an empty update, other than an empty
! 1864: * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise).
! 1865: */
! 1866: else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
! 1867: && nlris[NLRI_MP_WITHDRAW].length == 0
! 1868: && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
! 1869: &nlris[NLRI_MP_WITHDRAW].safi))
! 1870: {
! 1871: afi = nlris[NLRI_MP_WITHDRAW].afi;
! 1872: safi = nlris[NLRI_MP_WITHDRAW].safi;
! 1873: }
! 1874:
! 1875: if (afi && peer->afc[afi][safi])
! 1876: {
1.1 misho 1877: /* End-of-RIB received */
1.1.1.5 ! misho 1878: SET_FLAG (peer->af_sflags[afi][safi],
1.1 misho 1879: PEER_STATUS_EOR_RECEIVED);
1880:
1881: /* NSF delete stale route */
1.1.1.5 ! misho 1882: if (peer->nsf[afi][safi])
! 1883: bgp_clear_stale_route (peer, afi, safi);
1.1 misho 1884:
1885: if (BGP_DEBUG (normal, NORMAL))
1.1.1.5 ! misho 1886: zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s",
! 1887: peer->host, afi_safi_print (afi, safi));
! 1888: }
1.1 misho 1889: }
1.1.1.5 ! misho 1890:
1.1 misho 1891: /* Everything is done. We unintern temporary structures which
1892: interned in bgp_attr_parse(). */
1893: bgp_attr_unintern_sub (&attr);
1.1.1.5 ! misho 1894: bgp_attr_flush (&attr);
1.1.1.4 misho 1895:
1.1 misho 1896: /* If peering is stopped due to some reason, do not generate BGP
1897: event. */
1898: if (peer->status != Established)
1899: return 0;
1900:
1901: /* Increment packet counter. */
1902: peer->update_in++;
1903: peer->update_time = bgp_clock ();
1904:
1.1.1.4 misho 1905: /* Rearm holdtime timer */
1906: BGP_TIMER_OFF (peer->t_holdtime);
1907: bgp_timer_set (peer);
1.1 misho 1908:
1909: return 0;
1910: }
1911:
1912: /* Notify message treatment function. */
1913: static void
1914: bgp_notify_receive (struct peer *peer, bgp_size_t size)
1915: {
1916: struct bgp_notify bgp_notify;
1917:
1918: if (peer->notify.data)
1919: {
1920: XFREE (MTYPE_TMP, peer->notify.data);
1921: peer->notify.data = NULL;
1922: peer->notify.length = 0;
1923: }
1924:
1925: bgp_notify.code = stream_getc (peer->ibuf);
1926: bgp_notify.subcode = stream_getc (peer->ibuf);
1927: bgp_notify.length = size - 2;
1928: bgp_notify.data = NULL;
1929:
1930: /* Preserv notify code and sub code. */
1931: peer->notify.code = bgp_notify.code;
1932: peer->notify.subcode = bgp_notify.subcode;
1933: /* For further diagnostic record returned Data. */
1934: if (bgp_notify.length)
1935: {
1936: peer->notify.length = size - 2;
1937: peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1938: memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1939: }
1940:
1941: /* For debug */
1942: {
1943: int i;
1944: int first = 0;
1945: char c[4];
1946:
1947: if (bgp_notify.length)
1948: {
1949: bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1950: for (i = 0; i < bgp_notify.length; i++)
1951: if (first)
1952: {
1953: sprintf (c, " %02x", stream_getc (peer->ibuf));
1954: strcat (bgp_notify.data, c);
1955: }
1956: else
1957: {
1958: first = 1;
1959: sprintf (c, "%02x", stream_getc (peer->ibuf));
1960: strcpy (bgp_notify.data, c);
1961: }
1962: }
1963:
1964: bgp_notify_print(peer, &bgp_notify, "received");
1965: if (bgp_notify.data)
1.1.1.5 ! misho 1966: {
! 1967: XFREE (MTYPE_TMP, bgp_notify.data);
! 1968: bgp_notify.data = NULL;
! 1969: bgp_notify.length = 0;
! 1970: }
1.1 misho 1971: }
1972:
1973: /* peer count update */
1974: peer->notify_in++;
1975:
1976: if (peer->status == Established)
1977: peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1978:
1979: /* We have to check for Notify with Unsupported Optional Parameter.
1980: in that case we fallback to open without the capability option.
1981: But this done in bgp_stop. We just mark it here to avoid changing
1982: the fsm tables. */
1983: if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1984: bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1985: UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1986:
1987: BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1988: }
1989:
1990: /* Keepalive treatment function -- get keepalive send keepalive */
1991: static void
1992: bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1993: {
1994: if (BGP_DEBUG (keepalive, KEEPALIVE))
1995: zlog_debug ("%s KEEPALIVE rcvd", peer->host);
1996:
1997: BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1998: }
1999:
2000: /* Route refresh message is received. */
2001: static void
2002: bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2003: {
2004: afi_t afi;
2005: safi_t safi;
2006: struct stream *s;
2007:
2008: /* If peer does not have the capability, send notification. */
2009: if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2010: {
2011: plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2012: peer->host);
2013: bgp_notify_send (peer,
2014: BGP_NOTIFY_HEADER_ERR,
2015: BGP_NOTIFY_HEADER_BAD_MESTYPE);
2016: return;
2017: }
2018:
2019: /* Status must be Established. */
2020: if (peer->status != Established)
2021: {
2022: plog_err (peer->log,
2023: "%s [Error] Route refresh packet received under status %s",
2024: peer->host, LOOKUP (bgp_status_msg, peer->status));
2025: bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2026: return;
2027: }
2028:
2029: s = peer->ibuf;
2030:
2031: /* Parse packet. */
2032: afi = stream_getw (s);
1.1.1.5 ! misho 2033: /* reserved byte */
! 2034: stream_getc (s);
1.1 misho 2035: safi = stream_getc (s);
2036:
2037: if (BGP_DEBUG (normal, NORMAL))
2038: zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
2039: peer->host, afi, safi);
2040:
2041: /* Check AFI and SAFI. */
2042: if ((afi != AFI_IP && afi != AFI_IP6)
2043: || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
1.1.1.3 misho 2044: && safi != SAFI_MPLS_LABELED_VPN))
1.1 misho 2045: {
2046: if (BGP_DEBUG (normal, NORMAL))
2047: {
2048: zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
2049: peer->host, afi, safi);
2050: }
2051: return;
2052: }
2053:
2054: /* Adjust safi code. */
1.1.1.3 misho 2055: if (safi == SAFI_MPLS_LABELED_VPN)
1.1 misho 2056: safi = SAFI_MPLS_VPN;
2057:
2058: if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2059: {
2060: u_char *end;
2061: u_char when_to_refresh;
2062: u_char orf_type;
2063: u_int16_t orf_len;
2064:
2065: if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2066: {
2067: zlog_info ("%s ORF route refresh length error", peer->host);
2068: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2069: return;
2070: }
2071:
2072: when_to_refresh = stream_getc (s);
2073: end = stream_pnt (s) + (size - 5);
2074:
2075: while ((stream_pnt (s) + 2) < end)
2076: {
2077: orf_type = stream_getc (s);
2078: orf_len = stream_getw (s);
2079:
2080: /* orf_len in bounds? */
2081: if ((stream_pnt (s) + orf_len) > end)
2082: break; /* XXX: Notify instead?? */
2083: if (orf_type == ORF_TYPE_PREFIX
2084: || orf_type == ORF_TYPE_PREFIX_OLD)
2085: {
1.1.1.5 ! misho 2086: uint8_t *p_pnt = stream_pnt (s);
! 2087: uint8_t *p_end = stream_pnt (s) + orf_len;
1.1 misho 2088: struct orf_prefix orfp;
2089: u_char common = 0;
2090: u_int32_t seq;
2091: int psize;
2092: char name[BUFSIZ];
2093: int ret;
2094:
2095: if (BGP_DEBUG (normal, NORMAL))
2096: {
2097: zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
2098: peer->host, orf_type, orf_len);
2099: }
2100:
2101: /* we're going to read at least 1 byte of common ORF header,
2102: * and 7 bytes of ORF Address-filter entry from the stream
2103: */
2104: if (orf_len < 7)
2105: break;
2106:
2107: /* ORF prefix-list name */
2108: sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2109:
2110: while (p_pnt < p_end)
2111: {
2112: /* If the ORF entry is malformed, want to read as much of it
2113: * as possible without going beyond the bounds of the entry,
2114: * to maximise debug information.
2115: */
2116: int ok;
2117: memset (&orfp, 0, sizeof (struct orf_prefix));
2118: common = *p_pnt++;
2119: /* after ++: p_pnt <= p_end */
2120: if (common & ORF_COMMON_PART_REMOVE_ALL)
2121: {
2122: if (BGP_DEBUG (normal, NORMAL))
2123: zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
1.1.1.5 ! misho 2124: prefix_bgp_orf_remove_all (afi, name);
1.1 misho 2125: break;
2126: }
1.1.1.5 ! misho 2127: ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
1.1.1.3 misho 2128: if (ok)
1.1 misho 2129: {
2130: memcpy (&seq, p_pnt, sizeof (u_int32_t));
2131: p_pnt += sizeof (u_int32_t);
2132: orfp.seq = ntohl (seq);
2133: }
2134: else
2135: p_pnt = p_end ;
2136:
2137: if ((ok = (p_pnt < p_end)))
2138: orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2139: if ((ok = (p_pnt < p_end)))
2140: orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2141: if ((ok = (p_pnt < p_end)))
2142: orfp.p.prefixlen = *p_pnt++ ;
2143: orfp.p.family = afi2family (afi); /* afi checked already */
2144:
2145: psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2146: if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2147: {
2148: ok = 0 ;
2149: psize = prefix_blen(&orfp.p) ;
2150: }
2151: if (psize > (p_end - p_pnt)) /* valid for packet ? */
2152: {
2153: ok = 0 ;
2154: psize = p_end - p_pnt ;
2155: }
2156:
2157: if (psize > 0)
2158: memcpy (&orfp.p.u.prefix, p_pnt, psize);
2159: p_pnt += psize;
2160:
2161: if (BGP_DEBUG (normal, NORMAL))
1.1.1.4 misho 2162: {
2163: char buf[INET6_BUFSIZ];
2164:
2165: zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2166: peer->host,
2167: (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2168: (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2169: orfp.seq,
2170: inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2171: orfp.p.prefixlen, orfp.ge, orfp.le,
2172: ok ? "" : " MALFORMED");
2173: }
2174:
1.1 misho 2175: if (ok)
2176: ret = prefix_bgp_orf_set (name, afi, &orfp,
2177: (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2178: (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
1.1.1.5 ! misho 2179:
! 2180: if (!ok || (ok && ret != CMD_SUCCESS))
1.1 misho 2181: {
2182: if (BGP_DEBUG (normal, NORMAL))
2183: zlog_debug ("%s Received misformatted prefixlist ORF."
2184: " Remove All pfxlist", peer->host);
1.1.1.5 ! misho 2185: prefix_bgp_orf_remove_all (afi, name);
1.1 misho 2186: break;
2187: }
2188: }
2189: peer->orf_plist[afi][safi] =
1.1.1.5 ! misho 2190: prefix_bgp_orf_lookup (afi, name);
1.1 misho 2191: }
2192: stream_forward_getp (s, orf_len);
2193: }
2194: if (BGP_DEBUG (normal, NORMAL))
2195: zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
2196: when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2197: if (when_to_refresh == REFRESH_DEFER)
2198: return;
2199: }
2200:
2201: /* First update is deferred until ORF or ROUTE-REFRESH is received */
2202: if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2203: UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2204:
2205: /* Perform route refreshment to the peer */
2206: bgp_announce_route (peer, afi, safi);
2207: }
2208:
2209: static int
2210: bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2211: {
2212: u_char *end;
2213: struct capability_mp_data mpc;
2214: struct capability_header *hdr;
2215: u_char action;
2216: afi_t afi;
2217: safi_t safi;
2218:
2219: end = pnt + length;
2220:
2221: while (pnt < end)
2222: {
2223: /* We need at least action, capability code and capability length. */
2224: if (pnt + 3 > end)
2225: {
2226: zlog_info ("%s Capability length error", peer->host);
2227: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2228: return -1;
2229: }
2230: action = *pnt;
2231: hdr = (struct capability_header *)(pnt + 1);
2232:
2233: /* Action value check. */
2234: if (action != CAPABILITY_ACTION_SET
2235: && action != CAPABILITY_ACTION_UNSET)
2236: {
2237: zlog_info ("%s Capability Action Value error %d",
2238: peer->host, action);
2239: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2240: return -1;
2241: }
2242:
2243: if (BGP_DEBUG (normal, NORMAL))
2244: zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
2245: peer->host, action, hdr->code, hdr->length);
2246:
2247: /* Capability length check. */
2248: if ((pnt + hdr->length + 3) > end)
2249: {
2250: zlog_info ("%s Capability length error", peer->host);
2251: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2252: return -1;
2253: }
2254:
2255: /* Fetch structure to the byte stream. */
2256: memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2257:
2258: /* We know MP Capability Code. */
2259: if (hdr->code == CAPABILITY_CODE_MP)
2260: {
2261: afi = ntohs (mpc.afi);
2262: safi = mpc.safi;
2263:
2264: /* Ignore capability when override-capability is set. */
2265: if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2266: continue;
2267:
2268: if (!bgp_afi_safi_valid_indices (afi, &safi))
2269: {
2270: if (BGP_DEBUG (normal, NORMAL))
2271: zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2272: "(%u/%u)", peer->host, afi, safi);
2273: continue;
2274: }
2275:
2276: /* Address family check. */
2277: if (BGP_DEBUG (normal, NORMAL))
2278: zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2279: peer->host,
2280: action == CAPABILITY_ACTION_SET
2281: ? "Advertising" : "Removing",
2282: ntohs(mpc.afi) , mpc.safi);
2283:
2284: if (action == CAPABILITY_ACTION_SET)
2285: {
2286: peer->afc_recv[afi][safi] = 1;
2287: if (peer->afc[afi][safi])
2288: {
2289: peer->afc_nego[afi][safi] = 1;
2290: bgp_announce_route (peer, afi, safi);
2291: }
2292: }
2293: else
2294: {
2295: peer->afc_recv[afi][safi] = 0;
2296: peer->afc_nego[afi][safi] = 0;
2297:
2298: if (peer_active_nego (peer))
2299: bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
2300: else
2301: BGP_EVENT_ADD (peer, BGP_Stop);
2302: }
2303: }
2304: else
2305: {
2306: zlog_warn ("%s unrecognized capability code: %d - ignored",
2307: peer->host, hdr->code);
2308: }
2309: pnt += hdr->length + 3;
2310: }
2311: return 0;
2312: }
2313:
2314: /* Dynamic Capability is received.
2315: *
2316: * This is exported for unit-test purposes
2317: */
2318: int
2319: bgp_capability_receive (struct peer *peer, bgp_size_t size)
2320: {
2321: u_char *pnt;
2322:
2323: /* Fetch pointer. */
2324: pnt = stream_pnt (peer->ibuf);
2325:
2326: if (BGP_DEBUG (normal, NORMAL))
2327: zlog_debug ("%s rcv CAPABILITY", peer->host);
2328:
2329: /* If peer does not have the capability, send notification. */
2330: if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2331: {
2332: plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2333: peer->host);
2334: bgp_notify_send (peer,
2335: BGP_NOTIFY_HEADER_ERR,
2336: BGP_NOTIFY_HEADER_BAD_MESTYPE);
2337: return -1;
2338: }
2339:
2340: /* Status must be Established. */
2341: if (peer->status != Established)
2342: {
2343: plog_err (peer->log,
2344: "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2345: bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2346: return -1;
2347: }
2348:
2349: /* Parse packet. */
2350: return bgp_capability_msg_parse (peer, pnt, size);
2351: }
1.1.1.5 ! misho 2352:
1.1 misho 2353: /* BGP read utility function. */
2354: static int
2355: bgp_read_packet (struct peer *peer)
2356: {
2357: int nbytes;
2358: int readsize;
2359:
2360: readsize = peer->packet_size - stream_get_endp (peer->ibuf);
2361:
2362: /* If size is zero then return. */
2363: if (! readsize)
2364: return 0;
2365:
2366: /* Read packet from fd. */
2367: nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
2368:
2369: /* If read byte is smaller than zero then error occured. */
2370: if (nbytes < 0)
2371: {
2372: /* Transient error should retry */
2373: if (nbytes == -2)
2374: return -1;
2375:
2376: plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
2377: peer->host, safe_strerror (errno));
2378:
2379: if (peer->status == Established)
2380: {
2381: if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2382: {
2383: peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2384: SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2385: }
2386: else
2387: peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2388: }
2389:
2390: BGP_EVENT_ADD (peer, TCP_fatal_error);
2391: return -1;
2392: }
2393:
2394: /* When read byte is zero : clear bgp peer and return */
2395: if (nbytes == 0)
2396: {
2397: if (BGP_DEBUG (events, EVENTS))
2398: plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
2399: peer->host, peer->fd);
2400:
2401: if (peer->status == Established)
2402: {
2403: if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2404: {
2405: peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2406: SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2407: }
2408: else
2409: peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2410: }
2411:
2412: BGP_EVENT_ADD (peer, TCP_connection_closed);
2413: return -1;
2414: }
2415:
2416: /* We read partial packet. */
2417: if (stream_get_endp (peer->ibuf) != peer->packet_size)
2418: return -1;
2419:
2420: return 0;
2421: }
2422:
2423: /* Marker check. */
2424: static int
2425: bgp_marker_all_one (struct stream *s, int length)
2426: {
2427: int i;
2428:
2429: for (i = 0; i < length; i++)
2430: if (s->data[i] != 0xff)
2431: return 0;
2432:
2433: return 1;
2434: }
2435:
1.1.1.4 misho 2436: /* Recent thread time.
2437: On same clock base as bgp_clock (MONOTONIC)
2438: but can be time of last context switch to bgp_read thread. */
2439: static time_t
2440: bgp_recent_clock (void)
2441: {
2442: return recent_relative_time().tv_sec;
2443: }
2444:
1.1 misho 2445: /* Starting point of packet process function. */
2446: int
2447: bgp_read (struct thread *thread)
2448: {
2449: int ret;
2450: u_char type = 0;
2451: struct peer *peer;
2452: bgp_size_t size;
2453: char notify_data_length[2];
2454:
2455: /* Yes first of all get peer pointer. */
2456: peer = THREAD_ARG (thread);
2457: peer->t_read = NULL;
2458:
2459: /* For non-blocking IO check. */
2460: if (peer->status == Connect)
2461: {
2462: bgp_connect_check (peer);
2463: goto done;
2464: }
2465: else
2466: {
2467: if (peer->fd < 0)
2468: {
2469: zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
2470: return -1;
2471: }
2472: BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
2473: }
2474:
2475: /* Read packet header to determine type of the packet */
2476: if (peer->packet_size == 0)
2477: peer->packet_size = BGP_HEADER_SIZE;
2478:
2479: if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
2480: {
2481: ret = bgp_read_packet (peer);
2482:
2483: /* Header read error or partial read packet. */
2484: if (ret < 0)
2485: goto done;
2486:
2487: /* Get size and type. */
2488: stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
2489: memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2490: size = stream_getw (peer->ibuf);
2491: type = stream_getc (peer->ibuf);
2492:
2493: if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
2494: zlog_debug ("%s rcv message type %d, length (excl. header) %d",
2495: peer->host, type, size - BGP_HEADER_SIZE);
2496:
2497: /* Marker check */
2498: if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
2499: && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2500: {
2501: bgp_notify_send (peer,
2502: BGP_NOTIFY_HEADER_ERR,
2503: BGP_NOTIFY_HEADER_NOT_SYNC);
2504: goto done;
2505: }
2506:
2507: /* BGP type check. */
2508: if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2509: && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2510: && type != BGP_MSG_ROUTE_REFRESH_NEW
2511: && type != BGP_MSG_ROUTE_REFRESH_OLD
2512: && type != BGP_MSG_CAPABILITY)
2513: {
2514: if (BGP_DEBUG (normal, NORMAL))
2515: plog_debug (peer->log,
2516: "%s unknown message type 0x%02x",
2517: peer->host, type);
2518: bgp_notify_send_with_data (peer,
2519: BGP_NOTIFY_HEADER_ERR,
2520: BGP_NOTIFY_HEADER_BAD_MESTYPE,
2521: &type, 1);
2522: goto done;
2523: }
2524: /* Mimimum packet length check. */
2525: if ((size < BGP_HEADER_SIZE)
2526: || (size > BGP_MAX_PACKET_SIZE)
2527: || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2528: || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2529: || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2530: || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2531: || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2532: || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2533: || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2534: {
2535: if (BGP_DEBUG (normal, NORMAL))
2536: plog_debug (peer->log,
2537: "%s bad message length - %d for %s",
2538: peer->host, size,
2539: type == 128 ? "ROUTE-REFRESH" :
2540: bgp_type_str[(int) type]);
2541: bgp_notify_send_with_data (peer,
2542: BGP_NOTIFY_HEADER_ERR,
2543: BGP_NOTIFY_HEADER_BAD_MESLEN,
2544: (u_char *) notify_data_length, 2);
2545: goto done;
2546: }
2547:
2548: /* Adjust size to message length. */
2549: peer->packet_size = size;
2550: }
2551:
2552: ret = bgp_read_packet (peer);
2553: if (ret < 0)
2554: goto done;
2555:
2556: /* Get size and type again. */
2557: size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2558: type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2559:
2560: /* BGP packet dump function. */
2561: bgp_dump_packet (peer, type, peer->ibuf);
2562:
2563: size = (peer->packet_size - BGP_HEADER_SIZE);
2564:
2565: /* Read rest of the packet and call each sort of packet routine */
2566: switch (type)
2567: {
2568: case BGP_MSG_OPEN:
2569: peer->open_in++;
2570: bgp_open_receive (peer, size); /* XXX return value ignored! */
2571: break;
2572: case BGP_MSG_UPDATE:
1.1.1.4 misho 2573: peer->readtime = bgp_recent_clock ();
1.1 misho 2574: bgp_update_receive (peer, size);
2575: break;
2576: case BGP_MSG_NOTIFY:
2577: bgp_notify_receive (peer, size);
2578: break;
2579: case BGP_MSG_KEEPALIVE:
1.1.1.4 misho 2580: peer->readtime = bgp_recent_clock ();
1.1 misho 2581: bgp_keepalive_receive (peer, size);
2582: break;
2583: case BGP_MSG_ROUTE_REFRESH_NEW:
2584: case BGP_MSG_ROUTE_REFRESH_OLD:
2585: peer->refresh_in++;
2586: bgp_route_refresh_receive (peer, size);
2587: break;
2588: case BGP_MSG_CAPABILITY:
2589: peer->dynamic_cap_in++;
2590: bgp_capability_receive (peer, size);
2591: break;
2592: }
2593:
2594: /* Clear input buffer. */
2595: peer->packet_size = 0;
2596: if (peer->ibuf)
2597: stream_reset (peer->ibuf);
2598:
2599: done:
2600: if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2601: {
2602: if (BGP_DEBUG (events, EVENTS))
2603: zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
2604: peer_delete (peer);
2605: }
2606: return 0;
2607: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>