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:
29: #include "bgpd/bgpd.h"
30: #include "bgpd/bgp_table.h"
31: #include "bgpd/bgp_route.h"
32: #include "bgpd/bgp_attr.h"
33: #include "bgpd/bgp_mplsvpn.h"
34:
35: static u_int16_t
36: decode_rd_type (u_char *pnt)
37: {
38: u_int16_t v;
39:
40: v = ((u_int16_t) *pnt++ << 8);
41: v |= (u_int16_t) *pnt;
42: return v;
43: }
44:
45: u_int32_t
46: decode_label (u_char *pnt)
47: {
48: u_int32_t l;
49:
50: l = ((u_int32_t) *pnt++ << 12);
51: l |= (u_int32_t) *pnt++ << 4;
52: l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
53: return l;
54: }
55:
56: static void
57: decode_rd_as (u_char *pnt, struct rd_as *rd_as)
58: {
59: rd_as->as = (u_int16_t) *pnt++ << 8;
60: rd_as->as |= (u_int16_t) *pnt++;
61:
62: rd_as->val = ((u_int32_t) *pnt++ << 24);
63: rd_as->val |= ((u_int32_t) *pnt++ << 16);
64: rd_as->val |= ((u_int32_t) *pnt++ << 8);
65: rd_as->val |= (u_int32_t) *pnt;
66: }
67:
68: static void
69: decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
70: {
71: memcpy (&rd_ip->ip, pnt, 4);
72: pnt += 4;
73:
74: rd_ip->val = ((u_int16_t) *pnt++ << 8);
75: rd_ip->val |= (u_int16_t) *pnt;
76: }
77:
78: int
79: bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
80: struct bgp_nlri *packet)
81: {
82: u_char *pnt;
83: u_char *lim;
84: struct prefix p;
85: int psize;
86: int prefixlen;
87: u_int32_t label;
88: u_int16_t type;
89: struct rd_as rd_as;
90: struct rd_ip rd_ip;
91: struct prefix_rd prd;
92: u_char *tagpnt;
93:
94: /* Check peer status. */
95: if (peer->status != Established)
96: return 0;
97:
98: /* Make prefix_rd */
99: prd.family = AF_UNSPEC;
100: prd.prefixlen = 64;
101:
102: pnt = packet->nlri;
103: lim = pnt + packet->length;
104:
105: for (; pnt < lim; pnt += psize)
106: {
107: /* Clear prefix structure. */
108: memset (&p, 0, sizeof (struct prefix));
109:
110: /* Fetch prefix length. */
111: prefixlen = *pnt++;
112: p.family = AF_INET;
113: psize = PSIZE (prefixlen);
114:
115: if (prefixlen < 88)
116: {
117: zlog_err ("prefix length is less than 88: %d", prefixlen);
118: return -1;
119: }
120:
121: label = decode_label (pnt);
122:
123: /* Copyr label to prefix. */
124: tagpnt = pnt;;
125:
126: /* Copy routing distinguisher to rd. */
127: memcpy (&prd.val, pnt + 3, 8);
128:
129: /* Decode RD type. */
130: type = decode_rd_type (pnt + 3);
131:
132: /* Decode RD value. */
133: if (type == RD_TYPE_AS)
134: decode_rd_as (pnt + 5, &rd_as);
135: else if (type == RD_TYPE_IP)
136: decode_rd_ip (pnt + 5, &rd_ip);
137: else
138: {
139: zlog_err ("Invalid RD type %d", type);
140: return -1;
141: }
142:
143: p.prefixlen = prefixlen - 88;
144: memcpy (&p.u.prefix, pnt + 11, psize - 11);
145:
146: #if 0
147: if (type == RD_TYPE_AS)
148: zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
149: inet_ntoa (p.u.prefix4), p.prefixlen);
150: else if (type == RD_TYPE_IP)
151: zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
152: rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
153: #endif /* 0 */
154:
155: if (pnt + psize > lim)
156: return -1;
157:
158: if (attr)
159: bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
160: ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
161: else
162: bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
163: ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
164: }
165:
166: /* Packet length consistency check. */
167: if (pnt != lim)
168: return -1;
169:
170: return 0;
171: }
172:
173: int
174: str2prefix_rd (const char *str, struct prefix_rd *prd)
175: {
176: int ret;
177: char *p;
178: char *p2;
179: struct stream *s;
180: char *half;
181: struct in_addr addr;
182:
183: s = stream_new (8);
184:
185: prd->family = AF_UNSPEC;
186: prd->prefixlen = 64;
187:
188: p = strchr (str, ':');
189: if (! p)
190: return 0;
191:
192: if (! all_digit (p + 1))
193: return 0;
194:
195: half = XMALLOC (MTYPE_TMP, (p - str) + 1);
196: memcpy (half, str, (p - str));
197: half[p - str] = '\0';
198:
199: p2 = strchr (str, '.');
200:
201: if (! p2)
202: {
203: if (! all_digit (half))
204: {
205: XFREE (MTYPE_TMP, half);
206: return 0;
207: }
208: stream_putw (s, RD_TYPE_AS);
209: stream_putw (s, atoi (half));
210: stream_putl (s, atol (p + 1));
211: }
212: else
213: {
214: ret = inet_aton (half, &addr);
215: if (! ret)
216: {
217: XFREE (MTYPE_TMP, half);
218: return 0;
219: }
220: stream_putw (s, RD_TYPE_IP);
221: stream_put_in_addr (s, &addr);
222: stream_putw (s, atol (p + 1));
223: }
224: memcpy (prd->val, s->data, 8);
225:
226: return 1;
227: }
228:
229: int
230: str2tag (const char *str, u_char *tag)
231: {
232: unsigned long l;
233: char *endptr;
234: u_int32_t t;
235:
236: if (*str == '-')
237: return 0;
238:
239: errno = 0;
240: l = strtoul (str, &endptr, 10);
241:
242: if (*endptr != '\0' || errno || l > UINT32_MAX)
243: return 0;
244:
245: t = (u_int32_t) l;
246:
247: tag[0] = (u_char)(t >> 12);
248: tag[1] = (u_char)(t >> 4);
249: tag[2] = (u_char)(t << 4);
250:
251: return 1;
252: }
253:
254: char *
255: prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
256: {
257: u_char *pnt;
258: u_int16_t type;
259: struct rd_as rd_as;
260: struct rd_ip rd_ip;
261:
262: if (size < RD_ADDRSTRLEN)
263: return NULL;
264:
265: pnt = prd->val;
266:
267: type = decode_rd_type (pnt);
268:
269: if (type == RD_TYPE_AS)
270: {
271: decode_rd_as (pnt + 2, &rd_as);
272: snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
273: return buf;
274: }
275: else if (type == RD_TYPE_IP)
276: {
277: decode_rd_ip (pnt + 2, &rd_ip);
278: snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
279: return buf;
280: }
281:
282: return NULL;
283: }
284:
285: /* For testing purpose, static route of MPLS-VPN. */
286: DEFUN (vpnv4_network,
287: vpnv4_network_cmd,
288: "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
289: "Specify a network to announce via BGP\n"
290: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
291: "Specify Route Distinguisher\n"
292: "VPN Route Distinguisher\n"
293: "BGP tag\n"
294: "tag value\n")
295: {
296: return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
297: }
298:
299: /* For testing purpose, static route of MPLS-VPN. */
300: DEFUN (no_vpnv4_network,
301: no_vpnv4_network_cmd,
302: "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
303: NO_STR
304: "Specify a network to announce via BGP\n"
305: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
306: "Specify Route Distinguisher\n"
307: "VPN Route Distinguisher\n"
308: "BGP tag\n"
309: "tag value\n")
310: {
311: return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
312: }
313:
314: static int
315: show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
316: {
317: struct bgp *bgp;
318: struct bgp_table *table;
319: struct bgp_node *rn;
320: struct bgp_node *rm;
321: struct attr *attr;
322: int rd_header;
323: int header = 1;
324: char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
325:
326: bgp = bgp_get_default ();
327: if (bgp == NULL)
328: {
329: vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
330: return CMD_WARNING;
331: }
332:
333: for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
334: rn = bgp_route_next (rn))
335: {
336: if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
337: continue;
338:
339: if ((table = rn->info) != NULL)
340: {
341: rd_header = 1;
342:
343: for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
344: if ((attr = rm->info) != NULL)
345: {
346: if (header)
347: {
348: vty_out (vty, "BGP table version is 0, local router ID is %s%s",
349: inet_ntoa (bgp->router_id), VTY_NEWLINE);
350: vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
351: VTY_NEWLINE);
352: vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
353: VTY_NEWLINE, VTY_NEWLINE);
354: vty_out (vty, v4_header, VTY_NEWLINE);
355: header = 0;
356: }
357:
358: if (rd_header)
359: {
360: u_int16_t type;
361: struct rd_as rd_as;
362: struct rd_ip rd_ip;
363: u_char *pnt;
364:
365: pnt = rn->p.u.val;
366:
367: /* Decode RD type. */
368: type = decode_rd_type (pnt);
369: /* Decode RD value. */
370: if (type == RD_TYPE_AS)
371: decode_rd_as (pnt + 2, &rd_as);
372: else if (type == RD_TYPE_IP)
373: decode_rd_ip (pnt + 2, &rd_ip);
374:
375: vty_out (vty, "Route Distinguisher: ");
376:
377: if (type == RD_TYPE_AS)
378: vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
379: else if (type == RD_TYPE_IP)
380: vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
381:
382: vty_out (vty, "%s", VTY_NEWLINE);
383: rd_header = 0;
384: }
385: route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
386: }
387: }
388: }
389: return CMD_SUCCESS;
390: }
391:
392: enum bgp_show_type
393: {
394: bgp_show_type_normal,
395: bgp_show_type_regexp,
396: bgp_show_type_prefix_list,
397: bgp_show_type_filter_list,
398: bgp_show_type_neighbor,
399: bgp_show_type_cidr_only,
400: bgp_show_type_prefix_longer,
401: bgp_show_type_community_all,
402: bgp_show_type_community,
403: bgp_show_type_community_exact,
404: bgp_show_type_community_list,
405: bgp_show_type_community_list_exact
406: };
407:
408: static int
409: bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
410: void *output_arg, int tags)
411: {
412: struct bgp *bgp;
413: struct bgp_table *table;
414: struct bgp_node *rn;
415: struct bgp_node *rm;
416: struct bgp_info *ri;
417: int rd_header;
418: int header = 1;
419: char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
420: char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
421:
422: bgp = bgp_get_default ();
423: if (bgp == NULL)
424: {
425: vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
426: return CMD_WARNING;
427: }
428:
429: for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
430: {
431: if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
432: continue;
433:
434: if ((table = rn->info) != NULL)
435: {
436: rd_header = 1;
437:
438: for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
439: for (ri = rm->info; ri; ri = ri->next)
440: {
441: if (type == bgp_show_type_neighbor)
442: {
443: union sockunion *su = output_arg;
444:
445: if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
446: continue;
447: }
448: if (header)
449: {
450: if (tags)
451: vty_out (vty, v4_header_tag, VTY_NEWLINE);
452: else
453: {
454: vty_out (vty, "BGP table version is 0, local router ID is %s%s",
455: inet_ntoa (bgp->router_id), VTY_NEWLINE);
456: vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
457: VTY_NEWLINE);
458: vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
459: VTY_NEWLINE, VTY_NEWLINE);
460: vty_out (vty, v4_header, VTY_NEWLINE);
461: }
462: header = 0;
463: }
464:
465: if (rd_header)
466: {
467: u_int16_t type;
468: struct rd_as rd_as;
469: struct rd_ip rd_ip;
470: u_char *pnt;
471:
472: pnt = rn->p.u.val;
473:
474: /* Decode RD type. */
475: type = decode_rd_type (pnt);
476: /* Decode RD value. */
477: if (type == RD_TYPE_AS)
478: decode_rd_as (pnt + 2, &rd_as);
479: else if (type == RD_TYPE_IP)
480: decode_rd_ip (pnt + 2, &rd_ip);
481:
482: vty_out (vty, "Route Distinguisher: ");
483:
484: if (type == RD_TYPE_AS)
485: vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
486: else if (type == RD_TYPE_IP)
487: vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
488:
489: vty_out (vty, "%s", VTY_NEWLINE);
490: rd_header = 0;
491: }
492: if (tags)
493: route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
494: else
495: route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
496: }
497: }
498: }
499: return CMD_SUCCESS;
500: }
501:
502: DEFUN (show_ip_bgp_vpnv4_all,
503: show_ip_bgp_vpnv4_all_cmd,
504: "show ip bgp vpnv4 all",
505: SHOW_STR
506: IP_STR
507: BGP_STR
508: "Display VPNv4 NLRI specific information\n"
509: "Display information about all VPNv4 NLRIs\n")
510: {
511: return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
512: }
513:
514: DEFUN (show_ip_bgp_vpnv4_rd,
515: show_ip_bgp_vpnv4_rd_cmd,
516: "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
517: SHOW_STR
518: IP_STR
519: BGP_STR
520: "Display VPNv4 NLRI specific information\n"
521: "Display information for a route distinguisher\n"
522: "VPN Route Distinguisher\n")
523: {
524: int ret;
525: struct prefix_rd prd;
526:
527: ret = str2prefix_rd (argv[0], &prd);
528: if (! ret)
529: {
530: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
531: return CMD_WARNING;
532: }
533: return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
534: }
535:
536: DEFUN (show_ip_bgp_vpnv4_all_tags,
537: show_ip_bgp_vpnv4_all_tags_cmd,
538: "show ip bgp vpnv4 all tags",
539: SHOW_STR
540: IP_STR
541: BGP_STR
542: "Display VPNv4 NLRI specific information\n"
543: "Display information about all VPNv4 NLRIs\n"
544: "Display BGP tags for prefixes\n")
545: {
546: return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
547: }
548:
549: DEFUN (show_ip_bgp_vpnv4_rd_tags,
550: show_ip_bgp_vpnv4_rd_tags_cmd,
551: "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
552: SHOW_STR
553: IP_STR
554: BGP_STR
555: "Display VPNv4 NLRI specific information\n"
556: "Display information for a route distinguisher\n"
557: "VPN Route Distinguisher\n"
558: "Display BGP tags for prefixes\n")
559: {
560: int ret;
561: struct prefix_rd prd;
562:
563: ret = str2prefix_rd (argv[0], &prd);
564: if (! ret)
565: {
566: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
567: return CMD_WARNING;
568: }
569: return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
570: }
571:
572: DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
573: show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
574: "show ip bgp vpnv4 all neighbors A.B.C.D routes",
575: SHOW_STR
576: IP_STR
577: BGP_STR
578: "Display VPNv4 NLRI specific information\n"
579: "Display information about all VPNv4 NLRIs\n"
580: "Detailed information on TCP and BGP neighbor connections\n"
581: "Neighbor to display information about\n"
582: "Display routes learned from neighbor\n")
583: {
584: union sockunion *su;
585: struct peer *peer;
586:
587: su = sockunion_str2su (argv[0]);
588: if (su == NULL)
589: {
590: vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
591: return CMD_WARNING;
592: }
593:
594: peer = peer_lookup (NULL, su);
595: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
596: {
597: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
598: return CMD_WARNING;
599: }
600:
601: return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, su, 0);
602: }
603:
604: DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
605: show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
606: "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
607: SHOW_STR
608: IP_STR
609: BGP_STR
610: "Display VPNv4 NLRI specific information\n"
611: "Display information for a route distinguisher\n"
612: "VPN Route Distinguisher\n"
613: "Detailed information on TCP and BGP neighbor connections\n"
614: "Neighbor to display information about\n"
615: "Display routes learned from neighbor\n")
616: {
617: int ret;
618: union sockunion *su;
619: struct peer *peer;
620: struct prefix_rd prd;
621:
622: ret = str2prefix_rd (argv[0], &prd);
623: if (! ret)
624: {
625: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
626: return CMD_WARNING;
627: }
628:
629: su = sockunion_str2su (argv[1]);
630: if (su == NULL)
631: {
632: vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
633: return CMD_WARNING;
634: }
635:
636: peer = peer_lookup (NULL, su);
637: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
638: {
639: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
640: return CMD_WARNING;
641: }
642:
643: return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, su, 0);
644: }
645:
646: DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
647: show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
648: "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
649: SHOW_STR
650: IP_STR
651: BGP_STR
652: "Display VPNv4 NLRI specific information\n"
653: "Display information about all VPNv4 NLRIs\n"
654: "Detailed information on TCP and BGP neighbor connections\n"
655: "Neighbor to display information about\n"
656: "Display the routes advertised to a BGP neighbor\n")
657: {
658: int ret;
659: struct peer *peer;
660: union sockunion su;
661:
662: ret = str2sockunion (argv[0], &su);
663: if (ret < 0)
664: {
665: vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
666: return CMD_WARNING;
667: }
668: peer = peer_lookup (NULL, &su);
669: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
670: {
671: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
672: return CMD_WARNING;
673: }
674:
675: return show_adj_route_vpn (vty, peer, NULL);
676: }
677:
678: DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
679: show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
680: "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
681: SHOW_STR
682: IP_STR
683: BGP_STR
684: "Display VPNv4 NLRI specific information\n"
685: "Display information for a route distinguisher\n"
686: "VPN Route Distinguisher\n"
687: "Detailed information on TCP and BGP neighbor connections\n"
688: "Neighbor to display information about\n"
689: "Display the routes advertised to a BGP neighbor\n")
690: {
691: int ret;
692: struct peer *peer;
693: struct prefix_rd prd;
694: union sockunion su;
695:
696: ret = str2sockunion (argv[1], &su);
697: if (ret < 0)
698: {
699: vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
700: return CMD_WARNING;
701: }
702: peer = peer_lookup (NULL, &su);
703: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
704: {
705: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
706: return CMD_WARNING;
707: }
708:
709: ret = str2prefix_rd (argv[0], &prd);
710: if (! ret)
711: {
712: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
713: return CMD_WARNING;
714: }
715:
716: return show_adj_route_vpn (vty, peer, &prd);
717: }
718:
719: void
720: bgp_mplsvpn_init (void)
721: {
722: install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
723: install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
724:
725:
726: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
727: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
728: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
729: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
730: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
731: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
732: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
733: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
734:
735: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
736: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
737: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
738: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
739: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
740: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
741: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
742: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
743: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>