Annotation of embedaddon/quagga/bgpd/bgp_mplsvpn.c, revision 1.1
1.1 ! misho 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: l = strtoul (str, &endptr, 10);
! 237:
! 238: if (*endptr == '\0' || l == ULONG_MAX || l > UINT32_MAX)
! 239: return 0;
! 240:
! 241: t = (u_int32_t) l;
! 242:
! 243: tag[0] = (u_char)(t >> 12);
! 244: tag[1] = (u_char)(t >> 4);
! 245: tag[2] = (u_char)(t << 4);
! 246:
! 247: return 1;
! 248: }
! 249:
! 250: char *
! 251: prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
! 252: {
! 253: u_char *pnt;
! 254: u_int16_t type;
! 255: struct rd_as rd_as;
! 256: struct rd_ip rd_ip;
! 257:
! 258: if (size < RD_ADDRSTRLEN)
! 259: return NULL;
! 260:
! 261: pnt = prd->val;
! 262:
! 263: type = decode_rd_type (pnt);
! 264:
! 265: if (type == RD_TYPE_AS)
! 266: {
! 267: decode_rd_as (pnt + 2, &rd_as);
! 268: snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
! 269: return buf;
! 270: }
! 271: else if (type == RD_TYPE_IP)
! 272: {
! 273: decode_rd_ip (pnt + 2, &rd_ip);
! 274: snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
! 275: return buf;
! 276: }
! 277:
! 278: return NULL;
! 279: }
! 280:
! 281: /* For testing purpose, static route of MPLS-VPN. */
! 282: DEFUN (vpnv4_network,
! 283: vpnv4_network_cmd,
! 284: "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
! 285: "Specify a network to announce via BGP\n"
! 286: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
! 287: "Specify Route Distinguisher\n"
! 288: "VPN Route Distinguisher\n"
! 289: "BGP tag\n"
! 290: "tag value\n")
! 291: {
! 292: return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
! 293: }
! 294:
! 295: /* For testing purpose, static route of MPLS-VPN. */
! 296: DEFUN (no_vpnv4_network,
! 297: no_vpnv4_network_cmd,
! 298: "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
! 299: NO_STR
! 300: "Specify a network to announce via BGP\n"
! 301: "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
! 302: "Specify Route Distinguisher\n"
! 303: "VPN Route Distinguisher\n"
! 304: "BGP tag\n"
! 305: "tag value\n")
! 306: {
! 307: return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
! 308: }
! 309:
! 310: static int
! 311: show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
! 312: {
! 313: struct bgp *bgp;
! 314: struct bgp_table *table;
! 315: struct bgp_node *rn;
! 316: struct bgp_node *rm;
! 317: struct attr *attr;
! 318: int rd_header;
! 319: int header = 1;
! 320: char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
! 321:
! 322: bgp = bgp_get_default ();
! 323: if (bgp == NULL)
! 324: {
! 325: vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
! 326: return CMD_WARNING;
! 327: }
! 328:
! 329: for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
! 330: rn = bgp_route_next (rn))
! 331: {
! 332: if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
! 333: continue;
! 334:
! 335: if ((table = rn->info) != NULL)
! 336: {
! 337: rd_header = 1;
! 338:
! 339: for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
! 340: if ((attr = rm->info) != NULL)
! 341: {
! 342: if (header)
! 343: {
! 344: vty_out (vty, "BGP table version is 0, local router ID is %s%s",
! 345: inet_ntoa (bgp->router_id), VTY_NEWLINE);
! 346: vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
! 347: VTY_NEWLINE);
! 348: vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
! 349: VTY_NEWLINE, VTY_NEWLINE);
! 350: vty_out (vty, v4_header, VTY_NEWLINE);
! 351: header = 0;
! 352: }
! 353:
! 354: if (rd_header)
! 355: {
! 356: u_int16_t type;
! 357: struct rd_as rd_as;
! 358: struct rd_ip rd_ip;
! 359: u_char *pnt;
! 360:
! 361: pnt = rn->p.u.val;
! 362:
! 363: /* Decode RD type. */
! 364: type = decode_rd_type (pnt);
! 365: /* Decode RD value. */
! 366: if (type == RD_TYPE_AS)
! 367: decode_rd_as (pnt + 2, &rd_as);
! 368: else if (type == RD_TYPE_IP)
! 369: decode_rd_ip (pnt + 2, &rd_ip);
! 370:
! 371: vty_out (vty, "Route Distinguisher: ");
! 372:
! 373: if (type == RD_TYPE_AS)
! 374: vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
! 375: else if (type == RD_TYPE_IP)
! 376: vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
! 377:
! 378: vty_out (vty, "%s", VTY_NEWLINE);
! 379: rd_header = 0;
! 380: }
! 381: route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
! 382: }
! 383: }
! 384: }
! 385: return CMD_SUCCESS;
! 386: }
! 387:
! 388: enum bgp_show_type
! 389: {
! 390: bgp_show_type_normal,
! 391: bgp_show_type_regexp,
! 392: bgp_show_type_prefix_list,
! 393: bgp_show_type_filter_list,
! 394: bgp_show_type_neighbor,
! 395: bgp_show_type_cidr_only,
! 396: bgp_show_type_prefix_longer,
! 397: bgp_show_type_community_all,
! 398: bgp_show_type_community,
! 399: bgp_show_type_community_exact,
! 400: bgp_show_type_community_list,
! 401: bgp_show_type_community_list_exact
! 402: };
! 403:
! 404: static int
! 405: bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
! 406: void *output_arg, int tags)
! 407: {
! 408: struct bgp *bgp;
! 409: struct bgp_table *table;
! 410: struct bgp_node *rn;
! 411: struct bgp_node *rm;
! 412: struct bgp_info *ri;
! 413: int rd_header;
! 414: int header = 1;
! 415: char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
! 416: char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
! 417:
! 418: bgp = bgp_get_default ();
! 419: if (bgp == NULL)
! 420: {
! 421: vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
! 422: return CMD_WARNING;
! 423: }
! 424:
! 425: for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
! 426: {
! 427: if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
! 428: continue;
! 429:
! 430: if ((table = rn->info) != NULL)
! 431: {
! 432: rd_header = 1;
! 433:
! 434: for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
! 435: for (ri = rm->info; ri; ri = ri->next)
! 436: {
! 437: if (type == bgp_show_type_neighbor)
! 438: {
! 439: union sockunion *su = output_arg;
! 440:
! 441: if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
! 442: continue;
! 443: }
! 444: if (header)
! 445: {
! 446: if (tags)
! 447: vty_out (vty, v4_header_tag, VTY_NEWLINE);
! 448: else
! 449: {
! 450: vty_out (vty, "BGP table version is 0, local router ID is %s%s",
! 451: inet_ntoa (bgp->router_id), VTY_NEWLINE);
! 452: vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
! 453: VTY_NEWLINE);
! 454: vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
! 455: VTY_NEWLINE, VTY_NEWLINE);
! 456: vty_out (vty, v4_header, VTY_NEWLINE);
! 457: }
! 458: header = 0;
! 459: }
! 460:
! 461: if (rd_header)
! 462: {
! 463: u_int16_t type;
! 464: struct rd_as rd_as;
! 465: struct rd_ip rd_ip;
! 466: u_char *pnt;
! 467:
! 468: pnt = rn->p.u.val;
! 469:
! 470: /* Decode RD type. */
! 471: type = decode_rd_type (pnt);
! 472: /* Decode RD value. */
! 473: if (type == RD_TYPE_AS)
! 474: decode_rd_as (pnt + 2, &rd_as);
! 475: else if (type == RD_TYPE_IP)
! 476: decode_rd_ip (pnt + 2, &rd_ip);
! 477:
! 478: vty_out (vty, "Route Distinguisher: ");
! 479:
! 480: if (type == RD_TYPE_AS)
! 481: vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
! 482: else if (type == RD_TYPE_IP)
! 483: vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
! 484:
! 485: vty_out (vty, "%s", VTY_NEWLINE);
! 486: rd_header = 0;
! 487: }
! 488: if (tags)
! 489: route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
! 490: else
! 491: route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
! 492: }
! 493: }
! 494: }
! 495: return CMD_SUCCESS;
! 496: }
! 497:
! 498: DEFUN (show_ip_bgp_vpnv4_all,
! 499: show_ip_bgp_vpnv4_all_cmd,
! 500: "show ip bgp vpnv4 all",
! 501: SHOW_STR
! 502: IP_STR
! 503: BGP_STR
! 504: "Display VPNv4 NLRI specific information\n"
! 505: "Display information about all VPNv4 NLRIs\n")
! 506: {
! 507: return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
! 508: }
! 509:
! 510: DEFUN (show_ip_bgp_vpnv4_rd,
! 511: show_ip_bgp_vpnv4_rd_cmd,
! 512: "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
! 513: SHOW_STR
! 514: IP_STR
! 515: BGP_STR
! 516: "Display VPNv4 NLRI specific information\n"
! 517: "Display information for a route distinguisher\n"
! 518: "VPN Route Distinguisher\n")
! 519: {
! 520: int ret;
! 521: struct prefix_rd prd;
! 522:
! 523: ret = str2prefix_rd (argv[0], &prd);
! 524: if (! ret)
! 525: {
! 526: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
! 527: return CMD_WARNING;
! 528: }
! 529: return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
! 530: }
! 531:
! 532: DEFUN (show_ip_bgp_vpnv4_all_tags,
! 533: show_ip_bgp_vpnv4_all_tags_cmd,
! 534: "show ip bgp vpnv4 all tags",
! 535: SHOW_STR
! 536: IP_STR
! 537: BGP_STR
! 538: "Display VPNv4 NLRI specific information\n"
! 539: "Display information about all VPNv4 NLRIs\n"
! 540: "Display BGP tags for prefixes\n")
! 541: {
! 542: return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
! 543: }
! 544:
! 545: DEFUN (show_ip_bgp_vpnv4_rd_tags,
! 546: show_ip_bgp_vpnv4_rd_tags_cmd,
! 547: "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
! 548: SHOW_STR
! 549: IP_STR
! 550: BGP_STR
! 551: "Display VPNv4 NLRI specific information\n"
! 552: "Display information for a route distinguisher\n"
! 553: "VPN Route Distinguisher\n"
! 554: "Display BGP tags for prefixes\n")
! 555: {
! 556: int ret;
! 557: struct prefix_rd prd;
! 558:
! 559: ret = str2prefix_rd (argv[0], &prd);
! 560: if (! ret)
! 561: {
! 562: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
! 563: return CMD_WARNING;
! 564: }
! 565: return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
! 566: }
! 567:
! 568: DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
! 569: show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
! 570: "show ip bgp vpnv4 all neighbors A.B.C.D routes",
! 571: SHOW_STR
! 572: IP_STR
! 573: BGP_STR
! 574: "Display VPNv4 NLRI specific information\n"
! 575: "Display information about all VPNv4 NLRIs\n"
! 576: "Detailed information on TCP and BGP neighbor connections\n"
! 577: "Neighbor to display information about\n"
! 578: "Display routes learned from neighbor\n")
! 579: {
! 580: union sockunion *su;
! 581: struct peer *peer;
! 582:
! 583: su = sockunion_str2su (argv[0]);
! 584: if (su == NULL)
! 585: {
! 586: vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
! 587: return CMD_WARNING;
! 588: }
! 589:
! 590: peer = peer_lookup (NULL, su);
! 591: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
! 592: {
! 593: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
! 594: return CMD_WARNING;
! 595: }
! 596:
! 597: return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, su, 0);
! 598: }
! 599:
! 600: DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
! 601: show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
! 602: "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
! 603: SHOW_STR
! 604: IP_STR
! 605: BGP_STR
! 606: "Display VPNv4 NLRI specific information\n"
! 607: "Display information for a route distinguisher\n"
! 608: "VPN Route Distinguisher\n"
! 609: "Detailed information on TCP and BGP neighbor connections\n"
! 610: "Neighbor to display information about\n"
! 611: "Display routes learned from neighbor\n")
! 612: {
! 613: int ret;
! 614: union sockunion *su;
! 615: struct peer *peer;
! 616: struct prefix_rd prd;
! 617:
! 618: ret = str2prefix_rd (argv[0], &prd);
! 619: if (! ret)
! 620: {
! 621: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
! 622: return CMD_WARNING;
! 623: }
! 624:
! 625: su = sockunion_str2su (argv[1]);
! 626: if (su == NULL)
! 627: {
! 628: vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
! 629: return CMD_WARNING;
! 630: }
! 631:
! 632: peer = peer_lookup (NULL, su);
! 633: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
! 634: {
! 635: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
! 636: return CMD_WARNING;
! 637: }
! 638:
! 639: return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, su, 0);
! 640: }
! 641:
! 642: DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
! 643: show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
! 644: "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
! 645: SHOW_STR
! 646: IP_STR
! 647: BGP_STR
! 648: "Display VPNv4 NLRI specific information\n"
! 649: "Display information about all VPNv4 NLRIs\n"
! 650: "Detailed information on TCP and BGP neighbor connections\n"
! 651: "Neighbor to display information about\n"
! 652: "Display the routes advertised to a BGP neighbor\n")
! 653: {
! 654: int ret;
! 655: struct peer *peer;
! 656: union sockunion su;
! 657:
! 658: ret = str2sockunion (argv[0], &su);
! 659: if (ret < 0)
! 660: {
! 661: vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
! 662: return CMD_WARNING;
! 663: }
! 664: peer = peer_lookup (NULL, &su);
! 665: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
! 666: {
! 667: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
! 668: return CMD_WARNING;
! 669: }
! 670:
! 671: return show_adj_route_vpn (vty, peer, NULL);
! 672: }
! 673:
! 674: DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
! 675: show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
! 676: "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
! 677: SHOW_STR
! 678: IP_STR
! 679: BGP_STR
! 680: "Display VPNv4 NLRI specific information\n"
! 681: "Display information for a route distinguisher\n"
! 682: "VPN Route Distinguisher\n"
! 683: "Detailed information on TCP and BGP neighbor connections\n"
! 684: "Neighbor to display information about\n"
! 685: "Display the routes advertised to a BGP neighbor\n")
! 686: {
! 687: int ret;
! 688: struct peer *peer;
! 689: struct prefix_rd prd;
! 690: union sockunion su;
! 691:
! 692: ret = str2sockunion (argv[1], &su);
! 693: if (ret < 0)
! 694: {
! 695: vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
! 696: return CMD_WARNING;
! 697: }
! 698: peer = peer_lookup (NULL, &su);
! 699: if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
! 700: {
! 701: vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
! 702: return CMD_WARNING;
! 703: }
! 704:
! 705: ret = str2prefix_rd (argv[0], &prd);
! 706: if (! ret)
! 707: {
! 708: vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
! 709: return CMD_WARNING;
! 710: }
! 711:
! 712: return show_adj_route_vpn (vty, peer, &prd);
! 713: }
! 714:
! 715: void
! 716: bgp_mplsvpn_init (void)
! 717: {
! 718: install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
! 719: install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
! 720:
! 721:
! 722: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
! 723: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
! 724: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
! 725: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
! 726: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
! 727: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
! 728: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
! 729: install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
! 730:
! 731: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
! 732: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
! 733: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
! 734: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
! 735: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
! 736: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
! 737: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
! 738: install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
! 739: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>