1/* MPLS-VPN 2 Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org> 3 4This file is part of GNU Zebra. 5 6GNU Zebra is free software; you can redistribute it and/or modify it 7under the terms of the GNU General Public License as published by the 8Free Software Foundation; either version 2, or (at your option) any 9later version. 10 11GNU Zebra is distributed in the hope that it will be useful, but 12WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GNU Zebra; see the file COPYING. If not, write to the Free 18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 1902111-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 35static u_int16_t 36decode_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 45u_int32_t 46decode_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 56static void 57decode_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 68static void 69decode_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 78int 79bgp_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_int16_t type; 88 struct rd_as rd_as; 89 struct rd_ip rd_ip; 90 struct prefix_rd prd; 91 u_char *tagpnt; 92 93 /* Check peer status. */ 94 if (peer->status != Established) 95 return 0; 96 97 /* Make prefix_rd */ 98 prd.family = AF_UNSPEC; 99 prd.prefixlen = 64; 100 101 pnt = packet->nlri; 102 lim = pnt + packet->length; 103 104 for (; pnt < lim; pnt += psize) 105 { 106 /* Clear prefix structure. */ 107 memset (&p, 0, sizeof (struct prefix)); 108 109 /* Fetch prefix length. */ 110 prefixlen = *pnt++; 111 p.family = AF_INET; 112 psize = PSIZE (prefixlen); 113 114 if (prefixlen < 88) 115 { 116 zlog_err ("prefix length is less than 88: %d", prefixlen); 117 return -1; 118 } 119 120 /* XXX: Not doing anything with the label */ 121 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 173int 174str2prefix_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 229int 230str2tag (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 254char * 255prefix_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. */ 286DEFUN (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. */ 300DEFUN (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 314static int 315show_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 392enum 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 408static int 409bgp_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 502DEFUN (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 514DEFUN (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 536DEFUN (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 549DEFUN (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 572DEFUN (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 int ret; 587 588 ret = str2sockunion (argv[0], &su); 589 if (ret < 0) 590 { 591 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); 592 return CMD_WARNING; 593 } 594 595 peer = peer_lookup (NULL, &su); 596 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) 597 { 598 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); 599 return CMD_WARNING; 600 } 601 602 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0); 603} 604 605DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes, 606 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd, 607 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes", 608 SHOW_STR 609 IP_STR 610 BGP_STR 611 "Display VPNv4 NLRI specific information\n" 612 "Display information for a route distinguisher\n" 613 "VPN Route Distinguisher\n" 614 "Detailed information on TCP and BGP neighbor connections\n" 615 "Neighbor to display information about\n" 616 "Display routes learned from neighbor\n") 617{ 618 int ret; 619 union sockunion su; 620 struct peer *peer; 621 struct prefix_rd prd; 622 623 ret = str2prefix_rd (argv[0], &prd); 624 if (! ret) 625 { 626 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); 627 return CMD_WARNING; 628 } 629 630 ret = str2sockunion (argv[1], &su); 631 if (ret < 0) 632 { 633 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); 634 return CMD_WARNING; 635 } 636 637 peer = peer_lookup (NULL, &su); 638 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) 639 { 640 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); 641 return CMD_WARNING; 642 } 643 644 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0); 645} 646 647DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes, 648 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd, 649 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes", 650 SHOW_STR 651 IP_STR 652 BGP_STR 653 "Display VPNv4 NLRI specific information\n" 654 "Display information about all VPNv4 NLRIs\n" 655 "Detailed information on TCP and BGP neighbor connections\n" 656 "Neighbor to display information about\n" 657 "Display the routes advertised to a BGP neighbor\n") 658{ 659 int ret; 660 struct peer *peer; 661 union sockunion su; 662 663 ret = str2sockunion (argv[0], &su); 664 if (ret < 0) 665 { 666 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE); 667 return CMD_WARNING; 668 } 669 peer = peer_lookup (NULL, &su); 670 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) 671 { 672 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); 673 return CMD_WARNING; 674 } 675 676 return show_adj_route_vpn (vty, peer, NULL); 677} 678 679DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes, 680 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd, 681 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes", 682 SHOW_STR 683 IP_STR 684 BGP_STR 685 "Display VPNv4 NLRI specific information\n" 686 "Display information for a route distinguisher\n" 687 "VPN Route Distinguisher\n" 688 "Detailed information on TCP and BGP neighbor connections\n" 689 "Neighbor to display information about\n" 690 "Display the routes advertised to a BGP neighbor\n") 691{ 692 int ret; 693 struct peer *peer; 694 struct prefix_rd prd; 695 union sockunion su; 696 697 ret = str2sockunion (argv[1], &su); 698 if (ret < 0) 699 { 700 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE); 701 return CMD_WARNING; 702 } 703 peer = peer_lookup (NULL, &su); 704 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) 705 { 706 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); 707 return CMD_WARNING; 708 } 709 710 ret = str2prefix_rd (argv[0], &prd); 711 if (! ret) 712 { 713 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); 714 return CMD_WARNING; 715 } 716 717 return show_adj_route_vpn (vty, peer, &prd); 718} 719 720void 721bgp_mplsvpn_init (void) 722{ 723 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd); 724 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd); 725 726 727 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd); 728 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd); 729 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd); 730 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd); 731 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd); 732 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd); 733 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd); 734 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd); 735 736 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd); 737 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd); 738 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd); 739 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd); 740 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd); 741 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd); 742 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd); 743 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd); 744} 745