Diff for /embedaddon/quagga/bgpd/bgp_mplsvpn.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2013/07/21 23:54:37 version 1.1.1.4, 2016/11/02 10:09:10
Line 25  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 25  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "log.h"  #include "log.h"
 #include "memory.h"  #include "memory.h"
 #include "stream.h"  #include "stream.h"
   #include "filter.h"
   
 #include "bgpd/bgpd.h"  #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"  #include "bgpd/bgp_table.h"
 #include "bgpd/bgp_route.h"  #include "bgpd/bgp_route.h"
   #include "bgpd/bgp_packet.h"
 #include "bgpd/bgp_attr.h"  #include "bgpd/bgp_attr.h"
 #include "bgpd/bgp_mplsvpn.h"  #include "bgpd/bgp_mplsvpn.h"
   #include "bgpd/bgp_packet.h"
   
 static u_int16_t  static u_int16_t
 decode_rd_type (u_char *pnt)  decode_rd_type (u_char *pnt)
Line 53  decode_label (u_char *pnt) Line 56  decode_label (u_char *pnt)
   return l;    return l;
 }  }
   
   /* type == RD_TYPE_AS */
 static void  static void
 decode_rd_as (u_char *pnt, struct rd_as *rd_as)  decode_rd_as (u_char *pnt, struct rd_as *rd_as)
 {  {
Line 65  decode_rd_as (u_char *pnt, struct rd_as *rd_as) Line 69  decode_rd_as (u_char *pnt, struct rd_as *rd_as)
   rd_as->val |= (u_int32_t) *pnt;    rd_as->val |= (u_int32_t) *pnt;
 }  }
   
   /* type == RD_TYPE_AS4 */
 static void  static void
   decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
   {
     rd_as->as  = (u_int32_t) *pnt++ << 24;
     rd_as->as |= (u_int32_t) *pnt++ << 16;
     rd_as->as |= (u_int32_t) *pnt++ << 8;
     rd_as->as |= (u_int32_t) *pnt++;
   
     rd_as->val  = ((u_int16_t) *pnt++ << 8);
     rd_as->val |= (u_int16_t) *pnt;
   }
   
   /* type == RD_TYPE_IP */
   static void
 decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)  decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
 {  {
   memcpy (&rd_ip->ip, pnt, 4);    memcpy (&rd_ip->ip, pnt, 4);
Line 76  decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip) Line 94  decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
 }  }
   
 int  int
bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr, bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr, 
                      struct bgp_nlri *packet)                    struct bgp_nlri *packet)
 {  {
   u_char *pnt;    u_char *pnt;
   u_char *lim;    u_char *lim;
   struct prefix p;    struct prefix p;
  int psize;  int psize = 0;
   int prefixlen;    int prefixlen;
   u_int32_t label;  
   u_int16_t type;    u_int16_t type;
   struct rd_as rd_as;    struct rd_as rd_as;
   struct rd_ip rd_ip;    struct rd_ip rd_ip;
Line 102  bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr * Line 119  bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *
   pnt = packet->nlri;    pnt = packet->nlri;
   lim = pnt + packet->length;    lim = pnt + packet->length;
   
   #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
   for (; pnt < lim; pnt += psize)    for (; pnt < lim; pnt += psize)
     {      {
       /* Clear prefix structure. */        /* Clear prefix structure. */
Line 109  bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr * Line 127  bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *
   
       /* Fetch prefix length. */        /* Fetch prefix length. */
       prefixlen = *pnt++;        prefixlen = *pnt++;
      p.family = AF_INET;      p.family = afi2family (packet->afi);
       psize = PSIZE (prefixlen);        psize = PSIZE (prefixlen);
      
      if (prefixlen < 88)      /* sanity check against packet data */
        {      if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8)
          zlog_err ("prefix length is less than 88: %d", prefixlen);        {
          return -1;          plog_err (peer->log, 
        }                    "%s [Error] Update packet error / VPNv4"
                     " (prefix length %d less than VPNv4 min length)",
      label = decode_label (pnt);                    peer->host, prefixlen);
          return -1;
         }
       if ((pnt + psize) > lim)
         {
           plog_err (peer->log,
                     "%s [Error] Update packet error / VPNv4"
                     " (psize %u exceeds packet size (%u)",
                     peer->host, 
                     prefixlen, (uint)(lim-pnt));
           return -1;
         }
       
       /* sanity check against storage for the IP address portion */
       if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
         {
           plog_err (peer->log,
                     "%s [Error] Update packet error / VPNv4"
                     " (psize %u exceeds storage size (%zu)",
                     peer->host,
                     prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
           return -1;
         }
       
       /* Sanity check against max bitlen of the address family */
       if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
         {
           plog_err (peer->log,
                     "%s [Error] Update packet error / VPNv4"
                     " (psize %u exceeds family (%u) max byte len %u)",
                     peer->host,
                     prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, 
                     p.family, prefix_blen (&p));
           return -1;
         }
       
       /* Copyr label to prefix. */        /* Copyr label to prefix. */
      tagpnt = pnt;;      tagpnt = pnt;
   
       /* Copy routing distinguisher to rd. */        /* Copy routing distinguisher to rd. */
       memcpy (&prd.val, pnt + 3, 8);        memcpy (&prd.val, pnt + 3, 8);
Line 129  bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr * Line 181  bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *
       /* Decode RD type. */        /* Decode RD type. */
       type = decode_rd_type (pnt + 3);        type = decode_rd_type (pnt + 3);
   
      /* Decode RD value. */      switch (type)
      if (type == RD_TYPE_AS)        {
        decode_rd_as (pnt + 5, &rd_as);        case RD_TYPE_AS:
      else if (type == RD_TYPE_IP)          decode_rd_as (pnt + 5, &rd_as);
        decode_rd_ip (pnt + 5, &rd_ip);          break;
      else 
        { 
          zlog_err ("Invalid RD type %d", type); 
          return -1; 
        } 
   
      p.prefixlen = prefixlen - 88;        case RD_TYPE_AS4:
      memcpy (&p.u.prefix, pnt + 11, psize - 11);          decode_rd_as4 (pnt + 5, &rd_as);
           break;
   
#if 0        case RD_TYPE_IP:
      if (type == RD_TYPE_AS)          decode_rd_ip (pnt + 5, &rd_ip);
        zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,          break;
                   inet_ntoa (p.u.prefix4), p.prefixlen); 
      else if (type == RD_TYPE_IP) 
        zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip), 
                   rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen); 
#endif /* 0 */ 
   
      if (pnt + psize > lim)        default:
        return -1;          zlog_err ("Unknown RD type %d", type);
           break;  /* just report */
       }
   
         p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
         memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES, 
                 psize - VPN_PREFIXLEN_MIN_BYTES);
   
       if (attr)        if (attr)
        bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,        bgp_update (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
                    ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);                    ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
       else        else
        bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,        bgp_withdraw (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
                      ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);                      ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
     }      }
   
   /* Packet length consistency check. */    /* Packet length consistency check. */
   if (pnt != lim)    if (pnt != lim)
    return -1;    {
      plog_err (peer->log,
                 "%s [Error] Update packet error / VPNv4"
                 " (%zu data remaining after parsing)",
                 peer->host, lim - pnt);
       return -1;
     }
   
   return 0;    return 0;
   #undef VPN_PREFIXLEN_MIN_BYTES
 }  }
   
 int  int
 str2prefix_rd (const char *str, struct prefix_rd *prd)  str2prefix_rd (const char *str, struct prefix_rd *prd)
 {  {
  int ret;  int ret; /* ret of called functions */
   int lret; /* local ret, of this func */
   char *p;    char *p;
   char *p2;    char *p2;
  struct stream *s;  struct stream *s = NULL;
  char *half;  char *half = NULL;
   struct in_addr addr;    struct in_addr addr;
   
   s = stream_new (8);    s = stream_new (8);
Line 185  str2prefix_rd (const char *str, struct prefix_rd *prd) Line 241  str2prefix_rd (const char *str, struct prefix_rd *prd)
   prd->family = AF_UNSPEC;    prd->family = AF_UNSPEC;
   prd->prefixlen = 64;    prd->prefixlen = 64;
   
     lret = 0;
   p = strchr (str, ':');    p = strchr (str, ':');
   if (! p)    if (! p)
    return 0;    goto out;
   
   if (! all_digit (p + 1))    if (! all_digit (p + 1))
    return 0;    goto out;
   
   half = XMALLOC (MTYPE_TMP, (p - str) + 1);    half = XMALLOC (MTYPE_TMP, (p - str) + 1);
   memcpy (half, str, (p - str));    memcpy (half, str, (p - str));
Line 201  str2prefix_rd (const char *str, struct prefix_rd *prd) Line 258  str2prefix_rd (const char *str, struct prefix_rd *prd)
   if (! p2)    if (! p2)
     {      {
       if (! all_digit (half))        if (! all_digit (half))
        {        goto out;
          XFREE (MTYPE_TMP, half);      
          return 0; 
        } 
       stream_putw (s, RD_TYPE_AS);        stream_putw (s, RD_TYPE_AS);
       stream_putw (s, atoi (half));        stream_putw (s, atoi (half));
       stream_putl (s, atol (p + 1));        stream_putl (s, atol (p + 1));
Line 213  str2prefix_rd (const char *str, struct prefix_rd *prd) Line 268  str2prefix_rd (const char *str, struct prefix_rd *prd)
     {      {
       ret = inet_aton (half, &addr);        ret = inet_aton (half, &addr);
       if (! ret)        if (! ret)
        {        goto out;
          XFREE (MTYPE_TMP, half);      
          return 0; 
        } 
       stream_putw (s, RD_TYPE_IP);        stream_putw (s, RD_TYPE_IP);
       stream_put_in_addr (s, &addr);        stream_put_in_addr (s, &addr);
       stream_putw (s, atol (p + 1));        stream_putw (s, atol (p + 1));
     }      }
   memcpy (prd->val, s->data, 8);    memcpy (prd->val, s->data, 8);
     lret = 1;
   
  return 1;out:
   if (s)
     stream_free (s);
   if (half)
     XFREE(MTYPE_TMP, half);
   return lret;
 }  }
   
 int  int
Line 272  prefix_rd2str (struct prefix_rd *prd, char *buf, size_ Line 331  prefix_rd2str (struct prefix_rd *prd, char *buf, size_
       snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);        snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
       return buf;        return buf;
     }      }
     else if (type == RD_TYPE_AS4)
       {
         decode_rd_as4 (pnt + 2, &rd_as);
         snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
         return buf;
       }
   else if (type == RD_TYPE_IP)    else if (type == RD_TYPE_IP)
     {      {
       decode_rd_ip (pnt + 2, &rd_ip);        decode_rd_ip (pnt + 2, &rd_ip);
       snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);        snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
       return buf;        return buf;
     }      }
   
   return NULL;    return NULL;
 }  }
   
Line 293  DEFUN (vpnv4_network, Line 357  DEFUN (vpnv4_network,
        "BGP tag\n"         "BGP tag\n"
        "tag value\n")         "tag value\n")
 {  {
  return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
 }  }
   
   DEFUN (vpnv4_network_route_map,
          vpnv4_network_route_map_cmd,
          "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
          "Specify a network to announce via BGP\n"
          "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
          "Specify Route Distinguisher\n"
          "VPN Route Distinguisher\n"
          "BGP tag\n"
          "tag value\n"
          "route map\n"
          "route map name\n")
   {
     return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
   }
   
 /* For testing purpose, static route of MPLS-VPN. */  /* For testing purpose, static route of MPLS-VPN. */
 DEFUN (no_vpnv4_network,  DEFUN (no_vpnv4_network,
        no_vpnv4_network_cmd,         no_vpnv4_network_cmd,
Line 308  DEFUN (no_vpnv4_network, Line 387  DEFUN (no_vpnv4_network,
        "BGP tag\n"         "BGP tag\n"
        "tag value\n")         "tag value\n")
 {  {
  return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);  return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
 }  }
   
 static int  static int
Line 369  show_adj_route_vpn (struct vty *vty, struct peer *peer Line 448  show_adj_route_vpn (struct vty *vty, struct peer *peer
                     /* Decode RD value. */                      /* Decode RD value. */
                     if (type == RD_TYPE_AS)                      if (type == RD_TYPE_AS)
                       decode_rd_as (pnt + 2, &rd_as);                        decode_rd_as (pnt + 2, &rd_as);
                       else if (type == RD_TYPE_AS4)
                         decode_rd_as4 (pnt + 2, &rd_as);
                     else if (type == RD_TYPE_IP)                      else if (type == RD_TYPE_IP)
                       decode_rd_ip (pnt + 2, &rd_ip);                        decode_rd_ip (pnt + 2, &rd_ip);
   
Line 376  show_adj_route_vpn (struct vty *vty, struct peer *peer Line 457  show_adj_route_vpn (struct vty *vty, struct peer *peer
   
                     if (type == RD_TYPE_AS)                      if (type == RD_TYPE_AS)
                       vty_out (vty, "%u:%d", rd_as.as, rd_as.val);                        vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
                       else if (type == RD_TYPE_AS4)
                         vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
                     else if (type == RD_TYPE_IP)                      else if (type == RD_TYPE_IP)
                       vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);                        vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
   
Line 406  enum bgp_show_type Line 489  enum bgp_show_type
 };  };
   
 static int  static int
bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,bgp_show_mpls_vpn(
                   void *output_arg, int tags)    struct vty *vty,
     afi_t afi,
     struct prefix_rd *prd,
     enum bgp_show_type type,
     void *output_arg,
     int tags)
 {  {
   struct bgp *bgp;    struct bgp *bgp;
   struct bgp_table *table;    struct bgp_table *table;
Line 419  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd * Line 507  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *
   char v4_header[] = "   Network          Next Hop            Metric LocPrf Weight Path%s";    char v4_header[] = "   Network          Next Hop            Metric LocPrf Weight Path%s";
   char v4_header_tag[] = "   Network          Next Hop      In tag/Out tag%s";    char v4_header_tag[] = "   Network          Next Hop      In tag/Out tag%s";
   
     unsigned long output_count = 0;
     unsigned long total_count  = 0;
   
   bgp = bgp_get_default ();    bgp = bgp_get_default ();
   if (bgp == NULL)    if (bgp == NULL)
     {      {
Line 426  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd * Line 517  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *
       return CMD_WARNING;        return CMD_WARNING;
     }      }
       
  for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))  if ((afi != AFI_IP) && (afi != AFI_IP6))
     {      {
         vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
         return CMD_WARNING;
       }
   
     for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
       {
       if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)        if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
         continue;          continue;
   
Line 438  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd * Line 535  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *
           for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))            for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
             for (ri = rm->info; ri; ri = ri->next)              for (ri = rm->info; ri; ri = ri->next)
               {                {
                   total_count++;
                 if (type == bgp_show_type_neighbor)                  if (type == bgp_show_type_neighbor)
                   {                    {
                     union sockunion *su = output_arg;                      union sockunion *su = output_arg;
Line 476  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd * Line 574  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *
                     /* Decode RD value. */                      /* Decode RD value. */
                     if (type == RD_TYPE_AS)                      if (type == RD_TYPE_AS)
                       decode_rd_as (pnt + 2, &rd_as);                        decode_rd_as (pnt + 2, &rd_as);
                       else if (type == RD_TYPE_AS4)
                         decode_rd_as4 (pnt + 2, &rd_as);
                     else if (type == RD_TYPE_IP)                      else if (type == RD_TYPE_IP)
                       decode_rd_ip (pnt + 2, &rd_ip);                        decode_rd_ip (pnt + 2, &rd_ip);
   
                     vty_out (vty, "Route Distinguisher: ");                      vty_out (vty, "Route Distinguisher: ");
   
                     if (type == RD_TYPE_AS)                      if (type == RD_TYPE_AS)
                      vty_out (vty, "%u:%d", rd_as.as, rd_as.val);                      vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
                     else if (type == RD_TYPE_AS4)
                       vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
                     else if (type == RD_TYPE_IP)                      else if (type == RD_TYPE_IP)
                      vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);                      vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
                                       
                     vty_out (vty, "%s", VTY_NEWLINE);                                   vty_out (vty, "%s", VTY_NEWLINE);             
                     rd_header = 0;                      rd_header = 0;
Line 493  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd * Line 595  bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *
                   route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);                    route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
                 else                  else
                   route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);                    route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
                   output_count++;
               }                }
         }          }
     }      }
   
     if (output_count == 0)
       {
         vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
       }
     else
       vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s",
                VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
   
   return CMD_SUCCESS;    return CMD_SUCCESS;
 }  }
   
DEFUN (show_ip_bgp_vpnv4_all,DEFUN (show_bgp_ipv4_vpn,
       show_ip_bgp_vpnv4_all_cmd,       show_bgp_ipv4_vpn_cmd,
       "show ip bgp vpnv4 all",       "show bgp ipv4 vpn",
        SHOW_STR         SHOW_STR
        IP_STR  
        BGP_STR         BGP_STR
       "Display VPNv4 NLRI specific information\n"       "Address Family\n"
       "Display information about all VPNv4 NLRIs\n")       "Display VPN NLRI specific information\n")
 {  {
  return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);  return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0);
 }  }
   
DEFUN (show_ip_bgp_vpnv4_rd,DEFUN (show_bgp_ipv6_vpn,
       show_ip_bgp_vpnv4_rd_cmd,       show_bgp_ipv6_vpn_cmd,
       "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",       "show bgp ipv6 vpn",
        SHOW_STR         SHOW_STR
        IP_STR  
        BGP_STR         BGP_STR
       "Display VPNv4 NLRI specific information\n"       "Address Family\n"
        "Display VPN NLRI specific information\n")
 {
   return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0);
 }
 
 DEFUN (show_bgp_ipv4_vpn_rd,
        show_bgp_ipv4_vpn_rd_cmd,
        "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn",
        SHOW_STR
        BGP_STR
        "Address Family\n"
        "Display VPN NLRI specific information\n"
        "Display information for a route distinguisher\n"         "Display information for a route distinguisher\n"
        "VPN Route Distinguisher\n")         "VPN Route Distinguisher\n")
 {  {
Line 530  DEFUN (show_ip_bgp_vpnv4_rd, Line 652  DEFUN (show_ip_bgp_vpnv4_rd,
       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);        vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
       return CMD_WARNING;        return CMD_WARNING;
     }      }
  return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);  return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0);
 }  }
   
DEFUN (show_ip_bgp_vpnv4_all_tags,DEFUN (show_bgp_ipv6_vpn_rd,
       show_ip_bgp_vpnv4_all_tags_cmd,       show_bgp_ipv6_vpn_rd_cmd,
       "show ip bgp vpnv4 all tags",       "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn",
        SHOW_STR         SHOW_STR
        IP_STR  
        BGP_STR         BGP_STR
       "Display VPNv4 NLRI specific information\n"       "Address Family\n"
       "Display information about all VPNv4 NLRIs\n"       "Display VPN NLRI specific information\n"
        "Display information for a route distinguisher\n"
        "VPN Route Distinguisher\n")
 {
   int ret;
   struct prefix_rd prd;
 
   ret = str2prefix_rd (argv[0], &prd);
   if (! ret)
     {
       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
   return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0);
 }
 
 
 DEFUN (show_bgp_ipv4_vpn_tags,
        show_bgp_ipv4_vpn_tags_cmd,
        "show bgp ipv4 vpn tags",
        SHOW_STR
        BGP_STR
        "Address Family\n"
        "Display VPN NLRI specific information\n"
        "Display BGP tags for prefixes\n")         "Display BGP tags for prefixes\n")
 {  {
  return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL,  1);  return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL,  1);
 }  }
   DEFUN (show_bgp_ipv6_vpn_tags,
          show_bgp_ipv6_vpn_tags_cmd,
          "show bgp ipv6 vpn tags",
          SHOW_STR
          BGP_STR
          "Address Family\n"
          "Display VPN NLRI specific information\n"
          "Display BGP tags for prefixes\n")
   {
     return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL,  1);
   }
   
DEFUN (show_ip_bgp_vpnv4_rd_tags,DEFUN (show_bgp_ipv4_vpn_rd_tags,
       show_ip_bgp_vpnv4_rd_tags_cmd,       show_bgp_ipv4_vpn_rd_tags_cmd,
       "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",       "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn tags",
        SHOW_STR         SHOW_STR
        IP_STR  
        BGP_STR         BGP_STR
       "Display VPNv4 NLRI specific information\n"       "Address Family\n"
        "Display VPN NLRI specific information\n"
        "Display information for a route distinguisher\n"         "Display information for a route distinguisher\n"
        "VPN Route Distinguisher\n"         "VPN Route Distinguisher\n"
        "Display BGP tags for prefixes\n")         "Display BGP tags for prefixes\n")
Line 566  DEFUN (show_ip_bgp_vpnv4_rd_tags, Line 721  DEFUN (show_ip_bgp_vpnv4_rd_tags,
       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);        vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
       return CMD_WARNING;        return CMD_WARNING;
     }      }
  return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);  return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1);
 }  }
   DEFUN (show_bgp_ipv6_vpn_rd_tags,
          show_bgp_ipv6_vpn_rd_tags_cmd,
          "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn tags",
          SHOW_STR
          BGP_STR
          "Address Family\n"
          "Display VPN NLRI specific information\n"
          "Display information for a route distinguisher\n"
          "VPN Route Distinguisher\n"
          "Display BGP tags for prefixes\n")
   {
     int ret;
     struct prefix_rd prd;
   
DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,  ret = str2prefix_rd (argv[0], &prd);
       show_ip_bgp_vpnv4_all_neighbor_routes_cmd,  if (! ret)
       "show ip bgp vpnv4 all neighbors A.B.C.D routes",    {
       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
   return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 1);
 }
 
 DEFUN (show_bgp_ipv4_vpn_neighbor_routes,
        show_bgp_ipv4_vpn_neighbor_routes_cmd,
        "show bgp ipv4 vpn neighbors (A.B.C.D|X:X::X:X) routes",
        SHOW_STR         SHOW_STR
        IP_STR  
        BGP_STR         BGP_STR
       "Display VPNv4 NLRI specific information\n"       "Address Family\n"
       "Display information about all VPNv4 NLRIs\n"       "Display VPN NLRI specific information\n"
        "Detailed information on TCP and BGP neighbor connections\n"         "Detailed information on TCP and BGP neighbor connections\n"
        "Neighbor to display information about\n"         "Neighbor to display information about\n"
          "Neighbor to display information about\n"
        "Display routes learned from neighbor\n")         "Display routes learned from neighbor\n")
 {  {
   union sockunion su;    union sockunion su;
Line 599  DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes, Line 776  DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
       return CMD_WARNING;        return CMD_WARNING;
     }      }
   
  return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);  return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0);
 }  }
   
DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,DEFUN (show_bgp_ipv6_vpn_neighbor_routes,
       show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,       show_bgp_ipv6_vpn_neighbor_routes_cmd,
       "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",       "show bgp ipv6 vpn neighbors (A.B.C.D|X:X::X:X) routes",
        SHOW_STR         SHOW_STR
        IP_STR  
        BGP_STR         BGP_STR
       "Display VPNv4 NLRI specific information\n"       "Address Family\n"
       "Display information for a route distinguisher\n"       "Display VPN NLRI specific information\n"
       "VPN Route Distinguisher\n" 
        "Detailed information on TCP and BGP neighbor connections\n"         "Detailed information on TCP and BGP neighbor connections\n"
        "Neighbor to display information about\n"         "Neighbor to display information about\n"
          "Neighbor to display information about\n"
        "Display routes learned from neighbor\n")         "Display routes learned from neighbor\n")
 {  {
   int ret;  
   union sockunion su;    union sockunion su;
   struct peer *peer;    struct peer *peer;
   struct prefix_rd prd;  
   
  ret = str2prefix_rd (argv[0], &prd);  int ret;
  if (! ret) 
    { 
      vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); 
      return CMD_WARNING; 
    } 
   
  ret = str2sockunion (argv[1], &su);  ret = str2sockunion (argv[0], &su);
   if (ret < 0)    if (ret < 0)
     {      {
       vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);        vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Line 635  DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes, Line 804  DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
     }      }
   
   peer = peer_lookup (NULL, &su);    peer = peer_lookup (NULL, &su);
  if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])  if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
     {      {
       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);        vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
       return CMD_WARNING;        return CMD_WARNING;
     }      }
   
  return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);  return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0);
 }  }
   
DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,DEFUN (show_bgp_ipv4_vpn_neighbor_advertised_routes,
       show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,       show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd,
       "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",       "show bgp ipv4 vpn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
        SHOW_STR         SHOW_STR
        IP_STR  
        BGP_STR         BGP_STR
       "Display VPNv4 NLRI specific information\n"       "Address Family\n"
       "Display information about all VPNv4 NLRIs\n"       "Display VPN NLRI specific information\n"
        "Detailed information on TCP and BGP neighbor connections\n"         "Detailed information on TCP and BGP neighbor connections\n"
        "Neighbor to display information about\n"         "Neighbor to display information about\n"
        "Display the routes advertised to a BGP neighbor\n")         "Display the routes advertised to a BGP neighbor\n")
Line 675  DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_route Line 843  DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_route
   
   return show_adj_route_vpn (vty, peer, NULL);    return show_adj_route_vpn (vty, peer, NULL);
 }  }
   DEFUN (show_bgp_ipv6_vpn_neighbor_advertised_routes,
          show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd,
          "show bgp ipv6 vpn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
          SHOW_STR
          BGP_STR
          "Address Family\n"
          "Display VPN NLRI specific information\n"
          "Detailed information on TCP and BGP neighbor connections\n"
          "Neighbor to display information about\n"
          "Display the routes advertised to a BGP neighbor\n")
   {
     int ret;
     struct peer *peer;
     union sockunion su;
   
     ret = str2sockunion (argv[0], &su);
     if (ret < 0)
       {
         vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
         return CMD_WARNING;
       }
     peer = peer_lookup (NULL, &su);
     if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
       {
         vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
         return CMD_WARNING;
       }
   
     return show_adj_route_vpn (vty, peer, NULL);
   }
   
 DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,  DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
       show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,       show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd,
       "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",       "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
        SHOW_STR         SHOW_STR
        IP_STR  
        BGP_STR         BGP_STR
       "Display VPNv4 NLRI specific information\n"       "Address Family\n"
        "Display VPN NLRI specific information\n"
        "Display information for a route distinguisher\n"         "Display information for a route distinguisher\n"
        "VPN Route Distinguisher\n"         "VPN Route Distinguisher\n"
        "Detailed information on TCP and BGP neighbor connections\n"         "Detailed information on TCP and BGP neighbor connections\n"
        "Neighbor to display information about\n"         "Neighbor to display information about\n"
          "Neighbor to display information about\n"
        "Display the routes advertised to a BGP neighbor\n")         "Display the routes advertised to a BGP neighbor\n")
 {  {
   int ret;    int ret;
   struct peer *peer;    struct peer *peer;
   struct prefix_rd prd;    struct prefix_rd prd;
   union sockunion su;    union sockunion su;
   
   ret = str2sockunion (argv[1], &su);    ret = str2sockunion (argv[1], &su);
   if (ret < 0)    if (ret < 0)
     {      {
      vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);      vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
       return CMD_WARNING;        return CMD_WARNING;
     }      }
   peer = peer_lookup (NULL, &su);    peer = peer_lookup (NULL, &su);
Line 716  DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes Line 914  DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes
   
   return show_adj_route_vpn (vty, peer, &prd);    return show_adj_route_vpn (vty, peer, &prd);
 }  }
   DEFUN (show_ip_bgp_vpnv6_rd_neighbor_advertised_routes,
          show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd,
          "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) advertised-routes",
          SHOW_STR
          BGP_STR
          "Address Family\n"
          "Display VPN NLRI specific information\n"
          "Display information for a route distinguisher\n"
          "VPN Route Distinguisher\n"
          "Detailed information on TCP and BGP neighbor connections\n"
          "Neighbor to display information about\n"
          "Neighbor to display information about\n"
          "Display the routes advertised to a BGP neighbor\n")
   {
     int ret;
     struct peer *peer;
     struct prefix_rd prd;
     union sockunion su;
     ret = str2sockunion (argv[1], &su);
     if (ret < 0)
       {
         vty_out (vty, "%% Malformed address: %s%s", argv[1], VTY_NEWLINE);
         return CMD_WARNING;
       }
     peer = peer_lookup (NULL, &su);
     if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
       {
         vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
         return CMD_WARNING;
       }
   
     ret = str2prefix_rd (argv[0], &prd);
     if (! ret)
       {
         vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
         return CMD_WARNING;
       }
   
     return show_adj_route_vpn (vty, peer, &prd);
   }
   
   DEFUN (show_bgp_ipv4_vpn_rd_neighbor_routes,
          show_bgp_ipv4_vpn_rd_neighbor_routes_cmd,
          "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
          SHOW_STR
          BGP_STR
          "Address Family\n"
          "Address Family modifier\n"
          "Display information for a route distinguisher\n"
          "VPN Route Distinguisher\n"
          "Detailed information on TCP and BGP neighbor connections\n"
          "Neighbor to display information about\n"
          "Display routes learned from neighbor\n")
   {
     int ret;
     union sockunion *su;
     struct peer *peer;
     struct prefix_rd prd;
   
     ret = str2prefix_rd (argv[0], &prd);
     if (! ret)
       {
         vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
         return CMD_WARNING;
       }
   
     su = sockunion_str2su (argv[1]);
     if (su == NULL)
       {
         vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
                  return CMD_WARNING;
       }
   
     peer = peer_lookup (NULL, su);
     if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
       {
         vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
         return CMD_WARNING;
       }
   
     return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_neighbor, su, 0);
   }
   DEFUN (show_bgp_ipv6_vpn_rd_neighbor_routes,
          show_bgp_ipv6_vpn_rd_neighbor_routes_cmd,
          "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn neighbors (A.B.C.D|X:X::X:X) routes",
          SHOW_STR
          BGP_STR
          "Address Family\n"
          "Address Family modifier\n"
          "Display information for a route distinguisher\n"
          "VPN Route Distinguisher\n"
          "Detailed information on TCP and BGP neighbor connections\n"
          "Neighbor to display information about\n"
          "Display routes learned from neighbor\n")
   {
     int ret;
     union sockunion *su;
     struct peer *peer;
     struct prefix_rd prd;
   
     ret = str2prefix_rd (argv[0], &prd);
     if (! ret)
       {
         vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
         return CMD_WARNING;
       }
   
     su = sockunion_str2su (argv[1]);
     if (su == NULL)
       {
         vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
                  return CMD_WARNING;
       }
   
     peer = peer_lookup (NULL, su);
     if (! peer || ! peer->afc[AFI_IP6][SAFI_MPLS_VPN])
       {
         vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
         return CMD_WARNING;
       }
   
     return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_neighbor, su, 0);
   }
   
 void  void
 bgp_mplsvpn_init (void)  bgp_mplsvpn_init (void)
 {  {
   install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);    install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
     install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
   install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);    install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
   
     install_element (VIEW_NODE, &show_bgp_ipv4_vpn_cmd);
     install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_cmd);
     install_element (VIEW_NODE, &show_bgp_ipv4_vpn_tags_cmd);
     install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_tags_cmd);
     install_element (VIEW_NODE, &show_bgp_ipv4_vpn_neighbor_routes_cmd);
     install_element (VIEW_NODE, &show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd);
     install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd);
     install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_neighbor_routes_cmd);
   
  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_cmd);
  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_cmd);
  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_tags_cmd);
  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_tags_cmd);
  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_neighbor_routes_cmd);
  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd);
  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd);
  install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);  install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_neighbor_routes_cmd);
   
  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);  install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_cmd);
  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);  install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_cmd);
  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);  install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_tags_cmd);
  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);  install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_tags_cmd);
  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);  install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_neighbor_routes_cmd);
  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);  install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_neighbor_advertised_routes_cmd);
  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);  install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_neighbor_advertised_routes_cmd);
  install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);  install_element (ENABLE_NODE, &show_bgp_ipv4_vpn_rd_neighbor_routes_cmd);
 
   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_tags_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_tags_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_neighbor_routes_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_neighbor_advertised_routes_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_neighbor_advertised_routes_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_vpn_rd_neighbor_routes_cmd);
 }  }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


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