back to topotato report
topotato coverage report
Current view: top level - bgpd/rfapi - rfapi_vty.c (source / functions) Hit Total Coverage
Test: test_bgp_distance_change.py::BGPDistanceChange Lines: 52 2096 2.5 %
Date: 2023-02-24 18:37:13 Functions: 1 109 0.9 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2009-2016, LabN Consulting, L.L.C.
       4             :  *
       5             :  *
       6             :  * This program is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU General Public License
       8             :  * as published by the Free Software Foundation; either version 2
       9             :  * of the License, or (at your option) any later version.
      10             :  *
      11             :  * This program is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include "lib/zebra.h"
      22             : #include "lib/prefix.h"
      23             : #include "lib/agg_table.h"
      24             : #include "lib/vty.h"
      25             : #include "lib/memory.h"
      26             : #include "lib/routemap.h"
      27             : #include "lib/log.h"
      28             : #include "lib/linklist.h"
      29             : #include "lib/command.h"
      30             : 
      31             : #include "bgpd/bgpd.h"
      32             : #include "bgpd/bgp_ecommunity.h"
      33             : #include "bgpd/bgp_attr.h"
      34             : #include "bgpd/bgp_route.h"
      35             : #include "bgpd/bgp_mplsvpn.h"
      36             : 
      37             : #include "bgpd/rfapi/bgp_rfapi_cfg.h"
      38             : #include "bgpd/rfapi/rfapi.h"
      39             : #include "bgpd/rfapi/rfapi_backend.h"
      40             : 
      41             : #include "bgpd/bgp_route.h"
      42             : #include "bgpd/bgp_aspath.h"
      43             : #include "bgpd/bgp_community.h"
      44             : #include "bgpd/bgp_vnc_types.h"
      45             : #include "bgpd/bgp_label.h"
      46             : 
      47             : #include "bgpd/rfapi/rfapi_import.h"
      48             : #include "bgpd/rfapi/rfapi_private.h"
      49             : #include "bgpd/rfapi/rfapi_monitor.h"
      50             : #include "bgpd/rfapi/rfapi_rib.h"
      51             : #include "bgpd/rfapi/rfapi_vty.h"
      52             : #include "bgpd/rfapi/rfapi_ap.h"
      53             : #include "bgpd/rfapi/rfapi_encap_tlv.h"
      54             : #include "bgpd/rfapi/vnc_debug.h"
      55             : 
      56             : #define DEBUG_L2_EXTRA 0
      57             : #define DEBUG_SHOW_EXTRA 0
      58             : 
      59             : #define VNC_SHOW_STR "VNC information\n"
      60             : 
      61             : /* format related utilies */
      62             : 
      63             : 
      64             : #define FMT_MIN      60         /* seconds */
      65             : #define FMT_HOUR    (60  * FMT_MIN)
      66             : #define FMT_DAY     (24  * FMT_HOUR)
      67             : #define FMT_YEAR    (365 * FMT_DAY)
      68             : 
      69           0 : char *rfapiFormatSeconds(uint32_t seconds, char *buf, size_t len)
      70             : {
      71           0 :         int year, day, hour, min;
      72             : 
      73           0 :         if (seconds >= FMT_YEAR) {
      74           0 :                 year = seconds / FMT_YEAR;
      75           0 :                 seconds -= year * FMT_YEAR;
      76             :         } else
      77             :                 year = 0;
      78             : 
      79           0 :         if (seconds >= FMT_DAY) {
      80           0 :                 day = seconds / FMT_DAY;
      81           0 :                 seconds -= day * FMT_DAY;
      82             :         } else
      83             :                 day = 0;
      84             : 
      85           0 :         if (seconds >= FMT_HOUR) {
      86           0 :                 hour = seconds / FMT_HOUR;
      87           0 :                 seconds -= hour * FMT_HOUR;
      88             :         } else
      89             :                 hour = 0;
      90             : 
      91           0 :         if (seconds >= FMT_MIN) {
      92           0 :                 min = seconds / FMT_MIN;
      93           0 :                 seconds -= min * FMT_MIN;
      94             :         } else
      95             :                 min = 0;
      96             : 
      97           0 :         if (year > 0) {
      98           0 :                 snprintf(buf, len, "%dy%dd%dh", year, day, hour);
      99           0 :         } else if (day > 0) {
     100           0 :                 snprintf(buf, len, "%dd%dh%dm", day, hour, min);
     101             :         } else {
     102           0 :                 snprintf(buf, len, "%02d:%02d:%02d", hour, min, seconds);
     103             :         }
     104             : 
     105           0 :         return buf;
     106             : }
     107             : 
     108           0 : char *rfapiFormatAge(time_t age, char *buf, size_t len)
     109             : {
     110           0 :         time_t now, age_adjusted;
     111             : 
     112           0 :         now = monotime(NULL);
     113           0 :         age_adjusted = now - age;
     114             : 
     115           0 :         return rfapiFormatSeconds(age_adjusted, buf, len);
     116             : }
     117             : 
     118             : 
     119             : /*
     120             :  * Reimplementation of quagga/lib/prefix.c function, but
     121             :  * for RFAPI-style prefixes
     122             :  */
     123           0 : void rfapiRprefixApplyMask(struct rfapi_ip_prefix *rprefix)
     124             : {
     125           0 :         uint8_t *pnt;
     126           0 :         int index;
     127           0 :         int offset;
     128             : 
     129           0 :         static const uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
     130             :                                           0xf8, 0xfc, 0xfe, 0xff};
     131             : 
     132           0 :         switch (rprefix->prefix.addr_family) {
     133           0 :         case AF_INET:
     134           0 :                 index = rprefix->length / 8;
     135           0 :                 if (index < 4) {
     136           0 :                         pnt = (uint8_t *)&rprefix->prefix.addr.v4;
     137           0 :                         offset = rprefix->length % 8;
     138           0 :                         pnt[index] &= maskbit[offset];
     139           0 :                         index++;
     140           0 :                         while (index < 4)
     141           0 :                                 pnt[index++] = 0;
     142             :                 }
     143             :                 break;
     144             : 
     145           0 :         case AF_INET6:
     146           0 :                 index = rprefix->length / 8;
     147           0 :                 if (index < 16) {
     148           0 :                         pnt = (uint8_t *)&rprefix->prefix.addr.v6;
     149           0 :                         offset = rprefix->length % 8;
     150           0 :                         pnt[index] &= maskbit[offset];
     151           0 :                         index++;
     152           0 :                         while (index < 16)
     153           0 :                                 pnt[index++] = 0;
     154             :                 }
     155             :                 break;
     156             : 
     157             :         default:
     158           0 :                 assert(0);
     159             :         }
     160           0 : }
     161             : 
     162             : /*
     163             :  * translate a quagga prefix into a rfapi IP address. The
     164             :  * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
     165             :  *
     166             :  * RETURNS:
     167             :  *
     168             :  *      0       Success
     169             :  *      <0   Error
     170             :  */
     171           0 : int rfapiQprefix2Raddr(struct prefix *qprefix, struct rfapi_ip_addr *raddr)
     172             : {
     173           0 :         memset(raddr, 0, sizeof(struct rfapi_ip_addr));
     174           0 :         raddr->addr_family = qprefix->family;
     175           0 :         switch (qprefix->family) {
     176           0 :         case AF_INET:
     177           0 :                 if (qprefix->prefixlen != IPV4_MAX_BITLEN)
     178             :                         return -1;
     179           0 :                 raddr->addr.v4 = qprefix->u.prefix4;
     180           0 :                 break;
     181           0 :         case AF_INET6:
     182           0 :                 if (qprefix->prefixlen != IPV6_MAX_BITLEN)
     183             :                         return -1;
     184           0 :                 raddr->addr.v6 = qprefix->u.prefix6;
     185           0 :                 break;
     186             :         default:
     187             :                 return -1;
     188             :         }
     189             :         return 0;
     190             : }
     191             : 
     192             : /*
     193             :  * Translate Quagga prefix to RFAPI prefix
     194             :  */
     195             : /* rprefix->cost set to 0 */
     196           0 : void rfapiQprefix2Rprefix(const struct prefix *qprefix,
     197             :                           struct rfapi_ip_prefix *rprefix)
     198             : {
     199           0 :         memset(rprefix, 0, sizeof(struct rfapi_ip_prefix));
     200           0 :         rprefix->length = qprefix->prefixlen;
     201           0 :         rprefix->prefix.addr_family = qprefix->family;
     202           0 :         switch (qprefix->family) {
     203           0 :         case AF_INET:
     204           0 :                 rprefix->prefix.addr.v4 = qprefix->u.prefix4;
     205           0 :                 break;
     206           0 :         case AF_INET6:
     207           0 :                 rprefix->prefix.addr.v6 = qprefix->u.prefix6;
     208           0 :                 break;
     209             :         default:
     210           0 :                 assert(0);
     211             :         }
     212           0 : }
     213             : 
     214           0 : int rfapiRprefix2Qprefix(struct rfapi_ip_prefix *rprefix,
     215             :                          struct prefix *qprefix)
     216             : {
     217           0 :         memset(qprefix, 0, sizeof(struct prefix));
     218           0 :         qprefix->prefixlen = rprefix->length;
     219           0 :         qprefix->family = rprefix->prefix.addr_family;
     220             : 
     221           0 :         switch (rprefix->prefix.addr_family) {
     222           0 :         case AF_INET:
     223           0 :                 qprefix->u.prefix4 = rprefix->prefix.addr.v4;
     224           0 :                 break;
     225           0 :         case AF_INET6:
     226           0 :                 qprefix->u.prefix6 = rprefix->prefix.addr.v6;
     227           0 :                 break;
     228             :         default:
     229             :                 return EAFNOSUPPORT;
     230             :         }
     231             :         return 0;
     232             : }
     233             : 
     234             : /*
     235             :  * returns 1 if prefixes have same addr family, prefix len, and address
     236             :  * Note that host bits matter in this comparison!
     237             :  *
     238             :  * For paralellism with quagga/lib/prefix.c. if we need a comparison
     239             :  * where host bits are ignored, call that function rfapiRprefixCmp.
     240             :  */
     241           0 : int rfapiRprefixSame(struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2)
     242             : {
     243           0 :         if (hp1->prefix.addr_family != hp2->prefix.addr_family)
     244             :                 return 0;
     245           0 :         if (hp1->length != hp2->length)
     246             :                 return 0;
     247           0 :         if (hp1->prefix.addr_family == AF_INET)
     248           0 :                 if (IPV4_ADDR_SAME(&hp1->prefix.addr.v4, &hp2->prefix.addr.v4))
     249             :                         return 1;
     250           0 :         if (hp1->prefix.addr_family == AF_INET6)
     251           0 :                 if (IPV6_ADDR_SAME(&hp1->prefix.addr.v6, &hp2->prefix.addr.v6))
     252             :                         return 1;
     253             :         return 0;
     254             : }
     255             : 
     256           0 : int rfapiRaddr2Qprefix(struct rfapi_ip_addr *hia, struct prefix *pfx)
     257             : {
     258           0 :         memset(pfx, 0, sizeof(struct prefix));
     259           0 :         pfx->family = hia->addr_family;
     260             : 
     261           0 :         switch (hia->addr_family) {
     262           0 :         case AF_INET:
     263           0 :                 pfx->prefixlen = IPV4_MAX_BITLEN;
     264           0 :                 pfx->u.prefix4 = hia->addr.v4;
     265           0 :                 break;
     266           0 :         case AF_INET6:
     267           0 :                 pfx->prefixlen = IPV6_MAX_BITLEN;
     268           0 :                 pfx->u.prefix6 = hia->addr.v6;
     269           0 :                 break;
     270             :         default:
     271             :                 return EAFNOSUPPORT;
     272             :         }
     273             :         return 0;
     274             : }
     275             : 
     276           0 : void rfapiL2o2Qprefix(struct rfapi_l2address_option *l2o, struct prefix *pfx)
     277             : {
     278           0 :         memset(pfx, 0, sizeof(struct prefix));
     279           0 :         pfx->family = AF_ETHERNET;
     280           0 :         pfx->prefixlen = 48;
     281           0 :         pfx->u.prefix_eth = l2o->macaddr;
     282           0 : }
     283             : 
     284           0 : char *rfapiEthAddr2Str(const struct ethaddr *ea, char *buf, int bufsize)
     285             : {
     286           0 :         return prefix_mac2str(ea, buf, bufsize);
     287             : }
     288             : 
     289           0 : int rfapiStr2EthAddr(const char *str, struct ethaddr *ea)
     290             : {
     291           0 :         unsigned int a[6];
     292           0 :         int i;
     293             : 
     294           0 :         if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1, a + 2, a + 3,
     295             :                    a + 4, a + 5)
     296             :             != 6) {
     297             : 
     298             :                 return EINVAL;
     299             :         }
     300             : 
     301           0 :         for (i = 0; i < 6; ++i)
     302           0 :                 ea->octet[i] = a[i] & 0xff;
     303             : 
     304             :         return 0;
     305             : }
     306             : 
     307           0 : const char *rfapi_ntop(int af, const void *src, char *buf, socklen_t size)
     308             : {
     309           0 :         if (af == AF_ETHERNET) {
     310           0 :                 return rfapiEthAddr2Str((const struct ethaddr *)src, buf, size);
     311             :         }
     312             : 
     313           0 :         return inet_ntop(af, src, buf, size);
     314             : }
     315             : 
     316           0 : int rfapiDebugPrintf(void *dummy, const char *format, ...)
     317             : {
     318           0 :         va_list args;
     319           0 :         va_start(args, format);
     320           0 :         vzlog(LOG_DEBUG, format, args);
     321           0 :         va_end(args);
     322           0 :         return 0;
     323             : }
     324             : 
     325             : PRINTFRR(2, 3)
     326           0 : static int rfapiStdioPrintf(void *stream, const char *format, ...)
     327             : {
     328           0 :         FILE *file = NULL;
     329             : 
     330           0 :         va_list args;
     331           0 :         va_start(args, format);
     332             : 
     333           0 :         switch ((uintptr_t)stream) {
     334           0 :         case 1:
     335           0 :                 file = stdout;
     336           0 :                 break;
     337           0 :         case 2:
     338           0 :                 file = stderr;
     339           0 :                 break;
     340             :         default:
     341           0 :                 assert(0);
     342             :         }
     343             : 
     344           0 :         vfprintf(file, format, args);
     345           0 :         va_end(args);
     346           0 :         return 0;
     347             : }
     348             : 
     349             : /* Fake out for debug logging */
     350             : static struct vty vty_dummy_zlog;
     351             : static struct vty vty_dummy_stdio;
     352             : #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n")
     353             : 
     354           0 : static const char *str_vty_newline(struct vty *vty)
     355             : {
     356           0 :         if (vty == &vty_dummy_zlog)
     357           0 :                 return "";
     358             :         return "\n";
     359             : }
     360             : 
     361           0 : int rfapiStream2Vty(void *stream,                          /* input */
     362             :                     int (**fp)(void *, const char *, ...), /* output */
     363             :                     struct vty **vty,                      /* output */
     364             :                     void **outstream,                      /* output */
     365             :                     const char **vty_newline)              /* output */
     366             : {
     367             : 
     368           0 :         if (!stream) {
     369           0 :                 vty_dummy_zlog.type = VTY_SHELL; /* for VTYNL */
     370           0 :                 *vty = &vty_dummy_zlog;
     371           0 :                 *fp = (int (*)(void *, const char *, ...))rfapiDebugPrintf;
     372           0 :                 *outstream = NULL;
     373           0 :                 *vty_newline = str_vty_newline(*vty);
     374           0 :                 return 1;
     375             :         }
     376             : 
     377           0 :         if (((uintptr_t)stream == (uintptr_t)1)
     378           0 :             || ((uintptr_t)stream == (uintptr_t)2)) {
     379             : 
     380           0 :                 vty_dummy_stdio.type = VTY_SHELL; /* for VTYNL */
     381           0 :                 *vty = &vty_dummy_stdio;
     382           0 :                 *fp = (int (*)(void *, const char *, ...))rfapiStdioPrintf;
     383           0 :                 *outstream = stream;
     384           0 :                 *vty_newline = str_vty_newline(*vty);
     385           0 :                 return 1;
     386             :         }
     387             : 
     388           0 :         *vty = stream; /* VTYNL requires vty to be legit */
     389           0 :         *fp = (int (*)(void *, const char *, ...))vty_out;
     390           0 :         *outstream = stream;
     391           0 :         *vty_newline = str_vty_newline(*vty);
     392           0 :         return 1;
     393             : }
     394             : 
     395             : /* called from bgpd/bgp_vty.c'route_vty_out() */
     396           0 : void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p,
     397             :                            struct bgp_path_info *bpi, safi_t safi)
     398             : {
     399           0 :         char *s;
     400           0 :         uint32_t lifetime;
     401             : 
     402             :         /*
     403             :          * Print, on an indented line:
     404             :          *  UN address [if VPN route and VNC UN addr subtlv]
     405             :          *  EC list
     406             :          *  VNC lifetime
     407             :          */
     408           0 :         vty_out(vty, "    ");
     409             : 
     410           0 :         if (safi == SAFI_MPLS_VPN) {
     411           0 :                 struct prefix pfx_un;
     412             : 
     413           0 :                 if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) {
     414           0 :                         char buf[BUFSIZ];
     415             : 
     416           0 :                         vty_out(vty, "UN=%s",
     417           0 :                                 inet_ntop(pfx_un.family, pfx_un.u.val, buf,
     418             :                                           sizeof(buf)));
     419             :                 }
     420             :         }
     421             : 
     422           0 :         if (bgp_attr_get_ecommunity(bpi->attr)) {
     423           0 :                 s = ecommunity_ecom2str(bgp_attr_get_ecommunity(bpi->attr),
     424             :                                         ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
     425           0 :                 vty_out(vty, " EC{%s}", s);
     426           0 :                 XFREE(MTYPE_ECOMMUNITY_STR, s);
     427             :         }
     428             : 
     429           0 :         if (bpi->extra != NULL) {
     430           0 :                 if (bpi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
     431           0 :                         vty_out(vty, " label=VRF2VRF");
     432             :                 else
     433           0 :                         vty_out(vty, " label=%u",
     434             :                                 decode_label(&bpi->extra->label[0]));
     435             : 
     436           0 :                 if (bpi->extra->num_sids) {
     437           0 :                         vty_out(vty, " sid=%pI6", &bpi->extra->sid[0].sid);
     438             : 
     439           0 :                         if (bpi->extra->sid[0].loc_block_len != 0) {
     440           0 :                                 vty_out(vty, " sid_structure=[%d,%d,%d,%d]",
     441             :                                         bpi->extra->sid[0].loc_block_len,
     442           0 :                                         bpi->extra->sid[0].loc_node_len,
     443           0 :                                         bpi->extra->sid[0].func_len,
     444           0 :                                         bpi->extra->sid[0].arg_len);
     445             :                         }
     446             :                 }
     447             :         }
     448             : 
     449           0 :         if (!rfapiGetVncLifetime(bpi->attr, &lifetime)) {
     450           0 :                 vty_out(vty, " life=%d", lifetime);
     451             :         }
     452             : 
     453           0 :         vty_out(vty, " type=%s, subtype=%d", zebra_route_string(bpi->type),
     454           0 :                 bpi->sub_type);
     455             : 
     456           0 :         vty_out(vty, "%s", HVTYNL);
     457           0 : }
     458             : 
     459           0 : void rfapiPrintAttrPtrs(void *stream, struct attr *attr)
     460             : {
     461           0 :         int (*fp)(void *, const char *, ...);
     462           0 :         struct vty *vty;
     463           0 :         void *out;
     464           0 :         const char *vty_newline;
     465           0 :         struct transit *transit;
     466           0 :         struct cluster_list *cluster;
     467           0 :         struct ecommunity *ecomm;
     468           0 :         struct community *comm;
     469             : 
     470           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
     471           0 :                 return;
     472             : 
     473           0 :         fp(out, "Attr[%p]:%s", attr, HVTYNL);
     474           0 :         if (!attr)
     475             :                 return;
     476             : 
     477             :         /* IPv4 Nexthop */
     478           0 :         fp(out, "  nexthop=%pI4%s", &attr->nexthop, HVTYNL);
     479             : 
     480           0 :         fp(out, "  aspath=%p, refcnt=%d%s", attr->aspath,
     481           0 :            (attr->aspath ? attr->aspath->refcnt : 0), HVTYNL);
     482             : 
     483           0 :         comm = bgp_attr_get_community(attr);
     484           0 :         fp(out, "  community=%p, refcnt=%d%s", comm, (comm ? comm->refcnt : 0),
     485             :            HVTYNL);
     486             : 
     487           0 :         ecomm = bgp_attr_get_ecommunity(attr);
     488           0 :         fp(out, "  ecommunity=%p, refcnt=%d%s", ecomm,
     489             :            (ecomm ? ecomm->refcnt : 0), HVTYNL);
     490             : 
     491           0 :         cluster = bgp_attr_get_cluster(attr);
     492           0 :         fp(out, "  cluster=%p, refcnt=%d%s", cluster,
     493             :            (cluster ? cluster->refcnt : 0), HVTYNL);
     494             : 
     495           0 :         transit = bgp_attr_get_transit(attr);
     496           0 :         fp(out, "  transit=%p, refcnt=%d%s", transit,
     497             :            (transit ? transit->refcnt : 0), HVTYNL);
     498             : }
     499             : 
     500             : /*
     501             :  * Print BPI in an Import Table
     502             :  */
     503           0 : void rfapiPrintBi(void *stream, struct bgp_path_info *bpi)
     504             : {
     505           0 :         char buf[BUFSIZ];
     506           0 :         char *s;
     507             : 
     508           0 :         int (*fp)(void *, const char *, ...);
     509           0 :         struct vty *vty;
     510           0 :         void *out;
     511           0 :         const char *vty_newline;
     512             : 
     513           0 :         char line[BUFSIZ];
     514           0 :         char *p = line;
     515           0 :         int r;
     516           0 :         int has_macaddr = 0;
     517           0 :         struct ethaddr macaddr = {{0}};
     518           0 :         struct rfapi_l2address_option l2o_buf;
     519           0 :         uint8_t l2hid = 0; /* valid if has_macaddr */
     520             : 
     521             : #define REMAIN (BUFSIZ - (p-line))
     522             : #define INCP {p += (r > REMAIN)? REMAIN: r;}
     523             : 
     524           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
     525           0 :                 return;
     526             : 
     527           0 :         if (!bpi)
     528             :                 return;
     529             : 
     530           0 :         if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
     531           0 :             && bpi->extra->vnc.import.timer) {
     532           0 :                 struct thread *t =
     533             :                         (struct thread *)bpi->extra->vnc.import.timer;
     534           0 :                 r = snprintf(p, REMAIN, " [%4lu] ",
     535             :                              thread_timer_remain_second(t));
     536           0 :                 INCP;
     537             : 
     538             :         } else {
     539           0 :                 r = snprintf(p, REMAIN, "        ");
     540           0 :                 INCP;
     541             :         }
     542             : 
     543           0 :         if (bpi->extra) {
     544             :                 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
     545           0 :                 if (decode_rd_type(bpi->extra->vnc.import.rd.val)
     546             :                     == RD_TYPE_VNC_ETH) {
     547           0 :                         has_macaddr = 1;
     548           0 :                         memcpy(macaddr.octet, bpi->extra->vnc.import.rd.val + 2,
     549             :                                6);
     550           0 :                         l2hid = bpi->extra->vnc.import.rd.val[1];
     551             :                 }
     552             :         }
     553             : 
     554             :         /*
     555             :          * Print these items:
     556             :          *          type/subtype
     557             :          *          nexthop address
     558             :          *          lifetime
     559             :          *          RFP option sizes (they are opaque values)
     560             :          *          extended communities (RTs)
     561             :          */
     562           0 :         uint32_t lifetime;
     563           0 :         int printed_1st_gol = 0;
     564           0 :         struct bgp_attr_encap_subtlv *pEncap;
     565           0 :         struct prefix pfx_un;
     566           0 :         int af = BGP_MP_NEXTHOP_FAMILY(bpi->attr->mp_nexthop_len);
     567             : 
     568             :         /* Nexthop */
     569           0 :         if (af == AF_INET) {
     570           0 :                 r = snprintfrr(p, REMAIN, "%pI4",
     571             :                                &bpi->attr->mp_nexthop_global_in);
     572           0 :                 INCP;
     573           0 :         } else if (af == AF_INET6) {
     574           0 :                 r = snprintfrr(p, REMAIN, "%pI6",
     575             :                                &bpi->attr->mp_nexthop_global);
     576           0 :                 INCP;
     577             :         } else {
     578           0 :                 r = snprintf(p, REMAIN, "?");
     579           0 :                 INCP;
     580             :         }
     581             : 
     582             :         /*
     583             :          * VNC tunnel subtlv, if present, contains UN address
     584             :          */
     585           0 :         if (!rfapiGetVncTunnelUnAddr(bpi->attr, &pfx_un)) {
     586           0 :                 r = snprintf(p, REMAIN, " un=%s",
     587           0 :                              inet_ntop(pfx_un.family, pfx_un.u.val, buf,
     588             :                                        sizeof(buf)));
     589           0 :                 INCP;
     590             :         }
     591             : 
     592             :         /* Lifetime */
     593           0 :         if (rfapiGetVncLifetime(bpi->attr, &lifetime)) {
     594           0 :                 r = snprintf(p, REMAIN, " nolife");
     595           0 :                 INCP;
     596             :         } else {
     597           0 :                 if (lifetime == 0xffffffff)
     598           0 :                         r = snprintf(p, REMAIN, " %6s", "infini");
     599             :                 else
     600           0 :                         r = snprintf(p, REMAIN, " %6u", lifetime);
     601           0 :                 INCP;
     602             :         }
     603             : 
     604             :         /* RFP option lengths */
     605           0 :         for (pEncap = bgp_attr_get_vnc_subtlvs(bpi->attr); pEncap;
     606           0 :              pEncap = pEncap->next) {
     607             : 
     608           0 :                 if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) {
     609           0 :                         if (printed_1st_gol) {
     610           0 :                                 r = snprintf(p, REMAIN, ",");
     611           0 :                                 INCP;
     612             :                         } else {
     613           0 :                                 r = snprintf(p, REMAIN,
     614             :                                              " "); /* leading space */
     615           0 :                                 INCP;
     616             :                         }
     617           0 :                         r = snprintf(p, REMAIN, "%d", pEncap->length);
     618           0 :                         INCP;
     619           0 :                         printed_1st_gol = 1;
     620             :                 }
     621             :         }
     622             : 
     623             :         /* RT list */
     624           0 :         if (bgp_attr_get_ecommunity(bpi->attr)) {
     625           0 :                 s = ecommunity_ecom2str(bgp_attr_get_ecommunity(bpi->attr),
     626             :                                         ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
     627           0 :                 r = snprintf(p, REMAIN, " %s", s);
     628           0 :                 INCP;
     629           0 :                 XFREE(MTYPE_ECOMMUNITY_STR, s);
     630             :         }
     631             : 
     632           0 :         r = snprintf(p, REMAIN, " bpi@%p", bpi);
     633           0 :         INCP;
     634             : 
     635           0 :         r = snprintf(p, REMAIN, " p@%p", bpi->peer);
     636           0 :         INCP;
     637             : 
     638           0 :         if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
     639           0 :                 r = snprintf(p, REMAIN, " HD=yes");
     640           0 :                 INCP;
     641             :         } else {
     642           0 :                 r = snprintf(p, REMAIN, " HD=no");
     643           0 :                 INCP;
     644             :         }
     645             : 
     646           0 :         if (bpi->attr->weight) {
     647           0 :                 r = snprintf(p, REMAIN, " W=%d", bpi->attr->weight);
     648           0 :                 INCP;
     649             :         }
     650             : 
     651           0 :         if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
     652           0 :                 r = snprintf(p, REMAIN, " LP=%d", bpi->attr->local_pref);
     653           0 :                 INCP;
     654             :         } else {
     655           0 :                 r = snprintf(p, REMAIN, " LP=unset");
     656           0 :                 INCP;
     657             :         }
     658             : 
     659           0 :         r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bpi->type),
     660           0 :                      bpi->sub_type);
     661           0 :         INCP;
     662             : 
     663           0 :         fp(out, "%s%s", line, HVTYNL);
     664             : 
     665           0 :         if (has_macaddr) {
     666           0 :                 fp(out, "        RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
     667             :                    l2hid, macaddr.octet[0], macaddr.octet[1], macaddr.octet[2],
     668             :                    macaddr.octet[3], macaddr.octet[4], macaddr.octet[5],
     669             :                    HVTYNL);
     670             :         }
     671             : 
     672           0 :         if (!rfapiGetL2o(bpi->attr, &l2o_buf)) {
     673           0 :                 fp(out,
     674             :                    "        L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
     675           0 :                    l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1],
     676           0 :                    l2o_buf.macaddr.octet[2], l2o_buf.macaddr.octet[3],
     677           0 :                    l2o_buf.macaddr.octet[4], l2o_buf.macaddr.octet[5],
     678           0 :                    l2o_buf.label, l2o_buf.logical_net_id, l2o_buf.local_nve_id,
     679             :                    HVTYNL);
     680             :         }
     681           0 :         if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
     682           0 :                 const char *sp;
     683             : 
     684           0 :                 sp = rfapi_ntop(bpi->extra->vnc.import.aux_prefix.family,
     685           0 :                                 &bpi->extra->vnc.import.aux_prefix.u.prefix,
     686             :                                 buf, BUFSIZ);
     687           0 :                 buf[BUFSIZ - 1] = 0;
     688           0 :                 if (sp) {
     689           0 :                         fp(out, "        IP: %s%s", sp, HVTYNL);
     690             :                 }
     691             :         }
     692             :         {
     693           0 :                 struct rfapi_un_option *uo =
     694           0 :                         rfapi_encap_tlv_to_un_option(bpi->attr);
     695           0 :                 if (uo) {
     696           0 :                         rfapi_print_tunneltype_option(stream, 8, &uo->v.tunnel);
     697           0 :                         rfapi_un_options_free(uo);
     698             :                 }
     699             :         }
     700             : }
     701             : 
     702           0 : char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn *m, char *buf, int size)
     703             : {
     704           0 :         char buf_pfx[BUFSIZ];
     705           0 :         char buf_vn[BUFSIZ];
     706           0 :         char buf_un[BUFSIZ];
     707           0 :         int rc;
     708             : 
     709           0 :         rfapiRfapiIpAddr2Str(&m->rfd->un_addr, buf_vn, BUFSIZ);
     710           0 :         rfapiRfapiIpAddr2Str(&m->rfd->vn_addr, buf_un, BUFSIZ);
     711             : 
     712           0 :         rc = snprintf(buf, size,
     713             :                       "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m,
     714             :                       m->next, m->rfd, buf_vn, buf_un,
     715           0 :                       inet_ntop(m->p.family, &m->p.u.prefix, buf_pfx,
     716             :                                 sizeof(buf_pfx)),
     717           0 :                       m->p.prefixlen, m->node);
     718           0 :         buf[size - 1] = 0;
     719           0 :         if (rc >= size)
     720           0 :                 return NULL;
     721             :         return buf;
     722             : }
     723             : 
     724           0 : static void rfapiDebugPrintMonitorVpn(void *stream, struct rfapi_monitor_vpn *m)
     725             : {
     726           0 :         char buf[BUFSIZ];
     727             : 
     728           0 :         int (*fp)(void *, const char *, ...);
     729           0 :         struct vty *vty;
     730           0 :         void *out;
     731           0 :         const char *vty_newline;
     732             : 
     733           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
     734           0 :                 return;
     735             : 
     736           0 :         rfapiMonitorVpn2Str(m, buf, BUFSIZ);
     737           0 :         fp(out, "    Mon %s%s", buf, HVTYNL);
     738             : }
     739             : 
     740           0 : static void rfapiDebugPrintMonitorEncap(void *stream,
     741             :                                         struct rfapi_monitor_encap *m)
     742             : {
     743           0 :         int (*fp)(void *, const char *, ...);
     744           0 :         struct vty *vty;
     745           0 :         void *out = NULL;
     746           0 :         const char *vty_newline;
     747             : 
     748           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
     749           0 :                 return;
     750             : 
     751           0 :         fp(out, "    Mon m=%p, next=%p, node=%p, bpi=%p%s", m, m->next, m->node,
     752           0 :            m->bpi, HVTYNL);
     753             : }
     754             : 
     755           0 : void rfapiShowItNode(void *stream, struct agg_node *rn)
     756             : {
     757           0 :         struct bgp_path_info *bpi;
     758             : 
     759           0 :         int (*fp)(void *, const char *, ...);
     760           0 :         struct vty *vty;
     761           0 :         void *out;
     762           0 :         const char *vty_newline;
     763             : 
     764           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
     765           0 :                 return;
     766             : 
     767           0 :         fp(out, "%pRN @%p #%d%s", rn, rn, agg_node_get_lock_count(rn), HVTYNL);
     768             : 
     769           0 :         for (bpi = rn->info; bpi; bpi = bpi->next) {
     770           0 :                 rfapiPrintBi(stream, bpi);
     771             :         }
     772             : 
     773             :         /* doesn't show montors */
     774             : }
     775             : 
     776           0 : void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt,
     777             :                           int isvpn)
     778             : {
     779           0 :         struct agg_node *rn;
     780           0 :         char buf[BUFSIZ];
     781             : 
     782           0 :         int (*fp)(void *, const char *, ...);
     783           0 :         struct vty *vty;
     784           0 :         void *out;
     785           0 :         const char *vty_newline;
     786             : 
     787           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
     788           0 :                 return;
     789             : 
     790           0 :         fp(out, "Import Table [%s]%s", label, HVTYNL);
     791             : 
     792           0 :         for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
     793           0 :                 struct bgp_path_info *bpi;
     794           0 :                 const struct prefix *p = agg_node_get_prefix(rn);
     795             : 
     796           0 :                 if (p->family == AF_ETHERNET) {
     797           0 :                         rfapiEthAddr2Str(&p->u.prefix_eth, buf, sizeof(buf));
     798             :                 } else {
     799           0 :                         inet_ntop(p->family, &p->u.prefix, buf, sizeof(buf));
     800             :                 }
     801             : 
     802           0 :                 fp(out, "%s/%d @%p #%d%s", buf, p->prefixlen, rn,
     803           0 :                    agg_node_get_lock_count(rn)
     804             :                            - 1, /* account for loop iterator locking */
     805             :                    HVTYNL);
     806             : 
     807           0 :                 for (bpi = rn->info; bpi; bpi = bpi->next) {
     808           0 :                         rfapiPrintBi(stream, bpi);
     809             :                 }
     810             : 
     811           0 :                 if (isvpn) {
     812           0 :                         struct rfapi_monitor_vpn *m;
     813           0 :                         for (m = RFAPI_MONITOR_VPN(rn); m; m = m->next) {
     814           0 :                                 rfapiDebugPrintMonitorVpn(stream, m);
     815             :                         }
     816             :                 } else {
     817           0 :                         struct rfapi_monitor_encap *m;
     818           0 :                         for (m = RFAPI_MONITOR_ENCAP(rn); m; m = m->next) {
     819           0 :                                 rfapiDebugPrintMonitorEncap(stream, m);
     820             :                         }
     821             :                 }
     822             :         }
     823             : }
     824             : 
     825           0 : int rfapiShowVncQueries(void *stream, struct prefix *pfx_match)
     826             : {
     827           0 :         struct bgp *bgp;
     828           0 :         struct rfapi *h;
     829           0 :         struct listnode *node;
     830           0 :         struct rfapi_descriptor *rfd;
     831             : 
     832           0 :         int (*fp)(void *, const char *, ...);
     833           0 :         struct vty *vty;
     834           0 :         void *out;
     835           0 :         const char *vty_newline;
     836             : 
     837           0 :         int printedheader = 0;
     838             : 
     839           0 :         int nves_total = 0;
     840           0 :         int nves_with_queries = 0;
     841           0 :         int nves_displayed = 0;
     842             : 
     843           0 :         int queries_total = 0;
     844           0 :         int queries_displayed = 0;
     845             : 
     846           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
     847             :                 return CMD_WARNING;
     848             : 
     849           0 :         bgp = bgp_get_default(); /* assume 1 instance for now */
     850           0 :         if (!bgp) {
     851           0 :                 vty_out(vty, "No BGP instance\n");
     852           0 :                 return CMD_WARNING;
     853             :         }
     854             : 
     855           0 :         h = bgp->rfapi;
     856           0 :         if (!h) {
     857           0 :                 vty_out(vty, "No RFAPI instance\n");
     858           0 :                 return CMD_WARNING;
     859             :         }
     860             : 
     861           0 :         for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) {
     862             : 
     863           0 :                 struct agg_node *rn;
     864           0 :                 int printedquerier = 0;
     865             : 
     866             : 
     867           0 :                 ++nves_total;
     868             : 
     869           0 :                 if (rfd->mon
     870           0 :                     || (rfd->mon_eth && skiplist_count(rfd->mon_eth))) {
     871           0 :                         ++nves_with_queries;
     872             :                 } else {
     873           0 :                         continue;
     874             :                 }
     875             : 
     876             :                 /*
     877             :                  * IP Queries
     878             :                  */
     879           0 :                 if (rfd->mon) {
     880           0 :                         for (rn = agg_route_top(rfd->mon); rn;
     881           0 :                              rn = agg_route_next(rn)) {
     882           0 :                                 const struct prefix *p =
     883           0 :                                         agg_node_get_prefix(rn);
     884           0 :                                 struct rfapi_monitor_vpn *m;
     885           0 :                                 char buf_remain[BUFSIZ];
     886           0 :                                 char buf_pfx[BUFSIZ];
     887             : 
     888           0 :                                 if (!rn->info)
     889           0 :                                         continue;
     890             : 
     891           0 :                                 m = rn->info;
     892             : 
     893           0 :                                 ++queries_total;
     894             : 
     895           0 :                                 if (pfx_match && !prefix_match(pfx_match, p)
     896           0 :                                     && !prefix_match(p, pfx_match))
     897           0 :                                         continue;
     898             : 
     899           0 :                                 ++queries_displayed;
     900             : 
     901           0 :                                 if (!printedheader) {
     902           0 :                                         ++printedheader;
     903           0 :                                         fp(out, "\n");
     904           0 :                                         fp(out, "%-15s %-15s %-15s %-10s\n",
     905             :                                            "VN Address", "UN Address", "Target",
     906             :                                            "Remaining");
     907             :                                 }
     908             : 
     909           0 :                                 if (!printedquerier) {
     910           0 :                                         char buf_vn[BUFSIZ];
     911           0 :                                         char buf_un[BUFSIZ];
     912             : 
     913           0 :                                         rfapiRfapiIpAddr2Str(&rfd->un_addr,
     914             :                                                              buf_un, BUFSIZ);
     915           0 :                                         rfapiRfapiIpAddr2Str(&rfd->vn_addr,
     916             :                                                              buf_vn, BUFSIZ);
     917             : 
     918           0 :                                         fp(out, "%-15s %-15s", buf_vn, buf_un);
     919           0 :                                         printedquerier = 1;
     920             : 
     921           0 :                                         ++nves_displayed;
     922             :                                 } else
     923           0 :                                         fp(out, "%-15s %-15s", "", "");
     924           0 :                                 buf_remain[0] = 0;
     925           0 :                                 rfapiFormatSeconds(
     926           0 :                                         thread_timer_remain_second(m->timer),
     927             :                                         buf_remain, BUFSIZ);
     928           0 :                                 fp(out, " %-15s %-10s\n",
     929           0 :                                    inet_ntop(m->p.family, &m->p.u.prefix,
     930             :                                              buf_pfx, sizeof(buf_pfx)),
     931             :                                    buf_remain);
     932             :                         }
     933             :                 }
     934             : 
     935             :                 /*
     936             :                  * Ethernet Queries
     937             :                  */
     938           0 :                 if (rfd->mon_eth && skiplist_count(rfd->mon_eth)) {
     939             : 
     940           0 :                         int rc;
     941           0 :                         void *cursor;
     942           0 :                         struct rfapi_monitor_eth *mon_eth;
     943             : 
     944           0 :                         for (cursor = NULL,
     945           0 :                             rc = skiplist_next(rfd->mon_eth, NULL,
     946             :                                                (void **)&mon_eth, &cursor);
     947           0 :                              rc == 0;
     948           0 :                              rc = skiplist_next(rfd->mon_eth, NULL,
     949             :                                                 (void **)&mon_eth, &cursor)) {
     950             : 
     951           0 :                                 char buf_remain[BUFSIZ];
     952           0 :                                 char buf_pfx[BUFSIZ];
     953           0 :                                 struct prefix pfx_mac;
     954             : 
     955           0 :                                 ++queries_total;
     956             : 
     957           0 :                                 vnc_zlog_debug_verbose(
     958             :                                         "%s: checking rfd=%p mon_eth=%p",
     959             :                                         __func__, rfd, mon_eth);
     960             : 
     961           0 :                                 memset((void *)&pfx_mac, 0,
     962             :                                        sizeof(struct prefix));
     963           0 :                                 pfx_mac.family = AF_ETHERNET;
     964           0 :                                 pfx_mac.prefixlen = 48;
     965           0 :                                 pfx_mac.u.prefix_eth = mon_eth->macaddr;
     966             : 
     967           0 :                                 if (pfx_match
     968           0 :                                     && !prefix_match(pfx_match, &pfx_mac)
     969           0 :                                     && !prefix_match(&pfx_mac, pfx_match))
     970           0 :                                         continue;
     971             : 
     972           0 :                                 ++queries_displayed;
     973             : 
     974           0 :                                 if (!printedheader) {
     975           0 :                                         ++printedheader;
     976           0 :                                         fp(out, "\n");
     977           0 :                                         fp(out,
     978             :                                            "%-15s %-15s %-17s %10s %-10s\n",
     979             :                                            "VN Address", "UN Address", "Target",
     980             :                                            "LNI", "Remaining");
     981             :                                 }
     982             : 
     983           0 :                                 if (!printedquerier) {
     984           0 :                                         char buf_vn[BUFSIZ];
     985           0 :                                         char buf_un[BUFSIZ];
     986             : 
     987           0 :                                         rfapiRfapiIpAddr2Str(&rfd->un_addr,
     988             :                                                              buf_un, BUFSIZ);
     989           0 :                                         rfapiRfapiIpAddr2Str(&rfd->vn_addr,
     990             :                                                              buf_vn, BUFSIZ);
     991             : 
     992           0 :                                         fp(out, "%-15s %-15s", buf_vn, buf_un);
     993           0 :                                         printedquerier = 1;
     994             : 
     995           0 :                                         ++nves_displayed;
     996             :                                 } else
     997           0 :                                         fp(out, "%-15s %-15s", "", "");
     998           0 :                                 buf_remain[0] = 0;
     999           0 :                                 rfapiFormatSeconds(thread_timer_remain_second(
    1000           0 :                                                            mon_eth->timer),
    1001             :                                                    buf_remain, BUFSIZ);
    1002           0 :                                 fp(out, " %-17s %10d %-10s\n",
    1003           0 :                                    rfapi_ntop(pfx_mac.family, &pfx_mac.u.prefix,
    1004             :                                               buf_pfx, BUFSIZ),
    1005           0 :                                    mon_eth->logical_net_id, buf_remain);
    1006             :                         }
    1007             :                 }
    1008             :         }
    1009             : 
    1010           0 :         if (queries_total) {
    1011           0 :                 fp(out, "\n");
    1012           0 :                 fp(out, "Displayed %d out of %d total queries\n",
    1013             :                    queries_displayed, queries_total);
    1014             :         }
    1015             :         return CMD_SUCCESS;
    1016             : }
    1017             : 
    1018           0 : static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream,
    1019             :                                  struct agg_node *rn, struct bgp_path_info *bpi)
    1020             : {
    1021           0 :         int (*fp)(void *, const char *, ...);
    1022           0 :         struct vty *vty;
    1023           0 :         void *out;
    1024           0 :         const char *vty_newline;
    1025           0 :         struct prefix pfx_un;
    1026           0 :         struct prefix pfx_vn;
    1027           0 :         uint8_t cost;
    1028           0 :         uint32_t lifetime;
    1029           0 :         bgp_encap_types tun_type = BGP_ENCAP_TYPE_MPLS;/*Default tunnel type*/
    1030             : 
    1031           0 :         char buf_pfx[BUFSIZ];
    1032           0 :         char buf_ntop[BUFSIZ];
    1033           0 :         char buf_un[BUFSIZ];
    1034           0 :         char buf_vn[BUFSIZ];
    1035           0 :         char buf_lifetime[BUFSIZ];
    1036           0 :         int nlines = 0;
    1037           0 :         const struct prefix *p = agg_node_get_prefix(rn);
    1038             : 
    1039           0 :         if (!stream)
    1040             :                 return 0; /* for debug log, print into buf & call output once */
    1041             : 
    1042           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
    1043             :                 return 0;
    1044             : 
    1045             :         /*
    1046             :          * Prefix
    1047             :          */
    1048           0 :         buf_pfx[0] = 0;
    1049           0 :         snprintf(
    1050             :                 buf_pfx, sizeof(buf_pfx), "%s/%d",
    1051           0 :                 rfapi_ntop(p->family, &p->u.prefix, buf_ntop, sizeof(buf_ntop)),
    1052           0 :                 p->prefixlen);
    1053           0 :         buf_pfx[BUFSIZ - 1] = 0;
    1054           0 :         nlines++;
    1055             : 
    1056             :         /*
    1057             :          * UN addr
    1058             :          */
    1059           0 :         buf_un[0] = 0;
    1060           0 :         if (!rfapiGetUnAddrOfVpnBi(bpi, &pfx_un)) {
    1061           0 :                 snprintf(buf_un, sizeof(buf_un), "%s",
    1062           0 :                          inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop,
    1063             :                                    sizeof(buf_ntop)));
    1064             :         }
    1065             : 
    1066           0 :         bgp_attr_extcom_tunnel_type(bpi->attr, &tun_type);
    1067             :         /*
    1068             :          * VN addr
    1069             :          */
    1070           0 :         buf_vn[0] = 0;
    1071           0 :         rfapiNexthop2Prefix(bpi->attr, &pfx_vn);
    1072           0 :         if (tun_type == BGP_ENCAP_TYPE_MPLS) {
    1073             :                 /* MPLS carries un in nrli next hop (same as vn for IP tunnels)
    1074             :                  */
    1075           0 :                 snprintf(buf_un, sizeof(buf_un), "%s",
    1076           0 :                          inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop,
    1077             :                                    sizeof(buf_ntop)));
    1078           0 :                 if (bpi->extra) {
    1079           0 :                         uint32_t l = decode_label(&bpi->extra->label[0]);
    1080           0 :                         snprintf(buf_vn, sizeof(buf_vn), "Label: %d", l);
    1081             :                 } else /* should never happen */
    1082             :                 {
    1083           0 :                         snprintf(buf_vn, sizeof(buf_vn), "Label: N/A");
    1084             :                 }
    1085             :         } else {
    1086           0 :                 snprintf(buf_vn, sizeof(buf_vn), "%s",
    1087           0 :                          inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop,
    1088             :                                    sizeof(buf_ntop)));
    1089             :         }
    1090           0 :         buf_vn[BUFSIZ - 1] = 0;
    1091           0 :         buf_un[BUFSIZ - 1] = 0;
    1092             : 
    1093             :         /*
    1094             :          * Cost is encoded in local_pref as (255-cost)
    1095             :          * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
    1096             :          * back to cost.
    1097             :          */
    1098           0 :         uint32_t local_pref;
    1099             : 
    1100           0 :         if (bpi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
    1101           0 :                 local_pref = bpi->attr->local_pref;
    1102             :         else
    1103             :                 local_pref = 0;
    1104           0 :         cost = (local_pref > 255) ? 0 : 255 - local_pref;
    1105             : 
    1106           0 :         fp(out, "%-20s ", buf_pfx);
    1107           0 :         fp(out, "%-15s ", buf_vn);
    1108           0 :         fp(out, "%-15s ", buf_un);
    1109           0 :         fp(out, "%-4d ", cost);
    1110             : 
    1111             :         /* Lifetime */
    1112             :         /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
    1113           0 :         if (rfapiGetVncLifetime(bpi->attr, &lifetime)
    1114           0 :             || (lifetime == RFAPI_INFINITE_LIFETIME)) {
    1115             : 
    1116           0 :                 fp(out, "%-10s ", "infinite");
    1117             :         } else {
    1118           0 :                 time_t t_lifetime = lifetime;
    1119           0 :                 rfapiFormatSeconds(t_lifetime, buf_lifetime, BUFSIZ);
    1120           0 :                 fp(out, "%-10s ", buf_lifetime);
    1121             :         }
    1122             : 
    1123           0 :         if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && bpi->extra
    1124           0 :             && bpi->extra->vnc.import.timer) {
    1125             : 
    1126           0 :                 uint32_t remaining;
    1127           0 :                 time_t age;
    1128           0 :                 char buf_age[BUFSIZ];
    1129             : 
    1130           0 :                 struct thread *t =
    1131             :                         (struct thread *)bpi->extra->vnc.import.timer;
    1132           0 :                 remaining = thread_timer_remain_second(t);
    1133             : 
    1134             : #ifdef RFAPI_REGISTRATIONS_REPORT_AGE
    1135             :                 /*
    1136             :                  * Calculate when the timer started. Doing so here saves
    1137             :                  * us a timestamp field in "struct bgp_path_info".
    1138             :                  *
    1139             :                  * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
    1140             :                  * original calculation.
    1141             :                  */
    1142             :                 age = rfapiGetHolddownFromLifetime(lifetime, factor)
    1143             :                       - remaining;
    1144             : #else /* report remaining time */
    1145           0 :                 age = remaining;
    1146             : #endif
    1147           0 :                 rfapiFormatSeconds(age, buf_age, BUFSIZ);
    1148             : 
    1149           0 :                 fp(out, "%-10s ", buf_age);
    1150             : 
    1151           0 :         } else if (RFAPI_LOCAL_BI(bpi)) {
    1152             : 
    1153           0 :                 char buf_age[BUFSIZ];
    1154             : 
    1155           0 :                 if (bpi->extra && bpi->extra->vnc.import.create_time) {
    1156           0 :                         rfapiFormatAge(bpi->extra->vnc.import.create_time,
    1157             :                                        buf_age, BUFSIZ);
    1158             :                 } else {
    1159           0 :                         buf_age[0] = '?';
    1160           0 :                         buf_age[1] = 0;
    1161             :                 }
    1162           0 :                 fp(out, "%-10s ", buf_age);
    1163             :         }
    1164           0 :         fp(out, "%s", HVTYNL);
    1165             : 
    1166           0 :         if (p->family == AF_ETHERNET) {
    1167             :                 /*
    1168             :                  * If there is a corresponding IP address && != VN address,
    1169             :                  * print that on the next line
    1170             :                  */
    1171             : 
    1172           0 :                 if (bpi->extra && bpi->extra->vnc.import.aux_prefix.family) {
    1173           0 :                         const char *sp;
    1174             : 
    1175           0 :                         sp = rfapi_ntop(
    1176             :                                 bpi->extra->vnc.import.aux_prefix.family,
    1177           0 :                                 &bpi->extra->vnc.import.aux_prefix.u.prefix,
    1178             :                                 buf_ntop, BUFSIZ);
    1179           0 :                         buf_ntop[BUFSIZ - 1] = 0;
    1180             : 
    1181           0 :                         if (sp && strcmp(buf_vn, sp) != 0) {
    1182           0 :                                 fp(out, "  IP: %s", sp);
    1183           0 :                                 if (nlines == 1)
    1184           0 :                                         nlines++;
    1185             :                         }
    1186             :                 }
    1187             :         }
    1188           0 :         if (tun_type != BGP_ENCAP_TYPE_MPLS && bpi->extra) {
    1189           0 :                 uint32_t l = decode_label(&bpi->extra->label[0]);
    1190           0 :                 if (!MPLS_LABEL_IS_NULL(l)) {
    1191           0 :                         fp(out, "  Label: %d", l);
    1192           0 :                         if (nlines == 1)
    1193             :                                 nlines++;
    1194             :                 }
    1195             :         }
    1196           0 :         if (nlines > 1)
    1197           0 :                 fp(out, "%s", HVTYNL);
    1198             : 
    1199             :         return 1;
    1200             : }
    1201             : 
    1202           0 : static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream,
    1203             :                                           struct rfapi_import_table *it,
    1204             :                                           struct prefix *prefix_only,
    1205             :                                           int show_expiring, /* either/or */
    1206             :                                           int show_local, int show_remote,
    1207             :                                           int show_imported, /* either/or */
    1208             :                                           uint32_t *pLni) /* AFI_L2VPN only */
    1209             : {
    1210           0 :         afi_t afi;
    1211           0 :         int printed_rtlist_hdr = 0;
    1212             : 
    1213           0 :         int (*fp)(void *, const char *, ...);
    1214           0 :         struct vty *vty;
    1215           0 :         void *out;
    1216           0 :         const char *vty_newline;
    1217           0 :         int total = 0;
    1218           0 :         int printed = 0;
    1219             : 
    1220           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
    1221             :                 return printed;
    1222             : 
    1223           0 :         for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
    1224             : 
    1225           0 :                 struct agg_node *rn;
    1226             : 
    1227           0 :                 if (!it->imported_vpn[afi])
    1228           0 :                         continue;
    1229             : 
    1230           0 :                 for (rn = agg_route_top(it->imported_vpn[afi]); rn;
    1231           0 :                      rn = agg_route_next(rn)) {
    1232           0 :                         const struct prefix *p = agg_node_get_prefix(rn);
    1233           0 :                         struct bgp_path_info *bpi;
    1234           0 :                         int count_only;
    1235             : 
    1236             :                         /* allow for wider or more narrow mask from user */
    1237           0 :                         if (prefix_only && !prefix_match(prefix_only, p)
    1238           0 :                             && !prefix_match(p, prefix_only))
    1239             :                                 count_only = 1;
    1240             :                         else
    1241             :                                 count_only = 0;
    1242             : 
    1243           0 :                         for (bpi = rn->info; bpi; bpi = bpi->next) {
    1244             : 
    1245           0 :                                 if (!show_local && RFAPI_LOCAL_BI(bpi)) {
    1246             : 
    1247             :                                         /* local route from RFP */
    1248           0 :                                         continue;
    1249             :                                 }
    1250             : 
    1251           0 :                                 if (!show_remote && !RFAPI_LOCAL_BI(bpi)) {
    1252             : 
    1253             :                                         /* remote route */
    1254           0 :                                         continue;
    1255             :                                 }
    1256             : 
    1257           0 :                                 if (show_expiring
    1258           0 :                                     && !CHECK_FLAG(bpi->flags,
    1259             :                                                    BGP_PATH_REMOVED))
    1260           0 :                                         continue;
    1261             : 
    1262             :                                 if (!show_expiring
    1263           0 :                                     && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
    1264           0 :                                         continue;
    1265             : 
    1266           0 :                                 if (bpi->type == ZEBRA_ROUTE_BGP_DIRECT
    1267           0 :                                     || bpi->type
    1268             :                                                == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
    1269           0 :                                         if (!show_imported)
    1270           0 :                                                 continue;
    1271             :                                 } else {
    1272           0 :                                         if (show_imported)
    1273           0 :                                                 continue;
    1274             :                                 }
    1275             : 
    1276           0 :                                 total++;
    1277           0 :                                 if (count_only == 1)
    1278           0 :                                         continue;
    1279           0 :                                 if (!printed_rtlist_hdr) {
    1280           0 :                                         const char *agetype = "";
    1281           0 :                                         char *s;
    1282           0 :                                         const char *type = "";
    1283           0 :                                         if (show_imported) {
    1284             :                                                 type = "Imported";
    1285             :                                         } else {
    1286           0 :                                                 if (show_expiring) {
    1287             :                                                         type = "Holddown";
    1288             :                                                 } else {
    1289           0 :                                                         if (RFAPI_LOCAL_BI(
    1290             :                                                                     bpi)) {
    1291             :                                                                 type = "Local";
    1292             :                                                         } else {
    1293           0 :                                                                 type = "Remote";
    1294             :                                                         }
    1295             :                                                 }
    1296             :                                         }
    1297             : 
    1298           0 :                                         s = ecommunity_ecom2str(
    1299             :                                                 it->rt_import_list,
    1300             :                                                 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
    1301             : 
    1302           0 :                                         if (pLni) {
    1303           0 :                                                 fp(out,
    1304             :                                                    "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
    1305           0 :                                                    HVTYNL, type, *pLni,
    1306           0 :                                                    (*pLni & 0xfff), s);
    1307             :                                         } else {
    1308           0 :                                                 fp(out, "%s[%s] Prefix RT={%s}",
    1309           0 :                                                    HVTYNL, type, s);
    1310             :                                         }
    1311           0 :                                         XFREE(MTYPE_ECOMMUNITY_STR, s);
    1312             : 
    1313           0 :                                         if (it->rfg && it->rfg->name) {
    1314           0 :                                                 fp(out, " %s \"%s\"",
    1315           0 :                                                    (it->rfg->type == RFAPI_GROUP_CFG_VRF
    1316             :                                                             ? "VRF"
    1317             :                                                             : "NVE group"),
    1318             :                                                    it->rfg->name);
    1319             :                                         }
    1320           0 :                                         fp(out, "%s", HVTYNL);
    1321           0 :                                         if (show_expiring) {
    1322             : #ifdef RFAPI_REGISTRATIONS_REPORT_AGE
    1323             :                                                 agetype = "Age";
    1324             : #else
    1325             :                                                 agetype = "Remaining";
    1326             : #endif
    1327           0 :                                         } else if (show_local) {
    1328           0 :                                                 agetype = "Age";
    1329             :                                         }
    1330             : 
    1331           0 :                                         printed_rtlist_hdr = 1;
    1332             : 
    1333           0 :                                         fp(out,
    1334             :                                            "%-20s %-15s %-15s %4s %-10s %-10s%s",
    1335             :                                            (pLni ? "L2 Address/IP" : "Prefix"),
    1336             :                                            "VN Address", "UN Address", "Cost",
    1337             :                                            "Lifetime", agetype, HVTYNL);
    1338             :                                 }
    1339           0 :                                 printed += rfapiPrintRemoteRegBi(bgp, stream,
    1340             :                                                                  rn, bpi);
    1341             :                         }
    1342             :                 }
    1343             :         }
    1344             : 
    1345           0 :         if (printed > 0) {
    1346             : 
    1347           0 :                 const char *type = "prefixes";
    1348             : 
    1349           0 :                 if (show_imported) {
    1350             :                         type = "imported prefixes";
    1351             :                 } else {
    1352           0 :                         if (show_expiring) {
    1353             :                                 type = "prefixes in holddown";
    1354             :                         } else {
    1355           0 :                                 if (show_local && !show_remote) {
    1356             :                                         type = "locally registered prefixes";
    1357           0 :                                 } else if (!show_local && show_remote) {
    1358           0 :                                         type = "remotely registered prefixes";
    1359             :                                 }
    1360             :                         }
    1361             :                 }
    1362             : 
    1363           0 :                 fp(out, "Displayed %d out of %d %s%s", printed, total, type,
    1364           0 :                    HVTYNL);
    1365             : #if DEBUG_SHOW_EXTRA
    1366             :                 fp(out, "IT table above: it=%p%s", it, HVTYNL);
    1367             : #endif
    1368             :         }
    1369             :         return printed;
    1370             : }
    1371             : 
    1372             : 
    1373             : /*
    1374             :  * rfapiShowRemoteRegistrations
    1375             :  *
    1376             :  * Similar to rfapiShowImportTable() above. This function
    1377             :  * is mean to produce the "remote" portion of the output
    1378             :  * of "show vnc registrations".
    1379             :  */
    1380           0 : int rfapiShowRemoteRegistrations(void *stream, struct prefix *prefix_only,
    1381             :                                  int show_expiring, int show_local,
    1382             :                                  int show_remote, int show_imported)
    1383             : {
    1384           0 :         struct bgp *bgp;
    1385           0 :         struct rfapi *h;
    1386           0 :         struct rfapi_import_table *it;
    1387           0 :         int printed = 0;
    1388             : 
    1389           0 :         bgp = bgp_get_default();
    1390           0 :         if (!bgp) {
    1391             :                 return printed;
    1392             :         }
    1393             : 
    1394           0 :         h = bgp->rfapi;
    1395           0 :         if (!h) {
    1396             :                 return printed;
    1397             :         }
    1398             : 
    1399           0 :         for (it = h->imports; it; it = it->next) {
    1400           0 :                 printed += rfapiShowRemoteRegistrationsIt(
    1401             :                         bgp, stream, it, prefix_only, show_expiring, show_local,
    1402             :                         show_remote, show_imported, NULL);
    1403             :         }
    1404             : 
    1405           0 :         if (h->import_mac) {
    1406           0 :                 void *cursor = NULL;
    1407           0 :                 int rc;
    1408           0 :                 uintptr_t lni_as_ptr;
    1409           0 :                 uint32_t lni;
    1410           0 :                 uint32_t *pLni;
    1411             : 
    1412           0 :                 for (rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr,
    1413             :                                         (void **)&it, &cursor);
    1414           0 :                      !rc;
    1415           0 :                      rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr,
    1416             :                                         (void **)&it, &cursor)) {
    1417           0 :                         pLni = NULL;
    1418           0 :                         if ((lni_as_ptr & 0xffffffff) == lni_as_ptr) {
    1419           0 :                                 lni = (uint32_t)(lni_as_ptr & 0xffffffff);
    1420           0 :                                 pLni = &lni;
    1421             :                         }
    1422             : 
    1423           0 :                         printed += rfapiShowRemoteRegistrationsIt(
    1424             :                                 bgp, stream, it, prefix_only, show_expiring,
    1425             :                                 show_local, show_remote, show_imported, pLni);
    1426             :                 }
    1427             :         }
    1428             : 
    1429             :         return printed;
    1430             : }
    1431             : 
    1432             : /*------------------------------------------
    1433             :  * rfapiRfapiIpAddr2Str
    1434             :  *
    1435             :  * UI helper: generate string from rfapi_ip_addr
    1436             :  *
    1437             :  * input:
    1438             :  *      a                       IP v4/v6 address
    1439             :  *
    1440             :  * output
    1441             :  *      buf                     put string here
    1442             :  *      bufsize                 max space to write
    1443             :  *
    1444             :  * return value:
    1445             :  *      NULL                    conversion failed
    1446             :  *      non-NULL                pointer to buf
    1447             :  --------------------------------------------*/
    1448           0 : const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr *a, char *buf,
    1449             :                                  int bufsize)
    1450             : {
    1451           0 :         const char *rc = NULL;
    1452             : 
    1453           0 :         switch (a->addr_family) {
    1454           0 :         case AF_INET:
    1455           0 :                 rc = inet_ntop(a->addr_family, &a->addr.v4, buf, bufsize);
    1456           0 :                 break;
    1457           0 :         case AF_INET6:
    1458           0 :                 rc = inet_ntop(a->addr_family, &a->addr.v6, buf, bufsize);
    1459           0 :                 break;
    1460             :         }
    1461           0 :         return rc;
    1462             : }
    1463             : 
    1464           0 : void rfapiPrintRfapiIpAddr(void *stream, struct rfapi_ip_addr *a)
    1465             : {
    1466           0 :         char buf[BUFSIZ];
    1467           0 :         const char *rc = NULL;
    1468             : 
    1469           0 :         int (*fp)(void *, const char *, ...);
    1470           0 :         struct vty *vty;
    1471           0 :         void *out = NULL;
    1472           0 :         const char *vty_newline;
    1473             : 
    1474           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
    1475           0 :                 return;
    1476             : 
    1477           0 :         rc = rfapiRfapiIpAddr2Str(a, buf, BUFSIZ);
    1478             : 
    1479           0 :         if (rc)
    1480           0 :                 fp(out, "%s", buf);
    1481             : }
    1482             : 
    1483           0 : const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix *p, char *buf,
    1484             :                                    int bufsize)
    1485             : {
    1486           0 :         struct rfapi_ip_addr *a = &p->prefix;
    1487           0 :         const char *rc = NULL;
    1488             : 
    1489           0 :         switch (a->addr_family) {
    1490           0 :         case AF_INET:
    1491           0 :                 rc = inet_ntop(a->addr_family, &a->addr.v4, buf, bufsize);
    1492           0 :                 break;
    1493           0 :         case AF_INET6:
    1494           0 :                 rc = inet_ntop(a->addr_family, &a->addr.v6, buf, bufsize);
    1495           0 :                 break;
    1496             :         }
    1497             : 
    1498           0 :         if (rc) {
    1499           0 :                 int alen = strlen(buf);
    1500           0 :                 int remaining = bufsize - alen - 1;
    1501           0 :                 int slen;
    1502             : 
    1503           0 :                 if (remaining > 0) {
    1504           0 :                         slen = snprintf(buf + alen, remaining, "/%u",
    1505           0 :                                         p->length);
    1506           0 :                         if (slen < remaining) /* see man page for snprintf(3) */
    1507             :                                 return rc;
    1508             :                 }
    1509             :         }
    1510             : 
    1511             :         return NULL;
    1512             : }
    1513             : 
    1514           0 : void rfapiPrintRfapiIpPrefix(void *stream, struct rfapi_ip_prefix *p)
    1515             : {
    1516           0 :         char buf[BUFSIZ];
    1517           0 :         const char *rc;
    1518             : 
    1519           0 :         int (*fp)(void *, const char *, ...);
    1520           0 :         struct vty *vty;
    1521           0 :         void *out = NULL;
    1522           0 :         const char *vty_newline;
    1523             : 
    1524           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
    1525           0 :                 return;
    1526             : 
    1527           0 :         rc = rfapiRfapiIpPrefix2Str(p, buf, BUFSIZ);
    1528             : 
    1529           0 :         if (rc)
    1530           0 :                 fp(out, "%s:%u", buf, p->cost);
    1531             :         else
    1532           0 :                 fp(out, "?/?:?");
    1533             : }
    1534             : 
    1535           0 : void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
    1536             :                               safi_t safi, struct prefix *p)
    1537             : {
    1538           0 :         afi_t afi; /* of the VN address */
    1539           0 :         struct bgp_dest *bd;
    1540           0 :         struct bgp_path_info *bpi;
    1541           0 :         uint8_t type = ZEBRA_ROUTE_BGP;
    1542           0 :         struct bgp *bgp;
    1543           0 :         int printed = 0;
    1544           0 :         struct prefix_rd prd0;
    1545           0 :         struct prefix_rd *prd;
    1546             : 
    1547             :         /*
    1548             :          * Find the bgp_path in the RIB corresponding to this
    1549             :          * prefix and rfd
    1550             :          */
    1551             : 
    1552           0 :         afi = family2afi(p->family);
    1553           0 :         assert(afi == AFI_IP || afi == AFI_IP6);
    1554             : 
    1555           0 :         bgp = bgp_get_default(); /* assume 1 instance for now */
    1556           0 :         assert(bgp);
    1557             : 
    1558           0 :         if (safi == SAFI_ENCAP) {
    1559           0 :                 memset(&prd0, 0, sizeof(prd0));
    1560           0 :                 prd0.family = AF_UNSPEC;
    1561           0 :                 prd0.prefixlen = 64;
    1562           0 :                 prd = &prd0;
    1563             :         } else {
    1564           0 :                 prd = &rfd->rd;
    1565             :         }
    1566           0 :         bd = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
    1567             : 
    1568           0 :         vty_out(vty, "  bd=%p%s", bd, HVTYNL);
    1569             : 
    1570           0 :         for (bpi = bgp_dest_get_bgp_path_info(bd); bpi; bpi = bpi->next) {
    1571           0 :                 if (bpi->peer == rfd->peer && bpi->type == type
    1572           0 :                     && bpi->sub_type == BGP_ROUTE_RFP && bpi->extra
    1573           0 :                     && bpi->extra->vnc.export.rfapi_handle == (void *)rfd) {
    1574             : 
    1575           0 :                         rfapiPrintBi(vty, bpi);
    1576           0 :                         printed = 1;
    1577             :                 }
    1578             :         }
    1579             : 
    1580           0 :         if (!printed) {
    1581           0 :                 vty_out(vty, "    --?--%s", HVTYNL);
    1582           0 :                 return;
    1583             :         }
    1584             : }
    1585             : 
    1586           0 : void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd)
    1587             : {
    1588             :         /* pHD un-addr vn-addr pCB cookie rd lifetime */
    1589             :         /* RT export list */
    1590             :         /* RT import list */
    1591             :         /* list of advertised prefixes */
    1592             :         /* dump import table */
    1593             : 
    1594           0 :         char *s;
    1595           0 :         void *cursor;
    1596           0 :         int rc;
    1597           0 :         afi_t afi;
    1598           0 :         struct rfapi_adb *adb;
    1599             : 
    1600           0 :         vty_out(vty, "%-10p ", rfd);
    1601           0 :         rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
    1602           0 :         vty_out(vty, " ");
    1603           0 :         rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
    1604           0 :         vty_out(vty, " %p %p ", rfd->response_cb, rfd->cookie);
    1605           0 :         vty_out(vty, "%pRD", &rfd->rd);
    1606           0 :         vty_out(vty, " %d", rfd->response_lifetime);
    1607           0 :         vty_out(vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>"));
    1608           0 :         vty_out(vty, "%s", HVTYNL);
    1609             : 
    1610           0 :         vty_out(vty, " Peer %p #%d%s", rfd->peer, rfd->peer->lock, HVTYNL);
    1611             : 
    1612             :         /* export RT list */
    1613           0 :         if (rfd->rt_export_list) {
    1614           0 :                 s = ecommunity_ecom2str(rfd->rt_export_list,
    1615             :                                         ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
    1616           0 :                 vty_out(vty, " Export %s%s", s, HVTYNL);
    1617           0 :                 XFREE(MTYPE_ECOMMUNITY_STR, s);
    1618             :         } else {
    1619           0 :                 vty_out(vty, " Export (nil)%s", HVTYNL);
    1620             :         }
    1621             : 
    1622             :         /* import RT list */
    1623           0 :         if (rfd->import_table) {
    1624           0 :                 s = ecommunity_ecom2str(rfd->import_table->rt_import_list,
    1625             :                                         ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
    1626           0 :                 vty_out(vty, " Import %s%s", s, HVTYNL);
    1627           0 :                 XFREE(MTYPE_ECOMMUNITY_STR, s);
    1628             :         } else {
    1629           0 :                 vty_out(vty, " Import (nil)%s", HVTYNL);
    1630             :         }
    1631             : 
    1632           0 :         for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
    1633           0 :                 uint8_t family;
    1634             : 
    1635           0 :                 family = afi2family(afi);
    1636           0 :                 if (!family)
    1637           0 :                         continue;
    1638             : 
    1639           0 :                 cursor = NULL;
    1640           0 :                 for (rc = skiplist_next(rfd->advertised.ipN_by_prefix, NULL,
    1641             :                                         (void **)&adb, &cursor);
    1642           0 :                      rc == 0;
    1643           0 :                      rc = skiplist_next(rfd->advertised.ipN_by_prefix, NULL,
    1644             :                                         (void **)&adb, &cursor)) {
    1645             : 
    1646             :                         /* group like family prefixes together in output */
    1647           0 :                         if (family != adb->u.s.prefix_ip.family)
    1648           0 :                                 continue;
    1649             : 
    1650           0 :                         vty_out(vty, "  Adv Pfx: %pFX%s", &adb->u.s.prefix_ip,
    1651             :                                 HVTYNL);
    1652           0 :                         rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN,
    1653           0 :                                                  &adb->u.s.prefix_ip);
    1654             :                 }
    1655             :         }
    1656           0 :         for (rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL,
    1657             :                                 (void **)&adb, &cursor);
    1658           0 :              rc == 0; rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL,
    1659             :                                          (void **)&adb, &cursor)) {
    1660           0 :                 vty_out(vty, "  Adv Pfx: %pFX%s", &adb->u.s.prefix_eth, HVTYNL);
    1661             : 
    1662             :                 /* TBD update the following function to print ethernet info */
    1663             :                 /* Also need to pass/use rd */
    1664           0 :                 rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN,
    1665           0 :                                          &adb->u.s.prefix_ip);
    1666             :         }
    1667           0 :         vty_out(vty, "%s", HVTYNL);
    1668           0 : }
    1669             : 
    1670             : /*
    1671             :  * test scripts rely on first line for each nve starting in 1st column,
    1672             :  * leading whitespace for additional detail of that nve
    1673             :  */
    1674           0 : void rfapiPrintMatchingDescriptors(struct vty *vty, struct prefix *vn_prefix,
    1675             :                                    struct prefix *un_prefix)
    1676             : {
    1677           0 :         struct bgp *bgp;
    1678           0 :         struct rfapi *h;
    1679           0 :         struct listnode *ln;
    1680           0 :         struct rfapi_descriptor *rfd;
    1681           0 :         int printed = 0;
    1682             : 
    1683           0 :         bgp = bgp_get_default(); /* assume 1 instance for now */
    1684           0 :         if (!bgp)
    1685             :                 return;
    1686             : 
    1687           0 :         h = bgp->rfapi;
    1688           0 :         assert(h);
    1689             : 
    1690           0 :         for (ln = listhead(&h->descriptors); ln; ln = listnextnode(ln)) {
    1691           0 :                 rfd = listgetdata(ln);
    1692             : 
    1693           0 :                 struct prefix pfx;
    1694             : 
    1695           0 :                 if (vn_prefix) {
    1696           0 :                         assert(!rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx));
    1697           0 :                         if (!prefix_match(vn_prefix, &pfx))
    1698           0 :                                 continue;
    1699             :                 }
    1700             : 
    1701           0 :                 if (un_prefix) {
    1702           0 :                         assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx));
    1703           0 :                         if (!prefix_match(un_prefix, &pfx))
    1704           0 :                                 continue;
    1705             :                 }
    1706             : 
    1707           0 :                 if (!printed) {
    1708             :                         /* print column header */
    1709           0 :                         vty_out(vty, "%s %s %s %s %s %s %s %s%s", "descriptor",
    1710             :                                 "un-addr", "vn-addr", "callback", "cookie",
    1711             :                                 "RD", "lifetime", "group", HVTYNL);
    1712             :                 }
    1713           0 :                 rfapiPrintDescriptor(vty, rfd);
    1714           0 :                 printed = 1;
    1715             :         }
    1716             : }
    1717             : 
    1718             : 
    1719             : /*
    1720             :  * Parse an address and put into a struct prefix
    1721             :  */
    1722           0 : int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, struct prefix *p)
    1723             : {
    1724           0 :         if (!str2prefix(str, p)) {
    1725           0 :                 vty_out(vty, "Malformed address \"%s\"%s", str ? str : "null",
    1726             :                         HVTYNL);
    1727           0 :                 return CMD_WARNING;
    1728             :         }
    1729           0 :         switch (p->family) {
    1730           0 :         case AF_INET:
    1731           0 :                 if (p->prefixlen != IPV4_MAX_BITLEN) {
    1732           0 :                         vty_out(vty, "Not a host address: \"%s\"%s", str,
    1733             :                                 HVTYNL);
    1734           0 :                         return CMD_WARNING;
    1735             :                 }
    1736             :                 break;
    1737           0 :         case AF_INET6:
    1738           0 :                 if (p->prefixlen != IPV6_MAX_BITLEN) {
    1739           0 :                         vty_out(vty, "Not a host address: \"%s\"%s", str,
    1740             :                                 HVTYNL);
    1741           0 :                         return CMD_WARNING;
    1742             :                 }
    1743             :                 break;
    1744           0 :         default:
    1745           0 :                 vty_out(vty, "Invalid address \"%s\"%s", str, HVTYNL);
    1746           0 :                 return CMD_WARNING;
    1747             :         }
    1748             :         return 0;
    1749             : }
    1750             : 
    1751           0 : int rfapiCliGetRfapiIpAddr(struct vty *vty, const char *str,
    1752             :                            struct rfapi_ip_addr *hai)
    1753             : {
    1754           0 :         struct prefix pfx;
    1755           0 :         int rc;
    1756             : 
    1757           0 :         rc = rfapiCliGetPrefixAddr(vty, str, &pfx);
    1758           0 :         if (rc)
    1759             :                 return rc;
    1760             : 
    1761           0 :         hai->addr_family = pfx.family;
    1762           0 :         if (pfx.family == AF_INET)
    1763           0 :                 hai->addr.v4 = pfx.u.prefix4;
    1764             :         else
    1765           0 :                 hai->addr.v6 = pfx.u.prefix6;
    1766             : 
    1767             :         return 0;
    1768             : }
    1769             : 
    1770             : /*
    1771             :  * Note: this function does not flush vty output, so if it is called
    1772             :  * with a stream pointing to a vty, the user will have to type something
    1773             :  * before the callback output shows up
    1774             :  */
    1775           0 : void rfapiPrintNhl(void *stream, struct rfapi_next_hop_entry *next_hops)
    1776             : {
    1777           0 :         struct rfapi_next_hop_entry *nh;
    1778           0 :         int count;
    1779             : 
    1780           0 :         int (*fp)(void *, const char *, ...);
    1781           0 :         struct vty *vty;
    1782           0 :         void *out;
    1783           0 :         const char *vty_newline;
    1784             : 
    1785             : #define REMAIN (BUFSIZ - (p-line))
    1786             : #define INCP {p += (r > REMAIN)? REMAIN: r;}
    1787             : 
    1788           0 :         if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
    1789           0 :                 return;
    1790             : 
    1791           0 :         for (nh = next_hops, count = 1; nh; nh = nh->next, ++count) {
    1792             : 
    1793           0 :                 char line[BUFSIZ];
    1794           0 :                 char *p = line;
    1795           0 :                 int r;
    1796             : 
    1797           0 :                 r = snprintf(p, REMAIN, "%3d  pfx=", count);
    1798           0 :                 INCP;
    1799             : 
    1800           0 :                 if (rfapiRfapiIpPrefix2Str(&nh->prefix, p, REMAIN)) {
    1801             :                         /* it fit, so count length */
    1802           0 :                         r = strlen(p);
    1803             :                 } else {
    1804             :                         /* didn't fit */
    1805           0 :                         goto truncate;
    1806             :                 }
    1807           0 :                 INCP;
    1808             : 
    1809           0 :                 r = snprintf(p, REMAIN, ", un=");
    1810           0 :                 INCP;
    1811             : 
    1812           0 :                 if (rfapiRfapiIpAddr2Str(&nh->un_address, p, REMAIN)) {
    1813             :                         /* it fit, so count length */
    1814           0 :                         r = strlen(p);
    1815             :                 } else {
    1816             :                         /* didn't fit */
    1817           0 :                         goto truncate;
    1818             :                 }
    1819           0 :                 INCP;
    1820             : 
    1821           0 :                 r = snprintf(p, REMAIN, ", vn=");
    1822           0 :                 INCP;
    1823             : 
    1824           0 :                 if (rfapiRfapiIpAddr2Str(&nh->vn_address, p, REMAIN)) {
    1825             :                         /* it fit, so count length */
    1826           0 :                         r = strlen(p);
    1827             :                 } else {
    1828             :                         /* didn't fit */
    1829             :                         goto truncate;
    1830             :                 }
    1831           0 :                 INCP;
    1832             : 
    1833           0 :         truncate:
    1834           0 :                 line[BUFSIZ - 1] = 0;
    1835           0 :                 fp(out, "%s%s", line, HVTYNL);
    1836             : 
    1837             :                 /*
    1838             :                  * options
    1839             :                  */
    1840           0 :                 if (nh->vn_options) {
    1841           0 :                         struct rfapi_vn_option *vo;
    1842           0 :                         char offset[] = "     ";
    1843             : 
    1844           0 :                         for (vo = nh->vn_options; vo; vo = vo->next) {
    1845           0 :                                 char pbuf[100];
    1846             : 
    1847           0 :                                 switch (vo->type) {
    1848           0 :                                 case RFAPI_VN_OPTION_TYPE_L2ADDR:
    1849           0 :                                         rfapiEthAddr2Str(&vo->v.l2addr.macaddr,
    1850             :                                                          pbuf, sizeof(pbuf));
    1851           0 :                                         fp(out,
    1852             :                                            "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
    1853             :                                            offset, pbuf,
    1854           0 :                                            (vo->v.l2addr.label & 0x00ffffff),
    1855           0 :                                            (vo->v.l2addr.logical_net_id
    1856             :                                             & 0x00ffffff),
    1857           0 :                                            vo->v.l2addr.local_nve_id, HVTYNL);
    1858           0 :                                         break;
    1859             : 
    1860             :                                 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP:
    1861           0 :                                         fp(out, "%sLNH %pFX cost=%d%s", offset,
    1862             :                                            &vo->v.local_nexthop.addr,
    1863           0 :                                            vo->v.local_nexthop.cost, HVTYNL);
    1864           0 :                                         break;
    1865             : 
    1866             :                                 case RFAPI_VN_OPTION_TYPE_INTERNAL_RD:
    1867           0 :                                         fp(out,
    1868             :                                            "%svn option type %d (unknown)%s",
    1869             :                                            offset, vo->type, HVTYNL);
    1870           0 :                                         break;
    1871             :                                 }
    1872             :                         }
    1873             :                 }
    1874           0 :                 if (nh->un_options) {
    1875           0 :                         struct rfapi_un_option *uo;
    1876           0 :                         char offset[] = "     ";
    1877             : 
    1878           0 :                         for (uo = nh->un_options; uo; uo = uo->next) {
    1879           0 :                                 switch (uo->type) {
    1880           0 :                                 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE:
    1881           0 :                                         rfapi_print_tunneltype_option(
    1882             :                                                 stream, 8, &uo->v.tunnel);
    1883           0 :                                         break;
    1884           0 :                                 case RFAPI_UN_OPTION_TYPE_PROVISIONAL:
    1885           0 :                                         fp(out, "%sUN Option type %d%s", offset,
    1886             :                                            uo->type, vty_newline);
    1887           0 :                                         break;
    1888             :                                 }
    1889             :                         }
    1890             :                 }
    1891             :         }
    1892             : }
    1893             : 
    1894             : /***********************************************************************
    1895             :  *                      STATIC ROUTES
    1896             :  ***********************************************************************/
    1897             : 
    1898             : /*
    1899             :  * Add another nexthop to the NHL
    1900             :  */
    1901           0 : static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr *un_addr,
    1902             :                                          struct rfapi_ip_addr *vn_addr,
    1903             :                                          struct rfapi_ip_prefix *rprefix,
    1904             :                                          int is_add,
    1905             :                                          uint32_t lifetime, /* add only */
    1906             :                                          struct rfapi_vn_option *vn_options,
    1907             :                                          struct rfapi_next_hop_entry **head,
    1908             :                                          struct rfapi_next_hop_entry **tail)
    1909             : {
    1910           0 :         struct rfapi_next_hop_entry *new;
    1911             : 
    1912             :         /*
    1913             :          * construct NHL
    1914             :          */
    1915             : 
    1916           0 :         new = XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_next_hop_entry));
    1917           0 :         new->prefix = *rprefix;
    1918           0 :         new->un_address = *un_addr;
    1919           0 :         new->vn_address = *vn_addr;
    1920             : 
    1921           0 :         new->vn_options = vn_options;
    1922           0 :         if (is_add) {
    1923           0 :                 new->lifetime = lifetime;
    1924             :         } else {
    1925           0 :                 new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME;
    1926             :         }
    1927             : 
    1928           0 :         if (*tail)
    1929           0 :                 (*tail)->next = new;
    1930           0 :         *tail = new;
    1931           0 :         if (!*head) {
    1932           0 :                 *head = new;
    1933             :         }
    1934           0 : }
    1935             : 
    1936             : 
    1937             : static int
    1938           0 : register_add(struct vty *vty, struct cmd_token *carg_prefix,
    1939             :              struct cmd_token *carg_vn, struct cmd_token *carg_un,
    1940             :              struct cmd_token *carg_cost,     /* optional */
    1941             :              struct cmd_token *carg_lifetime, /* optional */
    1942             :              struct cmd_token *carg_macaddr,  /* optional */
    1943             :              struct cmd_token
    1944             :                      *carg_vni, /* mac present=>mandatory Virtual Network ID */
    1945             :              int argc, struct cmd_token **argv)
    1946             : {
    1947           0 :         const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL;
    1948           0 :         const char *arg_vn = carg_vn ? carg_vn->arg : NULL;
    1949           0 :         const char *arg_un = carg_un ? carg_un->arg : NULL;
    1950           0 :         const char *arg_cost = carg_cost ? carg_cost->arg : NULL;
    1951           0 :         const char *arg_lifetime = carg_lifetime ? carg_lifetime->arg : NULL;
    1952           0 :         const char *arg_macaddr = carg_macaddr ? carg_macaddr->arg : NULL;
    1953           0 :         const char *arg_vni = carg_vni ? carg_vni->arg : NULL;
    1954           0 :         struct rfapi_ip_addr vn_address;
    1955           0 :         struct rfapi_ip_addr un_address;
    1956           0 :         struct prefix pfx;
    1957           0 :         struct rfapi_ip_prefix rpfx;
    1958           0 :         uint32_t cost;
    1959           0 :         uint32_t lnh_cost;
    1960           0 :         uint32_t lifetime;
    1961           0 :         rfapi_handle rfd;
    1962           0 :         struct rfapi_vn_option optary[10]; /* XXX must be big enough */
    1963           0 :         struct rfapi_vn_option *opt = NULL;
    1964           0 :         int opt_next = 0;
    1965             : 
    1966           0 :         int rc = CMD_WARNING_CONFIG_FAILED;
    1967           0 :         char *endptr;
    1968           0 :         struct bgp *bgp;
    1969           0 :         struct rfapi *h;
    1970           0 :         struct rfapi_cfg *rfapi_cfg;
    1971             : 
    1972           0 :         const char *arg_lnh = NULL;
    1973           0 :         const char *arg_lnh_cost = NULL;
    1974             : 
    1975           0 :         bgp = bgp_get_default(); /* assume 1 instance for now */
    1976           0 :         if (!bgp) {
    1977           0 :                 if (vty)
    1978           0 :                         vty_out(vty, "BGP not configured\n");
    1979           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1980             :         }
    1981             : 
    1982           0 :         h = bgp->rfapi;
    1983           0 :         rfapi_cfg = bgp->rfapi_cfg;
    1984           0 :         if (!h || !rfapi_cfg) {
    1985           0 :                 if (vty)
    1986           0 :                         vty_out(vty, "RFAPI not configured\n");
    1987           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1988             :         }
    1989             : 
    1990           0 :         for (; argc; --argc, ++argv) {
    1991           0 :                 if (strmatch(argv[0]->text, "local-next-hop")) {
    1992           0 :                         if (arg_lnh) {
    1993           0 :                                 vty_out(vty,
    1994             :                                         "local-next-hop specified more than once\n");
    1995           0 :                                 return CMD_WARNING_CONFIG_FAILED;
    1996             :                         }
    1997           0 :                         if (argc <= 1) {
    1998           0 :                                 vty_out(vty,
    1999             :                                         "Missing parameter for local-next-hop\n");
    2000           0 :                                 return CMD_WARNING_CONFIG_FAILED;
    2001             :                         }
    2002           0 :                         ++argv;
    2003           0 :                         --argc;
    2004           0 :                         arg_lnh = argv[0]->arg;
    2005             :                 }
    2006           0 :                 if (strmatch(argv[0]->text, "local-cost")) {
    2007           0 :                         if (arg_lnh_cost) {
    2008           0 :                                 vty_out(vty,
    2009             :                                         "local-cost specified more than once\n");
    2010           0 :                                 return CMD_WARNING_CONFIG_FAILED;
    2011             :                         }
    2012           0 :                         if (argc <= 1) {
    2013           0 :                                 vty_out(vty,
    2014             :                                         "Missing parameter for local-cost\n");
    2015           0 :                                 return CMD_WARNING_CONFIG_FAILED;
    2016             :                         }
    2017           0 :                         ++argv;
    2018           0 :                         --argc;
    2019           0 :                         arg_lnh_cost = argv[0]->arg;
    2020             :                 }
    2021             :         }
    2022             : 
    2023           0 :         if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_vn, &vn_address)))
    2024           0 :                 goto fail;
    2025           0 :         if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_un, &un_address)))
    2026           0 :                 goto fail;
    2027             : 
    2028             :         /* arg_prefix is optional if mac address is given */
    2029           0 :         if (arg_macaddr && !arg_prefix) {
    2030             :                 /*
    2031             :                  * fake up a 0/32 or 0/128 prefix
    2032             :                  */
    2033           0 :                 switch (vn_address.addr_family) {
    2034             :                 case AF_INET:
    2035             :                         arg_prefix = "0.0.0.0/32";
    2036             :                         break;
    2037           0 :                 case AF_INET6:
    2038           0 :                         arg_prefix = "0::0/128";
    2039           0 :                         break;
    2040           0 :                 default:
    2041           0 :                         vty_out(vty,
    2042             :                                 "Internal error, unknown VN address family\n");
    2043           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2044             :                 }
    2045             :         }
    2046             : 
    2047           0 :         if (!str2prefix(arg_prefix, &pfx)) {
    2048           0 :                 vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix);
    2049           0 :                 goto fail;
    2050             :         }
    2051           0 :         if (pfx.family != AF_INET && pfx.family != AF_INET6) {
    2052           0 :                 vty_out(vty, "prefix \"%s\" has invalid address family\n",
    2053             :                         arg_prefix);
    2054           0 :                 goto fail;
    2055             :         }
    2056             : 
    2057             : 
    2058           0 :         memset(optary, 0, sizeof(optary));
    2059             : 
    2060           0 :         if (arg_cost) {
    2061           0 :                 endptr = NULL;
    2062           0 :                 cost = strtoul(arg_cost, &endptr, 10);
    2063           0 :                 if (*endptr != '\0' || cost > 255) {
    2064           0 :                         vty_out(vty, "%% Invalid %s value\n", "cost");
    2065           0 :                         goto fail;
    2066             :                 }
    2067             :         } else {
    2068             :                 cost = 255;
    2069             :         }
    2070             : 
    2071           0 :         if (arg_lifetime) {
    2072           0 :                 if (!strcmp(arg_lifetime, "infinite")) {
    2073             :                         lifetime = RFAPI_INFINITE_LIFETIME;
    2074             :                 } else {
    2075           0 :                         endptr = NULL;
    2076           0 :                         lifetime = strtoul(arg_lifetime, &endptr, 10);
    2077           0 :                         if (*endptr != '\0') {
    2078           0 :                                 vty_out(vty, "%% Invalid %s value\n",
    2079             :                                         "lifetime");
    2080           0 :                                 goto fail;
    2081             :                         }
    2082             :                 }
    2083             :         } else {
    2084             :                 lifetime = RFAPI_INFINITE_LIFETIME; /* default infinite */
    2085             :         }
    2086             : 
    2087           0 :         if (arg_lnh_cost) {
    2088           0 :                 if (!arg_lnh) {
    2089           0 :                         vty_out(vty,
    2090             :                                 "%% %s may only be specified with local-next-hop\n",
    2091             :                                 "local-cost");
    2092           0 :                         goto fail;
    2093             :                 }
    2094           0 :                 endptr = NULL;
    2095           0 :                 lnh_cost = strtoul(arg_lnh_cost, &endptr, 10);
    2096           0 :                 if (*endptr != '\0' || lnh_cost > 255) {
    2097           0 :                         vty_out(vty, "%% Invalid %s value\n", "local-cost");
    2098           0 :                         goto fail;
    2099             :                 }
    2100             :         } else {
    2101             :                 lnh_cost = 255;
    2102             :         }
    2103             : 
    2104           0 :         if (arg_lnh) {
    2105           0 :                 if (!arg_prefix) {
    2106           0 :                         vty_out(vty,
    2107             :                                 "%% %s may only be specified with prefix\n",
    2108             :                                 "local-next-hop");
    2109           0 :                         goto fail;
    2110             :                 }
    2111           0 :                 if ((rc = rfapiCliGetPrefixAddr(
    2112             :                              vty, arg_lnh,
    2113             :                              &optary[opt_next].v.local_nexthop.addr))) {
    2114             : 
    2115           0 :                         goto fail;
    2116             :                 }
    2117             : 
    2118           0 :                 optary[opt_next].v.local_nexthop.cost = lnh_cost;
    2119           0 :                 optary[opt_next].type = RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP;
    2120             : 
    2121           0 :                 if (opt_next) {
    2122             :                         optary[opt_next - 1].next = optary + opt_next;
    2123             :                 } else {
    2124           0 :                         opt = optary;
    2125             :                 }
    2126           0 :                 ++opt_next;
    2127             :         }
    2128             : 
    2129           0 :         if (arg_vni && !arg_macaddr) {
    2130           0 :                 vty_out(vty, "%% %s may only be specified with mac address\n",
    2131             :                         "virtual-network-identifier");
    2132           0 :                 goto fail;
    2133             :         }
    2134             : 
    2135           0 :         if (arg_macaddr) {
    2136           0 :                 if (!arg_vni) {
    2137           0 :                         vty_out(vty,
    2138             :                                 "Missing \"vni\" parameter (mandatory with mac)\n");
    2139           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2140             :                 }
    2141           0 :                 optary[opt_next].v.l2addr.logical_net_id =
    2142           0 :                         strtoul(arg_vni, NULL, 10);
    2143             : 
    2144           0 :                 if ((rc = rfapiStr2EthAddr(
    2145             :                              arg_macaddr,
    2146             :                              &optary[opt_next].v.l2addr.macaddr))) {
    2147           0 :                         vty_out(vty, "Invalid %s value\n", "mac address");
    2148           0 :                         goto fail;
    2149             :                 }
    2150             :                 /* TBD label, NVE ID */
    2151             : 
    2152           0 :                 optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR;
    2153             : 
    2154           0 :                 if (opt_next) {
    2155           0 :                         optary[opt_next - 1].next = optary + opt_next;
    2156             :                 } else {
    2157             :                         opt = optary;
    2158             :                 }
    2159           0 :                 ++opt_next;
    2160             :         }
    2161             : 
    2162           0 :         vnc_zlog_debug_verbose(
    2163             :                 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
    2164             :                 __func__, arg_vn, arg_un, arg_prefix,
    2165             :                 (arg_cost ? arg_cost : "NULL"),
    2166             :                 (arg_lifetime ? arg_lifetime : "NULL"),
    2167             :                 (arg_lnh ? arg_lnh : "NULL"));
    2168             : 
    2169           0 :         rfapiQprefix2Rprefix(&pfx, &rpfx);
    2170             : 
    2171           0 :         rpfx.cost = cost & 255;
    2172             : 
    2173             :         /* look up rf descriptor, call open if it doesn't exist  */
    2174           0 :         rc = rfapi_find_rfd(bgp, &vn_address, &un_address,
    2175             :                             (struct rfapi_descriptor **)&rfd);
    2176           0 :         if (rc) {
    2177           0 :                 if (ENOENT == rc) {
    2178           0 :                         struct rfapi_un_option uo;
    2179             : 
    2180             :                         /*
    2181             :                          * flag descriptor as provisionally opened for static
    2182             :                          * route
    2183             :                          * registration so that we can fix up the other
    2184             :                          * parameters
    2185             :                          * when the real open comes along
    2186             :                          */
    2187           0 :                         memset(&uo, 0, sizeof(uo));
    2188           0 :                         uo.type = RFAPI_UN_OPTION_TYPE_PROVISIONAL;
    2189             : 
    2190           0 :                         rc = rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp),
    2191             :                                         &vn_address, &un_address,
    2192             :                                         &uo,        /* flags */
    2193             :                                         NULL, NULL, /* no userdata */
    2194             :                                         &rfd);
    2195           0 :                         if (rc) {
    2196           0 :                                 vty_out(vty,
    2197             :                                         "Can't open session for this NVE: %s\n",
    2198             :                                         rfapi_error_str(rc));
    2199           0 :                                 rc = CMD_WARNING_CONFIG_FAILED;
    2200           0 :                                 goto fail;
    2201             :                         }
    2202             :                 } else {
    2203           0 :                         vty_out(vty, "Can't find session for this NVE: %s\n",
    2204             :                                 rfapi_error_str(rc));
    2205           0 :                         goto fail;
    2206             :                 }
    2207             :         }
    2208             : 
    2209           0 :         rc = rfapi_register(rfd, &rpfx, lifetime, NULL, opt,
    2210             :                             RFAPI_REGISTER_ADD);
    2211           0 :         if (!rc) {
    2212           0 :                 struct rfapi_next_hop_entry *head = NULL;
    2213           0 :                 struct rfapi_next_hop_entry *tail = NULL;
    2214           0 :                 struct rfapi_vn_option *vn_opt_new;
    2215             : 
    2216           0 :                 vnc_zlog_debug_verbose(
    2217             :                         "%s: rfapi_register succeeded, returning 0", __func__);
    2218             : 
    2219           0 :                 if (h->rfp_methods.local_cb) {
    2220           0 :                         struct rfapi_descriptor *r =
    2221             :                                 (struct rfapi_descriptor *)rfd;
    2222           0 :                         vn_opt_new = rfapi_vn_options_dup(opt);
    2223             : 
    2224           0 :                         rfapiAddDeleteLocalRfpPrefix(&r->un_addr, &r->vn_addr,
    2225             :                                                      &rpfx, 1, lifetime,
    2226             :                                                      vn_opt_new, &head, &tail);
    2227           0 :                         if (head) {
    2228           0 :                                 h->flags |= RFAPI_INCALLBACK;
    2229           0 :                                 (*h->rfp_methods.local_cb)(head, r->cookie);
    2230           0 :                                 h->flags &= ~RFAPI_INCALLBACK;
    2231             :                         }
    2232           0 :                         head = tail = NULL;
    2233             :                 }
    2234           0 :                 return 0;
    2235             :         }
    2236             : 
    2237           0 :         vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__);
    2238           0 :         vty_out(vty, "\n");
    2239           0 :         vty_out(vty, "Registration failed.\n");
    2240           0 :         vty_out(vty,
    2241             :                 "Confirm that either the VN or UN address matches a configured NVE group.\n");
    2242           0 :         return CMD_WARNING_CONFIG_FAILED;
    2243             : 
    2244           0 : fail:
    2245           0 :         vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__, rc);
    2246             :         return rc;
    2247             : }
    2248             : 
    2249             : /************************************************************************
    2250             :  *              Add prefix With LNH_OPTIONS...
    2251             :  ************************************************************************/
    2252           0 : DEFUN (add_vnc_prefix_cost_life_lnh,
    2253             :        add_vnc_prefix_cost_life_lnh_cmd,
    2254             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295) LNH_OPTIONS...",
    2255             :        "Add registration\n"
    2256             :        "VNC Information\n"
    2257             :        "Add/modify prefix related information\n"
    2258             :        "IPv4 prefix\n"
    2259             :        "IPv6 prefix\n"
    2260             :        "VN address of NVE\n"
    2261             :        "VN IPv4 interface address\n"
    2262             :        "VN IPv6 interface address\n"
    2263             :        "UN address of NVE\n"
    2264             :        "UN IPv4 interface address\n"
    2265             :        "UN IPv6 interface address\n"
    2266             :        "Administrative cost   [default: 255]\n"
    2267             :        "Administrative cost\n"
    2268             :        "Registration lifetime [default: infinite]\n"
    2269             :        "Lifetime value in seconds\n"
    2270             :        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
    2271             : {
    2272             :         /*                       pfx      vn       un       cost     life */
    2273           0 :         return register_add(vty, argv[3], argv[5], argv[7], argv[9], argv[11],
    2274             :                             /* mac vni */
    2275             :                             NULL, NULL, argc - 12, argv + 12);
    2276             : }
    2277             : 
    2278           0 : DEFUN (add_vnc_prefix_life_cost_lnh,
    2279             :        add_vnc_prefix_life_cost_lnh_cmd,
    2280             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255) LNH_OPTIONS...",
    2281             :        "Add registration\n"
    2282             :        "VNC Information\n"
    2283             :        "Add/modify prefix related information\n"
    2284             :        "IPv4 prefix\n"
    2285             :        "IPv6 prefix\n"
    2286             :        "VN address of NVE\n"
    2287             :        "VN IPv4 interface address\n"
    2288             :        "VN IPv6 interface address\n"
    2289             :        "UN address of NVE\n"
    2290             :        "UN IPv4 interface address\n"
    2291             :        "UN IPv6 interface address\n"
    2292             :        "Registration lifetime [default: infinite]\n"
    2293             :        "Lifetime value in seconds\n"
    2294             :        "Administrative cost   [default: 255]\n"
    2295             :        "Administrative cost\n"
    2296             :        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
    2297             : {
    2298             :         /*                       pfx      vn       un       cost     life */
    2299           0 :         return register_add(vty, argv[3], argv[5], argv[7], argv[11], argv[9],
    2300             :                             /* mac vni */
    2301             :                             NULL, NULL, argc - 12, argv + 12);
    2302             : }
    2303             : 
    2304           0 : DEFUN (add_vnc_prefix_cost_lnh,
    2305             :        add_vnc_prefix_cost_lnh_cmd,
    2306             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) LNH_OPTIONS...",
    2307             :        "Add registration\n"
    2308             :        "VNC Information\n"
    2309             :        "Add/modify prefix related information\n"
    2310             :        "IPv4 prefix\n"
    2311             :        "IPv6 prefix\n"
    2312             :        "VN address of NVE\n"
    2313             :        "VN IPv4 interface address\n"
    2314             :        "VN IPv6 interface address\n"
    2315             :        "UN address of NVE\n"
    2316             :        "UN IPv4 interface address\n"
    2317             :        "UN IPv6 interface address\n"
    2318             :        "Administrative cost   [default: 255]\n"
    2319             :        "Administrative cost\n"
    2320             :        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
    2321             : {
    2322             :         /*                       pfx      vn       un       cost     life */
    2323           0 :         return register_add(vty, argv[3], argv[5], argv[7], argv[9], NULL,
    2324             :                             /* mac vni */
    2325             :                             NULL, NULL, argc - 10, argv + 10);
    2326             : }
    2327             : 
    2328           0 : DEFUN (add_vnc_prefix_life_lnh,
    2329             :        add_vnc_prefix_life_lnh_cmd,
    2330             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) LNH_OPTIONS...",
    2331             :        "Add registration\n"
    2332             :        "VNC Information\n"
    2333             :        "Add/modify prefix related information\n"
    2334             :        "IPv4 prefix\n"
    2335             :        "IPv6 prefix\n"
    2336             :        "VN address of NVE\n"
    2337             :        "VN IPv4 interface address\n"
    2338             :        "VN IPv6 interface address\n"
    2339             :        "UN address of NVE\n"
    2340             :        "UN IPv4 interface address\n"
    2341             :        "UN IPv6 interface address\n"
    2342             :        "Registration lifetime [default: infinite]\n"
    2343             :        "Lifetime value in seconds\n"
    2344             :        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
    2345             : {
    2346             :         /*                       pfx      vn       un       cost     life */
    2347           0 :         return register_add(vty, argv[3], argv[5], argv[7], NULL, argv[9],
    2348             :                             /* mac vni */
    2349             :                             NULL, NULL, argc - 10, argv + 10);
    2350             : }
    2351             : 
    2352           0 : DEFUN (add_vnc_prefix_lnh,
    2353             :        add_vnc_prefix_lnh_cmd,
    2354             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> LNH_OPTIONS...",
    2355             :        "Add registration\n"
    2356             :        "VNC Information\n"
    2357             :        "Add/modify prefix related information\n"
    2358             :        "IPv4 prefix\n"
    2359             :        "IPv6 prefix\n"
    2360             :        "VN address of NVE\n"
    2361             :        "VN IPv4 interface address\n"
    2362             :        "VN IPv6 interface address\n"
    2363             :        "UN address of NVE\n"
    2364             :        "UN IPv4 interface address\n"
    2365             :        "UN IPv6 interface address\n"
    2366             :        "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
    2367             : {
    2368             :         /*                       pfx      vn       un       cost     life */
    2369           0 :         return register_add(vty, argv[3], argv[5], argv[7], NULL, NULL,
    2370             :                             /* mac vni */
    2371             :                             NULL, NULL, argc - 8, argv + 8);
    2372             : }
    2373             : 
    2374             : /************************************************************************
    2375             :  *              Add prefix Without LNH_OPTIONS...
    2376             :  ************************************************************************/
    2377           0 : DEFUN (add_vnc_prefix_cost_life,
    2378             :        add_vnc_prefix_cost_life_cmd,
    2379             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
    2380             :        "Add registration\n"
    2381             :        "VNC Information\n"
    2382             :        "Add/modify prefix related information\n"
    2383             :        "IPv4 prefix\n"
    2384             :        "IPv6 prefix\n"
    2385             :        "VN address of NVE\n"
    2386             :        "VN IPv4 interface address\n"
    2387             :        "VN IPv6 interface address\n"
    2388             :        "UN address of NVE\n"
    2389             :        "UN IPv4 interface address\n"
    2390             :        "UN IPv6 interface address\n"
    2391             :        "Administrative cost   [default: 255]\n"
    2392             :        "Administrative cost\n"
    2393             :        "Registration lifetime [default: infinite]\n"
    2394             :        "Lifetime value in seconds\n")
    2395             : {
    2396             :         /*                       pfx      vn       un       cost     life */
    2397           0 :         return register_add(vty, argv[3], argv[5], argv[7], argv[9], argv[11],
    2398             :                             /* mac vni */
    2399             :                             NULL, NULL, 0, NULL);
    2400             : }
    2401             : 
    2402           0 : DEFUN (add_vnc_prefix_life_cost,
    2403             :        add_vnc_prefix_life_cost_cmd,
    2404             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255)",
    2405             :        "Add registration\n"
    2406             :        "VNC Information\n"
    2407             :        "Add/modify prefix related information\n"
    2408             :        "IPv4 prefix\n"
    2409             :        "IPv6 prefix\n"
    2410             :        "VN address of NVE\n"
    2411             :        "VN IPv4 interface address\n"
    2412             :        "VN IPv6 interface address\n"
    2413             :        "UN address of NVE\n"
    2414             :        "UN IPv4 interface address\n"
    2415             :        "UN IPv6 interface address\n"
    2416             :        "Registration lifetime [default: infinite]\n"
    2417             :        "Lifetime value in seconds\n"
    2418             :        "Administrative cost   [default: 255]\n"
    2419             :        "Administrative cost\n")
    2420             : {
    2421             :         /*                       pfx      vn       un       cost     life */
    2422           0 :         return register_add(vty, argv[3], argv[5], argv[7], argv[11], argv[9],
    2423             :                             /* mac vni */
    2424             :                             NULL, NULL, 0, NULL);
    2425             : }
    2426             : 
    2427           0 : DEFUN (add_vnc_prefix_cost,
    2428             :        add_vnc_prefix_cost_cmd,
    2429             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
    2430             :        "Add registration\n"
    2431             :        "VNC Information\n"
    2432             :        "Add/modify prefix related information\n"
    2433             :        "IPv4 prefix\n"
    2434             :        "IPv6 prefix\n"
    2435             :        "VN address of NVE\n"
    2436             :        "VN IPv4 interface address\n"
    2437             :        "VN IPv6 interface address\n"
    2438             :        "UN address of NVE\n"
    2439             :        "UN IPv4 interface address\n"
    2440             :        "UN IPv6 interface address\n"
    2441             :        "Administrative cost   [default: 255]\n"
    2442             :        "Administrative cost\n")
    2443             : {
    2444             :         /*                       pfx      vn       un       cost     life */
    2445           0 :         return register_add(vty, argv[3], argv[5], argv[7], argv[9], NULL,
    2446             :                             /* mac vni */
    2447             :                             NULL, NULL, 0, NULL);
    2448             : }
    2449             : 
    2450           0 : DEFUN (add_vnc_prefix_life,
    2451             :        add_vnc_prefix_life_cmd,
    2452             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
    2453             :        "Add registration\n"
    2454             :        "VNC Information\n"
    2455             :        "Add/modify prefix related information\n"
    2456             :        "IPv4 prefix\n"
    2457             :        "IPv6 prefix\n"
    2458             :        "VN address of NVE\n"
    2459             :        "VN IPv4 interface address\n"
    2460             :        "VN IPv6 interface address\n"
    2461             :        "UN address of NVE\n"
    2462             :        "UN IPv4 interface address\n"
    2463             :        "UN IPv6 interface address\n"
    2464             :        "Registration lifetime [default: infinite]\n"
    2465             :        "Lifetime value in seconds\n")
    2466             : {
    2467             :         /*                       pfx      vn       un       cost     life */
    2468           0 :         return register_add(vty, argv[3], argv[5], argv[7], NULL, argv[9],
    2469             :                             /* mac vni */
    2470             :                             NULL, NULL, 0, NULL);
    2471             : }
    2472             : 
    2473           0 : DEFUN (add_vnc_prefix,
    2474             :        add_vnc_prefix_cmd,
    2475             :        "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
    2476             :        "Add registration\n"
    2477             :        "VNC Information\n"
    2478             :        "Add/modify prefix related information\n"
    2479             :        "IPv4 prefix\n"
    2480             :        "IPv6 prefix\n"
    2481             :        "VN address of NVE\n"
    2482             :        "VN IPv4 interface address\n"
    2483             :        "VN IPv6 interface address\n"
    2484             :        "UN address of NVE\n"
    2485             :        "UN IPv4 interface address\n"
    2486             :        "UN IPv6 interface address\n")
    2487             : {
    2488             :         /*                       pfx      vn       un       cost     life */
    2489           0 :         return register_add(vty, argv[3], argv[5], argv[7], NULL, NULL,
    2490             :                             /* mac vni */
    2491             :                             NULL, NULL, 0, NULL);
    2492             : }
    2493             : 
    2494             : /************************************************************************
    2495             :  *                      Mac address registrations
    2496             :  ************************************************************************/
    2497           0 : DEFUN (add_vnc_mac_vni_prefix_cost_life,
    2498             :        add_vnc_mac_vni_prefix_cost_life_cmd,
    2499             :        "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255) lifetime (1-4294967295)",
    2500             :        "Add registration\n"
    2501             :        "VNC Information\n"
    2502             :        "Add/modify mac address information\n"
    2503             :        "MAC address\n"
    2504             :        "Virtual Network Identifier follows\n"
    2505             :        "Virtual Network Identifier\n"
    2506             :        "VN address of NVE\n"
    2507             :        "VN IPv4 interface address\n"
    2508             :        "VN IPv6 interface address\n"
    2509             :        "UN address of NVE\n"
    2510             :        "UN IPv4 interface address\n"
    2511             :        "UN IPv6 interface address\n"
    2512             :        "Add/modify prefix related information\n"
    2513             :        "IPv4 prefix\n"
    2514             :        "IPv6 prefix\n"
    2515             :        "Administrative cost   [default: 255]\n"
    2516             :        "Administrative cost\n"
    2517             :        "Registration lifetime [default: infinite]\n"
    2518             :        "Lifetime value in seconds\n")
    2519             : {
    2520             :         /*                       pfx      vn       un       cost     life */
    2521           0 :         return register_add(vty, argv[11], argv[7], argv[9], argv[13], argv[15],
    2522             :                             /* mac vni */
    2523             :                             argv[3], argv[5], 0, NULL);
    2524             : }
    2525             : 
    2526             : 
    2527           0 : DEFUN (add_vnc_mac_vni_prefix_life,
    2528             :        add_vnc_mac_vni_prefix_life_cmd,
    2529             :        "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime (1-4294967295)",
    2530             :        "Add registration\n"
    2531             :        "VNC Information\n"
    2532             :        "Add/modify mac address information\n"
    2533             :        "MAC address\n"
    2534             :        "Virtual Network Identifier follows\n"
    2535             :        "Virtual Network Identifier\n"
    2536             :        "VN address of NVE\n"
    2537             :        "VN IPv4 interface address\n"
    2538             :        "VN IPv6 interface address\n"
    2539             :        "UN address of NVE\n"
    2540             :        "UN IPv4 interface address\n"
    2541             :        "UN IPv6 interface address\n"
    2542             :        "Add/modify prefix related information\n"
    2543             :        "IPv4 prefix\n"
    2544             :        "IPv6 prefix\n"
    2545             :        "Registration lifetime [default: infinite]\n"
    2546             :        "Lifetime value in seconds\n")
    2547             : {
    2548             :         /*                       pfx      vn       un       cost     life */
    2549           0 :         return register_add(vty, argv[11], argv[7], argv[9], NULL, argv[13],
    2550             :                             /* mac vni */
    2551             :                             argv[3], argv[5], 0, NULL);
    2552             : }
    2553             : 
    2554           0 : DEFUN (add_vnc_mac_vni_prefix_cost,
    2555             :        add_vnc_mac_vni_prefix_cost_cmd,
    2556             :        "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255)",
    2557             :        "Add registration\n"
    2558             :        "VNC Information\n"
    2559             :        "Add/modify mac address information\n"
    2560             :        "MAC address\n"
    2561             :        "Virtual Network Identifier follows\n"
    2562             :        "Virtual Network Identifier\n"
    2563             :        "VN address of NVE\n"
    2564             :        "VN IPv4 interface address\n"
    2565             :        "VN IPv6 interface address\n"
    2566             :        "UN address of NVE\n"
    2567             :        "UN IPv4 interface address\n"
    2568             :        "UN IPv6 interface address\n"
    2569             :        "Add/modify prefix related information\n"
    2570             :        "IPv4 prefix\n"
    2571             :        "IPv6 prefix\n"
    2572             :        "Administrative cost   [default: 255]\n" "Administrative cost\n")
    2573             : {
    2574             :         /*                       pfx      vn       un       cost     life */
    2575           0 :         return register_add(vty, argv[11], argv[7], argv[9], argv[13], NULL,
    2576             :                             /* mac vni */
    2577             :                             argv[3], argv[5], 0, NULL);
    2578             : }
    2579             : 
    2580           0 : DEFUN (add_vnc_mac_vni_prefix,
    2581             :        add_vnc_mac_vni_prefix_cmd,
    2582             :        "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>",
    2583             :        "Add registration\n"
    2584             :        "VNC Information\n"
    2585             :        "Add/modify mac address information\n"
    2586             :        "MAC address\n"
    2587             :        "Virtual Network Identifier follows\n"
    2588             :        "Virtual Network Identifier\n"
    2589             :        "VN address of NVE\n"
    2590             :        "VN IPv4 interface address\n"
    2591             :        "VN IPv6 interface address\n"
    2592             :        "UN address of NVE\n"
    2593             :        "UN IPv4 interface address\n"
    2594             :        "UN IPv6 interface address\n"
    2595             :        "Add/modify prefix related information\n"
    2596             :        "IPv4 prefix\n" "IPv6 prefix\n")
    2597             : {
    2598             :         /*                       pfx      vn       un       cost     life */
    2599           0 :         return register_add(vty, argv[11], argv[7], argv[9], NULL, NULL,
    2600             :                             /* mac vni */
    2601             :                             argv[3], argv[5], 0, NULL);
    2602             : }
    2603             : 
    2604           0 : DEFUN (add_vnc_mac_vni_cost_life,
    2605             :        add_vnc_mac_vni_cost_life_cmd,
    2606             :        "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
    2607             :        "Add registration\n"
    2608             :        "VNC Information\n"
    2609             :        "Add/modify mac address information\n"
    2610             :        "MAC address\n"
    2611             :        "Virtual Network Identifier follows\n"
    2612             :        "Virtual Network Identifier\n"
    2613             :        "VN address of NVE\n"
    2614             :        "VN IPv4 interface address\n"
    2615             :        "VN IPv6 interface address\n"
    2616             :        "UN address of NVE\n"
    2617             :        "UN IPv4 interface address\n"
    2618             :        "UN IPv6 interface address\n"
    2619             :        "Administrative cost   [default: 255]\n"
    2620             :        "Administrative cost\n"
    2621             :        "Registration lifetime [default: infinite]\n"
    2622             :        "Lifetime value in seconds\n")
    2623             : {
    2624             :         /*                       pfx      vn       un       cost     life */
    2625           0 :         return register_add(vty, NULL, argv[7], argv[9], argv[11], argv[13],
    2626             :                             /* mac vni */
    2627             :                             argv[3], argv[5], 0, NULL);
    2628             : }
    2629             : 
    2630             : 
    2631           0 : DEFUN (add_vnc_mac_vni_cost,
    2632             :        add_vnc_mac_vni_cost_cmd,
    2633             :        "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
    2634             :        "Add registration\n"
    2635             :        "VNC Information\n"
    2636             :        "Add/modify mac address information\n"
    2637             :        "MAC address\n"
    2638             :        "Virtual Network Identifier follows\n"
    2639             :        "Virtual Network Identifier\n"
    2640             :        "VN address of NVE\n"
    2641             :        "VN IPv4 interface address\n"
    2642             :        "VN IPv6 interface address\n"
    2643             :        "UN address of NVE\n"
    2644             :        "UN IPv4 interface address\n"
    2645             :        "UN IPv6 interface address\n"
    2646             :        "Administrative cost   [default: 255]\n" "Administrative cost\n")
    2647             : {
    2648             :         /*                       pfx      vn       un    cost     life */
    2649           0 :         return register_add(vty, NULL, argv[7], argv[9], argv[11], NULL,
    2650             :                             /* mac vni */
    2651             :                             argv[3], argv[5], 0, NULL);
    2652             : }
    2653             : 
    2654             : 
    2655           0 : DEFUN (add_vnc_mac_vni_life,
    2656             :        add_vnc_mac_vni_life_cmd,
    2657             :        "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
    2658             :        "Add registration\n"
    2659             :        "VNC Information\n"
    2660             :        "Add/modify mac address information\n"
    2661             :        "MAC address\n"
    2662             :        "Virtual Network Identifier follows\n"
    2663             :        "Virtual Network Identifier\n"
    2664             :        "VN address of NVE\n"
    2665             :        "VN IPv4 interface address\n"
    2666             :        "VN IPv6 interface address\n"
    2667             :        "UN address of NVE\n"
    2668             :        "UN IPv4 interface address\n"
    2669             :        "UN IPv6 interface address\n"
    2670             :        "Registration lifetime [default: infinite]\n"
    2671             :        "Lifetime value in seconds\n")
    2672             : {
    2673             :         /*                       pfx      vn       un    cost  life */
    2674           0 :         return register_add(vty, NULL, argv[7], argv[9], NULL, argv[11],
    2675             :                             /* mac vni */
    2676             :                             argv[3], argv[5], 0, NULL);
    2677             : }
    2678             : 
    2679             : 
    2680           0 : DEFUN (add_vnc_mac_vni,
    2681             :        add_vnc_mac_vni_cmd,
    2682             :        "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
    2683             :        "Add registration\n"
    2684             :        "VNC Information\n"
    2685             :        "Add/modify mac address information\n"
    2686             :        "MAC address\n"
    2687             :        "Virtual Network Identifier follows\n"
    2688             :        "Virtual Network Identifier\n"
    2689             :        "VN address of NVE\n"
    2690             :        "VN IPv4 interface address\n"
    2691             :        "VN IPv6 interface address\n"
    2692             :        "UN address of NVE\n"
    2693             :        "UN IPv4 interface address\n" "UN IPv6 interface address\n")
    2694             : {
    2695             :         /*                       pfx      vn       un    cost  life */
    2696           0 :         return register_add(vty, NULL, argv[7], argv[9], NULL, NULL,
    2697             :                             /* mac vni */
    2698             :                             argv[3], argv[5], 0, NULL);
    2699             : }
    2700             : 
    2701             : /************************************************************************
    2702             :  *                      Delete prefix
    2703             :  ************************************************************************/
    2704             : 
    2705             : struct rfapi_local_reg_delete_arg {
    2706             :         /*
    2707             :          * match parameters
    2708             :          */
    2709             :         struct bgp *bgp;
    2710             :         struct rfapi_ip_addr un_address; /* AF==0: wildcard */
    2711             :         struct rfapi_ip_addr vn_address; /* AF==0: wildcard */
    2712             :         struct prefix prefix;            /* AF==0: wildcard */
    2713             :         struct prefix_rd rd;             /* plen!=64: wildcard */
    2714             :         struct rfapi_nve_group_cfg *rfg; /* NULL: wildcard */
    2715             : 
    2716             :         struct rfapi_l2address_option_match l2o;
    2717             : 
    2718             :         /*
    2719             :          * result parameters
    2720             :          */
    2721             :         struct vty *vty;
    2722             :         uint32_t reg_count;
    2723             :         uint32_t pfx_count;
    2724             :         uint32_t query_count;
    2725             : 
    2726             :         uint32_t failed_pfx_count;
    2727             : 
    2728             :         uint32_t nve_count;
    2729             :         struct skiplist *nves;
    2730             : 
    2731             :         uint32_t remote_active_nve_count;
    2732             :         uint32_t remote_active_pfx_count;
    2733             :         uint32_t remote_holddown_nve_count;
    2734             :         uint32_t remote_holddown_pfx_count;
    2735             : };
    2736             : 
    2737             : struct nve_addr {
    2738             :         struct rfapi_ip_addr vn;
    2739             :         struct rfapi_ip_addr un;
    2740             :         struct rfapi_descriptor *rfd;
    2741             :         struct rfapi_local_reg_delete_arg *cda;
    2742             : };
    2743             : 
    2744           0 : static void nve_addr_free(void *hap)
    2745             : {
    2746           0 :         ((struct nve_addr *)hap)->cda->nve_count += 1;
    2747           0 :         XFREE(MTYPE_RFAPI_NVE_ADDR, hap);
    2748           0 : }
    2749             : 
    2750           0 : static int nve_addr_cmp(const void *k1, const void *k2)
    2751             : {
    2752           0 :         const struct nve_addr *a = (struct nve_addr *)k1;
    2753           0 :         const struct nve_addr *b = (struct nve_addr *)k2;
    2754           0 :         int ret = 0;
    2755             : 
    2756           0 :         if (!a || !b) {
    2757           0 :                 return (a - b);
    2758             :         }
    2759           0 :         if (a->un.addr_family != b->un.addr_family) {
    2760           0 :                 return (a->un.addr_family - b->un.addr_family);
    2761             :         }
    2762           0 :         if (a->vn.addr_family != b->vn.addr_family) {
    2763           0 :                 return (a->vn.addr_family - b->vn.addr_family);
    2764             :         }
    2765           0 :         if (a->un.addr_family == AF_INET) {
    2766           0 :                 ret = IPV4_ADDR_CMP(&a->un.addr.v4, &b->un.addr.v4);
    2767           0 :                 if (ret != 0) {
    2768             :                         return ret;
    2769             :                 }
    2770           0 :         } else if (a->un.addr_family == AF_INET6) {
    2771           0 :                 ret = IPV6_ADDR_CMP(&a->un.addr.v6, &b->un.addr.v6);
    2772           0 :                 if (ret != 0) {
    2773             :                         return ret;
    2774             :                 }
    2775             :         } else {
    2776           0 :                 assert(0);
    2777             :         }
    2778           0 :         if (a->vn.addr_family == AF_INET) {
    2779           0 :                 ret = IPV4_ADDR_CMP(&a->vn.addr.v4, &b->vn.addr.v4);
    2780           0 :                 if (ret != 0)
    2781             :                         return ret;
    2782           0 :         } else if (a->vn.addr_family == AF_INET6) {
    2783           0 :                 ret = IPV6_ADDR_CMP(&a->vn.addr.v6, &b->vn.addr.v6);
    2784             :                 if (ret == 0) {
    2785             :                         return ret;
    2786             :                 }
    2787             :         } else {
    2788           0 :                 assert(0);
    2789             :         }
    2790             :         return 0;
    2791             : }
    2792             : 
    2793           0 : static int parse_deleter_args(struct vty *vty, struct bgp *bgp,
    2794             :                               const char *arg_prefix, const char *arg_vn,
    2795             :                               const char *arg_un, const char *arg_l2addr,
    2796             :                               const char *arg_vni, const char *arg_rd,
    2797             :                               struct rfapi_nve_group_cfg *arg_rfg,
    2798             :                               struct rfapi_local_reg_delete_arg *rcdarg)
    2799             : {
    2800           0 :         int rc = CMD_WARNING;
    2801             : 
    2802           0 :         memset(rcdarg, 0, sizeof(struct rfapi_local_reg_delete_arg));
    2803             : 
    2804           0 :         rcdarg->vty = vty;
    2805           0 :         if (bgp == NULL)
    2806           0 :                 bgp = bgp_get_default();
    2807           0 :         rcdarg->bgp = bgp;
    2808           0 :         rcdarg->rfg = arg_rfg; /* may be NULL */
    2809             : 
    2810           0 :         if (arg_vn && strcmp(arg_vn, "*")) {
    2811           0 :                 if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_vn,
    2812             :                                                  &rcdarg->vn_address)))
    2813             :                         return rc;
    2814             :         }
    2815           0 :         if (arg_un && strcmp(arg_un, "*")) {
    2816           0 :                 if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_un,
    2817             :                                                  &rcdarg->un_address)))
    2818             :                         return rc;
    2819             :         }
    2820           0 :         if (arg_prefix && strcmp(arg_prefix, "*")) {
    2821             : 
    2822           0 :                 if (!str2prefix(arg_prefix, &rcdarg->prefix)) {
    2823           0 :                         vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix);
    2824           0 :                         return rc;
    2825             :                 }
    2826             :         }
    2827             : 
    2828           0 :         if (arg_l2addr) {
    2829           0 :                 if (!arg_vni) {
    2830           0 :                         vty_out(vty, "Missing VNI\n");
    2831           0 :                         return rc;
    2832             :                 }
    2833           0 :                 if (strcmp(arg_l2addr, "*")) {
    2834           0 :                         if ((rc = rfapiStr2EthAddr(arg_l2addr,
    2835             :                                                    &rcdarg->l2o.o.macaddr))) {
    2836           0 :                                 vty_out(vty, "Malformed L2 Address \"%s\"\n",
    2837             :                                         arg_l2addr);
    2838           0 :                                 return rc;
    2839             :                         }
    2840           0 :                         rcdarg->l2o.flags |= RFAPI_L2O_MACADDR;
    2841             :                 }
    2842           0 :                 if (strcmp(arg_vni, "*")) {
    2843           0 :                         rcdarg->l2o.o.logical_net_id =
    2844           0 :                                 strtoul(arg_vni, NULL, 10);
    2845           0 :                         rcdarg->l2o.flags |= RFAPI_L2O_LNI;
    2846             :                 }
    2847             :         }
    2848           0 :         if (arg_rd) {
    2849           0 :                 if (!str2prefix_rd(arg_rd, &rcdarg->rd)) {
    2850           0 :                         vty_out(vty, "Malformed RD \"%s\"\n", arg_rd);
    2851           0 :                         return rc;
    2852             :                 }
    2853             :         }
    2854             : 
    2855             :         return CMD_SUCCESS;
    2856             : }
    2857             : 
    2858             : static int
    2859           0 : parse_deleter_tokens(struct vty *vty, struct bgp *bgp,
    2860             :                      struct cmd_token *carg_prefix, struct cmd_token *carg_vn,
    2861             :                      struct cmd_token *carg_un, struct cmd_token *carg_l2addr,
    2862             :                      struct cmd_token *carg_vni, struct cmd_token *carg_rd,
    2863             :                      struct rfapi_nve_group_cfg *arg_rfg,
    2864             :                      struct rfapi_local_reg_delete_arg *rcdarg)
    2865             : {
    2866           0 :         const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL;
    2867           0 :         const char *arg_vn = carg_vn ? carg_vn->arg : NULL;
    2868           0 :         const char *arg_un = carg_un ? carg_un->arg : NULL;
    2869           0 :         const char *arg_l2addr = carg_l2addr ? carg_l2addr->arg : NULL;
    2870           0 :         const char *arg_vni = carg_vni ? carg_vni->arg : NULL;
    2871           0 :         const char *arg_rd = carg_rd ? carg_rd->arg : NULL;
    2872           0 :         return parse_deleter_args(vty, bgp, arg_prefix, arg_vn, arg_un,
    2873             :                                   arg_l2addr, arg_vni, arg_rd, arg_rfg, rcdarg);
    2874             : }
    2875             : 
    2876           0 : static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg *cda,
    2877             :                                    struct rfapi_ip_addr *un_address,
    2878             :                                    struct rfapi_ip_addr *vn_address,
    2879             :                                    struct rfapi_descriptor *rfd)
    2880             : {
    2881           0 :         struct nve_addr ha;
    2882           0 :         struct nve_addr *hap;
    2883             : 
    2884           0 :         memset(&ha, 0, sizeof(ha));
    2885           0 :         ha.un = *un_address;
    2886           0 :         ha.vn = *vn_address;
    2887           0 :         ha.rfd = rfd;
    2888             : 
    2889           0 :         if (!cda->nves)
    2890           0 :                 cda->nves = skiplist_new(0, nve_addr_cmp, nve_addr_free);
    2891             : 
    2892           0 :         if (skiplist_search(cda->nves, &ha, (void *)&hap)) {
    2893           0 :                 hap = XCALLOC(MTYPE_RFAPI_NVE_ADDR, sizeof(struct nve_addr));
    2894           0 :                 assert(hap);
    2895           0 :                 ha.cda = cda;
    2896           0 :                 *hap = ha;
    2897           0 :                 skiplist_insert(cda->nves, hap, hap);
    2898             :         }
    2899           0 : }
    2900             : 
    2901           0 : static void clear_vnc_responses(struct rfapi_local_reg_delete_arg *cda)
    2902             : {
    2903           0 :         struct rfapi *h;
    2904           0 :         struct rfapi_descriptor *rfd;
    2905           0 :         int query_count = 0;
    2906           0 :         struct listnode *node;
    2907           0 :         struct bgp *bgp_default = bgp_get_default();
    2908             : 
    2909           0 :         if (cda->vn_address.addr_family && cda->un_address.addr_family) {
    2910             :                 /*
    2911             :                  * Single nve case
    2912             :                  */
    2913           0 :                 if (rfapi_find_rfd(bgp_default, &cda->vn_address,
    2914             :                                    &cda->un_address, &rfd))
    2915           0 :                         return;
    2916             : 
    2917           0 :                 rfapiRibClear(rfd);
    2918           0 :                 rfapi_query_done_all(rfd, &query_count);
    2919           0 :                 cda->query_count += query_count;
    2920             : 
    2921             :                 /*
    2922             :                  * Track unique nves seen
    2923             :                  */
    2924           0 :                 record_nve_in_cda_list(cda, &rfd->un_addr, &rfd->vn_addr, rfd);
    2925           0 :                 return;
    2926             :         }
    2927             : 
    2928             :         /*
    2929             :          * wildcard case
    2930             :          */
    2931             : 
    2932           0 :         if (!bgp_default)
    2933             :                 return; /* ENXIO */
    2934             : 
    2935           0 :         h = bgp_default->rfapi;
    2936             : 
    2937           0 :         if (!h)
    2938             :                 return; /* ENXIO */
    2939             : 
    2940           0 :         for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) {
    2941             :                 /*
    2942             :                  * match un, vn addresses of NVEs
    2943             :                  */
    2944           0 :                 if (cda->un_address.addr_family
    2945           0 :                     && rfapi_ip_addr_cmp(&cda->un_address, &rfd->un_addr)) {
    2946           0 :                         continue;
    2947             :                 }
    2948           0 :                 if (cda->vn_address.addr_family
    2949           0 :                     && rfapi_ip_addr_cmp(&cda->vn_address, &rfd->vn_addr)) {
    2950           0 :                         continue;
    2951             :                 }
    2952             : 
    2953           0 :                 rfapiRibClear(rfd);
    2954             : 
    2955           0 :                 rfapi_query_done_all(rfd, &query_count);
    2956           0 :                 cda->query_count += query_count;
    2957             : 
    2958             :                 /*
    2959             :                  * Track unique nves seen
    2960             :                  */
    2961           0 :                 record_nve_in_cda_list(cda, &rfd->un_addr, &rfd->vn_addr, rfd);
    2962             :         }
    2963             : }
    2964             : 
    2965             : /*
    2966             :  * TBD need to count deleted prefixes and nves?
    2967             :  *
    2968             :  * ENXIO        BGP or VNC not configured
    2969             :  */
    2970           0 : static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg *cda,
    2971             :                                          struct rfapi_descriptor *rfd)
    2972             : {
    2973           0 :         struct rfapi_ip_addr *pUn; /* NULL = wildcard */
    2974           0 :         struct rfapi_ip_addr *pVn; /* NULL = wildcard */
    2975           0 :         struct prefix *pPrefix;    /* NULL = wildcard */
    2976           0 :         struct prefix_rd *pPrd;    /* NULL = wildcard */
    2977             : 
    2978           0 :         struct rfapi_ip_prefix rprefix;
    2979           0 :         struct rfapi_next_hop_entry *head = NULL;
    2980           0 :         struct rfapi_next_hop_entry *tail = NULL;
    2981             : 
    2982             : #if DEBUG_L2_EXTRA
    2983             :         vnc_zlog_debug_verbose("%s: entry", __func__);
    2984             : #endif
    2985             : 
    2986           0 :         pUn = (cda->un_address.addr_family ? &cda->un_address : NULL);
    2987           0 :         pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL);
    2988           0 :         pPrefix = (cda->prefix.family ? &cda->prefix : NULL);
    2989           0 :         pPrd = (cda->rd.prefixlen == 64 ? &cda->rd : NULL);
    2990             : 
    2991           0 :         if (pPrefix) {
    2992           0 :                 rfapiQprefix2Rprefix(pPrefix, &rprefix);
    2993             :         }
    2994             : 
    2995           0 :         do /* to preserve old code structure */
    2996           0 :         {
    2997           0 :                 struct rfapi *h = cda->bgp->rfapi;
    2998           0 :                 ;
    2999           0 :                 struct rfapi_adb *adb;
    3000           0 :                 int rc;
    3001           0 :                 int deleted_from_this_nve;
    3002           0 :                 struct nve_addr ha;
    3003           0 :                 struct nve_addr *hap;
    3004             : 
    3005             : #if DEBUG_L2_EXTRA
    3006             :                 vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd);
    3007             : #endif
    3008             : 
    3009             :                 /*
    3010             :                  * match un, vn addresses of NVEs
    3011             :                  */
    3012           0 :                 if (pUn && (rfapi_ip_addr_cmp(pUn, &rfd->un_addr)))
    3013             :                         break;
    3014           0 :                 if (pVn && (rfapi_ip_addr_cmp(pVn, &rfd->vn_addr)))
    3015             :                         break;
    3016             : 
    3017             : #if DEBUG_L2_EXTRA
    3018             :                 vnc_zlog_debug_verbose("%s: un, vn match", __func__);
    3019             : #endif
    3020             : 
    3021             :                 /*
    3022             :                  * match prefix
    3023             :                  */
    3024             : 
    3025           0 :                 deleted_from_this_nve = 0;
    3026             : 
    3027             :                 {
    3028           0 :                         struct skiplist *sl;
    3029           0 :                         struct rfapi_ip_prefix rp;
    3030           0 :                         void *cursor;
    3031           0 :                         struct list *adb_delete_list;
    3032             : 
    3033             :                         /*
    3034             :                          * The advertisements are stored in a skiplist.
    3035             :                          * Withdrawing
    3036             :                          * the registration deletes the advertisement from the
    3037             :                          * skiplist, which we can't do while iterating over that
    3038             :                          * same skiplist using the current skiplist API.
    3039             :                          *
    3040             :                          * Strategy: iterate over the skiplist and build another
    3041             :                          * list containing only the matching ADBs. Then delete
    3042             :                          * _everything_ in that second list (which can be done
    3043             :                          * using either skiplists or quagga linklists).
    3044             :                          */
    3045           0 :                         adb_delete_list = list_new();
    3046             : 
    3047             :                         /*
    3048             :                          * Advertised IP prefixes (not 0/32 or 0/128)
    3049             :                          */
    3050           0 :                         sl = rfd->advertised.ipN_by_prefix;
    3051             : 
    3052           0 :                         for (cursor = NULL,
    3053           0 :                             rc = skiplist_next(sl, NULL, (void **)&adb,
    3054             :                                                &cursor);
    3055           0 :                              !rc; rc = skiplist_next(sl, NULL, (void **)&adb,
    3056             :                                                      &cursor)) {
    3057             : 
    3058           0 :                                 if (pPrefix) {
    3059           0 :                                         if (!prefix_same(pPrefix,
    3060           0 :                                                          &adb->u.s.prefix_ip)) {
    3061             : #if DEBUG_L2_EXTRA
    3062             :                                                 vnc_zlog_debug_verbose(
    3063             :                                                         "%s: adb=%p, prefix doesn't match, skipping",
    3064             :                                                         __func__, adb);
    3065             : #endif
    3066           0 :                                                 continue;
    3067             :                                         }
    3068             :                                 }
    3069           0 :                                 if (pPrd) {
    3070           0 :                                         if (memcmp(pPrd->val, adb->u.s.prd.val,
    3071             :                                                    8)
    3072             :                                             != 0) {
    3073             : #if DEBUG_L2_EXTRA
    3074             :                                                 vnc_zlog_debug_verbose(
    3075             :                                                         "%s: adb=%p, RD doesn't match, skipping",
    3076             :                                                         __func__, adb);
    3077             : #endif
    3078           0 :                                                 continue;
    3079             :                                         }
    3080             :                                 }
    3081           0 :                                 if (CHECK_FLAG(cda->l2o.flags,
    3082             :                                                RFAPI_L2O_MACADDR)) {
    3083           0 :                                         if (memcmp(cda->l2o.o.macaddr.octet,
    3084           0 :                                                    adb->u.s.prefix_eth.u
    3085           0 :                                                            .prefix_eth.octet,
    3086             :                                                    ETH_ALEN)) {
    3087             : #if DEBUG_L2_EXTRA
    3088             :                                                 vnc_zlog_debug_verbose(
    3089             :                                                         "%s: adb=%p, macaddr doesn't match, skipping",
    3090             :                                                         __func__, adb);
    3091             : #endif
    3092           0 :                                                 continue;
    3093             :                                         }
    3094             :                                 }
    3095             : 
    3096           0 :                                 if (CHECK_FLAG(cda->l2o.flags, RFAPI_L2O_LNI)) {
    3097           0 :                                         if (cda->l2o.o.logical_net_id
    3098           0 :                                             != adb->l2o.logical_net_id) {
    3099             : #if DEBUG_L2_EXTRA
    3100             :                                                 vnc_zlog_debug_verbose(
    3101             :                                                         "%s: adb=%p, LNI doesn't match, skipping",
    3102             :                                                         __func__, adb);
    3103             : #endif
    3104           0 :                                                 continue;
    3105             :                                         }
    3106             :                                 }
    3107             : 
    3108             : #if DEBUG_L2_EXTRA
    3109             :                                 vnc_zlog_debug_verbose(
    3110             :                                         "%s: ipN adding adb %p to delete list",
    3111             :                                         __func__, adb);
    3112             : #endif
    3113             : 
    3114           0 :                                 listnode_add(adb_delete_list, adb);
    3115             :                         }
    3116             : 
    3117           0 :                         struct listnode *node;
    3118             : 
    3119           0 :                         for (ALL_LIST_ELEMENTS_RO(adb_delete_list, node, adb)) {
    3120           0 :                                 int this_advertisement_prefix_count;
    3121           0 :                                 struct rfapi_vn_option optary[3];
    3122           0 :                                 struct rfapi_vn_option *opt = NULL;
    3123           0 :                                 int cur_opt = 0;
    3124             : 
    3125           0 :                                 this_advertisement_prefix_count = 1;
    3126             : 
    3127           0 :                                 rfapiQprefix2Rprefix(&adb->u.s.prefix_ip, &rp);
    3128             : 
    3129           0 :                                 memset(optary, 0, sizeof(optary));
    3130             : 
    3131             :                                 /* if mac addr present in advert,  make l2o vn
    3132             :                                  * option */
    3133           0 :                                 if (adb->u.s.prefix_eth.family == AF_ETHERNET) {
    3134           0 :                                         if (opt != NULL)
    3135             :                                                 opt->next = &optary[cur_opt];
    3136           0 :                                         opt = &optary[cur_opt++];
    3137           0 :                                         opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
    3138           0 :                                         opt->v.l2addr.macaddr =
    3139             :                                                 adb->u.s.prefix_eth.u
    3140             :                                                         .prefix_eth;
    3141           0 :                                         ++this_advertisement_prefix_count;
    3142             :                                 }
    3143             :                                 /*
    3144             :                                  * use saved RD value instead of trying to
    3145             :                                  * invert
    3146             :                                  * complex RD computation in rfapi_register()
    3147             :                                  */
    3148           0 :                                 if (opt != NULL)
    3149           0 :                                         opt->next = &optary[cur_opt];
    3150           0 :                                 opt = &optary[cur_opt++];
    3151           0 :                                 opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
    3152           0 :                                 opt->v.internal_rd = adb->u.s.prd;
    3153             : 
    3154             : #if DEBUG_L2_EXTRA
    3155             :                                 vnc_zlog_debug_verbose(
    3156             :                                         "%s: ipN killing reg from adb %p ",
    3157             :                                         __func__, adb);
    3158             : #endif
    3159             : 
    3160           0 :                                 rc = rfapi_register(rfd, &rp, 0, NULL,
    3161             :                                                     (cur_opt ? optary : NULL),
    3162             :                                                     RFAPI_REGISTER_KILL);
    3163           0 :                                 if (!rc) {
    3164           0 :                                         cda->pfx_count +=
    3165             :                                                 this_advertisement_prefix_count;
    3166           0 :                                         cda->reg_count += 1;
    3167           0 :                                         deleted_from_this_nve = 1;
    3168             :                                 }
    3169           0 :                                 if (h->rfp_methods.local_cb) {
    3170           0 :                                         rfapiAddDeleteLocalRfpPrefix(
    3171             :                                                 &rfd->un_addr, &rfd->vn_addr,
    3172             :                                                 &rp, 0, 0, NULL, &head, &tail);
    3173             :                                 }
    3174             :                         }
    3175           0 :                         list_delete_all_node(adb_delete_list);
    3176             : 
    3177           0 :                         if (!(pPrefix && !RFAPI_0_PREFIX(pPrefix))) {
    3178             :                                 /*
    3179             :                                  * Caller didn't specify a prefix, or specified
    3180             :                                  * (0/32 or 0/128)
    3181             :                                  */
    3182             : 
    3183             :                                 /*
    3184             :                                  * Advertised 0/32 and 0/128 (indexed by
    3185             :                                  * ethernet address)
    3186             :                                  */
    3187           0 :                                 sl = rfd->advertised.ip0_by_ether;
    3188             : 
    3189           0 :                                 for (cursor = NULL,
    3190           0 :                                     rc = skiplist_next(sl, NULL, (void **)&adb,
    3191             :                                                        &cursor);
    3192           0 :                                      !rc;
    3193           0 :                                      rc = skiplist_next(sl, NULL, (void **)&adb,
    3194             :                                                         &cursor)) {
    3195             : 
    3196           0 :                                         if (CHECK_FLAG(cda->l2o.flags,
    3197             :                                                        RFAPI_L2O_MACADDR)) {
    3198           0 :                                                 if (memcmp(cda->l2o.o.macaddr
    3199           0 :                                                                    .octet,
    3200           0 :                                                            adb->u.s.prefix_eth.u
    3201             :                                                                    .prefix_eth
    3202           0 :                                                                    .octet,
    3203             :                                                            ETH_ALEN)) {
    3204             : 
    3205           0 :                                                         continue;
    3206             :                                                 }
    3207             :                                         }
    3208           0 :                                         if (CHECK_FLAG(cda->l2o.flags,
    3209             :                                                        RFAPI_L2O_LNI)) {
    3210           0 :                                                 if (cda->l2o.o.logical_net_id
    3211           0 :                                                     != adb->l2o.logical_net_id) {
    3212           0 :                                                         continue;
    3213             :                                                 }
    3214             :                                         }
    3215             : #if DEBUG_L2_EXTRA
    3216             :                                         vnc_zlog_debug_verbose(
    3217             :                                                 "%s: ip0 adding adb %p to delete list",
    3218             :                                                 __func__, adb);
    3219             : #endif
    3220           0 :                                         listnode_add(adb_delete_list, adb);
    3221             :                                 }
    3222             : 
    3223             : 
    3224           0 :                                 for (ALL_LIST_ELEMENTS_RO(adb_delete_list, node,
    3225             :                                                           adb)) {
    3226             : 
    3227           0 :                                         struct rfapi_vn_option vn;
    3228             : 
    3229           0 :                                         rfapiQprefix2Rprefix(
    3230           0 :                                                 &adb->u.s.prefix_ip, &rp);
    3231             : 
    3232           0 :                                         memset(&vn, 0, sizeof(vn));
    3233           0 :                                         vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
    3234           0 :                                         vn.v.l2addr = adb->l2o;
    3235             : 
    3236             : #if DEBUG_L2_EXTRA
    3237             :                                         vnc_zlog_debug_verbose(
    3238             :                                                 "%s: ip0 killing reg from adb %p ",
    3239             :                                                 __func__, adb);
    3240             : #endif
    3241             : 
    3242           0 :                                         rc = rfapi_register(
    3243             :                                                 rfd, &rp, 0, NULL, &vn,
    3244             :                                                 RFAPI_REGISTER_KILL);
    3245           0 :                                         if (!rc) {
    3246           0 :                                                 cda->pfx_count += 1;
    3247           0 :                                                 cda->reg_count += 1;
    3248           0 :                                                 deleted_from_this_nve = 1;
    3249             :                                         }
    3250           0 :                                         if (h->rfp_methods.local_cb) {
    3251           0 :                                                 struct rfapi_vn_option
    3252             :                                                         *vn_opt_new;
    3253             : 
    3254           0 :                                                 vn_opt_new =
    3255           0 :                                                         rfapi_vn_options_dup(
    3256             :                                                                 &vn);
    3257           0 :                                                 rfapiAddDeleteLocalRfpPrefix(
    3258             :                                                         &rfd->un_addr,
    3259             :                                                         &rfd->vn_addr, &rp, 0,
    3260             :                                                         0, vn_opt_new, &head,
    3261             :                                                         &tail);
    3262             :                                         }
    3263             :                                 }
    3264           0 :                                 list_delete_all_node(adb_delete_list);
    3265             :                         }
    3266           0 :                         list_delete(&adb_delete_list);
    3267             :                 }
    3268             : 
    3269             : 
    3270           0 :                 if (head) { /* should not be set if (NULL ==
    3271             :                                rfapi_cfg->local_cb) */
    3272           0 :                         h->flags |= RFAPI_INCALLBACK;
    3273           0 :                         (*h->rfp_methods.local_cb)(head, rfd->cookie);
    3274           0 :                         h->flags &= ~RFAPI_INCALLBACK;
    3275           0 :                         head = tail = NULL;
    3276             :                 }
    3277             : 
    3278           0 :                 if (deleted_from_this_nve) {
    3279             :                         /*
    3280             :                          * track unique NVEs seen
    3281             :                          */
    3282           0 :                         memset(&ha, 0, sizeof(ha));
    3283           0 :                         ha.un = rfd->un_addr;
    3284           0 :                         ha.vn = rfd->vn_addr;
    3285             : 
    3286           0 :                         if (!cda->nves)
    3287           0 :                                 cda->nves = skiplist_new(0, nve_addr_cmp,
    3288             :                                                          nve_addr_free);
    3289           0 :                         if (skiplist_search(cda->nves, &ha, (void **)&hap)) {
    3290           0 :                                 hap = XCALLOC(MTYPE_RFAPI_NVE_ADDR,
    3291             :                                               sizeof(struct nve_addr));
    3292           0 :                                 assert(hap);
    3293           0 :                                 ha.cda = cda;
    3294           0 :                                 *hap = ha;
    3295           0 :                                 skiplist_insert(cda->nves, hap, hap);
    3296             :                         }
    3297             :                 }
    3298             :         } while (0); /*  to preserve old code structure */
    3299             : 
    3300           0 :         return 0;
    3301             : }
    3302             : 
    3303           0 : static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg *cda)
    3304             : {
    3305           0 :         int rc = 0;
    3306             : 
    3307           0 :         if (cda->rfg) {
    3308           0 :                 if (cda->rfg->rfd) /* if not open, nothing to delete */
    3309           0 :                         rc = rfapiDeleteLocalPrefixesByRFD(cda, cda->rfg->rfd);
    3310             :         } else {
    3311           0 :                 struct bgp *bgp = cda->bgp;
    3312           0 :                 struct rfapi *h;
    3313           0 :                 struct rfapi_cfg *rfapi_cfg;
    3314             : 
    3315           0 :                 struct listnode *node;
    3316           0 :                 struct rfapi_descriptor *rfd;
    3317           0 :                 if (!bgp)
    3318             :                         return ENXIO;
    3319           0 :                 h = bgp->rfapi;
    3320           0 :                 rfapi_cfg = bgp->rfapi_cfg;
    3321           0 :                 if (!h || !rfapi_cfg)
    3322             :                         return ENXIO;
    3323           0 :                 vnc_zlog_debug_verbose("%s: starting descriptor loop",
    3324             :                                        __func__);
    3325           0 :                 for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) {
    3326           0 :                         rc = rfapiDeleteLocalPrefixesByRFD(cda, rfd);
    3327             :                 }
    3328             :         }
    3329             :         return rc;
    3330             : }
    3331             : 
    3332             : /*
    3333             :  * clear_vnc_prefix
    3334             :  *
    3335             :  * Deletes local and remote prefixes that match
    3336             :  */
    3337           0 : static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg *cda)
    3338             : {
    3339           0 :         struct prefix pfx_un;
    3340           0 :         struct prefix pfx_vn;
    3341             : 
    3342           0 :         struct prefix *pUN = NULL;
    3343           0 :         struct prefix *pVN = NULL;
    3344           0 :         struct prefix *pPrefix = NULL;
    3345             : 
    3346           0 :         struct rfapi_import_table *it = NULL;
    3347             : 
    3348             :         /*
    3349             :          * Delete matching remote prefixes in holddown
    3350             :          */
    3351           0 :         if (cda->vn_address.addr_family) {
    3352           0 :                 if (!rfapiRaddr2Qprefix(&cda->vn_address, &pfx_vn))
    3353           0 :                         pVN = &pfx_vn;
    3354             :         }
    3355           0 :         if (cda->un_address.addr_family) {
    3356           0 :                 if (!rfapiRaddr2Qprefix(&cda->un_address, &pfx_un))
    3357           0 :                         pUN = &pfx_un;
    3358             :         }
    3359           0 :         if (cda->prefix.family) {
    3360           0 :                 pPrefix = &cda->prefix;
    3361             :         }
    3362           0 :         if (cda->rfg) {
    3363           0 :                 it = cda->rfg->rfapi_import_table;
    3364             :         }
    3365           0 :         rfapiDeleteRemotePrefixes(
    3366             :                 pUN, pVN, pPrefix, it, 0, 1, &cda->remote_active_pfx_count,
    3367             :                 &cda->remote_active_nve_count, &cda->remote_holddown_pfx_count,
    3368             :                 &cda->remote_holddown_nve_count);
    3369             : 
    3370             :         /*
    3371             :          * Now do local prefixes
    3372             :          */
    3373           0 :         rfapiDeleteLocalPrefixes(cda);
    3374           0 : }
    3375             : 
    3376           0 : static void print_cleared_stats(struct rfapi_local_reg_delete_arg *cda)
    3377             : {
    3378           0 :         struct vty *vty = cda->vty; /* for benefit of VTYNL */
    3379             : 
    3380             :         /* Our special element-deleting function counts nves */
    3381           0 :         if (cda->nves) {
    3382           0 :                 skiplist_free(cda->nves);
    3383           0 :                 cda->nves = NULL;
    3384             :         }
    3385           0 :         if (cda->failed_pfx_count)
    3386           0 :                 vty_out(vty, "Failed to delete %d prefixes\n",
    3387             :                         cda->failed_pfx_count);
    3388             : 
    3389             :         /* left as "prefixes" even in single case for ease of machine parsing */
    3390           0 :         vty_out(vty,
    3391             :                 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
    3392             :                 cda->reg_count, cda->pfx_count, cda->query_count,
    3393             :                 cda->nve_count);
    3394             : 
    3395             :         /*
    3396             :          * We don't currently allow deletion of active remote prefixes from
    3397             :          * the command line
    3398             :          */
    3399             : 
    3400           0 :         vty_out(vty, "[Holddown] Cleared %u prefixes from %u NVEs\n",
    3401             :                 cda->remote_holddown_pfx_count, cda->remote_holddown_nve_count);
    3402           0 : }
    3403             : 
    3404             : /*
    3405             :  * Caller has already deleted registrations and queries for this/these
    3406             :  * NVEs. Now we just have to close their descriptors.
    3407             :  */
    3408           0 : static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg *cda)
    3409             : {
    3410           0 :         struct skiplist *sl = cda->nves; /* contains affected NVEs */
    3411           0 :         struct nve_addr *pKey;
    3412           0 :         struct nve_addr *pValue;
    3413           0 :         void *cursor = NULL;
    3414           0 :         int rc;
    3415             : 
    3416           0 :         if (!sl)
    3417           0 :                 return;
    3418             : 
    3419           0 :         for (rc = skiplist_next(sl, (void **)&pKey, (void **)&pValue, &cursor);
    3420           0 :              !rc; rc = skiplist_next(sl, (void **)&pKey, (void **)&pValue,
    3421             :                                      &cursor)) {
    3422             : 
    3423           0 :                 if (pValue->rfd) {
    3424           0 :                         pValue->rfd->flags |=
    3425             :                                 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY;
    3426           0 :                         rfapi_close(pValue->rfd);
    3427             :                 }
    3428             :         }
    3429             : }
    3430             : 
    3431           0 : DEFUN (clear_vnc_nve_all,
    3432             :        clear_vnc_nve_all_cmd,
    3433             :        "clear vnc nve *",
    3434             :        "clear\n"
    3435             :        "VNC Information\n"
    3436             :        "Clear per NVE information\n"
    3437             :        "For all NVEs\n")
    3438             : {
    3439             : 
    3440           0 :         struct rfapi_local_reg_delete_arg cda;
    3441           0 :         int rc;
    3442             : 
    3443           0 :         if ((rc = parse_deleter_args(vty, NULL, NULL, NULL, NULL, NULL, NULL,
    3444             :                                      NULL, NULL, &cda)))
    3445             :                 return rc;
    3446             : 
    3447           0 :         cda.vty = vty;
    3448             : 
    3449           0 :         clear_vnc_responses(&cda);
    3450           0 :         clear_vnc_prefix(&cda);
    3451           0 :         clear_vnc_nve_closer(&cda);
    3452             : 
    3453           0 :         print_cleared_stats(&cda);
    3454             : 
    3455           0 :         return 0;
    3456             : }
    3457             : 
    3458           0 : DEFUN (clear_vnc_nve_vn_un,
    3459             :        clear_vnc_nve_vn_un_cmd,
    3460             :        "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
    3461             :        "clear\n"
    3462             :        "VNC Information\n"
    3463             :        "Clear prefix registration information\n"
    3464             :        "VN address of NVE\n"
    3465             :        "For all NVEs\n"
    3466             :        "VN IPv4 interface address\n"
    3467             :        "VN IPv6 interface address\n"
    3468             :        "UN address of NVE\n"
    3469             :        "For all UN addresses\n"
    3470             :        "UN IPv4 interface address\n"
    3471             :        "UN IPv6 interface address\n")
    3472             : {
    3473           0 :         struct rfapi_local_reg_delete_arg cda;
    3474           0 :         int rc;
    3475             : 
    3476           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[4], argv[6], NULL,
    3477             :                                        NULL, NULL, NULL, &cda)))
    3478             :                 return rc;
    3479             : 
    3480           0 :         cda.vty = vty;
    3481             : 
    3482           0 :         clear_vnc_responses(&cda);
    3483           0 :         clear_vnc_prefix(&cda);
    3484           0 :         clear_vnc_nve_closer(&cda);
    3485             : 
    3486           0 :         print_cleared_stats(&cda);
    3487             : 
    3488           0 :         return 0;
    3489             : }
    3490             : 
    3491           0 : DEFUN (clear_vnc_nve_un_vn,
    3492             :        clear_vnc_nve_un_vn_cmd,
    3493             :        "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
    3494             :        "clear\n"
    3495             :        "VNC Information\n"
    3496             :        "Clear prefix registration information\n"
    3497             :        "UN address of NVE\n"
    3498             :        "For all un NVEs\n"
    3499             :        "UN IPv4 interface address\n"
    3500             :        "UN IPv6 interface address\n"
    3501             :        "VN address of NVE\n"
    3502             :        "For all vn NVEs\n"
    3503             :        "VN IPv4 interface address\n"
    3504             :        "VN IPv6 interface address\n")
    3505             : {
    3506           0 :         struct rfapi_local_reg_delete_arg cda;
    3507           0 :         int rc;
    3508             : 
    3509           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[6], argv[4], NULL,
    3510             :                                        NULL, NULL, NULL, &cda)))
    3511             :                 return rc;
    3512             : 
    3513           0 :         cda.vty = vty;
    3514             : 
    3515           0 :         clear_vnc_responses(&cda);
    3516           0 :         clear_vnc_prefix(&cda);
    3517           0 :         clear_vnc_nve_closer(&cda);
    3518             : 
    3519           0 :         print_cleared_stats(&cda);
    3520             : 
    3521           0 :         return 0;
    3522             : }
    3523             : 
    3524           0 : DEFUN (clear_vnc_nve_vn,
    3525             :        clear_vnc_nve_vn_cmd,
    3526             :        "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
    3527             :        "clear\n"
    3528             :        "VNC Information\n"
    3529             :        "Clear prefix registration information\n"
    3530             :        "VN address of NVE\n"
    3531             :        "All addresses\n"
    3532             :        "VN IPv4 interface address\n"
    3533             :        "VN IPv6 interface address\n")
    3534             : {
    3535           0 :         struct rfapi_local_reg_delete_arg cda;
    3536           0 :         int rc;
    3537             : 
    3538           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[4], NULL, NULL,
    3539             :                                        NULL, NULL, NULL, &cda)))
    3540             :                 return rc;
    3541             : 
    3542           0 :         cda.vty = vty;
    3543             : 
    3544           0 :         clear_vnc_responses(&cda);
    3545           0 :         clear_vnc_prefix(&cda);
    3546           0 :         clear_vnc_nve_closer(&cda);
    3547             : 
    3548           0 :         print_cleared_stats(&cda);
    3549           0 :         return 0;
    3550             : }
    3551             : 
    3552           0 : DEFUN (clear_vnc_nve_un,
    3553             :        clear_vnc_nve_un_cmd,
    3554             :        "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
    3555             :        "clear\n"
    3556             :        "VNC Information\n"
    3557             :        "Clear prefix registration information\n"
    3558             :        "UN address of NVE\n"
    3559             :        "All un nves\n"
    3560             :        "UN IPv4 interface address\n"
    3561             :        "UN IPv6 interface address\n")
    3562             : {
    3563           0 :         struct rfapi_local_reg_delete_arg cda;
    3564           0 :         int rc;
    3565             : 
    3566           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, argv[4], NULL,
    3567             :                                        NULL, NULL, NULL, &cda)))
    3568             :                 return rc;
    3569             : 
    3570           0 :         cda.vty = vty;
    3571             : 
    3572           0 :         clear_vnc_responses(&cda);
    3573           0 :         clear_vnc_prefix(&cda);
    3574           0 :         clear_vnc_nve_closer(&cda);
    3575             : 
    3576           0 :         print_cleared_stats(&cda);
    3577           0 :         return 0;
    3578             : }
    3579             : 
    3580             : /*-------------------------------------------------
    3581             :  *              Clear VNC Prefix
    3582             :  *-------------------------------------------------*/
    3583             : 
    3584             : /*
    3585             :  * This function is defined in this file (rather than in rfp_registration.c)
    3586             :  * because here we have access to all the task handles.
    3587             :  */
    3588           0 : DEFUN (clear_vnc_prefix_vn_un,
    3589             :        clear_vnc_prefix_vn_un_cmd,
    3590             :        "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
    3591             :        "clear\n"
    3592             :        "VNC Information\n"
    3593             :        "Clear prefix registration information\n"
    3594             :        "All prefixes\n"
    3595             :        "IPv4 prefix\n"
    3596             :        "IPv6 prefix\n"
    3597             :        "VN address of NVE\n"
    3598             :        "All VN addresses\n"
    3599             :        "VN IPv4 interface address\n"
    3600             :        "VN IPv6 interface address\n"
    3601             :        "UN address of NVE\n"
    3602             :        "All UN addresses\n"
    3603             :        "UN IPv4 interface address\n"
    3604             :        "UN IPv6 interface address\n")
    3605             : {
    3606           0 :         struct rfapi_local_reg_delete_arg cda;
    3607           0 :         int rc;
    3608             : 
    3609           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[5], argv[7],
    3610             :                                        NULL, NULL, NULL, NULL, &cda)))
    3611             :                 return rc;
    3612           0 :         cda.vty = vty;
    3613           0 :         clear_vnc_prefix(&cda);
    3614           0 :         print_cleared_stats(&cda);
    3615           0 :         return 0;
    3616             : }
    3617             : 
    3618           0 : DEFUN (clear_vnc_prefix_un_vn,
    3619             :        clear_vnc_prefix_un_vn_cmd,
    3620             :        "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
    3621             :        "clear\n"
    3622             :        "VNC Information\n"
    3623             :        "Clear prefix registration information\n"
    3624             :        "All prefixes\n"
    3625             :        "IPv4 prefix\n"
    3626             :        "IPv6 prefix\n"
    3627             :        "UN address of NVE\n"
    3628             :        "All UN addresses\n"
    3629             :        "UN IPv4 interface address\n"
    3630             :        "UN IPv6 interface address\n"
    3631             :        "VN address of NVE\n"
    3632             :        "All VN addresses\n"
    3633             :        "VN IPv4 interface address\n"
    3634             :        "VN IPv6 interface address\n")
    3635             : {
    3636           0 :         struct rfapi_local_reg_delete_arg cda;
    3637           0 :         int rc;
    3638             : 
    3639           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[7], argv[5],
    3640             :                                        NULL, NULL, NULL, NULL, &cda)))
    3641             :                 return rc;
    3642           0 :         cda.vty = vty;
    3643           0 :         clear_vnc_prefix(&cda);
    3644           0 :         print_cleared_stats(&cda);
    3645           0 :         return 0;
    3646             : }
    3647             : 
    3648           0 : DEFUN (clear_vnc_prefix_un,
    3649             :        clear_vnc_prefix_un_cmd,
    3650             :        "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
    3651             :        "clear\n"
    3652             :        "VNC Information\n"
    3653             :        "Clear prefix registration information\n"
    3654             :        "All prefixes\n"
    3655             :        "IPv4 prefix\n"
    3656             :        "IPv6 prefix\n"
    3657             :        "UN address of NVE\n"
    3658             :        "All UN addresses\n"
    3659             :        "UN IPv4 interface address\n"
    3660             :        "UN IPv6 interface address\n")
    3661             : {
    3662           0 :         struct rfapi_local_reg_delete_arg cda;
    3663           0 :         int rc;
    3664             : 
    3665           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[3], NULL, argv[5], NULL,
    3666             :                                        NULL, NULL, NULL, &cda)))
    3667             :                 return rc;
    3668           0 :         cda.vty = vty;
    3669           0 :         clear_vnc_prefix(&cda);
    3670           0 :         print_cleared_stats(&cda);
    3671           0 :         return 0;
    3672             : }
    3673             : 
    3674           0 : DEFUN (clear_vnc_prefix_vn,
    3675             :        clear_vnc_prefix_vn_cmd,
    3676             :        "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
    3677             :        "clear\n"
    3678             :        "VNC Information\n"
    3679             :        "Clear prefix registration information\n"
    3680             :        "All prefixes\n"
    3681             :        "IPv4 prefix\n"
    3682             :        "IPv6 prefix\n"
    3683             :        "UN address of NVE\n"
    3684             :        "All VN addresses\n"
    3685             :        "VN IPv4 interface address\n"
    3686             :        "VN IPv6 interface address\n")
    3687             : {
    3688           0 :         struct rfapi_local_reg_delete_arg cda;
    3689           0 :         int rc;
    3690             : 
    3691           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[5], NULL, NULL,
    3692             :                                        NULL, NULL, NULL, &cda)))
    3693             :                 return rc;
    3694           0 :         cda.vty = vty;
    3695           0 :         clear_vnc_prefix(&cda);
    3696           0 :         print_cleared_stats(&cda);
    3697           0 :         return 0;
    3698             : }
    3699             : 
    3700           0 : DEFUN (clear_vnc_prefix_all,
    3701             :        clear_vnc_prefix_all_cmd,
    3702             :        "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
    3703             :        "clear\n"
    3704             :        "VNC Information\n"
    3705             :        "Clear prefix registration information\n"
    3706             :        "All prefixes\n"
    3707             :        "IPv4 prefix\n"
    3708             :        "IPv6 prefix\n"
    3709             :        "From any NVE\n")
    3710             : {
    3711           0 :         struct rfapi_local_reg_delete_arg cda;
    3712           0 :         int rc;
    3713             : 
    3714           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[3], NULL, NULL, NULL,
    3715             :                                        NULL, NULL, NULL, &cda)))
    3716             :                 return rc;
    3717           0 :         cda.vty = vty;
    3718           0 :         clear_vnc_prefix(&cda);
    3719           0 :         print_cleared_stats(&cda);
    3720           0 :         return 0;
    3721             : }
    3722             : 
    3723             : /*-------------------------------------------------
    3724             :  *              Clear VNC MAC
    3725             :  *-------------------------------------------------*/
    3726             : 
    3727             : /*
    3728             :  * This function is defined in this file (rather than in rfp_registration.c)
    3729             :  * because here we have access to all the task handles.
    3730             :  */
    3731           0 : DEFUN (clear_vnc_mac_vn_un,
    3732             :        clear_vnc_mac_vn_un_cmd,
    3733             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
    3734             :        "clear\n"
    3735             :        "VNC Information\n"
    3736             :        "Clear mac registration information\n"
    3737             :        "All macs\n"
    3738             :        "MAC address\n"
    3739             :        "VNI keyword\n"
    3740             :        "Any virtual network identifier\n"
    3741             :        "Virtual network identifier\n"
    3742             :        "VN address of NVE\n"
    3743             :        "All VN addresses\n"
    3744             :        "VN IPv4 interface address\n"
    3745             :        "VN IPv6 interface address\n"
    3746             :        "UN address of NVE\n"
    3747             :        "All UN addresses\n"
    3748             :        "UN IPv4 interface address\n"
    3749             :        "UN IPv6 interface address\n")
    3750             : {
    3751           0 :         struct rfapi_local_reg_delete_arg cda;
    3752           0 :         int rc;
    3753             : 
    3754             :         /* pfx vn un L2 VNI */
    3755           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[7], argv[9],
    3756             :                                        argv[3], argv[5], NULL, NULL, &cda)))
    3757             :                 return rc;
    3758           0 :         cda.vty = vty;
    3759           0 :         clear_vnc_prefix(&cda);
    3760           0 :         print_cleared_stats(&cda);
    3761           0 :         return 0;
    3762             : }
    3763             : 
    3764           0 : DEFUN (clear_vnc_mac_un_vn,
    3765             :        clear_vnc_mac_un_vn_cmd,
    3766             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
    3767             :        "clear\n"
    3768             :        "VNC Information\n"
    3769             :        "Clear mac registration information\n"
    3770             :        "All macs\n"
    3771             :        "MAC address\n"
    3772             :        "VNI keyword\n"
    3773             :        "Any virtual network identifier\n"
    3774             :        "Virtual network identifier\n"
    3775             :        "UN address of NVE\n"
    3776             :        "All UN addresses\n"
    3777             :        "UN IPv4 interface address\n"
    3778             :        "UN IPv6 interface address\n"
    3779             :        "VN address of NVE\n"
    3780             :        "All VN addresses\n"
    3781             :        "VN IPv4 interface address\n"
    3782             :        "VN IPv6 interface address\n")
    3783             : {
    3784           0 :         struct rfapi_local_reg_delete_arg cda;
    3785           0 :         int rc;
    3786             : 
    3787             :         /* pfx vn un L2 VNI */
    3788           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[9], argv[7],
    3789             :                                        argv[3], argv[5], NULL, NULL, &cda)))
    3790             :                 return rc;
    3791           0 :         cda.vty = vty;
    3792           0 :         clear_vnc_prefix(&cda);
    3793           0 :         print_cleared_stats(&cda);
    3794           0 :         return 0;
    3795             : }
    3796             : 
    3797           0 : DEFUN (clear_vnc_mac_un,
    3798             :        clear_vnc_mac_un_cmd,
    3799             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
    3800             :        "clear\n"
    3801             :        "VNC Information\n"
    3802             :        "Clear mac registration information\n"
    3803             :        "All macs\n"
    3804             :        "MAC address\n"
    3805             :        "VNI keyword\n"
    3806             :        "Any virtual network identifier\n"
    3807             :        "Virtual network identifier\n"
    3808             :        "UN address of NVE\n"
    3809             :        "All UN addresses\n"
    3810             :        "UN IPv4 interface address\n"
    3811             :        "UN IPv6 interface address\n")
    3812             : {
    3813           0 :         struct rfapi_local_reg_delete_arg cda;
    3814           0 :         int rc;
    3815             : 
    3816             :         /* pfx vn un L2 VNI */
    3817           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, argv[7], argv[3],
    3818             :                                        argv[5], NULL, NULL, &cda)))
    3819             :                 return rc;
    3820           0 :         cda.vty = vty;
    3821           0 :         clear_vnc_prefix(&cda);
    3822           0 :         print_cleared_stats(&cda);
    3823           0 :         return 0;
    3824             : }
    3825             : 
    3826           0 : DEFUN (clear_vnc_mac_vn,
    3827             :        clear_vnc_mac_vn_cmd,
    3828             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
    3829             :        "clear\n"
    3830             :        "VNC Information\n"
    3831             :        "Clear mac registration information\n"
    3832             :        "All macs\n"
    3833             :        "MAC address\n"
    3834             :        "VNI keyword\n"
    3835             :        "Any virtual network identifier\n"
    3836             :        "Virtual network identifier\n"
    3837             :        "UN address of NVE\n"
    3838             :        "All VN addresses\n"
    3839             :        "VN IPv4 interface address\n"
    3840             :        "VN IPv6 interface address\n")
    3841             : {
    3842           0 :         struct rfapi_local_reg_delete_arg cda;
    3843           0 :         int rc;
    3844             : 
    3845             :         /* pfx vn un L2 VNI */
    3846           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[7], NULL, argv[3],
    3847             :                                        argv[5], NULL, NULL, &cda)))
    3848             :                 return rc;
    3849           0 :         cda.vty = vty;
    3850           0 :         clear_vnc_prefix(&cda);
    3851           0 :         print_cleared_stats(&cda);
    3852           0 :         return 0;
    3853             : }
    3854             : 
    3855           0 : DEFUN (clear_vnc_mac_all,
    3856             :        clear_vnc_mac_all_cmd,
    3857             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> *",
    3858             :        "clear\n"
    3859             :        "VNC Information\n"
    3860             :        "Clear mac registration information\n"
    3861             :        "All macs\n"
    3862             :        "MAC address\n"
    3863             :        "VNI keyword\n"
    3864             :        "Any virtual network identifier\n"
    3865             :        "Virtual network identifier\n"
    3866             :        "From any NVE\n")
    3867             : {
    3868           0 :         struct rfapi_local_reg_delete_arg cda;
    3869           0 :         int rc;
    3870             : 
    3871             :         /* pfx vn un L2 VNI */
    3872           0 :         if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, NULL, argv[3],
    3873             :                                        argv[5], NULL, NULL, &cda)))
    3874             :                 return rc;
    3875           0 :         cda.vty = vty;
    3876           0 :         clear_vnc_prefix(&cda);
    3877           0 :         print_cleared_stats(&cda);
    3878           0 :         return 0;
    3879             : }
    3880             : 
    3881             : /*-------------------------------------------------
    3882             :  *              Clear VNC MAC PREFIX
    3883             :  *-------------------------------------------------*/
    3884             : 
    3885           0 : DEFUN (clear_vnc_mac_vn_un_prefix,
    3886             :        clear_vnc_mac_vn_un_prefix_cmd,
    3887             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
    3888             :        "clear\n"
    3889             :        "VNC Information\n"
    3890             :        "Clear mac registration information\n"
    3891             :        "All macs\n"
    3892             :        "MAC address\n"
    3893             :        "VNI keyword\n"
    3894             :        "Any virtual network identifier\n"
    3895             :        "Virtual network identifier\n"
    3896             :        "VN address of NVE\n"
    3897             :        "All VN addresses\n"
    3898             :        "VN IPv4 interface address\n"
    3899             :        "VN IPv6 interface address\n"
    3900             :        "UN address of NVE\n"
    3901             :        "All UN addresses\n"
    3902             :        "UN IPv4 interface address\n"
    3903             :        "UN IPv6 interface address\n"
    3904             :        "Clear prefix registration information\n"
    3905             :        "All prefixes\n"
    3906             :        "IPv4 prefix\n"
    3907             :        "IPv6 prefix\n")
    3908             : {
    3909           0 :         struct rfapi_local_reg_delete_arg cda;
    3910           0 :         int rc;
    3911             : 
    3912             :         /* pfx vn un L2 VNI */
    3913           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[11], argv[7], argv[9],
    3914             :                                        argv[3], argv[5], NULL, NULL, &cda)))
    3915             :                 return rc;
    3916           0 :         cda.vty = vty;
    3917           0 :         clear_vnc_prefix(&cda);
    3918           0 :         print_cleared_stats(&cda);
    3919           0 :         return 0;
    3920             : }
    3921             : 
    3922           0 : DEFUN (clear_vnc_mac_un_vn_prefix,
    3923             :        clear_vnc_mac_un_vn_prefix_cmd,
    3924             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M> prefix <*|A.B.C.D/M|X:X::X:X/M>",
    3925             :        "clear\n"
    3926             :        "VNC Information\n"
    3927             :        "Clear mac registration information\n"
    3928             :        "All macs\n"
    3929             :        "MAC address\n"
    3930             :        "VNI keyword\n"
    3931             :        "Any virtual network identifier\n"
    3932             :        "Virtual network identifier\n"
    3933             :        "UN address of NVE\n"
    3934             :        "All UN addresses\n"
    3935             :        "UN IPv4 interface address\n"
    3936             :        "UN IPv6 interface address\n"
    3937             :        "VN address of NVE\n"
    3938             :        "All VN addresses\n"
    3939             :        "VN IPv4 interface address\n"
    3940             :        "VN IPv6 interface address\n"
    3941             :        "Clear prefix registration information\n"
    3942             :        "All prefixes\n"
    3943             :        "IPv4 prefix\n"
    3944             :        "IPv6 prefix\n"
    3945             :        "Clear prefix registration information\n"
    3946             :        "All prefixes\n"
    3947             :        "IPv4 prefix\n"
    3948             :        "IPv6 prefix\n")
    3949             : {
    3950           0 :         struct rfapi_local_reg_delete_arg cda;
    3951           0 :         int rc;
    3952             : 
    3953             :         /* pfx vn un L2 VNI */
    3954           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[11], argv[9], argv[7],
    3955             :                                        argv[3], argv[5], NULL, NULL, &cda)))
    3956             :                 return rc;
    3957           0 :         cda.vty = vty;
    3958           0 :         clear_vnc_prefix(&cda);
    3959           0 :         print_cleared_stats(&cda);
    3960           0 :         return 0;
    3961             : }
    3962             : 
    3963           0 : DEFUN (clear_vnc_mac_un_prefix,
    3964             :        clear_vnc_mac_un_prefix_cmd,
    3965             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
    3966             :        "clear\n"
    3967             :        "VNC Information\n"
    3968             :        "Clear mac registration information\n"
    3969             :        "All macs\n"
    3970             :        "MAC address\n"
    3971             :        "VNI keyword\n"
    3972             :        "Any virtual network identifier\n"
    3973             :        "Virtual network identifier\n"
    3974             :        "UN address of NVE\n"
    3975             :        "All UN addresses\n"
    3976             :        "UN IPv4 interface address\n"
    3977             :        "UN IPv6 interface address\n"
    3978             :        "Clear prefix registration information\n"
    3979             :        "All prefixes\n"
    3980             :        "IPv4 Prefix\n"
    3981             :        "IPv6 Prefix\n")
    3982             : {
    3983           0 :         struct rfapi_local_reg_delete_arg cda;
    3984           0 :         int rc;
    3985             : 
    3986             :         /* pfx vn un L2 VNI */
    3987           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[9], NULL, argv[7],
    3988             :                                        argv[3], argv[5], NULL, NULL, &cda)))
    3989             :                 return rc;
    3990           0 :         cda.vty = vty;
    3991           0 :         clear_vnc_prefix(&cda);
    3992           0 :         print_cleared_stats(&cda);
    3993           0 :         return 0;
    3994             : }
    3995             : 
    3996           0 : DEFUN (clear_vnc_mac_vn_prefix,
    3997             :        clear_vnc_mac_vn_prefix_cmd,
    3998             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
    3999             :        "clear\n"
    4000             :        "VNC Information\n"
    4001             :        "Clear mac registration information\n"
    4002             :        "All macs\n"
    4003             :        "MAC address\n"
    4004             :        "VNI keyword\n"
    4005             :        "Any virtual network identifier\n"
    4006             :        "Virtual network identifier\n"
    4007             :        "UN address of NVE\n"
    4008             :        "All VN addresses\n"
    4009             :        "VN IPv4 interface address\n"
    4010             :        "VN IPv6 interface address\n"
    4011             :        "Clear prefix registration information\n"
    4012             :        "All prefixes\n"
    4013             :        "IPv4 Prefix\n"
    4014             :        "IPv6 Prefix\n")
    4015             : {
    4016           0 :         struct rfapi_local_reg_delete_arg cda;
    4017           0 :         int rc;
    4018             : 
    4019             :         /* pfx vn un L2 VNI */
    4020           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[9], argv[7], NULL,
    4021             :                                        argv[3], argv[5], NULL, NULL, &cda)))
    4022             :                 return rc;
    4023           0 :         cda.vty = vty;
    4024           0 :         clear_vnc_prefix(&cda);
    4025           0 :         print_cleared_stats(&cda);
    4026           0 :         return 0;
    4027             : }
    4028             : 
    4029           0 : DEFUN (clear_vnc_mac_all_prefix,
    4030             :        clear_vnc_mac_all_prefix_cmd,
    4031             :        "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> prefix <*|A.B.C.D/M|X:X::X:X/M>",
    4032             :        "clear\n"
    4033             :        "VNC Information\n"
    4034             :        "Clear mac registration information\n"
    4035             :        "All macs\n"
    4036             :        "MAC address\n"
    4037             :        "VNI keyword\n"
    4038             :        "Any virtual network identifier\n"
    4039             :        "Virtual network identifier\n"
    4040             :        "UN address of NVE\n"
    4041             :        "All VN addresses\n"
    4042             :        "VN IPv4 interface address\n"
    4043             :        "VN IPv6 interface address\n")
    4044             : {
    4045           0 :         struct rfapi_local_reg_delete_arg cda;
    4046           0 :         int rc;
    4047             : 
    4048             :         /* pfx vn un L2 VNI */
    4049           0 :         if ((rc = parse_deleter_tokens(vty, NULL, argv[7], NULL, NULL, argv[3],
    4050             :                                        argv[5], NULL, NULL, &cda)))
    4051             :                 return rc;
    4052           0 :         cda.vty = vty;
    4053           0 :         clear_vnc_prefix(&cda);
    4054           0 :         print_cleared_stats(&cda);
    4055           0 :         return 0;
    4056             : }
    4057             : 
    4058             : /************************************************************************
    4059             :  *                      Show commands
    4060             :  ************************************************************************/
    4061             : 
    4062             : 
    4063             : /* copied from rfp_vty.c */
    4064           0 : static int check_and_display_is_vnc_running(struct vty *vty)
    4065             : {
    4066           0 :         if (bgp_rfapi_is_vnc_configured(NULL) == 0)
    4067             :                 return 1; /* is running */
    4068             : 
    4069           0 :         if (vty) {
    4070           0 :                 vty_out(vty, "VNC is not configured.\n");
    4071             :         }
    4072             :         return 0; /* not running */
    4073             : }
    4074             : 
    4075           0 : static int rfapi_vty_show_nve_summary(struct vty *vty,
    4076             :                                       show_nve_summary_t show_type)
    4077             : {
    4078           0 :         struct bgp *bgp_default = bgp_get_default();
    4079           0 :         struct rfapi *h;
    4080           0 :         int is_vnc_running = (bgp_rfapi_is_vnc_configured(bgp_default) == 0);
    4081             : 
    4082           0 :         int active_local_routes;
    4083           0 :         int active_remote_routes;
    4084           0 :         int holddown_remote_routes;
    4085           0 :         int imported_remote_routes;
    4086             : 
    4087           0 :         if (!bgp_default)
    4088           0 :                 goto notcfg;
    4089             : 
    4090           0 :         h = bgp_default->rfapi;
    4091             : 
    4092           0 :         if (!h)
    4093           0 :                 goto notcfg;
    4094             : 
    4095             :         /* don't show local info if not running RFP */
    4096           0 :         if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED) {
    4097             : 
    4098           0 :                 switch (show_type) {
    4099             : 
    4100           0 :                 case SHOW_NVE_SUMMARY_ACTIVE_NVES:
    4101           0 :                         vty_out(vty, "%-24s ", "NVEs:");
    4102           0 :                         vty_out(vty, "%-8s %-8u ",
    4103             :                                 "Active:", h->descriptors.count);
    4104           0 :                         vty_out(vty, "%-8s %-8u ",
    4105             :                                 "Maximum:", h->stat.max_descriptors);
    4106           0 :                         vty_out(vty, "%-8s %-8u",
    4107             :                                 "Unknown:", h->stat.count_unknown_nves);
    4108           0 :                         break;
    4109             : 
    4110           0 :                 case SHOW_NVE_SUMMARY_REGISTERED:
    4111             :                         /*
    4112             :                          * NB: With the introduction of L2 route support, we no
    4113             :                          * longer have a one-to-one correspondence between
    4114             :                          * locally-originated route advertisements and routes in
    4115             :                          * the import tables that have local origin. This
    4116             :                          * discrepancy arises because a single advertisement
    4117             :                          * may contain both an IP prefix and a MAC address.
    4118             :                          * Such an advertisement results in two import table
    4119             :                          * entries: one indexed by IP prefix, the other indexed
    4120             :                          * by MAC address.
    4121             :                          *
    4122             :                          * TBD: update computation and display of registration
    4123             :                          * statistics to reflect the underlying semantics.
    4124             :                          */
    4125           0 :                         if (is_vnc_running) {
    4126           0 :                                 vty_out(vty, "%-24s ", "Registrations:");
    4127           0 :                                 vty_out(vty, "%-8s %-8u ", "Active:",
    4128             :                                         rfapiApCountAll(bgp_default));
    4129           0 :                                 vty_out(vty, "%-8s %-8u ", "Failed:",
    4130             :                                         h->stat.count_registrations_failed);
    4131           0 :                                 vty_out(vty, "%-8s %-8u",
    4132             :                                         "Total:", h->stat.count_registrations);
    4133           0 :                                 vty_out(vty, "\n");
    4134             :                         }
    4135           0 :                         vty_out(vty, "%-24s ", "Prefixes registered:");
    4136           0 :                         vty_out(vty, "\n");
    4137             : 
    4138           0 :                         rfapiCountAllItRoutes(&active_local_routes,
    4139             :                                               &active_remote_routes,
    4140             :                                               &holddown_remote_routes,
    4141             :                                               &imported_remote_routes);
    4142             : 
    4143             :                         /* local */
    4144           0 :                         if (is_vnc_running) {
    4145           0 :                                 vty_out(vty, "    %-20s ", "Locally:");
    4146           0 :                                 vty_out(vty, "%-8s %-8u ",
    4147             :                                         "Active:", active_local_routes);
    4148           0 :                                 vty_out(vty, "\n");
    4149             :                         }
    4150             : 
    4151             : 
    4152           0 :                         vty_out(vty, "    %-20s ", "Remotely:");
    4153           0 :                         vty_out(vty, "%-8s %-8u",
    4154             :                                 "Active:", active_remote_routes);
    4155           0 :                         vty_out(vty, "\n");
    4156           0 :                         vty_out(vty, "    %-20s ", "In Holddown:");
    4157           0 :                         vty_out(vty, "%-8s %-8u",
    4158             :                                 "Active:", holddown_remote_routes);
    4159           0 :                         vty_out(vty, "\n");
    4160           0 :                         vty_out(vty, "    %-20s ", "Imported:");
    4161           0 :                         vty_out(vty, "%-8s %-8u",
    4162             :                                 "Active:", imported_remote_routes);
    4163           0 :                         break;
    4164             : 
    4165           0 :                 case SHOW_NVE_SUMMARY_QUERIES:
    4166           0 :                         vty_out(vty, "%-24s ", "Queries:");
    4167           0 :                         vty_out(vty, "%-8s %-8u ",
    4168             :                                 "Active:", rfapi_monitor_count(NULL));
    4169           0 :                         vty_out(vty, "%-8s %-8u ",
    4170             :                                 "Failed:", h->stat.count_queries_failed);
    4171           0 :                         vty_out(vty, "%-8s %-8u",
    4172             :                                 "Total:", h->stat.count_queries);
    4173           0 :                         break;
    4174             : 
    4175           0 :                 case SHOW_NVE_SUMMARY_RESPONSES:
    4176           0 :                         rfapiRibShowResponsesSummary(vty);
    4177             : 
    4178             :                 case SHOW_NVE_SUMMARY_UNKNOWN_NVES:
    4179             :                 case SHOW_NVE_SUMMARY_MAX:
    4180             :                         break;
    4181             :                 }
    4182           0 :                 vty_out(vty, "\n");
    4183             :         }
    4184             :         return 0;
    4185             : 
    4186           0 : notcfg:
    4187           0 :         vty_out(vty, "VNC is not configured.\n");
    4188           0 :         return CMD_WARNING;
    4189             : }
    4190             : 
    4191           0 : static int rfapi_show_nves(struct vty *vty, struct prefix *vn_prefix,
    4192             :                            struct prefix *un_prefix)
    4193             : {
    4194             :         // struct hash                      *rfds;
    4195             :         // struct rfp_rfapi_descriptor_param param;
    4196             : 
    4197           0 :         struct bgp *bgp_default = bgp_get_default();
    4198           0 :         struct rfapi *h;
    4199           0 :         struct listnode *node;
    4200           0 :         struct rfapi_descriptor *rfd;
    4201             : 
    4202           0 :         int total = 0;
    4203           0 :         int printed = 0;
    4204           0 :         int rc;
    4205             : 
    4206           0 :         if (!bgp_default)
    4207           0 :                 goto notcfg;
    4208             : 
    4209           0 :         h = bgp_default->rfapi;
    4210             : 
    4211           0 :         if (!h)
    4212           0 :                 goto notcfg;
    4213             : 
    4214           0 :         rc = rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_ACTIVE_NVES);
    4215           0 :         if (rc)
    4216             :                 return rc;
    4217             : 
    4218           0 :         for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) {
    4219           0 :                 struct prefix pfx;
    4220           0 :                 char vn_addr_buf[INET6_ADDRSTRLEN] = {
    4221             :                         0,
    4222             :                 };
    4223           0 :                 char un_addr_buf[INET6_ADDRSTRLEN] = {
    4224             :                         0,
    4225             :                 };
    4226           0 :                 char age[10];
    4227             : 
    4228           0 :                 ++total;
    4229             : 
    4230           0 :                 if (vn_prefix) {
    4231           0 :                         assert(!rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx));
    4232           0 :                         if (!prefix_match(vn_prefix, &pfx))
    4233           0 :                                 continue;
    4234             :                 }
    4235             : 
    4236           0 :                 if (un_prefix) {
    4237           0 :                         assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx));
    4238           0 :                         if (!prefix_match(un_prefix, &pfx))
    4239           0 :                                 continue;
    4240             :                 }
    4241             : 
    4242           0 :                 rfapiRfapiIpAddr2Str(&rfd->vn_addr, vn_addr_buf,
    4243             :                                      INET6_ADDRSTRLEN);
    4244           0 :                 rfapiRfapiIpAddr2Str(&rfd->un_addr, un_addr_buf,
    4245             :                                      INET6_ADDRSTRLEN);
    4246             : 
    4247           0 :                 if (!printed) {
    4248             :                         /* print out a header */
    4249           0 :                         vty_out(vty,
    4250             :                                 "                                Active      Next Hops\n");
    4251           0 :                         vty_out(vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
    4252             :                                 "VN Address", "UN Address", "Regis", "Resps",
    4253             :                                 "Reach", "Remove", "Age");
    4254             :                 }
    4255             : 
    4256           0 :                 ++printed;
    4257             : 
    4258           0 :                 vty_out(vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
    4259             :                         vn_addr_buf, un_addr_buf, rfapiApCount(rfd),
    4260             :                         rfapi_monitor_count(rfd), rfd->stat_count_nh_reachable,
    4261             :                         rfd->stat_count_nh_removal,
    4262             :                         rfapiFormatAge(rfd->open_time, age, 10));
    4263             :         }
    4264             : 
    4265           0 :         if (printed > 0 || vn_prefix || un_prefix)
    4266           0 :                 vty_out(vty, "Displayed %d out of %d active NVEs\n", printed,
    4267             :                         total);
    4268             : 
    4269             :         return 0;
    4270             : 
    4271           0 : notcfg:
    4272           0 :         vty_out(vty, "VNC is not configured.\n");
    4273           0 :         return CMD_WARNING;
    4274             : }
    4275             : 
    4276             : 
    4277           0 : DEFUN (vnc_show_summary,
    4278             :        vnc_show_summary_cmd,
    4279             :        "show vnc summary",
    4280             :        SHOW_STR
    4281             :        VNC_SHOW_STR
    4282             :        "Display VNC status summary\n")
    4283             : {
    4284           0 :         if (!check_and_display_is_vnc_running(vty))
    4285             :                 return CMD_SUCCESS;
    4286           0 :         bgp_rfapi_show_summary(bgp_get_default(), vty);
    4287           0 :         vty_out(vty, "\n");
    4288           0 :         rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_ACTIVE_NVES);
    4289           0 :         rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES);
    4290           0 :         rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_RESPONSES);
    4291           0 :         rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_REGISTERED);
    4292           0 :         return CMD_SUCCESS;
    4293             : }
    4294             : 
    4295           0 : DEFUN (vnc_show_nves,
    4296             :        vnc_show_nves_cmd,
    4297             :        "show vnc nves",
    4298             :        SHOW_STR
    4299             :        VNC_SHOW_STR
    4300             :        "List known NVEs\n")
    4301             : {
    4302           0 :         rfapi_show_nves(vty, NULL, NULL);
    4303           0 :         return CMD_SUCCESS;
    4304             : }
    4305             : 
    4306           0 : DEFUN (vnc_show_nves_ptct,
    4307             :        vnc_show_nves_ptct_cmd,
    4308             :        "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
    4309             :        SHOW_STR
    4310             :        VNC_SHOW_STR
    4311             :        "List known NVEs\n"
    4312             :        "VN address of NVE\n"
    4313             :        "UN address of NVE\n"
    4314             :        "IPv4 interface address\n"
    4315             :        "IPv6 interface address\n")
    4316             : {
    4317           0 :         struct prefix pfx;
    4318             : 
    4319           0 :         if (!check_and_display_is_vnc_running(vty))
    4320             :                 return CMD_SUCCESS;
    4321             : 
    4322           0 :         if (!str2prefix(argv[4]->arg, &pfx)) {
    4323           0 :                 vty_out(vty, "Malformed address \"%s\"\n", argv[4]->arg);
    4324           0 :                 return CMD_WARNING;
    4325             :         }
    4326           0 :         if (pfx.family != AF_INET && pfx.family != AF_INET6) {
    4327           0 :                 vty_out(vty, "Invalid address \"%s\"\n", argv[4]->arg);
    4328           0 :                 return CMD_WARNING;
    4329             :         }
    4330             : 
    4331           0 :         if (argv[3]->arg[0] == 'u') {
    4332           0 :                 rfapi_show_nves(vty, NULL, &pfx);
    4333             :         } else {
    4334           0 :                 rfapi_show_nves(vty, &pfx, NULL);
    4335             :         }
    4336             : 
    4337             :         return CMD_SUCCESS;
    4338             : }
    4339             : 
    4340             : /* adapted from rfp_registration_cache_log() */
    4341           0 : static void rfapi_show_registrations(struct vty *vty,
    4342             :                                      struct prefix *restrict_to, int show_local,
    4343             :                                      int show_remote, int show_holddown,
    4344             :                                      int show_imported)
    4345             : {
    4346           0 :         int printed = 0;
    4347             : 
    4348           0 :         if (!vty)
    4349             :                 return;
    4350             : 
    4351           0 :         rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_REGISTERED);
    4352             : 
    4353           0 :         if (show_local) {
    4354             :                 /* non-expiring, local */
    4355           0 :                 printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 1,
    4356             :                                                         0, 0);
    4357             :         }
    4358           0 :         if (show_remote) {
    4359             :                 /* non-expiring, non-local */
    4360           0 :                 printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 0,
    4361             :                                                         1, 0);
    4362             :         }
    4363           0 :         if (show_holddown) {
    4364             :                 /* expiring, including local */
    4365           0 :                 printed += rfapiShowRemoteRegistrations(vty, restrict_to, 1, 1,
    4366             :                                                         1, 0);
    4367             :         }
    4368           0 :         if (show_imported) {
    4369             :                 /* non-expiring, non-local */
    4370           0 :                 printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 0,
    4371             :                                                         1, 1);
    4372             :         }
    4373           0 :         if (!printed) {
    4374           0 :                 vty_out(vty, "\n");
    4375             :         }
    4376             : }
    4377             : 
    4378           0 : DEFUN (vnc_show_registrations_pfx,
    4379             :        vnc_show_registrations_pfx_cmd,
    4380             :        "show vnc registrations [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
    4381             :        SHOW_STR
    4382             :        VNC_SHOW_STR
    4383             :        "List active prefix registrations\n"
    4384             :        "Limit output to a particualr IPV4 address\n"
    4385             :        "Limit output to a particular IPv4 prefix\n"
    4386             :        "Limit output to a particualr IPV6 address\n"
    4387             :        "Limit output to a particular IPv6 prefix\n"
    4388             :        "Limit output to a particular MAC address\n")
    4389             : {
    4390           0 :         struct prefix p;
    4391           0 :         struct prefix *p_addr = NULL;
    4392             : 
    4393           0 :         if (argc > 3) {
    4394           0 :                 if (!str2prefix(argv[3]->arg, &p)) {
    4395           0 :                         vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg);
    4396           0 :                         return CMD_SUCCESS;
    4397             :                 } else {
    4398             :                         p_addr = &p;
    4399             :                 }
    4400             :         }
    4401             : 
    4402           0 :         rfapi_show_registrations(vty, p_addr, 1, 1, 1, 1);
    4403           0 :         return CMD_SUCCESS;
    4404             : }
    4405             : 
    4406           0 : DEFUN (vnc_show_registrations_some_pfx,
    4407             :          vnc_show_registrations_some_pfx_cmd,
    4408             :          "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
    4409             :          SHOW_STR
    4410             :          VNC_SHOW_STR
    4411             :          "List active prefix registrations\n"
    4412             :          "show all registrations\n"
    4413             :          "show only registrations in holddown\n"
    4414             :          "show only imported prefixes\n"
    4415             :          "show only local registrations\n"
    4416             :          "show only remote registrations\n"
    4417             :          "Limit output to a particualr IPV4 address\n"
    4418             :          "Limit output to a particular IPv4 prefix\n"
    4419             :          "Limit output to a particualr IPV6 address\n"
    4420             :          "Limit output to a particular IPv6 prefix\n"
    4421             :          "Limit output to a particular MAC address\n")
    4422             : {
    4423           0 :         struct prefix p;
    4424           0 :         struct prefix *p_addr = NULL;
    4425             : 
    4426           0 :         int show_local = 0;
    4427           0 :         int show_remote = 0;
    4428           0 :         int show_holddown = 0;
    4429           0 :         int show_imported = 0;
    4430             : 
    4431           0 :         if (argc > 4) {
    4432           0 :                 if (!str2prefix(argv[4]->arg, &p)) {
    4433           0 :                         vty_out(vty, "Invalid prefix: %s\n", argv[4]->arg);
    4434           0 :                         return CMD_SUCCESS;
    4435             :                 } else {
    4436             :                         p_addr = &p;
    4437             :                 }
    4438             :         }
    4439           0 :         switch (argv[3]->arg[0]) {
    4440             :         case 'a':
    4441             :                 show_local = 1;
    4442             :                 show_remote = 1;
    4443             :                 show_holddown = 1;
    4444             :                 show_imported = 1;
    4445             :                 break;
    4446             : 
    4447             :         case 'h':
    4448             :                 show_holddown = 1;
    4449             :                 break;
    4450             : 
    4451             :         case 'i':
    4452             :                 show_imported = 1;
    4453             :                 break;
    4454             : 
    4455             :         case 'l':
    4456             :                 show_local = 1;
    4457             :                 break;
    4458             : 
    4459             :         case 'r':
    4460             :                 show_remote = 1;
    4461             :                 break;
    4462             :         }
    4463             : 
    4464           0 :         rfapi_show_registrations(vty, p_addr, show_local, show_remote,
    4465             :                                  show_holddown, show_imported);
    4466           0 :         return CMD_SUCCESS;
    4467             : }
    4468             : 
    4469           0 : DEFUN (vnc_show_responses_pfx,
    4470             :        vnc_show_responses_pfx_cmd,
    4471             :        "show vnc responses [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
    4472             :        SHOW_STR
    4473             :        VNC_SHOW_STR
    4474             :        "List recent query responses\n"
    4475             :        "Limit output to a particualr IPV4 address\n"
    4476             :        "Limit output to a particular IPv4 prefix\n"
    4477             :        "Limit output to a particualr IPV6 address\n"
    4478             :        "Limit output to a particular IPv6 prefix\n"
    4479             :        "Limit output to a particular MAC address\n" )
    4480             : {
    4481           0 :         struct prefix p;
    4482           0 :         struct prefix *p_addr = NULL;
    4483             : 
    4484           0 :         if (argc > 3) {
    4485           0 :                 if (!str2prefix(argv[3]->arg, &p)) {
    4486           0 :                         vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg);
    4487           0 :                         return CMD_SUCCESS;
    4488             :                 } else {
    4489             :                         p_addr = &p;
    4490             :                 }
    4491             :         }
    4492           0 :         rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES);
    4493             : 
    4494           0 :         rfapiRibShowResponsesSummary(vty);
    4495             : 
    4496           0 :         rfapiRibShowResponses(vty, p_addr, 0);
    4497           0 :         rfapiRibShowResponses(vty, p_addr, 1);
    4498             : 
    4499           0 :         return CMD_SUCCESS;
    4500             : }
    4501             : 
    4502           0 : DEFUN (vnc_show_responses_some_pfx,
    4503             :        vnc_show_responses_some_pfx_cmd,
    4504             :        "show vnc responses <active|removed> [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
    4505             :        SHOW_STR
    4506             :        VNC_SHOW_STR
    4507             :        "List recent query responses\n"
    4508             :        "show only active query responses\n"
    4509             :        "show only removed query responses\n"
    4510             :        "Limit output to a particualr IPV4 address\n"
    4511             :        "Limit output to a particular IPv4 prefix\n"
    4512             :        "Limit output to a particualr IPV6 address\n"
    4513             :        "Limit output to a particular IPv6 prefix\n"
    4514             :        "Limit output to a particular MAC address\n")
    4515             : {
    4516           0 :         struct prefix p;
    4517           0 :         struct prefix *p_addr = NULL;
    4518             : 
    4519           0 :         int show_active = 0;
    4520           0 :         int show_removed = 0;
    4521             : 
    4522           0 :         if (!check_and_display_is_vnc_running(vty))
    4523             :                 return CMD_SUCCESS;
    4524             : 
    4525           0 :         if (argc > 4) {
    4526           0 :                 if (!str2prefix(argv[4]->arg, &p)) {
    4527           0 :                         vty_out(vty, "Invalid prefix: %s\n", argv[4]->arg);
    4528           0 :                         return CMD_SUCCESS;
    4529             :                 } else {
    4530             :                         p_addr = &p;
    4531             :                 }
    4532             :         }
    4533             : 
    4534           0 :         switch (argv[3]->arg[0]) {
    4535           0 :         case 'a':
    4536           0 :                 show_active = 1;
    4537           0 :                 break;
    4538             : 
    4539           0 :         case 'r':
    4540           0 :                 show_removed = 1;
    4541           0 :                 break;
    4542             :         }
    4543             : 
    4544           0 :         rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES);
    4545             : 
    4546           0 :         rfapiRibShowResponsesSummary(vty);
    4547             : 
    4548           0 :         if (show_active)
    4549           0 :                 rfapiRibShowResponses(vty, p_addr, 0);
    4550           0 :         if (show_removed)
    4551           0 :                 rfapiRibShowResponses(vty, p_addr, 1);
    4552             : 
    4553             :         return CMD_SUCCESS;
    4554             : }
    4555             : 
    4556           0 : DEFUN (show_vnc_queries_pfx,
    4557             :        show_vnc_queries_pfx_cmd,
    4558             :        "show vnc queries [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
    4559             :        SHOW_STR
    4560             :        VNC_SHOW_STR
    4561             :        "List active queries\n"
    4562             :        "Limit output to a particualr IPV4 address\n"
    4563             :        "Limit output to a particular IPv4 prefix\n"
    4564             :        "Limit output to a particualr IPV6 address\n"
    4565             :        "Limit output to a particular IPv6 prefix\n"
    4566             :        "Limit output to a particualr MAC address\n")
    4567             : {
    4568           0 :         struct prefix pfx;
    4569           0 :         struct prefix *p = NULL;
    4570             : 
    4571           0 :         if (argc > 3) {
    4572           0 :                 if (!str2prefix(argv[3]->arg, &pfx)) {
    4573           0 :                         vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg);
    4574           0 :                         return CMD_WARNING;
    4575             :                 }
    4576             :                 p = &pfx;
    4577             :         }
    4578             : 
    4579           0 :         rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES);
    4580             : 
    4581           0 :         return rfapiShowVncQueries(vty, p);
    4582             : }
    4583             : 
    4584           0 : DEFUN (vnc_clear_counters,
    4585             :        vnc_clear_counters_cmd,
    4586             :        "clear vnc counters",
    4587             :        CLEAR_STR
    4588             :        VNC_SHOW_STR
    4589             :        "Reset VNC counters\n")
    4590             : {
    4591           0 :         struct bgp *bgp_default = bgp_get_default();
    4592           0 :         struct rfapi *h;
    4593           0 :         struct listnode *node;
    4594           0 :         struct rfapi_descriptor *rfd;
    4595             : 
    4596           0 :         if (!bgp_default)
    4597           0 :                 goto notcfg;
    4598             : 
    4599           0 :         h = bgp_default->rfapi;
    4600             : 
    4601           0 :         if (!h)
    4602           0 :                 goto notcfg;
    4603             : 
    4604             :         /* per-rfd */
    4605           0 :         for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) {
    4606           0 :                 rfd->stat_count_nh_reachable = 0;
    4607           0 :                 rfd->stat_count_nh_removal = 0;
    4608             :         }
    4609             : 
    4610             :         /* global */
    4611           0 :         memset(&h->stat, 0, sizeof(h->stat));
    4612             : 
    4613             :         /*
    4614             :          * 151122 per bug 103, set count_registrations = number active.
    4615             :          * Do same for queries
    4616             :          */
    4617           0 :         h->stat.count_registrations = rfapiApCountAll(bgp_default);
    4618           0 :         h->stat.count_queries = rfapi_monitor_count(NULL);
    4619             : 
    4620           0 :         rfapiRibShowResponsesSummaryClear();
    4621             : 
    4622           0 :         return CMD_SUCCESS;
    4623             : 
    4624           0 : notcfg:
    4625           0 :         vty_out(vty, "VNC is not configured.\n");
    4626           0 :         return CMD_WARNING;
    4627             : }
    4628             : 
    4629             : /************************************************************************
    4630             :  *              Add prefix with vrf
    4631             :  *
    4632             :  * add [vrf <vrf-name>] prefix <prefix>
    4633             :  *     [rd <value>] [label <value>] [local-preference <0-4294967295>]
    4634             :  ************************************************************************/
    4635           0 : void vnc_add_vrf_opener(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg)
    4636             : {
    4637           0 :         if (rfg->rfd == NULL) { /* need new rfapi_handle */
    4638             :                 /* based on rfapi_open */
    4639           0 :                 struct rfapi_descriptor *rfd;
    4640             : 
    4641           0 :                 rfd = XCALLOC(MTYPE_RFAPI_DESC,
    4642             :                               sizeof(struct rfapi_descriptor));
    4643           0 :                 rfd->bgp = bgp;
    4644           0 :                 rfg->rfd = rfd;
    4645             :                 /* leave most fields empty as will get from (dynamic) config
    4646             :                  * when needed */
    4647           0 :                 rfd->default_tunneltype_option.type = BGP_ENCAP_TYPE_MPLS;
    4648           0 :                 rfd->cookie = rfg;
    4649           0 :                 if (rfg->vn_prefix.family
    4650           0 :                     && !CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) {
    4651           0 :                         rfapiQprefix2Raddr(&rfg->vn_prefix, &rfd->vn_addr);
    4652             :                 } else {
    4653           0 :                         memset(&rfd->vn_addr, 0, sizeof(struct rfapi_ip_addr));
    4654           0 :                         rfd->vn_addr.addr_family = AF_INET;
    4655           0 :                         rfd->vn_addr.addr.v4 = bgp->router_id;
    4656             :                 }
    4657           0 :                 rfd->un_addr = rfd->vn_addr; /* sigh, need something in UN for
    4658             :                                                 lookups */
    4659           0 :                 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__,
    4660             :                                        rfg->name);
    4661           0 :                 rfapi_init_and_open(bgp, rfd, rfg);
    4662             :         }
    4663           0 : }
    4664             : 
    4665             : /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
    4666           0 : static int vnc_add_vrf_prefix(struct vty *vty, const char *arg_vrf,
    4667             :                               const char *arg_prefix,
    4668             :                               const char *arg_rd,    /* optional */
    4669             :                               const char *arg_label, /* optional */
    4670             :                               const char *arg_pref)  /* optional */
    4671             : {
    4672           0 :         struct bgp *bgp;
    4673           0 :         struct rfapi_nve_group_cfg *rfg;
    4674           0 :         struct prefix pfx;
    4675           0 :         struct rfapi_ip_prefix rpfx;
    4676           0 :         uint32_t pref = 0;
    4677           0 :         struct rfapi_vn_option optary[3];
    4678           0 :         struct rfapi_vn_option *opt = NULL;
    4679           0 :         int cur_opt = 0;
    4680             : 
    4681           0 :         bgp = bgp_get_default(); /* assume main instance for now */
    4682           0 :         if (!bgp) {
    4683           0 :                 vty_out(vty, "No BGP process is configured\n");
    4684           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4685             :         }
    4686           0 :         if (!bgp->rfapi || !bgp->rfapi_cfg) {
    4687           0 :                 vty_out(vty, "VRF support not configured\n");
    4688           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4689             :         }
    4690             : 
    4691           0 :         rfg = bgp_rfapi_cfg_match_byname(bgp, arg_vrf, RFAPI_GROUP_CFG_VRF);
    4692             :         /* arg checks */
    4693           0 :         if (!rfg) {
    4694           0 :                 vty_out(vty, "VRF \"%s\" appears not to be configured.\n",
    4695             :                         arg_vrf);
    4696           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4697             :         }
    4698           0 :         if (!rfg->rt_export_list || !rfg->rfapi_import_table) {
    4699           0 :                 vty_out(vty,
    4700             :                         "VRF \"%s\" is missing RT import/export RT configuration.\n",
    4701             :                         arg_vrf);
    4702           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4703             :         }
    4704           0 :         if (!rfg->rd.prefixlen && !arg_rd) {
    4705           0 :                 vty_out(vty,
    4706             :                         "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
    4707             :                         arg_vrf);
    4708           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4709             :         }
    4710           0 :         if (rfg->label > MPLS_LABEL_MAX && !arg_label) {
    4711           0 :                 vty_out(vty,
    4712             :                         "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
    4713             :                         arg_vrf);
    4714           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4715             :         }
    4716           0 :         if (!str2prefix(arg_prefix, &pfx)) {
    4717           0 :                 vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix);
    4718           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4719             :         }
    4720           0 :         rfapiQprefix2Rprefix(&pfx, &rpfx);
    4721           0 :         memset(optary, 0, sizeof(optary));
    4722           0 :         if (arg_rd) {
    4723           0 :                 opt = &optary[cur_opt++];
    4724           0 :                 opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
    4725           0 :                 if (!str2prefix_rd(arg_rd, &opt->v.internal_rd)) {
    4726           0 :                         vty_out(vty, "Malformed RD \"%s\"\n", arg_rd);
    4727           0 :                         return CMD_WARNING_CONFIG_FAILED;
    4728             :                 }
    4729             :         }
    4730           0 :         if (rfg->label <= MPLS_LABEL_MAX || arg_label) {
    4731           0 :                 struct rfapi_l2address_option *l2o;
    4732           0 :                 if (opt != NULL)
    4733           0 :                         opt->next = &optary[cur_opt];
    4734           0 :                 opt = &optary[cur_opt++];
    4735           0 :                 opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
    4736           0 :                 l2o = &opt->v.l2addr;
    4737           0 :                 if (arg_label) {
    4738           0 :                         int32_t label;
    4739           0 :                         label = strtoul(arg_label, NULL, 10);
    4740           0 :                         l2o->label = label;
    4741             :                 } else
    4742           0 :                         l2o->label = rfg->label;
    4743             :         }
    4744           0 :         if (arg_pref) {
    4745           0 :                 char *endptr = NULL;
    4746           0 :                 pref = strtoul(arg_pref, &endptr, 10);
    4747           0 :                 if (*endptr != '\0') {
    4748           0 :                         vty_out(vty,
    4749             :                                 "%% Invalid local-preference value \"%s\"\n",
    4750             :                                 arg_pref);
    4751           0 :                         return CMD_WARNING_CONFIG_FAILED;
    4752             :                 }
    4753             :         }
    4754           0 :         rpfx.cost = 255 - (pref & 255);
    4755           0 :         vnc_add_vrf_opener(bgp, rfg);
    4756             : 
    4757           0 :         if (!rfapi_register(rfg->rfd, &rpfx, RFAPI_INFINITE_LIFETIME, NULL,
    4758             :                             (cur_opt ? optary : NULL), RFAPI_REGISTER_ADD)) {
    4759           0 :                 struct rfapi_next_hop_entry *head = NULL;
    4760           0 :                 struct rfapi_next_hop_entry *tail = NULL;
    4761           0 :                 struct rfapi_vn_option *vn_opt_new;
    4762             : 
    4763           0 :                 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
    4764             :                                        __func__);
    4765             : 
    4766           0 :                 if (bgp->rfapi->rfp_methods.local_cb) {
    4767           0 :                         struct rfapi_descriptor *r =
    4768             :                                 (struct rfapi_descriptor *)rfg->rfd;
    4769           0 :                         vn_opt_new = rfapi_vn_options_dup(opt);
    4770             : 
    4771           0 :                         rfapiAddDeleteLocalRfpPrefix(&r->un_addr, &r->vn_addr,
    4772             :                                                      &rpfx, 1,
    4773             :                                                      RFAPI_INFINITE_LIFETIME,
    4774             :                                                      vn_opt_new, &head, &tail);
    4775           0 :                         if (head) {
    4776           0 :                                 bgp->rfapi->flags |= RFAPI_INCALLBACK;
    4777           0 :                                 (*bgp->rfapi->rfp_methods.local_cb)(head,
    4778             :                                                                     r->cookie);
    4779           0 :                                 bgp->rfapi->flags &= ~RFAPI_INCALLBACK;
    4780             :                         }
    4781           0 :                         head = tail = NULL;
    4782             :                 }
    4783           0 :                 vnc_zlog_debug_verbose(
    4784             :                         "%s completed, count=%d/%d", __func__,
    4785             :                         rfg->rfapi_import_table->local_count[AFI_IP],
    4786             :                         rfg->rfapi_import_table->local_count[AFI_IP6]);
    4787           0 :                 return CMD_SUCCESS;
    4788             :         }
    4789             : 
    4790           0 :         vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__);
    4791           0 :         vty_out(vty, "Add failed.\n");
    4792           0 :         return CMD_WARNING_CONFIG_FAILED;
    4793             : }
    4794             : 
    4795           0 : DEFUN (add_vrf_prefix_rd_label_pref,
    4796             :        add_vrf_prefix_rd_label_pref_cmd,
    4797             :       "add vrf NAME prefix <A.B.C.D/M|X:X::X:X/M> [{rd ASN:NN_OR_IP-ADDRESS|label (0-1048575)|preference (0-4294967295)}]",
    4798             :        "Add\n"
    4799             :        "To a VRF\n"
    4800             :        "VRF name\n"
    4801             :        "Add/modify prefix related information\n"
    4802             :        "IPv4 prefix\n"
    4803             :        "IPv6 prefix\n"
    4804             :        "Override configured VRF Route Distinguisher\n"
    4805             :        "<as-number>:<number> or <ip-address>:<number>\n"
    4806             :        "Override configured VRF label\n"
    4807             :        "Label Value <0-1048575>\n"
    4808             :        "Set advertised local preference\n"
    4809             :        "local preference (higher=more preferred)\n")
    4810             : {
    4811           0 :         char *arg_vrf = argv[2]->arg;
    4812           0 :         char *arg_prefix = argv[4]->arg;
    4813           0 :         char *arg_rd = NULL;    /* optional */
    4814           0 :         char *arg_label = NULL; /* optional */
    4815           0 :         char *arg_pref = NULL;  /* optional */
    4816           0 :         int pargc = 5;
    4817           0 :         argc--; /* don't parse argument */
    4818           0 :         while (pargc < argc) {
    4819           0 :                 switch (argv[pargc++]->arg[0]) {
    4820           0 :                 case 'r':
    4821           0 :                         arg_rd = argv[pargc]->arg;
    4822           0 :                         break;
    4823           0 :                 case 'l':
    4824           0 :                         arg_label = argv[pargc]->arg;
    4825           0 :                         break;
    4826           0 :                 case 'p':
    4827           0 :                         arg_pref = argv[pargc]->arg;
    4828           0 :                         break;
    4829             :                 default:
    4830             :                         break;
    4831             :                 }
    4832           0 :                 pargc++;
    4833             :         }
    4834             : 
    4835           0 :         return vnc_add_vrf_prefix(vty, arg_vrf, arg_prefix, arg_rd, arg_label,
    4836             :                                   arg_pref);
    4837             : }
    4838             : 
    4839             : /************************************************************************
    4840             :  *              del prefix with vrf
    4841             :  *
    4842             :  * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
    4843             :  ************************************************************************/
    4844           0 : static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg)
    4845             : {
    4846           0 :         int count = 0;
    4847             : 
    4848           0 :         if (rfg->rfapi_import_table == NULL)
    4849             :                 return 0;
    4850             : 
    4851             :         afi_t afi = AFI_MAX;
    4852           0 :         while (afi-- > 0) {
    4853           0 :                 count += rfg->rfapi_import_table->local_count[afi];
    4854             :         }
    4855             :         return count;
    4856             : }
    4857             : 
    4858           0 : void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg *rfg)
    4859             : {
    4860           0 :         struct rfapi_descriptor *rfd = rfg->rfd;
    4861           0 :         afi_t afi;
    4862             : 
    4863           0 :         if (rfd == NULL)
    4864             :                 return;
    4865             :         /* check if IT is empty */
    4866             :         for (afi = 0;
    4867           0 :              afi < AFI_MAX && rfg->rfapi_import_table->local_count[afi] == 0;
    4868           0 :              afi++)
    4869             :                 ;
    4870             : 
    4871           0 :         if (afi == AFI_MAX) {
    4872           0 :                 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__,
    4873             :                                        rfg->name);
    4874           0 :                 rfg->rfd = NULL;
    4875           0 :                 rfapi_close(rfd);
    4876             :         } else {
    4877           0 :                 vnc_zlog_debug_verbose(
    4878             :                         "%s: VRF %s afi=%d count=%d", __func__, rfg->name, afi,
    4879             :                         rfg->rfapi_import_table->local_count[afi]);
    4880             :         }
    4881             : }
    4882             : 
    4883           0 : static int vnc_clear_vrf(struct vty *vty, struct bgp *bgp, const char *arg_vrf,
    4884             :                          const char *arg_prefix, /* NULL = all */
    4885             :                          const char *arg_rd)     /* optional */
    4886             : {
    4887           0 :         struct rfapi_nve_group_cfg *rfg;
    4888           0 :         struct rfapi_local_reg_delete_arg cda;
    4889           0 :         int rc;
    4890           0 :         int start_count;
    4891             : 
    4892           0 :         if (bgp == NULL)
    4893           0 :                 bgp = bgp_get_default(); /* assume main instance for now */
    4894           0 :         if (!bgp) {
    4895           0 :                 vty_out(vty, "No BGP process is configured\n");
    4896           0 :                 return CMD_WARNING;
    4897             :         }
    4898           0 :         if (!bgp->rfapi || !bgp->rfapi_cfg) {
    4899           0 :                 vty_out(vty, "VRF support not configured\n");
    4900           0 :                 return CMD_WARNING;
    4901             :         }
    4902           0 :         rfg = bgp_rfapi_cfg_match_byname(bgp, arg_vrf, RFAPI_GROUP_CFG_VRF);
    4903             :         /* arg checks */
    4904           0 :         if (!rfg) {
    4905           0 :                 vty_out(vty, "VRF \"%s\" appears not to be configured.\n",
    4906             :                         arg_vrf);
    4907           0 :                 return CMD_WARNING;
    4908             :         }
    4909           0 :         rc = parse_deleter_args(vty, bgp, arg_prefix, NULL, NULL, NULL, NULL,
    4910             :                                 arg_rd, rfg, &cda);
    4911           0 :         if (rc != CMD_SUCCESS) /* parse error */
    4912             :                 return rc;
    4913             : 
    4914           0 :         start_count = rfapi_cfg_group_it_count(rfg);
    4915           0 :         clear_vnc_prefix(&cda);
    4916           0 :         vty_out(vty, "Cleared %u out of %d prefixes.\n", cda.pfx_count,
    4917             :                 start_count);
    4918           0 :         return CMD_SUCCESS;
    4919             : }
    4920             : 
    4921           0 : DEFUN (clear_vrf_prefix_rd,
    4922             :        clear_vrf_prefix_rd_cmd,
    4923             :        "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
    4924             :        "Clear stored data\n"
    4925             :        "From a VRF\n"
    4926             :        "VRF name\n"
    4927             :        "Prefix related information\n"
    4928             :        "IPv4 prefix\n"
    4929             :        "IPv6 prefix\n"
    4930             :        "Specific VRF Route Distinguisher\n"
    4931             :        "<as-number>:<number> or <ip-address>:<number>\n")
    4932             : {
    4933           0 :         char *arg_vrf = argv[2]->arg;
    4934           0 :         char *arg_prefix = NULL; /* optional */
    4935           0 :         char *arg_rd = NULL;     /* optional */
    4936           0 :         int pargc = 3;
    4937           0 :         argc--; /* don't check parameter */
    4938           0 :         while (pargc < argc) {
    4939           0 :                 switch (argv[pargc++]->arg[0]) {
    4940           0 :                 case 'r':
    4941           0 :                         arg_rd = argv[pargc]->arg;
    4942           0 :                         break;
    4943           0 :                 case 'p':
    4944           0 :                         arg_prefix = argv[pargc]->arg;
    4945           0 :                         break;
    4946             :                 default:
    4947             :                         break;
    4948             :                 }
    4949           0 :                 pargc++;
    4950             :         }
    4951           0 :         return vnc_clear_vrf(vty, NULL, arg_vrf, arg_prefix, arg_rd);
    4952             : }
    4953             : 
    4954           0 : DEFUN (clear_vrf_all,
    4955             :        clear_vrf_all_cmd,
    4956             :        "clear vrf NAME all",
    4957             :        "Clear stored data\n"
    4958             :        "From a VRF\n"
    4959             :        "VRF name\n"
    4960             :        "All prefixes\n")
    4961             : {
    4962           0 :         char *arg_vrf = argv[2]->arg;
    4963           0 :         return vnc_clear_vrf(vty, NULL, arg_vrf, NULL, NULL);
    4964             : }
    4965             : 
    4966           2 : void rfapi_vty_init(void)
    4967             : {
    4968           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd);
    4969           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd);
    4970           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd);
    4971           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd);
    4972           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_lnh_cmd);
    4973             : 
    4974           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_cost_life_cmd);
    4975           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_life_cost_cmd);
    4976           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_cost_cmd);
    4977           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_life_cmd);
    4978           2 :         install_element(ENABLE_NODE, &add_vnc_prefix_cmd);
    4979             : 
    4980           2 :         install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd);
    4981           2 :         install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd);
    4982           2 :         install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd);
    4983           2 :         install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd);
    4984           2 :         install_element(ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd);
    4985           2 :         install_element(ENABLE_NODE, &add_vnc_mac_vni_cost_cmd);
    4986           2 :         install_element(ENABLE_NODE, &add_vnc_mac_vni_life_cmd);
    4987           2 :         install_element(ENABLE_NODE, &add_vnc_mac_vni_cmd);
    4988             : 
    4989           2 :         install_element(ENABLE_NODE, &add_vrf_prefix_rd_label_pref_cmd);
    4990             : 
    4991           2 :         install_element(ENABLE_NODE, &clear_vnc_nve_all_cmd);
    4992           2 :         install_element(ENABLE_NODE, &clear_vnc_nve_vn_un_cmd);
    4993           2 :         install_element(ENABLE_NODE, &clear_vnc_nve_un_vn_cmd);
    4994           2 :         install_element(ENABLE_NODE, &clear_vnc_nve_vn_cmd);
    4995           2 :         install_element(ENABLE_NODE, &clear_vnc_nve_un_cmd);
    4996             : 
    4997           2 :         install_element(ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd);
    4998           2 :         install_element(ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd);
    4999           2 :         install_element(ENABLE_NODE, &clear_vnc_prefix_un_cmd);
    5000           2 :         install_element(ENABLE_NODE, &clear_vnc_prefix_vn_cmd);
    5001           2 :         install_element(ENABLE_NODE, &clear_vnc_prefix_all_cmd);
    5002             : 
    5003           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_vn_un_cmd);
    5004           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_un_vn_cmd);
    5005           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_un_cmd);
    5006           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_vn_cmd);
    5007           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_all_cmd);
    5008             : 
    5009           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd);
    5010           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd);
    5011           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd);
    5012           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd);
    5013           2 :         install_element(ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd);
    5014             : 
    5015           2 :         install_element(ENABLE_NODE, &clear_vrf_prefix_rd_cmd);
    5016           2 :         install_element(ENABLE_NODE, &clear_vrf_all_cmd);
    5017             : 
    5018           2 :         install_element(ENABLE_NODE, &vnc_clear_counters_cmd);
    5019             : 
    5020           2 :         install_element(VIEW_NODE, &vnc_show_summary_cmd);
    5021           2 :         install_element(VIEW_NODE, &vnc_show_nves_cmd);
    5022           2 :         install_element(VIEW_NODE, &vnc_show_nves_ptct_cmd);
    5023             : 
    5024           2 :         install_element(VIEW_NODE, &vnc_show_registrations_pfx_cmd);
    5025           2 :         install_element(VIEW_NODE, &vnc_show_registrations_some_pfx_cmd);
    5026           2 :         install_element(VIEW_NODE, &vnc_show_responses_pfx_cmd);
    5027           2 :         install_element(VIEW_NODE, &vnc_show_responses_some_pfx_cmd);
    5028           2 :         install_element(VIEW_NODE, &show_vnc_queries_pfx_cmd);
    5029           2 : }

Generated by: LCOV version v1.16-topotato