Annotation of embedaddon/quagga/bgpd/bgp_mplsvpn.c, revision 1.1.1.1

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

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