File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgp_mplsvpn.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 7 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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: #include "filter.h"
   29: 
   30: #include "bgpd/bgpd.h"
   31: #include "bgpd/bgp_table.h"
   32: #include "bgpd/bgp_route.h"
   33: #include "bgpd/bgp_packet.h"
   34: #include "bgpd/bgp_attr.h"
   35: #include "bgpd/bgp_mplsvpn.h"
   36: #include "bgpd/bgp_packet.h"
   37: 
   38: static u_int16_t
   39: decode_rd_type (u_char *pnt)
   40: {
   41:   u_int16_t v;
   42:   
   43:   v = ((u_int16_t) *pnt++ << 8);
   44:   v |= (u_int16_t) *pnt;
   45:   return v;
   46: }
   47: 
   48: u_int32_t
   49: decode_label (u_char *pnt)
   50: {
   51:   u_int32_t l;
   52: 
   53:   l = ((u_int32_t) *pnt++ << 12);
   54:   l |= (u_int32_t) *pnt++ << 4;
   55:   l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
   56:   return l;
   57: }
   58: 
   59: /* type == RD_TYPE_AS */
   60: static void
   61: decode_rd_as (u_char *pnt, struct rd_as *rd_as)
   62: {
   63:   rd_as->as = (u_int16_t) *pnt++ << 8;
   64:   rd_as->as |= (u_int16_t) *pnt++;
   65:   
   66:   rd_as->val = ((u_int32_t) *pnt++ << 24);
   67:   rd_as->val |= ((u_int32_t) *pnt++ << 16);
   68:   rd_as->val |= ((u_int32_t) *pnt++ << 8);
   69:   rd_as->val |= (u_int32_t) *pnt;
   70: }
   71: 
   72: /* type == RD_TYPE_AS4 */
   73: static void
   74: decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
   75: {
   76:   rd_as->as  = (u_int32_t) *pnt++ << 24;
   77:   rd_as->as |= (u_int32_t) *pnt++ << 16;
   78:   rd_as->as |= (u_int32_t) *pnt++ << 8;
   79:   rd_as->as |= (u_int32_t) *pnt++;
   80: 
   81:   rd_as->val  = ((u_int16_t) *pnt++ << 8);
   82:   rd_as->val |= (u_int16_t) *pnt;
   83: }
   84: 
   85: /* type == RD_TYPE_IP */
   86: static void
   87: decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
   88: {
   89:   memcpy (&rd_ip->ip, pnt, 4);
   90:   pnt += 4;
   91:   
   92:   rd_ip->val = ((u_int16_t) *pnt++ << 8);
   93:   rd_ip->val |= (u_int16_t) *pnt;
   94: }
   95: 
   96: int
   97: bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr, 
   98:                     struct bgp_nlri *packet)
   99: {
  100:   u_char *pnt;
  101:   u_char *lim;
  102:   struct prefix p;
  103:   int psize = 0;
  104:   int prefixlen;
  105:   u_int16_t type;
  106:   struct rd_as rd_as;
  107:   struct rd_ip rd_ip;
  108:   struct prefix_rd prd;
  109:   u_char *tagpnt;
  110: 
  111:   /* Check peer status. */
  112:   if (peer->status != Established)
  113:     return 0;
  114:   
  115:   /* Make prefix_rd */
  116:   prd.family = AF_UNSPEC;
  117:   prd.prefixlen = 64;
  118: 
  119:   pnt = packet->nlri;
  120:   lim = pnt + packet->length;
  121: 
  122: #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
  123:   for (; pnt < lim; pnt += psize)
  124:     {
  125:       /* Clear prefix structure. */
  126:       memset (&p, 0, sizeof (struct prefix));
  127: 
  128:       /* Fetch prefix length. */
  129:       prefixlen = *pnt++;
  130:       p.family = afi2family (packet->afi);
  131:       psize = PSIZE (prefixlen);
  132:       
  133:       /* sanity check against packet data */
  134:       if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8)
  135:         {
  136:           plog_err (peer->log, 
  137:                     "%s [Error] Update packet error / VPNv4"
  138:                      " (prefix length %d less than VPNv4 min length)",
  139:                     peer->host, prefixlen);
  140:           return -1;
  141:         }
  142:       if ((pnt + psize) > lim)
  143:         {
  144:           plog_err (peer->log,
  145:                     "%s [Error] Update packet error / VPNv4"
  146:                     " (psize %u exceeds packet size (%u)",
  147:                     peer->host, 
  148:                     prefixlen, (uint)(lim-pnt));
  149:           return -1;
  150:         }
  151:       
  152:       /* sanity check against storage for the IP address portion */
  153:       if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
  154:         {
  155:           plog_err (peer->log,
  156:                     "%s [Error] Update packet error / VPNv4"
  157:                     " (psize %u exceeds storage size (%zu)",
  158:                     peer->host,
  159:                     prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
  160:           return -1;
  161:         }
  162:       
  163:       /* Sanity check against max bitlen of the address family */
  164:       if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
  165:         {
  166:           plog_err (peer->log,
  167:                     "%s [Error] Update packet error / VPNv4"
  168:                     " (psize %u exceeds family (%u) max byte len %u)",
  169:                     peer->host,
  170:                     prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, 
  171:                     p.family, prefix_blen (&p));
  172:           return -1;
  173:         }
  174:       
  175:       /* Copyr label to prefix. */
  176:       tagpnt = pnt;
  177: 
  178:       /* Copy routing distinguisher to rd. */
  179:       memcpy (&prd.val, pnt + 3, 8);
  180: 
  181:       /* Decode RD type. */
  182:       type = decode_rd_type (pnt + 3);
  183: 
  184:       switch (type)
  185:         {
  186:         case RD_TYPE_AS:
  187:           decode_rd_as (pnt + 5, &rd_as);
  188:           break;
  189: 
  190:         case RD_TYPE_AS4:
  191:           decode_rd_as4 (pnt + 5, &rd_as);
  192:           break;
  193: 
  194:         case RD_TYPE_IP:
  195:           decode_rd_ip (pnt + 5, &rd_ip);
  196:           break;
  197: 
  198: 	default:
  199: 	  zlog_err ("Unknown RD type %d", type);
  200:           break;  /* just report */
  201:       }
  202: 
  203:       p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
  204:       memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES, 
  205:               psize - VPN_PREFIXLEN_MIN_BYTES);
  206: 
  207:       if (attr)
  208:         bgp_update (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
  209:                     ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
  210:       else
  211:         bgp_withdraw (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
  212:                       ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
  213:     }
  214:   /* Packet length consistency check. */
  215:   if (pnt != lim)
  216:     {
  217:       plog_err (peer->log,
  218:                 "%s [Error] Update packet error / VPNv4"
  219:                 " (%zu data remaining after parsing)",
  220:                 peer->host, lim - pnt);
  221:       return -1;
  222:     }
  223:   
  224:   return 0;
  225: #undef VPN_PREFIXLEN_MIN_BYTES
  226: }
  227: 
  228: int
  229: str2prefix_rd (const char *str, struct prefix_rd *prd)
  230: {
  231:   int ret; /* ret of called functions */
  232:   int lret; /* local ret, of this func */
  233:   char *p;
  234:   char *p2;
  235:   struct stream *s = NULL;
  236:   char *half = NULL;
  237:   struct in_addr addr;
  238: 
  239:   s = stream_new (8);
  240: 
  241:   prd->family = AF_UNSPEC;
  242:   prd->prefixlen = 64;
  243: 
  244:   lret = 0;
  245:   p = strchr (str, ':');
  246:   if (! p)
  247:     goto out;
  248: 
  249:   if (! all_digit (p + 1))
  250:     goto out;
  251: 
  252:   half = XMALLOC (MTYPE_TMP, (p - str) + 1);
  253:   memcpy (half, str, (p - str));
  254:   half[p - str] = '\0';
  255: 
  256:   p2 = strchr (str, '.');
  257: 
  258:   if (! p2)
  259:     {
  260:       if (! all_digit (half))
  261:         goto out;
  262:       
  263:       stream_putw (s, RD_TYPE_AS);
  264:       stream_putw (s, atoi (half));
  265:       stream_putl (s, atol (p + 1));
  266:     }
  267:   else
  268:     {
  269:       ret = inet_aton (half, &addr);
  270:       if (! ret)
  271:         goto out;
  272:       
  273:       stream_putw (s, RD_TYPE_IP);
  274:       stream_put_in_addr (s, &addr);
  275:       stream_putw (s, atol (p + 1));
  276:     }
  277:   memcpy (prd->val, s->data, 8);
  278:   lret = 1;
  279: 
  280: out:
  281:   if (s)
  282:     stream_free (s);
  283:   if (half)
  284:     XFREE(MTYPE_TMP, half);
  285:   return lret;
  286: }
  287: 
  288: int
  289: str2tag (const char *str, u_char *tag)
  290: {
  291:   unsigned long l;
  292:   char *endptr;
  293:   u_int32_t t;
  294: 
  295:   if (*str == '-')
  296:     return 0;
  297:   
  298:   errno = 0;
  299:   l = strtoul (str, &endptr, 10);
  300: 
  301:   if (*endptr != '\0' || errno || l > UINT32_MAX)
  302:     return 0;
  303: 
  304:   t = (u_int32_t) l;
  305:   
  306:   tag[0] = (u_char)(t >> 12);
  307:   tag[1] = (u_char)(t >> 4);
  308:   tag[2] = (u_char)(t << 4);
  309: 
  310:   return 1;
  311: }
  312: 
  313: char *
  314: prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
  315: {
  316:   u_char *pnt;
  317:   u_int16_t type;
  318:   struct rd_as rd_as;
  319:   struct rd_ip rd_ip;
  320: 
  321:   if (size < RD_ADDRSTRLEN)
  322:     return NULL;
  323: 
  324:   pnt = prd->val;
  325: 
  326:   type = decode_rd_type (pnt);
  327: 
  328:   if (type == RD_TYPE_AS)
  329:     {
  330:       decode_rd_as (pnt + 2, &rd_as);
  331:       snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
  332:       return buf;
  333:     }
  334:   else if (type == RD_TYPE_AS4)
  335:     {
  336:       decode_rd_as4 (pnt + 2, &rd_as);
  337:       snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
  338:       return buf;
  339:     }
  340:   else if (type == RD_TYPE_IP)
  341:     {
  342:       decode_rd_ip (pnt + 2, &rd_ip);
  343:       snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
  344:       return buf;
  345:     }
  346:   return NULL;
  347: }
  348: 
  349: /* For testing purpose, static route of MPLS-VPN. */
  350: DEFUN (vpnv4_network,
  351:        vpnv4_network_cmd,
  352:        "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
  353:        "Specify a network to announce via BGP\n"
  354:        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
  355:        "Specify Route Distinguisher\n"
  356:        "VPN Route Distinguisher\n"
  357:        "BGP tag\n"
  358:        "tag value\n")
  359: {
  360:   return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
  361: }
  362: 
  363: DEFUN (vpnv4_network_route_map,
  364:        vpnv4_network_route_map_cmd,
  365:        "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
  366:        "Specify a network to announce via BGP\n"
  367:        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
  368:        "Specify Route Distinguisher\n"
  369:        "VPN Route Distinguisher\n"
  370:        "BGP tag\n"
  371:        "tag value\n"
  372:        "route map\n"
  373:        "route map name\n")
  374: {
  375:   return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
  376: }
  377: 
  378: /* For testing purpose, static route of MPLS-VPN. */
  379: DEFUN (no_vpnv4_network,
  380:        no_vpnv4_network_cmd,
  381:        "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
  382:        NO_STR
  383:        "Specify a network to announce via BGP\n"
  384:        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
  385:        "Specify Route Distinguisher\n"
  386:        "VPN Route Distinguisher\n"
  387:        "BGP tag\n"
  388:        "tag value\n")
  389: {
  390:   return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
  391: }
  392: 
  393: static int
  394: show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
  395: {
  396:   struct bgp *bgp;
  397:   struct bgp_table *table;
  398:   struct bgp_node *rn;
  399:   struct bgp_node *rm;
  400:   struct attr *attr;
  401:   int rd_header;
  402:   int header = 1;
  403:   char v4_header[] = "   Network          Next Hop            Metric LocPrf Weight Path%s";
  404: 
  405:   bgp = bgp_get_default ();
  406:   if (bgp == NULL)
  407:     {
  408:       vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
  409:       return CMD_WARNING;
  410:     }
  411: 
  412:   for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
  413:        rn = bgp_route_next (rn))
  414:     {
  415:       if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
  416:         continue;
  417: 
  418:       if ((table = rn->info) != NULL)
  419:         {
  420:           rd_header = 1;
  421: 
  422:           for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
  423:             if ((attr = rm->info) != NULL)
  424:               {
  425:                 if (header)
  426:                   {
  427:                     vty_out (vty, "BGP table version is 0, local router ID is %s%s",
  428:                              inet_ntoa (bgp->router_id), VTY_NEWLINE);
  429:                     vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
  430:                              VTY_NEWLINE);
  431:                     vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
  432:                              VTY_NEWLINE, VTY_NEWLINE);
  433:                     vty_out (vty, v4_header, VTY_NEWLINE);
  434:                     header = 0;
  435:                   }
  436: 
  437:                 if (rd_header)
  438:                   {
  439:                     u_int16_t type;
  440:                     struct rd_as rd_as;
  441:                     struct rd_ip rd_ip;
  442:                     u_char *pnt;
  443: 
  444:                     pnt = rn->p.u.val;
  445: 
  446:                     /* Decode RD type. */
  447:                     type = decode_rd_type (pnt);
  448:                     /* Decode RD value. */
  449:                     if (type == RD_TYPE_AS)
  450:                       decode_rd_as (pnt + 2, &rd_as);
  451:                     else if (type == RD_TYPE_AS4)
  452:                       decode_rd_as4 (pnt + 2, &rd_as);
  453:                     else if (type == RD_TYPE_IP)
  454:                       decode_rd_ip (pnt + 2, &rd_ip);
  455: 
  456:                     vty_out (vty, "Route Distinguisher: ");
  457: 
  458:                     if (type == RD_TYPE_AS)
  459:                       vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
  460:                     else if (type == RD_TYPE_AS4)
  461:                       vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
  462:                     else if (type == RD_TYPE_IP)
  463:                       vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
  464: 
  465:                     vty_out (vty, "%s", VTY_NEWLINE);
  466:                     rd_header = 0;
  467:                   }
  468:                 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
  469:               }
  470:         }
  471:     }
  472:   return CMD_SUCCESS;
  473: }
  474: 
  475: enum bgp_show_type
  476: {
  477:   bgp_show_type_normal,
  478:   bgp_show_type_regexp,
  479:   bgp_show_type_prefix_list,
  480:   bgp_show_type_filter_list,
  481:   bgp_show_type_neighbor,
  482:   bgp_show_type_cidr_only,
  483:   bgp_show_type_prefix_longer,
  484:   bgp_show_type_community_all,
  485:   bgp_show_type_community,
  486:   bgp_show_type_community_exact,
  487:   bgp_show_type_community_list,
  488:   bgp_show_type_community_list_exact
  489: };
  490: 
  491: static int
  492: bgp_show_mpls_vpn(
  493:     struct vty *vty,
  494:     afi_t afi,
  495:     struct prefix_rd *prd,
  496:     enum bgp_show_type type,
  497:     void *output_arg,
  498:     int tags)
  499: {
  500:   struct bgp *bgp;
  501:   struct bgp_table *table;
  502:   struct bgp_node *rn;
  503:   struct bgp_node *rm;
  504:   struct bgp_info *ri;
  505:   int rd_header;
  506:   int header = 1;
  507:   char v4_header[] = "   Network          Next Hop            Metric LocPrf Weight Path%s";
  508:   char v4_header_tag[] = "   Network          Next Hop      In tag/Out tag%s";
  509: 
  510:   unsigned long output_count = 0;
  511:   unsigned long total_count  = 0;
  512: 
  513:   bgp = bgp_get_default ();
  514:   if (bgp == NULL)
  515:     {
  516:       vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
  517:       return CMD_WARNING;
  518:     }
  519:   
  520:   if ((afi != AFI_IP) && (afi != AFI_IP6))
  521:     {
  522:       vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
  523:       return CMD_WARNING;
  524:     }
  525: 
  526:   for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
  527:     {
  528:       if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
  529: 	continue;
  530: 
  531:       if ((table = rn->info) != NULL)
  532: 	{
  533: 	  rd_header = 1;
  534: 
  535: 	  for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
  536: 	    for (ri = rm->info; ri; ri = ri->next)
  537: 	      {
  538:                 total_count++;
  539: 		if (type == bgp_show_type_neighbor)
  540: 		  {
  541: 		    union sockunion *su = output_arg;
  542: 
  543: 		    if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
  544: 		      continue;
  545: 		  }
  546: 		if (header)
  547: 		  {
  548: 		    if (tags)
  549: 		      vty_out (vty, v4_header_tag, VTY_NEWLINE);
  550: 		    else
  551: 		      {
  552: 			vty_out (vty, "BGP table version is 0, local router ID is %s%s",
  553: 				 inet_ntoa (bgp->router_id), VTY_NEWLINE);
  554: 			vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
  555: 				 VTY_NEWLINE);
  556: 			vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
  557: 				 VTY_NEWLINE, VTY_NEWLINE);
  558: 			vty_out (vty, v4_header, VTY_NEWLINE);
  559: 		      }
  560: 		    header = 0;
  561: 		  }
  562: 
  563: 		if (rd_header)
  564: 		  {
  565: 		    u_int16_t type;
  566: 		    struct rd_as rd_as;
  567: 		    struct rd_ip rd_ip;
  568: 		    u_char *pnt;
  569: 
  570: 		    pnt = rn->p.u.val;
  571: 
  572: 		    /* Decode RD type. */
  573: 		    type = decode_rd_type (pnt);
  574: 		    /* Decode RD value. */
  575: 		    if (type == RD_TYPE_AS)
  576: 		      decode_rd_as (pnt + 2, &rd_as);
  577: 		    else if (type == RD_TYPE_AS4)
  578: 		      decode_rd_as4 (pnt + 2, &rd_as);
  579: 		    else if (type == RD_TYPE_IP)
  580: 		      decode_rd_ip (pnt + 2, &rd_ip);
  581: 
  582: 		    vty_out (vty, "Route Distinguisher: ");
  583: 
  584: 		    if (type == RD_TYPE_AS)
  585: 		      vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
  586: 		    else if (type == RD_TYPE_AS4)
  587: 		      vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
  588: 		    else if (type == RD_TYPE_IP)
  589: 		      vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
  590: 		  
  591: 		    vty_out (vty, "%s", VTY_NEWLINE);		  
  592: 		    rd_header = 0;
  593: 		  }
  594: 	        if (tags)
  595: 		  route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
  596: 	        else
  597: 		  route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
  598:                 output_count++;
  599: 	      }
  600:         }
  601:     }
  602: 
  603:   if (output_count == 0)
  604:     {
  605:       vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
  606:     }
  607:   else
  608:     vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s",
  609: 	     VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
  610: 
  611:   return CMD_SUCCESS;
  612: }
  613: 
  614: DEFUN (show_bgp_ipv4_vpn,
  615:        show_bgp_ipv4_vpn_cmd,
  616:        "show bgp ipv4 vpn",
  617:        SHOW_STR
  618:        BGP_STR
  619:        "Address Family\n"
  620:        "Display VPN NLRI specific information\n")
  621: {
  622:   return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0);
  623: }
  624: 
  625: DEFUN (show_bgp_ipv6_vpn,
  626:        show_bgp_ipv6_vpn_cmd,
  627:        "show bgp ipv6 vpn",
  628:        SHOW_STR
  629:        BGP_STR
  630:        "Address Family\n"
  631:        "Display VPN NLRI specific information\n")
  632: {
  633:   return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0);
  634: }
  635: 
  636: DEFUN (show_bgp_ipv4_vpn_rd,
  637:        show_bgp_ipv4_vpn_rd_cmd,
  638:        "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn",
  639:        SHOW_STR
  640:        BGP_STR
  641:        "Address Family\n"
  642:        "Display VPN NLRI specific information\n"
  643:        "Display information for a route distinguisher\n"
  644:        "VPN Route Distinguisher\n")
  645: {
  646:   int ret;
  647:   struct prefix_rd prd;
  648: 
  649:   ret = str2prefix_rd (argv[0], &prd);
  650:   if (! ret)
  651:     {
  652:       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  653:       return CMD_WARNING;
  654:     }
  655:   return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0);
  656: }
  657: 
  658: DEFUN (show_bgp_ipv6_vpn_rd,
  659:        show_bgp_ipv6_vpn_rd_cmd,
  660:        "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn",
  661:        SHOW_STR
  662:        BGP_STR
  663:        "Address Family\n"
  664:        "Display VPN NLRI specific information\n"
  665:        "Display information for a route distinguisher\n"
  666:        "VPN Route Distinguisher\n")
  667: {
  668:   int ret;
  669:   struct prefix_rd prd;
  670: 
  671:   ret = str2prefix_rd (argv[0], &prd);
  672:   if (! ret)
  673:     {
  674:       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  675:       return CMD_WARNING;
  676:     }
  677:   return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0);
  678: }
  679: 
  680: 
  681: DEFUN (show_bgp_ipv4_vpn_tags,
  682:        show_bgp_ipv4_vpn_tags_cmd,
  683:        "show bgp ipv4 vpn tags",
  684:        SHOW_STR
  685:        BGP_STR
  686:        "Address Family\n"
  687:        "Display VPN NLRI specific information\n"
  688:        "Display BGP tags for prefixes\n")
  689: {
  690:   return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL,  1);
  691: }
  692: DEFUN (show_bgp_ipv6_vpn_tags,
  693:        show_bgp_ipv6_vpn_tags_cmd,
  694:        "show bgp ipv6 vpn tags",
  695:        SHOW_STR
  696:        BGP_STR
  697:        "Address Family\n"
  698:        "Display VPN NLRI specific information\n"
  699:        "Display BGP tags for prefixes\n")
  700: {
  701:   return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL,  1);
  702: }
  703: 
  704: DEFUN (show_bgp_ipv4_vpn_rd_tags,
  705:        show_bgp_ipv4_vpn_rd_tags_cmd,
  706:        "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn tags",
  707:        SHOW_STR
  708:        BGP_STR
  709:        "Address Family\n"
  710:        "Display VPN NLRI specific information\n"
  711:        "Display information for a route distinguisher\n"
  712:        "VPN Route Distinguisher\n"
  713:        "Display BGP tags for prefixes\n")
  714: {
  715:   int ret;
  716:   struct prefix_rd prd;
  717: 
  718:   ret = str2prefix_rd (argv[0], &prd);
  719:   if (! ret)
  720:     {
  721:       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  722:       return CMD_WARNING;
  723:     }
  724:   return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1);
  725: }
  726: DEFUN (show_bgp_ipv6_vpn_rd_tags,
  727:        show_bgp_ipv6_vpn_rd_tags_cmd,
  728:        "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn tags",
  729:        SHOW_STR
  730:        BGP_STR
  731:        "Address Family\n"
  732:        "Display VPN NLRI specific information\n"
  733:        "Display information for a route distinguisher\n"
  734:        "VPN Route Distinguisher\n"
  735:        "Display BGP tags for prefixes\n")
  736: {
  737:   int ret;
  738:   struct prefix_rd prd;
  739: 
  740:   ret = str2prefix_rd (argv[0], &prd);
  741:   if (! ret)
  742:     {
  743:       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  744:       return CMD_WARNING;
  745:     }
  746:   return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 1);
  747: }
  748: 
  749: DEFUN (show_bgp_ipv4_vpn_neighbor_routes,
  750:        show_bgp_ipv4_vpn_neighbor_routes_cmd,
  751:        "show bgp ipv4 vpn neighbors (A.B.C.D|X:X::X:X) routes",
  752:        SHOW_STR
  753:        BGP_STR
  754:        "Address Family\n"
  755:        "Display VPN NLRI specific information\n"
  756:        "Detailed information on TCP and BGP neighbor connections\n"
  757:        "Neighbor to display information about\n"
  758:        "Neighbor to display information about\n"
  759:        "Display routes learned from neighbor\n")
  760: {
  761:   union sockunion su;
  762:   struct peer *peer;
  763:   int ret;
  764: 
  765:   ret = str2sockunion (argv[0], &su);
  766:   if (ret < 0)
  767:     {
  768:       vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
  769:       return CMD_WARNING;
  770:     }
  771: 
  772:   peer = peer_lookup (NULL, &su);
  773:   if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
  774:     {
  775:       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  776:       return CMD_WARNING;
  777:     }
  778: 
  779:   return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0);
  780: }
  781: 
  782: DEFUN (show_bgp_ipv6_vpn_neighbor_routes,
  783:        show_bgp_ipv6_vpn_neighbor_routes_cmd,
  784:        "show bgp ipv6 vpn neighbors (A.B.C.D|X:X::X:X) routes",
  785:        SHOW_STR
  786:        BGP_STR
  787:        "Address Family\n"
  788:        "Display VPN NLRI specific information\n"
  789:        "Detailed information on TCP and BGP neighbor connections\n"
  790:        "Neighbor to display information about\n"
  791:        "Neighbor to display information about\n"
  792:        "Display routes learned from neighbor\n")
  793: {
  794:   union sockunion su;
  795:   struct peer *peer;
  796: 
  797:   int ret;
  798: 
  799:   ret = str2sockunion (argv[0], &su);
  800:   if (ret < 0)
  801:     {
  802:       vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
  803:       return CMD_WARNING;
  804:     }
  805: 
  806:   peer = peer_lookup (NULL, &su);
  807:   if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
  808:     {
  809:       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  810:       return CMD_WARNING;
  811:     }
  812: 
  813:   return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0);
  814: }
  815: 
  816: DEFUN (show_bgp_ipv4_vpn_neighbor_advertised_routes,
  817:        show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd,
  818:        "show bgp ipv4 vpn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
  819:        SHOW_STR
  820:        BGP_STR
  821:        "Address Family\n"
  822:        "Display VPN NLRI specific information\n"
  823:        "Detailed information on TCP and BGP neighbor connections\n"
  824:        "Neighbor to display information about\n"
  825:        "Display the routes advertised to a BGP neighbor\n")
  826: {
  827:   int ret;
  828:   struct peer *peer;
  829:   union sockunion su;
  830: 
  831:   ret = str2sockunion (argv[0], &su);
  832:   if (ret < 0)
  833:     {
  834:       vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
  835:       return CMD_WARNING;
  836:     }
  837:   peer = peer_lookup (NULL, &su);
  838:   if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
  839:     {
  840:       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  841:       return CMD_WARNING;
  842:     }
  843: 
  844:   return show_adj_route_vpn (vty, peer, NULL);
  845: }
  846: DEFUN (show_bgp_ipv6_vpn_neighbor_advertised_routes,
  847:        show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd,
  848:        "show bgp ipv6 vpn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
  849:        SHOW_STR
  850:        BGP_STR
  851:        "Address Family\n"
  852:        "Display VPN NLRI specific information\n"
  853:        "Detailed information on TCP and BGP neighbor connections\n"
  854:        "Neighbor to display information about\n"
  855:        "Display the routes advertised to a BGP neighbor\n")
  856: {
  857:   int ret;
  858:   struct peer *peer;
  859:   union sockunion su;
  860: 
  861:   ret = str2sockunion (argv[0], &su);
  862:   if (ret < 0)
  863:     {
  864:       vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
  865:       return CMD_WARNING;
  866:     }
  867:   peer = peer_lookup (NULL, &su);
  868:   if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
  869:     {
  870:       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  871:       return CMD_WARNING;
  872:     }
  873: 
  874:   return show_adj_route_vpn (vty, peer, NULL);
  875: }
  876: 
  877: DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
  878:        show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd,
  879:        "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
  880:        SHOW_STR
  881:        BGP_STR
  882:        "Address Family\n"
  883:        "Display VPN NLRI specific information\n"
  884:        "Display information for a route distinguisher\n"
  885:        "VPN Route Distinguisher\n"
  886:        "Detailed information on TCP and BGP neighbor connections\n"
  887:        "Neighbor to display information about\n"
  888:        "Neighbor to display information about\n"
  889:        "Display the routes advertised to a BGP neighbor\n")
  890: {
  891:   int ret;
  892:   struct peer *peer;
  893:   struct prefix_rd prd;
  894:   union sockunion su;
  895:   ret = str2sockunion (argv[1], &su);
  896:   if (ret < 0)
  897:     {
  898:       vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
  899:       return CMD_WARNING;
  900:     }
  901:   peer = peer_lookup (NULL, &su);
  902:   if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
  903:     {
  904:       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  905:       return CMD_WARNING;
  906:     }
  907: 
  908:   ret = str2prefix_rd (argv[0], &prd);
  909:   if (! ret)
  910:     {
  911:       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  912:       return CMD_WARNING;
  913:     }
  914: 
  915:   return show_adj_route_vpn (vty, peer, &prd);
  916: }
  917: DEFUN (show_ip_bgp_vpnv6_rd_neighbor_advertised_routes,
  918:        show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd,
  919:        "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
  920:        SHOW_STR
  921:        BGP_STR
  922:        "Address Family\n"
  923:        "Display VPN NLRI specific information\n"
  924:        "Display information for a route distinguisher\n"
  925:        "VPN Route Distinguisher\n"
  926:        "Detailed information on TCP and BGP neighbor connections\n"
  927:        "Neighbor to display information about\n"
  928:        "Neighbor to display information about\n"
  929:        "Display the routes advertised to a BGP neighbor\n")
  930: {
  931:   int ret;
  932:   struct peer *peer;
  933:   struct prefix_rd prd;
  934:   union sockunion su;
  935:   ret = str2sockunion (argv[1], &su);
  936:   if (ret < 0)
  937:     {
  938:       vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
  939:       return CMD_WARNING;
  940:     }
  941:   peer = peer_lookup (NULL, &su);
  942:   if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
  943:     {
  944:       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  945:       return CMD_WARNING;
  946:     }
  947: 
  948:   ret = str2prefix_rd (argv[0], &prd);
  949:   if (! ret)
  950:     {
  951:       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  952:       return CMD_WARNING;
  953:     }
  954: 
  955:   return show_adj_route_vpn (vty, peer, &prd);
  956: }
  957: 
  958: DEFUN (show_bgp_ipv4_vpn_rd_neighbor_routes,
  959:        show_bgp_ipv4_vpn_rd_neighbor_routes_cmd,
  960:        "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
  961:        SHOW_STR
  962:        BGP_STR
  963:        "Address Family\n"
  964:        "Address Family modifier\n"
  965:        "Display information for a route distinguisher\n"
  966:        "VPN Route Distinguisher\n"
  967:        "Detailed information on TCP and BGP neighbor connections\n"
  968:        "Neighbor to display information about\n"
  969:        "Display routes learned from neighbor\n")
  970: {
  971:   int ret;
  972:   union sockunion *su;
  973:   struct peer *peer;
  974:   struct prefix_rd prd;
  975: 
  976:   ret = str2prefix_rd (argv[0], &prd);
  977:   if (! ret)
  978:     {
  979:       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  980:       return CMD_WARNING;
  981:     }
  982: 
  983:   su = sockunion_str2su (argv[1]);
  984:   if (su == NULL)
  985:     {
  986:       vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
  987:                return CMD_WARNING;
  988:     }
  989: 
  990:   peer = peer_lookup (NULL, su);
  991:   if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
  992:     {
  993:       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
  994:       return CMD_WARNING;
  995:     }
  996: 
  997:   return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_neighbor, su, 0);
  998: }
  999: DEFUN (show_bgp_ipv6_vpn_rd_neighbor_routes,
 1000:        show_bgp_ipv6_vpn_rd_neighbor_routes_cmd,
 1001:        "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
 1002:        SHOW_STR
 1003:        BGP_STR
 1004:        "Address Family\n"
 1005:        "Address Family modifier\n"
 1006:        "Display information for a route distinguisher\n"
 1007:        "VPN Route Distinguisher\n"
 1008:        "Detailed information on TCP and BGP neighbor connections\n"
 1009:        "Neighbor to display information about\n"
 1010:        "Display routes learned from neighbor\n")
 1011: {
 1012:   int ret;
 1013:   union sockunion *su;
 1014:   struct peer *peer;
 1015:   struct prefix_rd prd;
 1016: 
 1017:   ret = str2prefix_rd (argv[0], &prd);
 1018:   if (! ret)
 1019:     {
 1020:       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
 1021:       return CMD_WARNING;
 1022:     }
 1023: 
 1024:   su = sockunion_str2su (argv[1]);
 1025:   if (su == NULL)
 1026:     {
 1027:       vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
 1028:                return CMD_WARNING;
 1029:     }
 1030: 
 1031:   peer = peer_lookup (NULL, su);
 1032:   if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
 1033:     {
 1034:       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
 1035:       return CMD_WARNING;
 1036:     }
 1037: 
 1038:   return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_neighbor, su, 0);
 1039: }
 1040: 
 1041: void
 1042: bgp_mplsvpn_init (void)
 1043: {
 1044:   install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
 1045:   install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
 1046:   install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
 1047: 
 1048:   install_element (VIEW_NODE, &show_bgp_ipv4_vpn_cmd);
 1049:   install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_cmd);
 1050:   install_element (VIEW_NODE, &show_bgp_ipv4_vpn_tags_cmd);
 1051:   install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_tags_cmd);
 1052:   install_element (VIEW_NODE, &show_bgp_ipv4_vpn_neighbor_routes_cmd);
 1053:   install_element (VIEW_NODE, &show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd);
 1054:   install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd);
 1055:   install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_neighbor_routes_cmd);
 1056: 
 1057:   install_element (VIEW_NODE, &show_bgp_ipv6_vpn_cmd);
 1058:   install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_cmd);
 1059:   install_element (VIEW_NODE, &show_bgp_ipv6_vpn_tags_cmd);
 1060:   install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_tags_cmd);
 1061:   install_element (VIEW_NODE, &show_bgp_ipv6_vpn_neighbor_routes_cmd);
 1062:   install_element (VIEW_NODE, &show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd);
 1063:   install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd);
 1064:   install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_neighbor_routes_cmd);
 1065: 
 1066:   install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_cmd);
 1067:   install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_cmd);
 1068:   install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_tags_cmd);
 1069:   install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_tags_cmd);
 1070:   install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_neighbor_routes_cmd);
 1071:   install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd);
 1072:   install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd);
 1073:   install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_neighbor_routes_cmd);
 1074: 
 1075:   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_cmd);
 1076:   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_cmd);
 1077:   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_tags_cmd);
 1078:   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_tags_cmd);
 1079:   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_neighbor_routes_cmd);
 1080:   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd);
 1081:   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd);
 1082:   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_neighbor_routes_cmd);
 1083: }

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