Annotation of embedaddon/quagga/bgpd/bgp_open.c, revision 1.1.1.1
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: {
436: as_t as4 = stream_getl (BGP_INPUT(peer));
437:
438: if (BGP_DEBUG (as4, AS4))
439: zlog_debug ("%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
440: peer->host, as4);
441: SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
442:
443: return as4;
444: }
445:
446: static const struct message capcode_str[] =
447: {
448: { CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
449: { CAPABILITY_CODE_REFRESH, "Route Refresh" },
450: { CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
451: { CAPABILITY_CODE_RESTART, "Graceful Restart" },
452: { CAPABILITY_CODE_AS4, "4-octet AS number" },
453: { CAPABILITY_CODE_DYNAMIC, "Dynamic" },
454: { CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
455: { CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
456: };
457: static const int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
458:
459: /* Minimum sizes for length field of each cap (so not inc. the header) */
460: static const size_t cap_minsizes[] =
461: {
462: [CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
463: [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
464: [CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
465: [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr),
466: [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
467: [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
468: [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
469: [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
470: };
471:
472: /* Parse given capability.
473: * XXX: This is reading into a stream, but not using stream API
474: */
475: static int
476: bgp_capability_parse (struct peer *peer, size_t length, u_char **error)
477: {
478: int ret;
479: struct stream *s = BGP_INPUT (peer);
480: size_t end = stream_get_getp (s) + length;
481:
482: assert (STREAM_READABLE (s) >= length);
483:
484: while (stream_get_getp (s) < end)
485: {
486: size_t start;
487: u_char *sp = stream_pnt (s);
488: struct capability_header caphdr;
489:
490: /* We need at least capability code and capability length. */
491: if (stream_get_getp(s) + 2 > end)
492: {
493: zlog_info ("%s Capability length error (< header)", peer->host);
494: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
495: return -1;
496: }
497:
498: caphdr.code = stream_getc (s);
499: caphdr.length = stream_getc (s);
500: start = stream_get_getp (s);
501:
502: /* Capability length check sanity check. */
503: if (start + caphdr.length > end)
504: {
505: zlog_info ("%s Capability length error (< length)", peer->host);
506: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
507: return -1;
508: }
509:
510: if (BGP_DEBUG (normal, NORMAL))
511: zlog_debug ("%s OPEN has %s capability (%u), length %u",
512: peer->host,
513: LOOKUP (capcode_str, caphdr.code),
514: caphdr.code, caphdr.length);
515:
516: /* Length sanity check, type-specific, for known capabilities */
517: switch (caphdr.code)
518: {
519: case CAPABILITY_CODE_MP:
520: case CAPABILITY_CODE_REFRESH:
521: case CAPABILITY_CODE_REFRESH_OLD:
522: case CAPABILITY_CODE_ORF:
523: case CAPABILITY_CODE_ORF_OLD:
524: case CAPABILITY_CODE_RESTART:
525: case CAPABILITY_CODE_AS4:
526: case CAPABILITY_CODE_DYNAMIC:
527: /* Check length. */
528: if (caphdr.length < cap_minsizes[caphdr.code])
529: {
530: zlog_info ("%s %s Capability length error: got %u,"
531: " expected at least %u",
532: peer->host,
533: LOOKUP (capcode_str, caphdr.code),
534: caphdr.length,
535: (unsigned) cap_minsizes[caphdr.code]);
536: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
537: return -1;
538: }
539: /* we deliberately ignore unknown codes, see below */
540: default:
541: break;
542: }
543:
544: switch (caphdr.code)
545: {
546: case CAPABILITY_CODE_MP:
547: {
548: /* Ignore capability when override-capability is set. */
549: if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
550: {
551: /* Set negotiated value. */
552: ret = bgp_capability_mp (peer, &caphdr);
553:
554: /* Unsupported Capability. */
555: if (ret < 0)
556: {
557: /* Store return data. */
558: memcpy (*error, sp, caphdr.length + 2);
559: *error += caphdr.length + 2;
560: }
561: }
562: }
563: break;
564: case CAPABILITY_CODE_REFRESH:
565: case CAPABILITY_CODE_REFRESH_OLD:
566: {
567: /* BGP refresh capability */
568: if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
569: SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
570: else
571: SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
572: }
573: break;
574: case CAPABILITY_CODE_ORF:
575: case CAPABILITY_CODE_ORF_OLD:
576: if (bgp_capability_orf (peer, &caphdr))
577: return -1;
578: break;
579: case CAPABILITY_CODE_RESTART:
580: if (bgp_capability_restart (peer, &caphdr))
581: return -1;
582: break;
583: case CAPABILITY_CODE_DYNAMIC:
584: SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
585: break;
586: case CAPABILITY_CODE_AS4:
587: /* Already handled as a special-case parsing of the capabilities
588: * at the beginning of OPEN processing. So we care not a jot
589: * for the value really, only error case.
590: */
591: if (!bgp_capability_as4 (peer, &caphdr))
592: return -1;
593: break;
594: default:
595: if (caphdr.code > 128)
596: {
597: /* We don't send Notification for unknown vendor specific
598: capabilities. It seems reasonable for now... */
599: zlog_warn ("%s Vendor specific capability %d",
600: peer->host, caphdr.code);
601: }
602: else
603: {
604: zlog_warn ("%s unrecognized capability code: %d - ignored",
605: peer->host, caphdr.code);
606: memcpy (*error, sp, caphdr.length + 2);
607: *error += caphdr.length + 2;
608: }
609: }
610: if (stream_get_getp(s) != (start + caphdr.length))
611: {
612: if (stream_get_getp(s) > (start + caphdr.length))
613: zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
614: peer->host, LOOKUP (capcode_str, caphdr.code),
615: caphdr.length);
616: stream_set_getp (s, start + caphdr.length);
617: }
618: }
619: return 0;
620: }
621:
622: static int
623: bgp_auth_parse (struct peer *peer, size_t length)
624: {
625: bgp_notify_send (peer,
626: BGP_NOTIFY_OPEN_ERR,
627: BGP_NOTIFY_OPEN_AUTH_FAILURE);
628: return -1;
629: }
630:
631: static int
632: strict_capability_same (struct peer *peer)
633: {
634: int i, j;
635:
636: for (i = AFI_IP; i < AFI_MAX; i++)
637: for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
638: if (peer->afc[i][j] != peer->afc_nego[i][j])
639: return 0;
640: return 1;
641: }
642:
643: /* peek into option, stores ASN to *as4 if the AS4 capability was found.
644: * Returns 0 if no as4 found, as4cap value otherwise.
645: */
646: as_t
647: peek_for_as4_capability (struct peer *peer, u_char length)
648: {
649: struct stream *s = BGP_INPUT (peer);
650: size_t orig_getp = stream_get_getp (s);
651: size_t end = orig_getp + length;
652: as_t as4 = 0;
653:
654: /* The full capability parser will better flag the error.. */
655: if (STREAM_READABLE(s) < length)
656: return 0;
657:
658: if (BGP_DEBUG (as4, AS4))
659: zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
660: " peeking for as4",
661: peer->host, length);
662: /* the error cases we DONT handle, we ONLY try to read as4 out of
663: * correctly formatted options.
664: */
665: while (stream_get_getp(s) < end)
666: {
667: u_char opt_type;
668: u_char opt_length;
669:
670: /* Check the length. */
671: if (stream_get_getp (s) + 2 > end)
672: goto end;
673:
674: /* Fetch option type and length. */
675: opt_type = stream_getc (s);
676: opt_length = stream_getc (s);
677:
678: /* Option length check. */
679: if (stream_get_getp (s) + opt_length > end)
680: goto end;
681:
682: if (opt_type == BGP_OPEN_OPT_CAP)
683: {
684: unsigned long capd_start = stream_get_getp (s);
685: unsigned long capd_end = capd_start + opt_length;
686:
687: assert (capd_end <= end);
688:
689: while (stream_get_getp (s) < capd_end)
690: {
691: struct capability_header hdr;
692:
693: if (stream_get_getp (s) + 2 > capd_end)
694: goto end;
695:
696: hdr.code = stream_getc (s);
697: hdr.length = stream_getc (s);
698:
699: if ((stream_get_getp(s) + hdr.length) > capd_end)
700: goto end;
701:
702: if (hdr.code == CAPABILITY_CODE_AS4)
703: {
704: if (hdr.length != CAPABILITY_CODE_AS4_LEN)
705: goto end;
706:
707: if (BGP_DEBUG (as4, AS4))
708: zlog_info ("[AS4] found AS4 capability, about to parse");
709: as4 = bgp_capability_as4 (peer, &hdr);
710:
711: goto end;
712: }
713: stream_forward_getp (s, hdr.length);
714: }
715: }
716: }
717:
718: end:
719: stream_set_getp (s, orig_getp);
720: return as4;
721: }
722:
723: /* Parse open option */
724: int
725: bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
726: {
727: int ret;
728: u_char *error;
729: u_char error_data[BGP_MAX_PACKET_SIZE];
730: struct stream *s = BGP_INPUT(peer);
731: size_t end = stream_get_getp (s) + length;
732:
733: ret = 0;
734: error = error_data;
735:
736: if (BGP_DEBUG (normal, NORMAL))
737: zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
738: peer->host, length);
739:
740: while (stream_get_getp(s) < end)
741: {
742: u_char opt_type;
743: u_char opt_length;
744:
745: /* Must have at least an OPEN option header */
746: if (STREAM_READABLE(s) < 2)
747: {
748: zlog_info ("%s Option length error", peer->host);
749: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
750: return -1;
751: }
752:
753: /* Fetch option type and length. */
754: opt_type = stream_getc (s);
755: opt_length = stream_getc (s);
756:
757: /* Option length check. */
758: if (STREAM_READABLE (s) < opt_length)
759: {
760: zlog_info ("%s Option length error", peer->host);
761: bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
762: return -1;
763: }
764:
765: if (BGP_DEBUG (normal, NORMAL))
766: zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
767: peer->host, opt_type,
768: opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
769: opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
770: opt_length);
771:
772: switch (opt_type)
773: {
774: case BGP_OPEN_OPT_AUTH:
775: ret = bgp_auth_parse (peer, opt_length);
776: break;
777: case BGP_OPEN_OPT_CAP:
778: ret = bgp_capability_parse (peer, opt_length, &error);
779: *capability = 1;
780: break;
781: default:
782: bgp_notify_send (peer,
783: BGP_NOTIFY_OPEN_ERR,
784: BGP_NOTIFY_OPEN_UNSUP_PARAM);
785: ret = -1;
786: break;
787: }
788:
789: /* Parse error. To accumulate all unsupported capability codes,
790: bgp_capability_parse does not return -1 when encounter
791: unsupported capability code. To detect that, please check
792: error and erro_data pointer, like below. */
793: if (ret < 0)
794: return -1;
795: }
796:
797: /* All OPEN option is parsed. Check capability when strict compare
798: flag is enabled.*/
799: if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
800: {
801: /* If Unsupported Capability exists. */
802: if (error != error_data)
803: {
804: bgp_notify_send_with_data (peer,
805: BGP_NOTIFY_OPEN_ERR,
806: BGP_NOTIFY_OPEN_UNSUP_CAPBL,
807: error_data, error - error_data);
808: return -1;
809: }
810:
811: /* Check local capability does not negotiated with remote
812: peer. */
813: if (! strict_capability_same (peer))
814: {
815: bgp_notify_send (peer,
816: BGP_NOTIFY_OPEN_ERR,
817: BGP_NOTIFY_OPEN_UNSUP_CAPBL);
818: return -1;
819: }
820: }
821:
822: /* Check there is no common capability send Unsupported Capability
823: error. */
824: if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
825: {
826: if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
827: && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
828: && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
829: && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
830: && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
831: {
832: plog_err (peer->log, "%s [Error] No common capability", peer->host);
833:
834: if (error != error_data)
835:
836: bgp_notify_send_with_data (peer,
837: BGP_NOTIFY_OPEN_ERR,
838: BGP_NOTIFY_OPEN_UNSUP_CAPBL,
839: error_data, error - error_data);
840: else
841: bgp_notify_send (peer,
842: BGP_NOTIFY_OPEN_ERR,
843: BGP_NOTIFY_OPEN_UNSUP_CAPBL);
844: return -1;
845: }
846: }
847: return 0;
848: }
849:
850: static void
851: bgp_open_capability_orf (struct stream *s, struct peer *peer,
852: afi_t afi, safi_t safi, u_char code)
853: {
854: u_char cap_len;
855: u_char orf_len;
856: unsigned long capp;
857: unsigned long orfp;
858: unsigned long numberp;
859: int number_of_orfs = 0;
860:
861: if (safi == SAFI_MPLS_VPN)
862: safi = BGP_SAFI_VPNV4;
863:
864: stream_putc (s, BGP_OPEN_OPT_CAP);
865: capp = stream_get_endp (s); /* Set Capability Len Pointer */
866: stream_putc (s, 0); /* Capability Length */
867: stream_putc (s, code); /* Capability Code */
868: orfp = stream_get_endp (s); /* Set ORF Len Pointer */
869: stream_putc (s, 0); /* ORF Length */
870: stream_putw (s, afi);
871: stream_putc (s, 0);
872: stream_putc (s, safi);
873: numberp = stream_get_endp (s); /* Set Number Pointer */
874: stream_putc (s, 0); /* Number of ORFs */
875:
876: /* Address Prefix ORF */
877: if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
878: || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
879: {
880: stream_putc (s, (code == CAPABILITY_CODE_ORF ?
881: ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
882:
883: if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
884: && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
885: {
886: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
887: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
888: stream_putc (s, ORF_MODE_BOTH);
889: }
890: else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
891: {
892: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
893: stream_putc (s, ORF_MODE_SEND);
894: }
895: else
896: {
897: SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
898: stream_putc (s, ORF_MODE_RECEIVE);
899: }
900: number_of_orfs++;
901: }
902:
903: /* Total Number of ORFs. */
904: stream_putc_at (s, numberp, number_of_orfs);
905:
906: /* Total ORF Len. */
907: orf_len = stream_get_endp (s) - orfp - 1;
908: stream_putc_at (s, orfp, orf_len);
909:
910: /* Total Capability Len. */
911: cap_len = stream_get_endp (s) - capp - 1;
912: stream_putc_at (s, capp, cap_len);
913: }
914:
915: /* Fill in capability open option to the packet. */
916: void
917: bgp_open_capability (struct stream *s, struct peer *peer)
918: {
919: u_char len;
920: unsigned long cp;
921: afi_t afi;
922: safi_t safi;
923: as_t local_as;
924:
925: /* Remember current pointer for Opt Parm Len. */
926: cp = stream_get_endp (s);
927:
928: /* Opt Parm Len. */
929: stream_putc (s, 0);
930:
931: /* Do not send capability. */
932: if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
933: || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
934: return;
935:
936: /* IPv4 unicast. */
937: if (peer->afc[AFI_IP][SAFI_UNICAST])
938: {
939: peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
940: stream_putc (s, BGP_OPEN_OPT_CAP);
941: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
942: stream_putc (s, CAPABILITY_CODE_MP);
943: stream_putc (s, CAPABILITY_CODE_MP_LEN);
944: stream_putw (s, AFI_IP);
945: stream_putc (s, 0);
946: stream_putc (s, SAFI_UNICAST);
947: }
948: /* IPv4 multicast. */
949: if (peer->afc[AFI_IP][SAFI_MULTICAST])
950: {
951: peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
952: stream_putc (s, BGP_OPEN_OPT_CAP);
953: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
954: stream_putc (s, CAPABILITY_CODE_MP);
955: stream_putc (s, CAPABILITY_CODE_MP_LEN);
956: stream_putw (s, AFI_IP);
957: stream_putc (s, 0);
958: stream_putc (s, SAFI_MULTICAST);
959: }
960: /* IPv4 VPN */
961: if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
962: {
963: peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
964: stream_putc (s, BGP_OPEN_OPT_CAP);
965: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
966: stream_putc (s, CAPABILITY_CODE_MP);
967: stream_putc (s, CAPABILITY_CODE_MP_LEN);
968: stream_putw (s, AFI_IP);
969: stream_putc (s, 0);
970: stream_putc (s, BGP_SAFI_VPNV4);
971: }
972: #ifdef HAVE_IPV6
973: /* IPv6 unicast. */
974: if (peer->afc[AFI_IP6][SAFI_UNICAST])
975: {
976: peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
977: stream_putc (s, BGP_OPEN_OPT_CAP);
978: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
979: stream_putc (s, CAPABILITY_CODE_MP);
980: stream_putc (s, CAPABILITY_CODE_MP_LEN);
981: stream_putw (s, AFI_IP6);
982: stream_putc (s, 0);
983: stream_putc (s, SAFI_UNICAST);
984: }
985: /* IPv6 multicast. */
986: if (peer->afc[AFI_IP6][SAFI_MULTICAST])
987: {
988: peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
989: stream_putc (s, BGP_OPEN_OPT_CAP);
990: stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
991: stream_putc (s, CAPABILITY_CODE_MP);
992: stream_putc (s, CAPABILITY_CODE_MP_LEN);
993: stream_putw (s, AFI_IP6);
994: stream_putc (s, 0);
995: stream_putc (s, SAFI_MULTICAST);
996: }
997: #endif /* HAVE_IPV6 */
998:
999: /* Route refresh. */
1000: SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
1001: stream_putc (s, BGP_OPEN_OPT_CAP);
1002: stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1003: stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
1004: stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
1005: stream_putc (s, BGP_OPEN_OPT_CAP);
1006: stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1007: stream_putc (s, CAPABILITY_CODE_REFRESH);
1008: stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
1009:
1010: /* AS4 */
1011: SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
1012: stream_putc (s, BGP_OPEN_OPT_CAP);
1013: stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
1014: stream_putc (s, CAPABILITY_CODE_AS4);
1015: stream_putc (s, CAPABILITY_CODE_AS4_LEN);
1016: if ( peer->change_local_as )
1017: local_as = peer->change_local_as;
1018: else
1019: local_as = peer->local_as;
1020: stream_putl (s, local_as );
1021:
1022: /* ORF capability. */
1023: for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1024: for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1025: if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1026: || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1027: {
1028: bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
1029: bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
1030: }
1031:
1032: /* Dynamic capability. */
1033: if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
1034: {
1035: SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
1036: stream_putc (s, BGP_OPEN_OPT_CAP);
1037: stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1038: stream_putc (s, CAPABILITY_CODE_DYNAMIC);
1039: stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
1040: }
1041:
1042: /* Graceful restart capability */
1043: if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
1044: {
1045: SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
1046: stream_putc (s, BGP_OPEN_OPT_CAP);
1047: stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
1048: stream_putc (s, CAPABILITY_CODE_RESTART);
1049: stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
1050: stream_putw (s, peer->bgp->restart_time);
1051: }
1052:
1053: /* Total Opt Parm Len. */
1054: len = stream_get_endp (s) - cp - 1;
1055: stream_putc_at (s, cp, len);
1056: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>