1: /* MPLS-VPN
2: Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
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 "command.h"
24: #include "prefix.h"
25: #include "log.h"
26: #include "memory.h"
27: #include "stream.h"
28: #include "filter.h"
29:
30: #include "bgpd/bgpd.h"
31: #include "bgpd/bgp_table.h"
32: #include "bgpd/bgp_route.h"
33: #include "bgpd/bgp_packet.h"
34: #include "bgpd/bgp_attr.h"
35: #include "bgpd/bgp_mplsvpn.h"
36: #include "bgpd/bgp_packet.h"
37:
38: static u_int16_t
39: decode_rd_type (u_char *pnt)
40: {
41: u_int16_t v;
42:
43: v = ((u_int16_t) *pnt++ << 8);
44: v |= (u_int16_t) *pnt;
45: return v;
46: }
47:
48: u_int32_t
49: decode_label (u_char *pnt)
50: {
51: u_int32_t l;
52:
53: l = ((u_int32_t) *pnt++ << 12);
54: l |= (u_int32_t) *pnt++ << 4;
55: l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
56: return l;
57: }
58:
59: /* type == RD_TYPE_AS */
60: static void
61: decode_rd_as (u_char *pnt, struct rd_as *rd_as)
62: {
63: rd_as->as = (u_int16_t) *pnt++ << 8;
64: rd_as->as |= (u_int16_t) *pnt++;
65:
66: rd_as->val = ((u_int32_t) *pnt++ << 24);
67: rd_as->val |= ((u_int32_t) *pnt++ << 16);
68: rd_as->val |= ((u_int32_t) *pnt++ << 8);
69: rd_as->val |= (u_int32_t) *pnt;
70: }
71:
72: /* type == RD_TYPE_AS4 */
73: static void
74: decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
75: {
76: rd_as->as = (u_int32_t) *pnt++ << 24;
77: rd_as->as |= (u_int32_t) *pnt++ << 16;
78: rd_as->as |= (u_int32_t) *pnt++ << 8;
79: rd_as->as |= (u_int32_t) *pnt++;
80:
81: rd_as->val = ((u_int16_t) *pnt++ << 8);
82: rd_as->val |= (u_int16_t) *pnt;
83: }
84:
85: /* type == RD_TYPE_IP */
86: static void
87: decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
88: {
89: memcpy (&rd_ip->ip, pnt, 4);
90: pnt += 4;
91:
92: rd_ip->val = ((u_int16_t) *pnt++ << 8);
93: rd_ip->val |= (u_int16_t) *pnt;
94: }
95:
96: int
97: bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
98: struct bgp_nlri *packet)
99: {
100: u_char *pnt;
101: u_char *lim;
102: struct prefix p;
103: int psize = 0;
104: int prefixlen;
105: u_int16_t type;
106: struct rd_as rd_as;
107: struct rd_ip rd_ip;
108: struct prefix_rd prd;
109: u_char *tagpnt;
110:
111: /* Check peer status. */
112: if (peer->status != Established)
113: return 0;
114:
115: /* Make prefix_rd */
116: prd.family = AF_UNSPEC;
117: prd.prefixlen = 64;
118:
119: pnt = packet->nlri;
120: lim = pnt + packet->length;
121:
122: #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
123: for (; pnt < lim; pnt += psize)
124: {
125: /* Clear prefix structure. */
126: memset (&p, 0, sizeof (struct prefix));
127:
128: /* Fetch prefix length. */
129: prefixlen = *pnt++;
130: p.family = afi2family (packet->afi);
131: psize = PSIZE (prefixlen);
132:
133: /* sanity check against packet data */
134: if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8)
135: {
136: plog_err (peer->log,
137: "%s [Error] Update packet error / VPNv4"
138: " (prefix length %d less than VPNv4 min length)",
139: peer->host, prefixlen);
140: return -1;
141: }
142: if ((pnt + psize) > lim)
143: {
144: plog_err (peer->log,
145: "%s [Error] Update packet error / VPNv4"
146: " (psize %u exceeds packet size (%u)",
147: peer->host,
148: prefixlen, (uint)(lim-pnt));
149: return -1;
150: }
151:
152: /* sanity check against storage for the IP address portion */
153: if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
154: {
155: plog_err (peer->log,
156: "%s [Error] Update packet error / VPNv4"
157: " (psize %u exceeds storage size (%zu)",
158: peer->host,
159: prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
160: return -1;
161: }
162:
163: /* Sanity check against max bitlen of the address family */
164: if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
165: {
166: plog_err (peer->log,
167: "%s [Error] Update packet error / VPNv4"
168: " (psize %u exceeds family (%u) max byte len %u)",
169: peer->host,
170: prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
171: p.family, prefix_blen (&p));
172: return -1;
173: }
174:
175: /* Copyr label to prefix. */
176: tagpnt = pnt;
177:
178: /* Copy routing distinguisher to rd. */
179: memcpy (&prd.val, pnt + 3, 8);
180:
181: /* Decode RD type. */
182: type = decode_rd_type (pnt + 3);
183:
184: switch (type)
185: {
186: case RD_TYPE_AS:
187: decode_rd_as (pnt + 5, &rd_as);
188: break;
189:
190: case RD_TYPE_AS4:
191: decode_rd_as4 (pnt + 5, &rd_as);
192: break;
193:
194: case RD_TYPE_IP:
195: decode_rd_ip (pnt + 5, &rd_ip);
196: break;
197:
198: default:
199: zlog_err ("Unknown RD type %d", type);
200: break; /* just report */
201: }
202:
203: p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
204: memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
205: psize - VPN_PREFIXLEN_MIN_BYTES);
206:
207: if (attr)
208: bgp_update (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
209: ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
210: else
211: bgp_withdraw (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
212: ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
213: }
214: /* Packet length consistency check. */
215: if (pnt != lim)
216: {
217: plog_err (peer->log,
218: "%s [Error] Update packet error / VPNv4"
219: " (%zu data remaining after parsing)",
220: peer->host, lim - pnt);
221: return -1;
222: }
223:
224: return 0;
225: #undef VPN_PREFIXLEN_MIN_BYTES
226: }
227:
228: int
229: str2prefix_rd (const char *str, struct prefix_rd *prd)
230: {
231: int ret; /* ret of called functions */
232: int lret; /* local ret, of this func */
233: char *p;
234: char *p2;
235: struct stream *s = NULL;
236: char *half = NULL;
237: struct in_addr addr;
238:
239: s = stream_new (8);
240:
241: prd->family = AF_UNSPEC;
242: prd->prefixlen = 64;
243:
244: lret = 0;
245: p = strchr (str, ':');
246: if (! p)
247: goto out;
248:
249: if (! all_digit (p + 1))
250: goto out;
251:
252: half = XMALLOC (MTYPE_TMP, (p - str) + 1);
253: memcpy (half, str, (p - str));
254: half[p - str] = '\0';
255:
256: p2 = strchr (str, '.');
257:
258: if (! p2)
259: {
260: if (! all_digit (half))
261: goto out;
262:
263: stream_putw (s, RD_TYPE_AS);
264: stream_putw (s, atoi (half));
265: stream_putl (s, atol (p + 1));
266: }
267: else
268: {
269: ret = inet_aton (half, &addr);
270: if (! ret)
271: goto out;
272:
273: stream_putw (s, RD_TYPE_IP);
274: stream_put_in_addr (s, &addr);
275: stream_putw (s, atol (p + 1));
276: }
277: memcpy (prd->val, s->data, 8);
278: lret = 1;
279:
280: out:
281: if (s)
282: stream_free (s);
283: if (half)
284: XFREE(MTYPE_TMP, half);
285: return lret;
286: }
287:
288: int
289: str2tag (const char *str, u_char *tag)
290: {
291: unsigned long l;
292: char *endptr;
293: u_int32_t t;
294:
295: if (*str == '-')
296: return 0;
297:
298: errno = 0;
299: l = strtoul (str, &endptr, 10);
300:
301: if (*endptr != '\0' || errno || l > UINT32_MAX)
302: return 0;
303:
304: t = (u_int32_t) l;
305:
306: tag[0] = (u_char)(t >> 12);
307: tag[1] = (u_char)(t >> 4);
308: tag[2] = (u_char)(t << 4);
309:
310: return 1;
311: }
312:
313: char *
314: prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
315: {
316: u_char *pnt;
317: u_int16_t type;
318: struct rd_as rd_as;
319: struct rd_ip rd_ip;
320:
321: if (size < RD_ADDRSTRLEN)
322: return NULL;
323:
324: pnt = prd->val;
325:
326: type = decode_rd_type (pnt);
327:
328: if (type == RD_TYPE_AS)
329: {
330: decode_rd_as (pnt + 2, &rd_as);
331: snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
332: return buf;
333: }
334: else if (type == RD_TYPE_AS4)
335: {
336: decode_rd_as4 (pnt + 2, &rd_as);
337: snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
338: return buf;
339: }
340: else if (type == RD_TYPE_IP)
341: {
342: decode_rd_ip (pnt + 2, &rd_ip);
343: snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
344: return buf;
345: }
346: return NULL;
347: }
348:
349: /* For testing purpose, static route of MPLS-VPN. */
350: DEFUN (vpnv4_network,
351: vpnv4_network_cmd,
352: "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
353: "Specify a network to announce via BGP\n"
354: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
355: "Specify Route Distinguisher\n"
356: "VPN Route Distinguisher\n"
357: "BGP tag\n"
358: "tag value\n")
359: {
360: return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
361: }
362:
363: DEFUN (vpnv4_network_route_map,
364: vpnv4_network_route_map_cmd,
365: "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
366: "Specify a network to announce via BGP\n"
367: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
368: "Specify Route Distinguisher\n"
369: "VPN Route Distinguisher\n"
370: "BGP tag\n"
371: "tag value\n"
372: "route map\n"
373: "route map name\n")
374: {
375: return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
376: }
377:
378: /* For testing purpose, static route of MPLS-VPN. */
379: DEFUN (no_vpnv4_network,
380: no_vpnv4_network_cmd,
381: "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
382: NO_STR
383: "Specify a network to announce via BGP\n"
384: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
385: "Specify Route Distinguisher\n"
386: "VPN Route Distinguisher\n"
387: "BGP tag\n"
388: "tag value\n")
389: {
390: return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
391: }
392:
393: static int
394: show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
395: {
396: struct bgp *bgp;
397: struct bgp_table *table;
398: struct bgp_node *rn;
399: struct bgp_node *rm;
400: struct attr *attr;
401: int rd_header;
402: int header = 1;
403: char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
404:
405: bgp = bgp_get_default ();
406: if (bgp == NULL)
407: {
408: vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
409: return CMD_WARNING;
410: }
411:
412: for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
413: rn = bgp_route_next (rn))
414: {
415: if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
416: continue;
417:
418: if ((table = rn->info) != NULL)
419: {
420: rd_header = 1;
421:
422: for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
423: if ((attr = rm->info) != NULL)
424: {
425: if (header)
426: {
427: vty_out (vty, "BGP table version is 0, local router ID is %s%s",
428: inet_ntoa (bgp->router_id), VTY_NEWLINE);
429: vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
430: VTY_NEWLINE);
431: vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
432: VTY_NEWLINE, VTY_NEWLINE);
433: vty_out (vty, v4_header, VTY_NEWLINE);
434: header = 0;
435: }
436:
437: if (rd_header)
438: {
439: u_int16_t type;
440: struct rd_as rd_as;
441: struct rd_ip rd_ip;
442: u_char *pnt;
443:
444: pnt = rn->p.u.val;
445:
446: /* Decode RD type. */
447: type = decode_rd_type (pnt);
448: /* Decode RD value. */
449: if (type == RD_TYPE_AS)
450: decode_rd_as (pnt + 2, &rd_as);
451: else if (type == RD_TYPE_AS4)
452: decode_rd_as4 (pnt + 2, &rd_as);
453: else if (type == RD_TYPE_IP)
454: decode_rd_ip (pnt + 2, &rd_ip);
455:
456: vty_out (vty, "Route Distinguisher: ");
457:
458: if (type == RD_TYPE_AS)
459: vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
460: else if (type == RD_TYPE_AS4)
461: vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
462: else if (type == RD_TYPE_IP)
463: vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
464:
465: vty_out (vty, "%s", VTY_NEWLINE);
466: rd_header = 0;
467: }
468: route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
469: }
470: }
471: }
472: return CMD_SUCCESS;
473: }
474:
475: enum bgp_show_type
476: {
477: bgp_show_type_normal,
478: bgp_show_type_regexp,
479: bgp_show_type_prefix_list,
480: bgp_show_type_filter_list,
481: bgp_show_type_neighbor,
482: bgp_show_type_cidr_only,
483: bgp_show_type_prefix_longer,
484: bgp_show_type_community_all,
485: bgp_show_type_community,
486: bgp_show_type_community_exact,
487: bgp_show_type_community_list,
488: bgp_show_type_community_list_exact
489: };
490:
491: static int
492: bgp_show_mpls_vpn(
493: struct vty *vty,
494: afi_t afi,
495: struct prefix_rd *prd,
496: enum bgp_show_type type,
497: void *output_arg,
498: int tags)
499: {
500: struct bgp *bgp;
501: struct bgp_table *table;
502: struct bgp_node *rn;
503: struct bgp_node *rm;
504: struct bgp_info *ri;
505: int rd_header;
506: int header = 1;
507: char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
508: char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
509:
510: unsigned long output_count = 0;
511: unsigned long total_count = 0;
512:
513: bgp = bgp_get_default ();
514: if (bgp == NULL)
515: {
516: vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
517: return CMD_WARNING;
518: }
519:
520: if ((afi != AFI_IP) && (afi != AFI_IP6))
521: {
522: vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
523: return CMD_WARNING;
524: }
525:
526: for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
527: {
528: if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
529: continue;
530:
531: if ((table = rn->info) != NULL)
532: {
533: rd_header = 1;
534:
535: for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
536: for (ri = rm->info; ri; ri = ri->next)
537: {
538: total_count++;
539: if (type == bgp_show_type_neighbor)
540: {
541: union sockunion *su = output_arg;
542:
543: if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
544: continue;
545: }
546: if (header)
547: {
548: if (tags)
549: vty_out (vty, v4_header_tag, VTY_NEWLINE);
550: else
551: {
552: vty_out (vty, "BGP table version is 0, local router ID is %s%s",
553: inet_ntoa (bgp->router_id), VTY_NEWLINE);
554: vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
555: VTY_NEWLINE);
556: vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
557: VTY_NEWLINE, VTY_NEWLINE);
558: vty_out (vty, v4_header, VTY_NEWLINE);
559: }
560: header = 0;
561: }
562:
563: if (rd_header)
564: {
565: u_int16_t type;
566: struct rd_as rd_as;
567: struct rd_ip rd_ip;
568: u_char *pnt;
569:
570: pnt = rn->p.u.val;
571:
572: /* Decode RD type. */
573: type = decode_rd_type (pnt);
574: /* Decode RD value. */
575: if (type == RD_TYPE_AS)
576: decode_rd_as (pnt + 2, &rd_as);
577: else if (type == RD_TYPE_AS4)
578: decode_rd_as4 (pnt + 2, &rd_as);
579: else if (type == RD_TYPE_IP)
580: decode_rd_ip (pnt + 2, &rd_ip);
581:
582: vty_out (vty, "Route Distinguisher: ");
583:
584: if (type == RD_TYPE_AS)
585: vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
586: else if (type == RD_TYPE_AS4)
587: vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
588: else if (type == RD_TYPE_IP)
589: vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
590:
591: vty_out (vty, "%s", VTY_NEWLINE);
592: rd_header = 0;
593: }
594: if (tags)
595: route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
596: else
597: route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
598: output_count++;
599: }
600: }
601: }
602:
603: if (output_count == 0)
604: {
605: vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
606: }
607: else
608: vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s",
609: VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
610:
611: return CMD_SUCCESS;
612: }
613:
614: DEFUN (show_bgp_ipv4_vpn,
615: show_bgp_ipv4_vpn_cmd,
616: "show bgp ipv4 vpn",
617: SHOW_STR
618: BGP_STR
619: "Address Family\n"
620: "Display VPN NLRI specific information\n")
621: {
622: return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0);
623: }
624:
625: DEFUN (show_bgp_ipv6_vpn,
626: show_bgp_ipv6_vpn_cmd,
627: "show bgp ipv6 vpn",
628: SHOW_STR
629: BGP_STR
630: "Address Family\n"
631: "Display VPN NLRI specific information\n")
632: {
633: return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0);
634: }
635:
636: DEFUN (show_bgp_ipv4_vpn_rd,
637: show_bgp_ipv4_vpn_rd_cmd,
638: "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn",
639: SHOW_STR
640: BGP_STR
641: "Address Family\n"
642: "Display VPN NLRI specific information\n"
643: "Display information for a route distinguisher\n"
644: "VPN Route Distinguisher\n")
645: {
646: int ret;
647: struct prefix_rd prd;
648:
649: ret = str2prefix_rd (argv[0], &prd);
650: if (! ret)
651: {
652: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
653: return CMD_WARNING;
654: }
655: return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0);
656: }
657:
658: DEFUN (show_bgp_ipv6_vpn_rd,
659: show_bgp_ipv6_vpn_rd_cmd,
660: "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn",
661: SHOW_STR
662: BGP_STR
663: "Address Family\n"
664: "Display VPN NLRI specific information\n"
665: "Display information for a route distinguisher\n"
666: "VPN Route Distinguisher\n")
667: {
668: int ret;
669: struct prefix_rd prd;
670:
671: ret = str2prefix_rd (argv[0], &prd);
672: if (! ret)
673: {
674: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
675: return CMD_WARNING;
676: }
677: return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0);
678: }
679:
680:
681: DEFUN (show_bgp_ipv4_vpn_tags,
682: show_bgp_ipv4_vpn_tags_cmd,
683: "show bgp ipv4 vpn tags",
684: SHOW_STR
685: BGP_STR
686: "Address Family\n"
687: "Display VPN NLRI specific information\n"
688: "Display BGP tags for prefixes\n")
689: {
690: return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 1);
691: }
692: DEFUN (show_bgp_ipv6_vpn_tags,
693: show_bgp_ipv6_vpn_tags_cmd,
694: "show bgp ipv6 vpn tags",
695: SHOW_STR
696: BGP_STR
697: "Address Family\n"
698: "Display VPN NLRI specific information\n"
699: "Display BGP tags for prefixes\n")
700: {
701: return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 1);
702: }
703:
704: DEFUN (show_bgp_ipv4_vpn_rd_tags,
705: show_bgp_ipv4_vpn_rd_tags_cmd,
706: "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn tags",
707: SHOW_STR
708: BGP_STR
709: "Address Family\n"
710: "Display VPN NLRI specific information\n"
711: "Display information for a route distinguisher\n"
712: "VPN Route Distinguisher\n"
713: "Display BGP tags for prefixes\n")
714: {
715: int ret;
716: struct prefix_rd prd;
717:
718: ret = str2prefix_rd (argv[0], &prd);
719: if (! ret)
720: {
721: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
722: return CMD_WARNING;
723: }
724: return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1);
725: }
726: DEFUN (show_bgp_ipv6_vpn_rd_tags,
727: show_bgp_ipv6_vpn_rd_tags_cmd,
728: "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn tags",
729: SHOW_STR
730: BGP_STR
731: "Address Family\n"
732: "Display VPN NLRI specific information\n"
733: "Display information for a route distinguisher\n"
734: "VPN Route Distinguisher\n"
735: "Display BGP tags for prefixes\n")
736: {
737: int ret;
738: struct prefix_rd prd;
739:
740: ret = str2prefix_rd (argv[0], &prd);
741: if (! ret)
742: {
743: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
744: return CMD_WARNING;
745: }
746: return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 1);
747: }
748:
749: DEFUN (show_bgp_ipv4_vpn_neighbor_routes,
750: show_bgp_ipv4_vpn_neighbor_routes_cmd,
751: "show bgp ipv4 vpn neighbors (A.B.C.D|X:X::X:X) routes",
752: SHOW_STR
753: BGP_STR
754: "Address Family\n"
755: "Display VPN NLRI specific information\n"
756: "Detailed information on TCP and BGP neighbor connections\n"
757: "Neighbor to display information about\n"
758: "Neighbor to display information about\n"
759: "Display routes learned from neighbor\n")
760: {
761: union sockunion su;
762: struct peer *peer;
763: int ret;
764:
765: ret = str2sockunion (argv[0], &su);
766: if (ret < 0)
767: {
768: vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
769: return CMD_WARNING;
770: }
771:
772: peer = peer_lookup (NULL, &su);
773: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
774: {
775: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
776: return CMD_WARNING;
777: }
778:
779: return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0);
780: }
781:
782: DEFUN (show_bgp_ipv6_vpn_neighbor_routes,
783: show_bgp_ipv6_vpn_neighbor_routes_cmd,
784: "show bgp ipv6 vpn neighbors (A.B.C.D|X:X::X:X) routes",
785: SHOW_STR
786: BGP_STR
787: "Address Family\n"
788: "Display VPN NLRI specific information\n"
789: "Detailed information on TCP and BGP neighbor connections\n"
790: "Neighbor to display information about\n"
791: "Neighbor to display information about\n"
792: "Display routes learned from neighbor\n")
793: {
794: union sockunion su;
795: struct peer *peer;
796:
797: int ret;
798:
799: ret = str2sockunion (argv[0], &su);
800: if (ret < 0)
801: {
802: vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
803: return CMD_WARNING;
804: }
805:
806: peer = peer_lookup (NULL, &su);
807: if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
808: {
809: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
810: return CMD_WARNING;
811: }
812:
813: return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0);
814: }
815:
816: DEFUN (show_bgp_ipv4_vpn_neighbor_advertised_routes,
817: show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd,
818: "show bgp ipv4 vpn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
819: SHOW_STR
820: BGP_STR
821: "Address Family\n"
822: "Display VPN NLRI specific information\n"
823: "Detailed information on TCP and BGP neighbor connections\n"
824: "Neighbor to display information about\n"
825: "Display the routes advertised to a BGP neighbor\n")
826: {
827: int ret;
828: struct peer *peer;
829: union sockunion su;
830:
831: ret = str2sockunion (argv[0], &su);
832: if (ret < 0)
833: {
834: vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
835: return CMD_WARNING;
836: }
837: peer = peer_lookup (NULL, &su);
838: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
839: {
840: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
841: return CMD_WARNING;
842: }
843:
844: return show_adj_route_vpn (vty, peer, NULL);
845: }
846: DEFUN (show_bgp_ipv6_vpn_neighbor_advertised_routes,
847: show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd,
848: "show bgp ipv6 vpn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
849: SHOW_STR
850: BGP_STR
851: "Address Family\n"
852: "Display VPN NLRI specific information\n"
853: "Detailed information on TCP and BGP neighbor connections\n"
854: "Neighbor to display information about\n"
855: "Display the routes advertised to a BGP neighbor\n")
856: {
857: int ret;
858: struct peer *peer;
859: union sockunion su;
860:
861: ret = str2sockunion (argv[0], &su);
862: if (ret < 0)
863: {
864: vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
865: return CMD_WARNING;
866: }
867: peer = peer_lookup (NULL, &su);
868: if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
869: {
870: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
871: return CMD_WARNING;
872: }
873:
874: return show_adj_route_vpn (vty, peer, NULL);
875: }
876:
877: DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
878: show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd,
879: "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
880: SHOW_STR
881: BGP_STR
882: "Address Family\n"
883: "Display VPN NLRI specific information\n"
884: "Display information for a route distinguisher\n"
885: "VPN Route Distinguisher\n"
886: "Detailed information on TCP and BGP neighbor connections\n"
887: "Neighbor to display information about\n"
888: "Neighbor to display information about\n"
889: "Display the routes advertised to a BGP neighbor\n")
890: {
891: int ret;
892: struct peer *peer;
893: struct prefix_rd prd;
894: union sockunion su;
895: ret = str2sockunion (argv[1], &su);
896: if (ret < 0)
897: {
898: vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
899: return CMD_WARNING;
900: }
901: peer = peer_lookup (NULL, &su);
902: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
903: {
904: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
905: return CMD_WARNING;
906: }
907:
908: ret = str2prefix_rd (argv[0], &prd);
909: if (! ret)
910: {
911: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
912: return CMD_WARNING;
913: }
914:
915: return show_adj_route_vpn (vty, peer, &prd);
916: }
917: DEFUN (show_ip_bgp_vpnv6_rd_neighbor_advertised_routes,
918: show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd,
919: "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
920: SHOW_STR
921: BGP_STR
922: "Address Family\n"
923: "Display VPN NLRI specific information\n"
924: "Display information for a route distinguisher\n"
925: "VPN Route Distinguisher\n"
926: "Detailed information on TCP and BGP neighbor connections\n"
927: "Neighbor to display information about\n"
928: "Neighbor to display information about\n"
929: "Display the routes advertised to a BGP neighbor\n")
930: {
931: int ret;
932: struct peer *peer;
933: struct prefix_rd prd;
934: union sockunion su;
935: ret = str2sockunion (argv[1], &su);
936: if (ret < 0)
937: {
938: vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
939: return CMD_WARNING;
940: }
941: peer = peer_lookup (NULL, &su);
942: if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
943: {
944: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
945: return CMD_WARNING;
946: }
947:
948: ret = str2prefix_rd (argv[0], &prd);
949: if (! ret)
950: {
951: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
952: return CMD_WARNING;
953: }
954:
955: return show_adj_route_vpn (vty, peer, &prd);
956: }
957:
958: DEFUN (show_bgp_ipv4_vpn_rd_neighbor_routes,
959: show_bgp_ipv4_vpn_rd_neighbor_routes_cmd,
960: "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
961: SHOW_STR
962: BGP_STR
963: "Address Family\n"
964: "Address Family modifier\n"
965: "Display information for a route distinguisher\n"
966: "VPN Route Distinguisher\n"
967: "Detailed information on TCP and BGP neighbor connections\n"
968: "Neighbor to display information about\n"
969: "Display routes learned from neighbor\n")
970: {
971: int ret;
972: union sockunion *su;
973: struct peer *peer;
974: struct prefix_rd prd;
975:
976: ret = str2prefix_rd (argv[0], &prd);
977: if (! ret)
978: {
979: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
980: return CMD_WARNING;
981: }
982:
983: su = sockunion_str2su (argv[1]);
984: if (su == NULL)
985: {
986: vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
987: return CMD_WARNING;
988: }
989:
990: peer = peer_lookup (NULL, su);
991: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
992: {
993: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
994: return CMD_WARNING;
995: }
996:
997: return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_neighbor, su, 0);
998: }
999: DEFUN (show_bgp_ipv6_vpn_rd_neighbor_routes,
1000: show_bgp_ipv6_vpn_rd_neighbor_routes_cmd,
1001: "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
1002: SHOW_STR
1003: BGP_STR
1004: "Address Family\n"
1005: "Address Family modifier\n"
1006: "Display information for a route distinguisher\n"
1007: "VPN Route Distinguisher\n"
1008: "Detailed information on TCP and BGP neighbor connections\n"
1009: "Neighbor to display information about\n"
1010: "Display routes learned from neighbor\n")
1011: {
1012: int ret;
1013: union sockunion *su;
1014: struct peer *peer;
1015: struct prefix_rd prd;
1016:
1017: ret = str2prefix_rd (argv[0], &prd);
1018: if (! ret)
1019: {
1020: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1021: return CMD_WARNING;
1022: }
1023:
1024: su = sockunion_str2su (argv[1]);
1025: if (su == NULL)
1026: {
1027: vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
1028: return CMD_WARNING;
1029: }
1030:
1031: peer = peer_lookup (NULL, su);
1032: if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
1033: {
1034: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1035: return CMD_WARNING;
1036: }
1037:
1038: return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_neighbor, su, 0);
1039: }
1040:
1041: void
1042: bgp_mplsvpn_init (void)
1043: {
1044: install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
1045: install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
1046: install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
1047:
1048: install_element (VIEW_NODE, &show_bgp_ipv4_vpn_cmd);
1049: install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_cmd);
1050: install_element (VIEW_NODE, &show_bgp_ipv4_vpn_tags_cmd);
1051: install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_tags_cmd);
1052: install_element (VIEW_NODE, &show_bgp_ipv4_vpn_neighbor_routes_cmd);
1053: install_element (VIEW_NODE, &show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd);
1054: install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd);
1055: install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_neighbor_routes_cmd);
1056:
1057: install_element (VIEW_NODE, &show_bgp_ipv6_vpn_cmd);
1058: install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_cmd);
1059: install_element (VIEW_NODE, &show_bgp_ipv6_vpn_tags_cmd);
1060: install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_tags_cmd);
1061: install_element (VIEW_NODE, &show_bgp_ipv6_vpn_neighbor_routes_cmd);
1062: install_element (VIEW_NODE, &show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd);
1063: install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd);
1064: install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_neighbor_routes_cmd);
1065:
1066: install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_cmd);
1067: install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_cmd);
1068: install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_tags_cmd);
1069: install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_tags_cmd);
1070: install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_neighbor_routes_cmd);
1071: install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd);
1072: install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd);
1073: install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_neighbor_routes_cmd);
1074:
1075: install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_cmd);
1076: install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_cmd);
1077: install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_tags_cmd);
1078: install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_tags_cmd);
1079: install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_neighbor_routes_cmd);
1080: install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd);
1081: install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd);
1082: install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_neighbor_routes_cmd);
1083: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>