File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgp_mplsvpn.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:37 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

    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:   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: 
  605: DEFUN (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: 
  647: DEFUN (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: 
  679: DEFUN (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: 
  720: void
  721: bgp_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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>