File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgp_mplsvpn.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:11 2012 UTC (12 years, 6 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>