bgp_mplsvpn.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:20k
源码类别:

网络

开发平台:

Unix_Linux

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