Annotation of embedaddon/quagga/bgpd/bgp_open.c, revision 1.1.1.2
1.1 misho 1: /* BGP open message handling
2: Copyright (C) 1998, 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 "linklist.h"
24: #include "prefix.h"
25: #include "stream.h"
26: #include "thread.h"
27: #include "log.h"
28: #include "command.h"
29: #include "memory.h"
30:
31: #include "bgpd/bgpd.h"
32: #include "bgpd/bgp_attr.h"
33: #include "bgpd/bgp_debug.h"
34: #include "bgpd/bgp_fsm.h"
35: #include "bgpd/bgp_packet.h"
36: #include "bgpd/bgp_open.h"
37: #include "bgpd/bgp_aspath.h"
38: #include "bgpd/bgp_vty.h"
39:
40: /* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
41: negotiate remote peer supports extentions or not. But if
42: remote-peer doesn't supports negotiation process itself. We would
43: like to do manual configuration.
44:
45: So there is many configurable point. First of all we want set each
46: peer whether we send capability negotiation to the peer or not.
47: Next, if we send capability to the peer we want to set my capabilty
48: inforation at each peer. */
49:
50: void
51: bgp_capability_vty_out (struct vty *vty, struct peer *peer)
52: {
53: char *pnt;
54: char *end;
55: struct capability_mp_data mpc;
56: struct capability_header *hdr;
57:
58: pnt = peer->notify.data;
59: end = pnt + peer->notify.length;
60:
61: while (pnt < end)
62: {
63: if (pnt + sizeof (struct capability_mp_data) + 2 > end)
64: return;
65:
66: hdr = (struct capability_header *)pnt;
67: if (pnt + hdr->length + 2 > end)
68: return;
69:
70: memcpy (&mpc, pnt + 2, sizeof(struct capability_mp_data));
71:
72: if (hdr->code == CAPABILITY_CODE_MP)
73: {
74: vty_out (vty, " Capability error for: Multi protocol ");
75:
76: switch (ntohs (mpc.afi))
77: {
78: case AFI_IP:
79: vty_out (vty, "AFI IPv4, ");
80: break;
81: case AFI_IP6:
82: vty_out (vty, "AFI IPv6, ");
83: break;
84: default:
85: vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
86: break;
87: }
88: switch (mpc.safi)
89: {
90: case SAFI_UNICAST:
91: vty_out (vty, "SAFI Unicast");
92: break;
93: case SAFI_MULTICAST:
94: vty_out (vty, "SAFI Multicast");
95: break;
96: case SAFI_UNICAST_MULTICAST:
97: vty_out (vty, "SAFI Unicast Multicast");
98: break;
99: case BGP_SAFI_VPNV4:
100: vty_out (vty, "SAFI MPLS-VPN");
101: break;
102: default:
103: vty_out (vty, "SAFI Unknown %d ", mpc.safi);
104: break;
105: }
106: vty_out (vty, "%s", VTY_NEWLINE);
107: }
108: else if (hdr->code >= 128)
109: vty_out (vty, " Capability error: vendor specific capability code %d",
110: hdr->code);
111: else
112: vty_out (vty, " Capability error: unknown capability code %d",
113: hdr->code);
114:
115: pnt += hdr->length + 2;
116: }
117: }
118:
119: static void
120: bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
121: {
122: mpc->afi = stream_getw (s);
123: mpc->reserved = stream_getc (s);
124: mpc->safi = stream_getc (s);
125: }
126:
127: int
128: bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
129: {
130: /* VPNvX are AFI specific */
131: if ((afi == AFI_IP6 && *safi == BGP_SAFI_VPNV4)
132: || (afi == AFI_IP && *safi == BGP_SAFI_VPNV6))
133: {
134: zlog_warn ("Invalid afi/safi combination (%u/%u)", afi, *safi);
135: return 0;
136: }
137:
138: switch (afi)
139: {
140: case AFI_IP:
141: #ifdef HAVE_IPV6
142: case AFI_IP6:
143: #endif
144: switch (*safi)
145: {
146: /* BGP VPNvX SAFI isn't contigious with others, remap */
147: case BGP_SAFI_VPNV4:
148: case BGP_SAFI_VPNV6:
149: *safi = SAFI_MPLS_VPN;
150: case SAFI_UNICAST:
151: case SAFI_MULTICAST:
152: case SAFI_MPLS_VPN:
153: return 1;
154: }
155: }
156: zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
157:
158: return 0;
159: }
160:
161: /* Set negotiated capability value. */
162: static int
163: bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
164: {
165: struct capability_mp_data mpc;
166: struct stream *s = BGP_INPUT (peer);
167:
168: bgp_capability_mp_data (s, &mpc);
169:
170: if (BGP_DEBUG (normal, NORMAL))
171: zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
172: peer->host, mpc.afi, mpc.safi);
173:
174: if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
175: return -1;
176:
177: /* Now safi remapped, and afi/safi are valid array indices */
178: peer->afc_recv[mpc.afi][mpc.safi] = 1;
179:
180: if (peer->afc[mpc.afi][mpc.safi])
181: peer->afc_nego[mpc.afi][mpc.safi] = 1;
182: else
183: return -1;
184:
185: return 0;
186: }
187:
188: static void
189: bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
190: u_char type, u_char mode)
191: {
192: if (BGP_DEBUG (normal, NORMAL))
193: zlog_debug ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
194: peer->host, afi, safi, type, mode);
195: }
196:
197: static const struct message orf_type_str[] =
198: {
199: { ORF_TYPE_PREFIX, "Prefixlist" },
200: { ORF_TYPE_PREFIX_OLD, "Prefixlist (old)" },
201: };
202: static const int orf_type_str_max
203: = sizeof(orf_type_str)/sizeof(orf_type_str[0]);
204:
205: static const struct message orf_mode_str[] =
206: {
207: { ORF_MODE_RECEIVE, "Receive" },
208: { ORF_MODE_SEND, "Send" },
209: { ORF_MODE_BOTH, "Both" },
210: };
211: static const int orf_mode_str_max
212: = sizeof(orf_mode_str)/sizeof(orf_mode_str[0]);
213:
214: static int
215: bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
216: {
217: struct stream *s = BGP_INPUT (peer);
218: struct capability_orf_entry entry;
219: afi_t afi;
220: safi_t safi;
221: u_char type;
222: u_char mode;
223: u_int16_t sm_cap = 0; /* capability send-mode receive */
224: u_int16_t rm_cap = 0; /* capability receive-mode receive */
225: int i;
226:
227: /* ORF Entry header */
228: bgp_capability_mp_data (s, &entry.mpc);
229: entry.num = stream_getc (s);
230: afi = entry.mpc.afi;
231: safi = entry.mpc.safi;
232:
233: if (BGP_DEBUG (normal, NORMAL))
234: zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
235: peer->host, entry.mpc.afi, entry.mpc.safi);
236:
237: /* Check AFI and SAFI. */
238: if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
239: {
240: zlog_info ("%s Addr-family %d/%d not supported."
241: " Ignoring the ORF capability",
242: peer->host, entry.mpc.afi, entry.mpc.safi);
243: return 0;
244: }
245:
246: /* validate number field */
247: if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)
248: {
249: zlog_info ("%s ORF Capability entry length error,"
250: " Cap length %u, num %u",
251: peer->host, hdr->length, entry.num);
252: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
253: return -1;
254: }
255:
256: for (i = 0 ; i < entry.num ; i++)
257: {
258: type = stream_getc(s);
259: mode = stream_getc(s);
260:
261: /* ORF Mode error check */
262: switch (mode)
263: {
264: case ORF_MODE_BOTH:
265: case ORF_MODE_SEND:
266: case ORF_MODE_RECEIVE:
267: break;
268: default:
269: bgp_capability_orf_not_support (peer, afi, safi, type, mode);
270: continue;
271: }
272: /* ORF Type and afi/safi error checks */
273: /* capcode versus type */
274: switch (hdr->code)
275: {
276: case CAPABILITY_CODE_ORF:
277: switch (type)
278: {
279: case ORF_TYPE_PREFIX:
280: break;
281: default:
282: bgp_capability_orf_not_support (peer, afi, safi, type, mode);
283: continue;
284: }
285: break;
286: case CAPABILITY_CODE_ORF_OLD:
287: switch (type)
288: {
289: case ORF_TYPE_PREFIX_OLD:
290: break;
291: default:
292: bgp_capability_orf_not_support (peer, afi, safi, type, mode);
293: continue;
294: }
295: break;
296: default:
297: bgp_capability_orf_not_support (peer, afi, safi, type, mode);
298: continue;
299: }
300:
301: /* AFI vs SAFI */
302: if (!((afi == AFI_IP && safi == SAFI_UNICAST)
303: || (afi == AFI_IP && safi == SAFI_MULTICAST)
304: || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
305: {
306: bgp_capability_orf_not_support (peer, afi, safi, type, mode);
307: continue;
308: }
309:
310: if (BGP_DEBUG (normal, NORMAL))
311: zlog_debug ("%s OPEN has %s ORF capability"
312: " as %s for afi/safi: %d/%d",
313: peer->host, LOOKUP (orf_type_str, type),
314: LOOKUP (orf_mode_str, mode),
315: entry.mpc.afi, safi);
316:
317: if (hdr->code == CAPABILITY_CODE_ORF)
318: {
319: sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
320: rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
321: }
322: else if (hdr->code == CAPABILITY_CODE_ORF_OLD)
323: {
324: sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
325: rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
326: }
327: else
328: {
329: bgp_capability_orf_not_support (peer, afi, safi, type, mode);
330: continue;
331: }
332:
333: switch (mode)
334: {
335: case ORF_MODE_BOTH:
336: SET_FLAG (peer->af_cap[afi][safi], sm_cap);
337: SET_FLAG (peer->af_cap[afi][safi], rm_cap);
338: break;
339: case ORF_MODE_SEND:
340: SET_FLAG (peer->af_cap[afi][safi], sm_cap);
341: break;
342: case ORF_MODE_RECEIVE:
343: SET_FLAG (peer->af_cap[afi][safi], rm_cap);
344: break;
345: }
346: }
347: return 0;
348: }
349:
350: static int
351: bgp_capability_orf (struct peer *peer, struct capability_header *hdr)
352: {
353: struct stream *s = BGP_INPUT (peer);
354: size_t end = stream_get_getp (s) + hdr->length;
355:
356: assert (stream_get_getp(s) + sizeof(struct capability_orf_entry) <= end);
357:
358: /* We must have at least one ORF entry, as the caller has already done
359: * minimum length validation for the capability code - for ORF there must
360: * at least one ORF entry (header and unknown number of pairs of bytes).
361: */
362: do
363: {
364: if (bgp_capability_orf_entry (peer, hdr) == -1)
365: return -1;
366: }
367: while (stream_get_getp(s) + sizeof(struct capability_orf_entry) < end);
368:
369: return 0;
370: }
371:
372: static int
373: bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
374: {
375: struct stream *s = BGP_INPUT (peer);
376: u_int16_t restart_flag_time;
377: int restart_bit = 0;
378: size_t end = stream_get_getp (s) + caphdr->length;
379:
380: SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
381: restart_flag_time = stream_getw(s);
382: if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
383: restart_bit = 1;
384: UNSET_FLAG (restart_flag_time, 0xF000);
385: peer->v_gr_restart = restart_flag_time;
386:
387: if (BGP_DEBUG (normal, NORMAL))
388: {
389: zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
390: zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
391: peer->host, restart_bit ? " " : " not ",
392: peer->v_gr_restart);
393: }
394:
395: while (stream_get_getp (s) + 4 < end)
396: {
397: afi_t afi = stream_getw (s);
398: safi_t safi = stream_getc (s);
399: u_char flag = stream_getc (s);
400:
401: if (!bgp_afi_safi_valid_indices (afi, &safi))
402: {
403: if (BGP_DEBUG (normal, NORMAL))
404: zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
405: " Ignore the Graceful Restart capability",
406: peer->host, afi, safi);
407: }
408: else if (!peer->afc[afi][safi])
409: {
410: if (BGP_DEBUG (normal, NORMAL))
411: zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
412: " Ignore the Graceful Restart capability",
413: peer->host, afi, safi);
414: }
415: else
416: {
417: if (BGP_DEBUG (normal, NORMAL))
418: zlog_debug ("%s Address family %s is%spreserved", peer->host,
419: afi_safi_print (afi, safi),
420: CHECK_FLAG (peer->af_cap[afi][safi],
421: PEER_CAP_RESTART_AF_PRESERVE_RCV)
422: ? " " : " not ");
423:
424: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
425: if (CHECK_FLAG (flag, RESTART_F_BIT))
426: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
427:
428: }
429: }
430: return 0;
431: }
432:
433: static as_t
434: bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
435: {
1.1.1.2 ! misho 436: SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
! 437:
! 438: if (hdr->length != CAPABILITY_CODE_AS4_LEN)
! 439: {
! 440: zlog_err ("%s AS4 capability has incorrect data length %d",
! 441: peer->host, hdr->length);
! 442: return 0;
! 443: }
! 444:
1.1 misho 445: as_t as4 = stream_getl (BGP_INPUT(peer));
446:
447: if (BGP_DEBUG (as4, AS4))
448: zlog_debug ("%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
449: peer->host, as4);
450: return as4;
451: }
452:
453: static const struct message capcode_str[] =
454: {
455: { CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
456: { CAPABILITY_CODE_REFRESH, "Route Refresh" },
457: { CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
458: { CAPABILITY_CODE_RESTART, "Graceful Restart" },
459: { CAPABILITY_CODE_AS4, "4-octet AS number" },
460: { CAPABILITY_CODE_DYNAMIC, "Dynamic" },
461: { CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
462: { CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
463: };
464: static const int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
465:
466: /* Minimum sizes for length field of each cap (so not inc. the header) */
467: static const size_t cap_minsizes[] =
468: {
469: [CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
470: [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
471: [CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
472: [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr),
473: [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
474: [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
475: [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
476: [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
477: };
478:
479: /* Parse given capability.
480: * XXX: This is reading into a stream, but not using stream API
481: */
482: static int
483: bgp_capability_parse (struct peer *peer, size_t length, u_char **error)
484: {
485: int ret;
486: struct stream *s = BGP_INPUT (peer);
487: size_t end = stream_get_getp (s) + length;
488:
489: assert (STREAM_READABLE (s) >= length);
490:
491: while (stream_get_getp (s) < end)
492: {
493: size_t start;
494: u_char *sp = stream_pnt (s);
495: struct capability_header caphdr;
496:
497: /* We need at least capability code and capability length. */
498: if (stream_get_getp(s) + 2 > end)
499: {
500: zlog_info ("%s Capability length error (< header)", peer->host);
501: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
502: return -1;
503: }
504:
505: caphdr.code = stream_getc (s);
506: caphdr.length = stream_getc (s);
507: start = stream_get_getp (s);
508:
509: /* Capability length check sanity check. */
510: if (start + caphdr.length > end)
511: {
512: zlog_info ("%s Capability length error (< length)", peer->host);
513: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
514: return -1;
515: }
516:
517: if (BGP_DEBUG (normal, NORMAL))
518: zlog_debug ("%s OPEN has %s capability (%u), length %u",
519: peer->host,
520: LOOKUP (capcode_str, caphdr.code),
521: caphdr.code, caphdr.length);
522:
523: /* Length sanity check, type-specific, for known capabilities */
524: switch (caphdr.code)
525: {
526: case CAPABILITY_CODE_MP:
527: case CAPABILITY_CODE_REFRESH:
528: case CAPABILITY_CODE_REFRESH_OLD:
529: case CAPABILITY_CODE_ORF:
530: case CAPABILITY_CODE_ORF_OLD:
531: case CAPABILITY_CODE_RESTART:
532: case CAPABILITY_CODE_AS4:
533: case CAPABILITY_CODE_DYNAMIC:
534: /* Check length. */
535: if (caphdr.length < cap_minsizes[caphdr.code])
536: {
537: zlog_info ("%s %s Capability length error: got %u,"
538: " expected at least %u",
539: peer->host,
540: LOOKUP (capcode_str, caphdr.code),
541: caphdr.length,
542: (unsigned) cap_minsizes[caphdr.code]);
543: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
544: return -1;
545: }
546: /* we deliberately ignore unknown codes, see below */
547: default:
548: break;
549: }
550:
551: switch (caphdr.code)
552: {
553: case CAPABILITY_CODE_MP:
554: {
555: /* Ignore capability when override-capability is set. */
556: if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
557: {
558: /* Set negotiated value. */
559: ret = bgp_capability_mp (peer, &caphdr);
560:
561: /* Unsupported Capability. */
562: if (ret < 0)
563: {
564: /* Store return data. */
565: memcpy (*error, sp, caphdr.length + 2);
566: *error += caphdr.length + 2;
567: }
568: }
569: }
570: break;
571: case CAPABILITY_CODE_REFRESH:
572: case CAPABILITY_CODE_REFRESH_OLD:
573: {
574: /* BGP refresh capability */
575: if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
576: SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
577: else
578: SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
579: }
580: break;
581: case CAPABILITY_CODE_ORF:
582: case CAPABILITY_CODE_ORF_OLD:
583: if (bgp_capability_orf (peer, &caphdr))
584: return -1;
585: break;
586: case CAPABILITY_CODE_RESTART:
587: if (bgp_capability_restart (peer, &caphdr))
588: return -1;
589: break;
590: case CAPABILITY_CODE_DYNAMIC:
591: SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
592: break;
593: case CAPABILITY_CODE_AS4:
594: /* Already handled as a special-case parsing of the capabilities
595: * at the beginning of OPEN processing. So we care not a jot
596: * for the value really, only error case.
597: */
598: if (!bgp_capability_as4 (peer, &caphdr))
599: return -1;
600: break;
601: default:
602: if (caphdr.code > 128)
603: {
604: /* We don't send Notification for unknown vendor specific
605: capabilities. It seems reasonable for now... */
606: zlog_warn ("%s Vendor specific capability %d",
607: peer->host, caphdr.code);
608: }
609: else
610: {
611: zlog_warn ("%s unrecognized capability code: %d - ignored",
612: peer->host, caphdr.code);
613: memcpy (*error, sp, caphdr.length + 2);
614: *error += caphdr.length + 2;
615: }
616: }
617: if (stream_get_getp(s) != (start + caphdr.length))
618: {
619: if (stream_get_getp(s) > (start + caphdr.length))
620: zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
621: peer->host, LOOKUP (capcode_str, caphdr.code),
622: caphdr.length);
623: stream_set_getp (s, start + caphdr.length);
624: }
625: }
626: return 0;
627: }
628:
629: static int
630: bgp_auth_parse (struct peer *peer, size_t length)
631: {
632: bgp_notify_send (peer,
633: BGP_NOTIFY_OPEN_ERR,
634: BGP_NOTIFY_OPEN_AUTH_FAILURE);
635: return -1;
636: }
637:
638: static int
639: strict_capability_same (struct peer *peer)
640: {
641: int i, j;
642:
643: for (i = AFI_IP; i < AFI_MAX; i++)
644: for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
645: if (peer->afc[i][j] != peer->afc_nego[i][j])
646: return 0;
647: return 1;
648: }
649:
650: /* peek into option, stores ASN to *as4 if the AS4 capability was found.
651: * Returns 0 if no as4 found, as4cap value otherwise.
652: */
653: as_t
654: peek_for_as4_capability (struct peer *peer, u_char length)
655: {
656: struct stream *s = BGP_INPUT (peer);
657: size_t orig_getp = stream_get_getp (s);
658: size_t end = orig_getp + length;
659: as_t as4 = 0;
660:
661: /* The full capability parser will better flag the error.. */
662: if (STREAM_READABLE(s) < length)
663: return 0;
664:
665: if (BGP_DEBUG (as4, AS4))
666: zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
667: " peeking for as4",
668: peer->host, length);
669: /* the error cases we DONT handle, we ONLY try to read as4 out of
670: * correctly formatted options.
671: */
672: while (stream_get_getp(s) < end)
673: {
674: u_char opt_type;
675: u_char opt_length;
676:
677: /* Check the length. */
678: if (stream_get_getp (s) + 2 > end)
679: goto end;
680:
681: /* Fetch option type and length. */
682: opt_type = stream_getc (s);
683: opt_length = stream_getc (s);
684:
685: /* Option length check. */
686: if (stream_get_getp (s) + opt_length > end)
687: goto end;
688:
689: if (opt_type == BGP_OPEN_OPT_CAP)
690: {
691: unsigned long capd_start = stream_get_getp (s);
692: unsigned long capd_end = capd_start + opt_length;
693:
694: assert (capd_end <= end);
695:
696: while (stream_get_getp (s) < capd_end)
697: {
698: struct capability_header hdr;
699:
700: if (stream_get_getp (s) + 2 > capd_end)
701: goto end;
702:
703: hdr.code = stream_getc (s);
704: hdr.length = stream_getc (s);
705:
706: if ((stream_get_getp(s) + hdr.length) > capd_end)
707: goto end;
708:
709: if (hdr.code == CAPABILITY_CODE_AS4)
710: {
711: if (BGP_DEBUG (as4, AS4))
712: zlog_info ("[AS4] found AS4 capability, about to parse");
713: as4 = bgp_capability_as4 (peer, &hdr);
714:
715: goto end;
716: }
717: stream_forward_getp (s, hdr.length);
718: }
719: }
720: }
721:
722: end:
723: stream_set_getp (s, orig_getp);
724: return as4;
725: }
726:
727: /* Parse open option */
728: int
729: bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
730: {
731: int ret;
732: u_char *error;
733: u_char error_data[BGP_MAX_PACKET_SIZE];
734: struct stream *s = BGP_INPUT(peer);
735: size_t end = stream_get_getp (s) + length;
736:
737: ret = 0;
738: error = error_data;
739:
740: if (BGP_DEBUG (normal, NORMAL))
741: zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
742: peer->host, length);
743:
744: while (stream_get_getp(s) < end)
745: {
746: u_char opt_type;
747: u_char opt_length;
748:
749: /* Must have at least an OPEN option header */
750: if (STREAM_READABLE(s) < 2)
751: {
752: zlog_info ("%s Option length error", peer->host);
753: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
754: return -1;
755: }
756:
757: /* Fetch option type and length. */
758: opt_type = stream_getc (s);
759: opt_length = stream_getc (s);
760:
761: /* Option length check. */
762: if (STREAM_READABLE (s) < opt_length)
763: {
764: zlog_info ("%s Option length error", peer->host);
765: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
766: return -1;
767: }
768:
769: if (BGP_DEBUG (normal, NORMAL))
770: zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
771: peer->host, opt_type,
772: opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
773: opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
774: opt_length);
775:
776: switch (opt_type)
777: {
778: case BGP_OPEN_OPT_AUTH:
779: ret = bgp_auth_parse (peer, opt_length);
780: break;
781: case BGP_OPEN_OPT_CAP:
782: ret = bgp_capability_parse (peer, opt_length, &error);
783: *capability = 1;
784: break;
785: default:
786: bgp_notify_send (peer,
787: BGP_NOTIFY_OPEN_ERR,
788: BGP_NOTIFY_OPEN_UNSUP_PARAM);
789: ret = -1;
790: break;
791: }
792:
793: /* Parse error. To accumulate all unsupported capability codes,
794: bgp_capability_parse does not return -1 when encounter
795: unsupported capability code. To detect that, please check
796: error and erro_data pointer, like below. */
797: if (ret < 0)
798: return -1;
799: }
800:
801: /* All OPEN option is parsed. Check capability when strict compare
802: flag is enabled.*/
803: if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
804: {
805: /* If Unsupported Capability exists. */
806: if (error != error_data)
807: {
808: bgp_notify_send_with_data (peer,
809: BGP_NOTIFY_OPEN_ERR,
810: BGP_NOTIFY_OPEN_UNSUP_CAPBL,
811: error_data, error - error_data);
812: return -1;
813: }
814:
815: /* Check local capability does not negotiated with remote
816: peer. */
817: if (! strict_capability_same (peer))
818: {
819: bgp_notify_send (peer,
820: BGP_NOTIFY_OPEN_ERR,
821: BGP_NOTIFY_OPEN_UNSUP_CAPBL);
822: return -1;
823: }
824: }
825:
826: /* Check there is no common capability send Unsupported Capability
827: error. */
828: if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
829: {
830: if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
831: && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
832: && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
833: && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
834: && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
835: {
836: plog_err (peer->log, "%s [Error] No common capability", peer->host);
837:
838: if (error != error_data)
839:
840: bgp_notify_send_with_data (peer,
841: BGP_NOTIFY_OPEN_ERR,
842: BGP_NOTIFY_OPEN_UNSUP_CAPBL,
843: error_data, error - error_data);
844: else
845: bgp_notify_send (peer,
846: BGP_NOTIFY_OPEN_ERR,
847: BGP_NOTIFY_OPEN_UNSUP_CAPBL);
848: return -1;
849: }
850: }
851: return 0;
852: }
853:
854: static void
855: bgp_open_capability_orf (struct stream *s, struct peer *peer,
856: afi_t afi, safi_t safi, u_char code)
857: {
858: u_char cap_len;
859: u_char orf_len;
860: unsigned long capp;
861: unsigned long orfp;
862: unsigned long numberp;
863: int number_of_orfs = 0;
864:
865: if (safi == SAFI_MPLS_VPN)
866: safi = BGP_SAFI_VPNV4;
867:
868: stream_putc (s, BGP_OPEN_OPT_CAP);
869: capp = stream_get_endp (s); /* Set Capability Len Pointer */
870: stream_putc (s, 0); /* Capability Length */
871: stream_putc (s, code); /* Capability Code */
872: orfp = stream_get_endp (s); /* Set ORF Len Pointer */
873: stream_putc (s, 0); /* ORF Length */
874: stream_putw (s, afi);
875: stream_putc (s, 0);
876: stream_putc (s, safi);
877: numberp = stream_get_endp (s); /* Set Number Pointer */
878: stream_putc (s, 0); /* Number of ORFs */
879:
880: /* Address Prefix ORF */
881: if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
882: || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
883: {
884: stream_putc (s, (code == CAPABILITY_CODE_ORF ?
885: ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
886:
887: if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
888: && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
889: {
890: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
891: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
892: stream_putc (s, ORF_MODE_BOTH);
893: }
894: else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
895: {
896: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
897: stream_putc (s, ORF_MODE_SEND);
898: }
899: else
900: {
901: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
902: stream_putc (s, ORF_MODE_RECEIVE);
903: }
904: number_of_orfs++;
905: }
906:
907: /* Total Number of ORFs. */
908: stream_putc_at (s, numberp, number_of_orfs);
909:
910: /* Total ORF Len. */
911: orf_len = stream_get_endp (s) - orfp - 1;
912: stream_putc_at (s, orfp, orf_len);
913:
914: /* Total Capability Len. */
915: cap_len = stream_get_endp (s) - capp - 1;
916: stream_putc_at (s, capp, cap_len);
917: }
918:
919: /* Fill in capability open option to the packet. */
920: void
921: bgp_open_capability (struct stream *s, struct peer *peer)
922: {
923: u_char len;
924: unsigned long cp;
925: afi_t afi;
926: safi_t safi;
927: as_t local_as;
928:
929: /* Remember current pointer for Opt Parm Len. */
930: cp = stream_get_endp (s);
931:
932: /* Opt Parm Len. */
933: stream_putc (s, 0);
934:
935: /* Do not send capability. */
936: if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
937: || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
938: return;
939:
940: /* IPv4 unicast. */
941: if (peer->afc[AFI_IP][SAFI_UNICAST])
942: {
943: peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
944: stream_putc (s, BGP_OPEN_OPT_CAP);
945: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
946: stream_putc (s, CAPABILITY_CODE_MP);
947: stream_putc (s, CAPABILITY_CODE_MP_LEN);
948: stream_putw (s, AFI_IP);
949: stream_putc (s, 0);
950: stream_putc (s, SAFI_UNICAST);
951: }
952: /* IPv4 multicast. */
953: if (peer->afc[AFI_IP][SAFI_MULTICAST])
954: {
955: peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
956: stream_putc (s, BGP_OPEN_OPT_CAP);
957: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
958: stream_putc (s, CAPABILITY_CODE_MP);
959: stream_putc (s, CAPABILITY_CODE_MP_LEN);
960: stream_putw (s, AFI_IP);
961: stream_putc (s, 0);
962: stream_putc (s, SAFI_MULTICAST);
963: }
964: /* IPv4 VPN */
965: if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
966: {
967: peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
968: stream_putc (s, BGP_OPEN_OPT_CAP);
969: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
970: stream_putc (s, CAPABILITY_CODE_MP);
971: stream_putc (s, CAPABILITY_CODE_MP_LEN);
972: stream_putw (s, AFI_IP);
973: stream_putc (s, 0);
974: stream_putc (s, BGP_SAFI_VPNV4);
975: }
976: #ifdef HAVE_IPV6
977: /* IPv6 unicast. */
978: if (peer->afc[AFI_IP6][SAFI_UNICAST])
979: {
980: peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
981: stream_putc (s, BGP_OPEN_OPT_CAP);
982: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
983: stream_putc (s, CAPABILITY_CODE_MP);
984: stream_putc (s, CAPABILITY_CODE_MP_LEN);
985: stream_putw (s, AFI_IP6);
986: stream_putc (s, 0);
987: stream_putc (s, SAFI_UNICAST);
988: }
989: /* IPv6 multicast. */
990: if (peer->afc[AFI_IP6][SAFI_MULTICAST])
991: {
992: peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
993: stream_putc (s, BGP_OPEN_OPT_CAP);
994: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
995: stream_putc (s, CAPABILITY_CODE_MP);
996: stream_putc (s, CAPABILITY_CODE_MP_LEN);
997: stream_putw (s, AFI_IP6);
998: stream_putc (s, 0);
999: stream_putc (s, SAFI_MULTICAST);
1000: }
1001: #endif /* HAVE_IPV6 */
1002:
1003: /* Route refresh. */
1004: SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
1005: stream_putc (s, BGP_OPEN_OPT_CAP);
1006: stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1007: stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
1008: stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
1009: stream_putc (s, BGP_OPEN_OPT_CAP);
1010: stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1011: stream_putc (s, CAPABILITY_CODE_REFRESH);
1012: stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
1013:
1014: /* AS4 */
1015: SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
1016: stream_putc (s, BGP_OPEN_OPT_CAP);
1017: stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
1018: stream_putc (s, CAPABILITY_CODE_AS4);
1019: stream_putc (s, CAPABILITY_CODE_AS4_LEN);
1020: if ( peer->change_local_as )
1021: local_as = peer->change_local_as;
1022: else
1023: local_as = peer->local_as;
1024: stream_putl (s, local_as );
1025:
1026: /* ORF capability. */
1027: for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1028: for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1029: if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1030: || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1031: {
1032: bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
1033: bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
1034: }
1035:
1036: /* Dynamic capability. */
1037: if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
1038: {
1039: SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
1040: stream_putc (s, BGP_OPEN_OPT_CAP);
1041: stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1042: stream_putc (s, CAPABILITY_CODE_DYNAMIC);
1043: stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
1044: }
1045:
1046: /* Graceful restart capability */
1047: if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
1048: {
1049: SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
1050: stream_putc (s, BGP_OPEN_OPT_CAP);
1051: stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
1052: stream_putc (s, CAPABILITY_CODE_RESTART);
1053: stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
1054: stream_putw (s, peer->bgp->restart_time);
1055: }
1056:
1057: /* Total Opt Parm Len. */
1058: len = stream_get_endp (s) - cp - 1;
1059: stream_putc_at (s, cp, len);
1060: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>