back to topotato report
topotato coverage report
Current view: top level - bgpd/rfapi - bgp_rfapi_cfg.c (source / functions) Hit Total Coverage
Test: test_exabgp_demo.py::ExaBGPDemo Lines: 190 2061 9.2 %
Date: 2023-02-24 18:37:55 Functions: 61 147 41.5 %

          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             : #include "lib/zebra.h"
      21             : 
      22             : #include "lib/command.h"
      23             : #include "lib/prefix.h"
      24             : #include "lib/memory.h"
      25             : #include "lib/linklist.h"
      26             : #include "lib/agg_table.h"
      27             : #include "lib/plist.h"
      28             : #include "lib/routemap.h"
      29             : 
      30             : #include "bgpd/bgpd.h"
      31             : #include "bgpd/bgp_attr.h"
      32             : #include "bgpd/bgp_route.h"
      33             : #include "bgpd/bgp_mplsvpn.h"
      34             : 
      35             : #include "bgpd/bgp_vty.h"
      36             : #include "bgpd/bgp_ecommunity.h"
      37             : #include "bgpd/rfapi/rfapi.h"
      38             : #include "bgpd/rfapi/bgp_rfapi_cfg.h"
      39             : #include "bgpd/rfapi/rfapi_backend.h"
      40             : #include "bgpd/rfapi/rfapi_import.h"
      41             : #include "bgpd/rfapi/rfapi_private.h"
      42             : #include "bgpd/rfapi/rfapi_monitor.h"
      43             : #include "bgpd/rfapi/vnc_zebra.h"
      44             : #include "bgpd/rfapi/vnc_export_bgp.h"
      45             : #include "bgpd/rfapi/vnc_export_bgp_p.h"
      46             : #include "bgpd/rfapi/rfapi_vty.h"
      47             : #include "bgpd/rfapi/vnc_import_bgp.h"
      48             : #include "bgpd/rfapi/vnc_debug.h"
      49             : 
      50             : #ifdef ENABLE_BGP_VNC
      51             : 
      52             : #undef BGP_VNC_DEBUG_MATCH_GROUP
      53             : 
      54             : 
      55           9 : DEFINE_MGROUP(RFAPI, "rfapi");
      56           9 : DEFINE_MTYPE(RFAPI, RFAPI_CFG, "NVE Configuration");
      57           9 : DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG, "NVE Group Configuration");
      58           9 : DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG, "RFAPI L2 Group Configuration");
      59           9 : DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG, "RFAPI RFP Group Configuration");
      60           9 : DEFINE_MTYPE(RFAPI, RFAPI, "RFAPI Generic");
      61           9 : DEFINE_MTYPE(RFAPI, RFAPI_DESC, "RFAPI Descriptor");
      62           9 : DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE, "RFAPI Import Table");
      63           9 : DEFINE_MTYPE(RFAPI, RFAPI_MONITOR, "RFAPI Monitor VPN");
      64           9 : DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP, "RFAPI Monitor Encap");
      65           9 : DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP, "RFAPI Next Hop");
      66           9 : DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION, "RFAPI VN Option");
      67           9 : DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION, "RFAPI UN Option");
      68           9 : DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW, "RFAPI Withdraw");
      69           9 : DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME, "RFAPI RFGName");
      70           9 : DEFINE_MTYPE(RFAPI, RFAPI_ADB, "RFAPI Advertisement Data");
      71           9 : DEFINE_MTYPE(RFAPI, RFAPI_ETI, "RFAPI Export Table Info");
      72           9 : DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR, "RFAPI NVE Address");
      73           9 : DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG, "RFAPI Prefix Bag");
      74           9 : DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA, "RFAPI IT Extra");
      75           9 : DEFINE_MTYPE(RFAPI, RFAPI_INFO, "RFAPI Info");
      76           9 : DEFINE_MTYPE(RFAPI, RFAPI_ADDR, "RFAPI Addr");
      77           9 : DEFINE_MTYPE(RFAPI, RFAPI_UPDATED_RESPONSE_QUEUE, "RFAPI Updated Rsp Queue");
      78           9 : DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE, "RFAPI Recently Deleted Route");
      79           9 : DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT, "RFAPI L2 Address Option");
      80           9 : DEFINE_MTYPE(RFAPI, RFAPI_AP, "RFAPI Advertised Prefix");
      81           9 : DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH, "RFAPI Monitor Ethernet");
      82             : 
      83             : DEFINE_QOBJ_TYPE(rfapi_nve_group_cfg);
      84             : DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg);
      85             : /***********************************************************************
      86             :  *                      RFAPI Support
      87             :  ***********************************************************************/
      88             : 
      89             : 
      90             : /*
      91             :  * compaitibility to old quagga_time call
      92             :  * time_t value in terms of stabilised absolute time.
      93             :  * replacement for POSIX time()
      94             :  */
      95           0 : time_t rfapi_time(time_t *t)
      96             : {
      97           0 :         time_t clock = monotime(NULL);
      98           0 :         if (t)
      99           0 :                 *t = clock;
     100           0 :         return clock;
     101             : }
     102             : 
     103           0 : void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg, struct list **nves,
     104             :                            uint8_t family) /* AF_INET, AF_INET6 */
     105             : {
     106           0 :         struct listnode *hln;
     107           0 :         struct rfapi_descriptor *rfd;
     108             : 
     109             :         /*
     110             :          * loop over nves in this grp, add to list
     111             :          */
     112           0 :         for (ALL_LIST_ELEMENTS_RO(rfg->nves, hln, rfd)) {
     113           0 :                 if (rfd->vn_addr.addr_family == family) {
     114           0 :                         if (!*nves)
     115           0 :                                 *nves = list_new();
     116           0 :                         listnode_add(*nves, rfd);
     117             :                 }
     118             :         }
     119           0 : }
     120             : 
     121             : 
     122           0 : struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
     123             :                                                       struct prefix *vn,
     124             :                                                       struct prefix *un)
     125             : {
     126           0 :         struct rfapi_nve_group_cfg *rfg_vn = NULL;
     127           0 :         struct rfapi_nve_group_cfg *rfg_un = NULL;
     128             : 
     129           0 :         struct agg_table *rt_vn;
     130           0 :         struct agg_table *rt_un;
     131           0 :         struct agg_node *rn_vn;
     132           0 :         struct agg_node *rn_un;
     133             : 
     134           0 :         struct rfapi_nve_group_cfg *rfg;
     135           0 :         struct listnode *node, *nnode;
     136             : 
     137           0 :         switch (vn->family) {
     138           0 :         case AF_INET:
     139           0 :                 rt_vn = hc->nve_groups_vn[AFI_IP];
     140           0 :                 break;
     141           0 :         case AF_INET6:
     142           0 :                 rt_vn = hc->nve_groups_vn[AFI_IP6];
     143           0 :                 break;
     144             :         default:
     145             :                 return NULL;
     146             :         }
     147             : 
     148           0 :         switch (un->family) {
     149           0 :         case AF_INET:
     150           0 :                 rt_un = hc->nve_groups_un[AFI_IP];
     151           0 :                 break;
     152           0 :         case AF_INET6:
     153           0 :                 rt_un = hc->nve_groups_un[AFI_IP6];
     154           0 :                 break;
     155             :         default:
     156             :                 return NULL;
     157             :         }
     158             : 
     159           0 :         rn_vn = agg_node_match(rt_vn, vn); /* NB locks node */
     160           0 :         if (rn_vn) {
     161           0 :                 rfg_vn = rn_vn->info;
     162           0 :                 agg_unlock_node(rn_vn);
     163             :         }
     164             : 
     165           0 :         rn_un = agg_node_match(rt_un, un); /* NB locks node */
     166           0 :         if (rn_un) {
     167           0 :                 rfg_un = rn_un->info;
     168           0 :                 agg_unlock_node(rn_un);
     169             :         }
     170             : 
     171             : #ifdef BGP_VNC_DEBUG_MATCH_GROUP
     172             :         {
     173             :                 vnc_zlog_debug_verbose("%s: vn prefix: %pFX", __func__, vn);
     174             :                 vnc_zlog_debug_verbose("%s: un prefix: %pFX", __func__, un);
     175             :                 vnc_zlog_debug_verbose(
     176             :                         "%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p",
     177             :                         __func__, rn_vn, rn_un, rfg_vn, rfg_un);
     178             :         }
     179             : #endif
     180             : 
     181             : 
     182           0 :         if (rfg_un == rfg_vn) /* same group */
     183             :                 return rfg_un;
     184           0 :         if (!rfg_un) /* un doesn't match, return vn-matched grp */
     185             :                 return rfg_vn;
     186           0 :         if (!rfg_vn) /* vn doesn't match, return un-matched grp */
     187             :                 return rfg_un;
     188             : 
     189             :         /*
     190             :          * Two different nve groups match: the group configured earlier wins.
     191             :          * For now, just walk the sequential list and pick the first one.
     192             :          * If this approach is too slow, then store serial numbers in the
     193             :          * nve group structures as they are defined and just compare
     194             :          * serial numbers.
     195             :          */
     196           0 :         for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg)) {
     197           0 :                 if ((rfg == rfg_un) || (rfg == rfg_vn)) {
     198           0 :                         return rfg;
     199             :                 }
     200             :         }
     201           0 :         vnc_zlog_debug_verbose(
     202             :                 "%s: shouldn't happen, returning NULL when un and vn match",
     203             :                 __func__);
     204             :         return NULL; /* shouldn't happen */
     205             : }
     206             : 
     207             : /*------------------------------------------
     208             :  * rfapi_get_rfp_start_val
     209             :  *
     210             :  * Returns value passed to rfapi on rfp_start
     211             :  *
     212             :  * input:
     213             :  *      void *          bgp structure
     214             :  *
     215             :  * returns:
     216             :  *      void *
     217             :  *------------------------------------------*/
     218           0 : void *rfapi_get_rfp_start_val(void *bgpv)
     219             : {
     220           0 :         struct bgp *bgp = bgpv;
     221           0 :         if (bgp == NULL || bgp->rfapi == NULL)
     222             :                 return NULL;
     223           0 :         return bgp->rfapi->rfp;
     224             : }
     225             : 
     226             : /*------------------------------------------
     227             :  * bgp_rfapi_is_vnc_configured
     228             :  *
     229             :  * Returns if VNC is configured
     230             :  *
     231             :  * input:
     232             :  *    bgp        NULL (=use default instance)
     233             :  *
     234             :  * output:
     235             :  *
     236             :  * return value: If VNC is configured for the bgpd instance
     237             :  *      0               Success
     238             :  *      EPERM           Not Default instance (VNC operations not allowed)
     239             :  *      ENXIO           VNC not configured
     240             :  --------------------------------------------*/
     241           0 : int bgp_rfapi_is_vnc_configured(struct bgp *bgp)
     242             : {
     243           0 :         if (bgp == NULL)
     244           0 :                 bgp = bgp_get_default();
     245             : 
     246           0 :         if (bgp && bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)
     247             :                 return EPERM;
     248             : 
     249           0 :         if (bgp && bgp->rfapi_cfg)
     250             :                 return 0;
     251             :         return ENXIO;
     252             : }
     253             : 
     254             : /***********************************************************************
     255             :  *                      VNC Configuration/CLI
     256             :  ***********************************************************************/
     257             : #define VNC_VTY_CONFIG_CHECK(bgp)                                                            \
     258             :         {                                                                                    \
     259             :                 switch (bgp_rfapi_is_vnc_configured(bgp)) {                                  \
     260             :                 case EPERM:                                                                  \
     261             :                         vty_out(vty,                                                         \
     262             :                                 "VNC operations only permitted on default BGP instance.\n"); \
     263             :                         return CMD_WARNING_CONFIG_FAILED;                                    \
     264             :                         break;                                                               \
     265             :                 case ENXIO:                                                                  \
     266             :                         vty_out(vty, "VNC not configured.\n");                               \
     267             :                         return CMD_WARNING_CONFIG_FAILED;                                    \
     268             :                         break;                                                               \
     269             :                 default:                                                                     \
     270             :                         break;                                                               \
     271             :                 }                                                                            \
     272             :         }
     273             : 
     274           0 : DEFUN (vnc_advertise_un_method,
     275             :        vnc_advertise_un_method_cmd,
     276             :        "vnc advertise-un-method encap-attr",
     277             :        VNC_CONFIG_STR
     278             :        "Method of advertising UN addresses\n"
     279             :        "Via Tunnel Encap attribute (in VPN SAFI)\n")
     280             : {
     281           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     282           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     283             : 
     284           0 :         if (!strncmp(argv[2]->arg, "encap-safi", 7)) {
     285           0 :                 bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP;
     286             :         } else {
     287           0 :                 bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP;
     288             :         }
     289             : 
     290             :         return CMD_SUCCESS;
     291             : }
     292             : 
     293             : /*-------------------------------------------------------------------------
     294             :  *                      RFG defaults
     295             :  *-----------------------------------------------------------------------*/
     296             : 
     297             : 
     298           0 : DEFUN_NOSH (vnc_defaults,
     299             :             vnc_defaults_cmd,
     300             :             "vnc defaults", VNC_CONFIG_STR "Configure default NVE group\n")
     301             : {
     302           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     303           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     304           0 :         if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
     305           0 :                 vty_out(vty, "Malformed community-list value\n");
     306           0 :                 return CMD_WARNING_CONFIG_FAILED;
     307             :         }
     308           0 :         vty->node = BGP_VNC_DEFAULTS_NODE;
     309           0 :         return CMD_SUCCESS;
     310             : }
     311             : 
     312           0 : static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv,
     313             :                          struct ecommunity **list)
     314             : {
     315           0 :         struct ecommunity *ecom = NULL;
     316           0 :         struct ecommunity *ecomadd;
     317             : 
     318           0 :         for (; argc; --argc, ++argv) {
     319             : 
     320           0 :                 ecomadd = ecommunity_str2com(argv[0]->arg,
     321             :                                              ECOMMUNITY_ROUTE_TARGET, 0);
     322           0 :                 if (!ecomadd) {
     323           0 :                         vty_out(vty, "Malformed community-list value\n");
     324           0 :                         if (ecom)
     325           0 :                                 ecommunity_free(&ecom);
     326           0 :                         return CMD_WARNING_CONFIG_FAILED;
     327             :                 }
     328             : 
     329           0 :                 if (ecom) {
     330           0 :                         ecommunity_merge(ecom, ecomadd);
     331           0 :                         ecommunity_free(&ecomadd);
     332             :                 } else {
     333           0 :                         ecom = ecomadd;
     334             :                 }
     335             :         }
     336             : 
     337           0 :         if (*list) {
     338           0 :                 ecommunity_free(&*list);
     339             :         }
     340           0 :         *list = ecom;
     341             : 
     342           0 :         return CMD_SUCCESS;
     343             : }
     344             : 
     345           0 : DEFUN (vnc_defaults_rt_import,
     346             :        vnc_defaults_rt_import_cmd,
     347             :        "rt import RTLIST...",
     348             :        "Specify default route targets\n"
     349             :        "Import filter\n"
     350             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
     351             : {
     352           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     353           0 :         return set_ecom_list(vty, argc - 2, argv + 2,
     354           0 :                              &bgp->rfapi_cfg->default_rt_import_list);
     355             : }
     356             : 
     357           0 : DEFUN (vnc_defaults_rt_export,
     358             :        vnc_defaults_rt_export_cmd,
     359             :        "rt export RTLIST...",
     360             :        "Configure default route targets\n"
     361             :        "Export filter\n"
     362             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
     363             : {
     364           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     365           0 :         return set_ecom_list(vty, argc - 2, argv + 2,
     366           0 :                              &bgp->rfapi_cfg->default_rt_export_list);
     367             : }
     368             : 
     369           0 : DEFUN (vnc_defaults_rt_both,
     370             :        vnc_defaults_rt_both_cmd,
     371             :        "rt both RTLIST...",
     372             :        "Configure default route targets\n"
     373             :        "Export+import filters\n"
     374             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
     375             : {
     376           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     377           0 :         int rc;
     378             : 
     379           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2,
     380           0 :                            &bgp->rfapi_cfg->default_rt_import_list);
     381           0 :         if (rc != CMD_SUCCESS)
     382             :                 return rc;
     383           0 :         return set_ecom_list(vty, argc - 2, argv + 2,
     384           0 :                              &bgp->rfapi_cfg->default_rt_export_list);
     385             : }
     386             : 
     387           0 : DEFUN (vnc_defaults_rd,
     388             :        vnc_defaults_rd_cmd,
     389             :        "rd ASN:NN_OR_IP-ADDRESS:NN",
     390             :        "Specify default route distinguisher\n"
     391             :        "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
     392             : {
     393           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     394           0 :         int ret;
     395           0 :         struct prefix_rd prd;
     396             : 
     397           0 :         if (!strncmp(argv[1]->arg, "auto:vn:", 8)) {
     398             :                 /*
     399             :                  * use AF_UNIX to designate automatically-assigned RD
     400             :                  * auto:vn:nn where nn is a 2-octet quantity
     401             :                  */
     402           0 :                 char *end = NULL;
     403           0 :                 uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
     404           0 :                 uint16_t value = value32 & 0xffff;
     405             : 
     406           0 :                 if (!argv[1]->arg[8] || *end) {
     407           0 :                         vty_out(vty, "%% Malformed rd\n");
     408           0 :                         return CMD_WARNING_CONFIG_FAILED;
     409             :                 }
     410           0 :                 if (value32 > 0xffff) {
     411           0 :                         vty_out(vty, "%% Malformed rd (must be less than %u\n",
     412             :                                 0x0ffff);
     413           0 :                         return CMD_WARNING_CONFIG_FAILED;
     414             :                 }
     415             : 
     416           0 :                 memset(&prd, 0, sizeof(prd));
     417           0 :                 prd.family = AF_UNIX;
     418           0 :                 prd.prefixlen = 64;
     419           0 :                 prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
     420           0 :                 prd.val[1] = RD_TYPE_IP & 0x0ff;
     421           0 :                 prd.val[6] = (value >> 8) & 0x0ff;
     422           0 :                 prd.val[7] = value & 0x0ff;
     423             : 
     424             :         } else {
     425             : 
     426           0 :                 ret = str2prefix_rd(argv[1]->arg, &prd);
     427           0 :                 if (!ret) {
     428           0 :                         vty_out(vty, "%% Malformed rd\n");
     429           0 :                         return CMD_WARNING_CONFIG_FAILED;
     430             :                 }
     431             :         }
     432             : 
     433           0 :         bgp->rfapi_cfg->default_rd = prd;
     434           0 :         return CMD_SUCCESS;
     435             : }
     436             : 
     437           0 : DEFUN (vnc_defaults_l2rd,
     438             :        vnc_defaults_l2rd_cmd,
     439             :        "l2rd <(1-255)|auto-vn>",
     440             :        "Specify default Local Nve ID value to use in RD for L2 routes\n"
     441             :        "Fixed value 1-255\n"
     442             :        "use the low-order octet of the NVE's VN address\n")
     443             : {
     444           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     445           0 :         uint8_t value = 0;
     446             : 
     447           0 :         if (strmatch(argv[1]->text, "auto-vn")) {
     448             :                 value = 0;
     449             :         } else {
     450           0 :                 char *end = NULL;
     451           0 :                 unsigned long value_l = strtoul(argv[1]->arg, &end, 10);
     452             : 
     453           0 :                 value = value_l & 0xff;
     454           0 :                 if (!argv[1]->arg[0] || *end) {
     455           0 :                         vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n",
     456             :                                 argv[1]->arg);
     457           0 :                         return CMD_WARNING_CONFIG_FAILED;
     458             :                 }
     459           0 :                 if ((value_l < 1) || (value_l > 0xff)) {
     460           0 :                         vty_out(vty,
     461             :                                 "%% Malformed l2 nve id (must be greater than 0 and less than %u\n",
     462             :                                 0x100);
     463           0 :                         return CMD_WARNING_CONFIG_FAILED;
     464             :                 }
     465             :         }
     466           0 :         bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_L2RD;
     467           0 :         bgp->rfapi_cfg->default_l2rd = value;
     468             : 
     469           0 :         return CMD_SUCCESS;
     470             : }
     471             : 
     472           0 : DEFUN (vnc_defaults_no_l2rd,
     473             :        vnc_defaults_no_l2rd_cmd,
     474             :        "no l2rd",
     475             :        NO_STR
     476             :        "Specify default Local Nve ID value to use in RD for L2 routes\n")
     477             : {
     478           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     479             : 
     480           0 :         bgp->rfapi_cfg->default_l2rd = 0;
     481           0 :         bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_L2RD;
     482             : 
     483           0 :         return CMD_SUCCESS;
     484             : }
     485             : 
     486           0 : DEFUN (vnc_defaults_responselifetime,
     487             :        vnc_defaults_responselifetime_cmd,
     488             :        "response-lifetime <LIFETIME|infinite>",
     489             :        "Specify default response lifetime\n"
     490             :        "Response lifetime in seconds\n" "Infinite response lifetime\n")
     491             : {
     492           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     493           0 :         uint32_t rspint;
     494           0 :         struct rfapi *h = NULL;
     495           0 :         struct listnode *hdnode;
     496           0 :         struct rfapi_descriptor *rfd;
     497             : 
     498           0 :         h = bgp->rfapi;
     499           0 :         if (!h)
     500             :                 return CMD_WARNING_CONFIG_FAILED;
     501             : 
     502           0 :         if (strmatch(argv[1]->text, "infinite")) {
     503             :                 rspint = RFAPI_INFINITE_LIFETIME;
     504             :         } else {
     505           0 :                 rspint = strtoul(argv[1]->arg, NULL, 10);
     506           0 :                 if (rspint > INT32_MAX)
     507           0 :                         rspint = INT32_MAX; /* is really an int, not an unsigned
     508             :                                                int */
     509             :         }
     510             : 
     511           0 :         bgp->rfapi_cfg->default_response_lifetime = rspint;
     512             : 
     513           0 :         for (ALL_LIST_ELEMENTS_RO(&h->descriptors, hdnode, rfd))
     514           0 :                 if (rfd->rfg
     515           0 :                     && !(rfd->rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME))
     516           0 :                         rfd->response_lifetime = rfd->rfg->response_lifetime =
     517             :                                 rspint;
     518             : 
     519             :         return CMD_SUCCESS;
     520             : }
     521             : 
     522             : struct rfapi_nve_group_cfg *
     523           0 : bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name,
     524             :                            rfapi_group_cfg_type_t type) /* _MAX = any */
     525             : {
     526           0 :         struct rfapi_nve_group_cfg *rfg;
     527           0 :         struct listnode *node, *nnode;
     528             : 
     529           0 :         for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, node,
     530             :                                nnode, rfg)) {
     531           0 :                 if ((type == RFAPI_GROUP_CFG_MAX || type == rfg->type)
     532           0 :                     && !strcmp(rfg->name, name))
     533           0 :                         return rfg;
     534             :         }
     535             :         return NULL;
     536             : }
     537             : 
     538             : static struct rfapi_nve_group_cfg *
     539           0 : rfapi_group_new(struct bgp *bgp, rfapi_group_cfg_type_t type, const char *name)
     540             : {
     541           0 :         struct rfapi_nve_group_cfg *rfg;
     542             : 
     543           0 :         rfg = XCALLOC(MTYPE_RFAPI_GROUP_CFG,
     544             :                       sizeof(struct rfapi_nve_group_cfg));
     545           0 :         rfg->type = type;
     546           0 :         rfg->name = strdup(name);
     547             :         /* add to tail of list */
     548           0 :         listnode_add(bgp->rfapi_cfg->nve_groups_sequential, rfg);
     549           0 :         rfg->label = MPLS_LABEL_NONE;
     550             : 
     551           0 :         QOBJ_REG(rfg, rfapi_nve_group_cfg);
     552             : 
     553           0 :         return rfg;
     554             : }
     555             : 
     556           0 : static struct rfapi_l2_group_cfg *rfapi_l2_group_lookup_byname(struct bgp *bgp,
     557             :                                                                const char *name)
     558             : {
     559           0 :         struct rfapi_l2_group_cfg *rfg;
     560           0 :         struct listnode *node, *nnode;
     561             : 
     562           0 :         if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */
     563           0 :                 bgp->rfapi_cfg->l2_groups = list_new();
     564             : 
     565           0 :         for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) {
     566           0 :                 if (!strcmp(rfg->name, name))
     567           0 :                         return rfg;
     568             :         }
     569             :         return NULL;
     570             : }
     571             : 
     572           0 : static struct rfapi_l2_group_cfg *rfapi_l2_group_new(void)
     573             : {
     574           0 :         struct rfapi_l2_group_cfg *rfg;
     575             : 
     576           0 :         rfg = XCALLOC(MTYPE_RFAPI_L2_CFG, sizeof(struct rfapi_l2_group_cfg));
     577           0 :         QOBJ_REG(rfg, rfapi_l2_group_cfg);
     578             : 
     579           0 :         return rfg;
     580             : }
     581             : 
     582           0 : static void rfapi_l2_group_del(struct rfapi_l2_group_cfg *rfg)
     583             : {
     584           0 :         QOBJ_UNREG(rfg);
     585           0 :         XFREE(MTYPE_RFAPI_L2_CFG, rfg);
     586           0 : }
     587             : 
     588           0 : static int rfapi_str2route_type(const char *l3str, const char *pstr, afi_t *afi,
     589             :                                 int *type)
     590             : {
     591           0 :         if (!l3str || !pstr)
     592             :                 return EINVAL;
     593             : 
     594           0 :         if (!strcmp(l3str, "ipv4")) {
     595           0 :                 *afi = AFI_IP;
     596             :         } else {
     597           0 :                 if (!strcmp(l3str, "ipv6"))
     598           0 :                         *afi = AFI_IP6;
     599             :                 else
     600             :                         return ENOENT;
     601             :         }
     602             : 
     603           0 :         if (!strcmp(pstr, "connected"))
     604           0 :                 *type = ZEBRA_ROUTE_CONNECT;
     605           0 :         if (!strcmp(pstr, "kernel"))
     606           0 :                 *type = ZEBRA_ROUTE_KERNEL;
     607           0 :         if (!strcmp(pstr, "static"))
     608           0 :                 *type = ZEBRA_ROUTE_STATIC;
     609           0 :         if (!strcmp(pstr, "bgp"))
     610           0 :                 *type = ZEBRA_ROUTE_BGP;
     611           0 :         if (!strcmp(pstr, "bgp-direct"))
     612           0 :                 *type = ZEBRA_ROUTE_BGP_DIRECT;
     613           0 :         if (!strcmp(pstr, "bgp-direct-to-nve-groups"))
     614           0 :                 *type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
     615             : 
     616           0 :         if (!strcmp(pstr, "rip")) {
     617           0 :                 if (*afi == AFI_IP)
     618           0 :                         *type = ZEBRA_ROUTE_RIP;
     619             :                 else
     620           0 :                         *type = ZEBRA_ROUTE_RIPNG;
     621             :         }
     622             : 
     623           0 :         if (!strcmp(pstr, "ripng")) {
     624           0 :                 if (*afi == AFI_IP)
     625             :                         return EAFNOSUPPORT;
     626           0 :                 *type = ZEBRA_ROUTE_RIPNG;
     627             :         }
     628             : 
     629           0 :         if (!strcmp(pstr, "ospf")) {
     630           0 :                 if (*afi == AFI_IP)
     631           0 :                         *type = ZEBRA_ROUTE_OSPF;
     632             :                 else
     633           0 :                         *type = ZEBRA_ROUTE_OSPF6;
     634             :         }
     635             : 
     636           0 :         if (!strcmp(pstr, "ospf6")) {
     637           0 :                 if (*afi == AFI_IP)
     638             :                         return EAFNOSUPPORT;
     639           0 :                 *type = ZEBRA_ROUTE_OSPF6;
     640             :         }
     641             : 
     642             :         return 0;
     643             : }
     644             : 
     645             : /*-------------------------------------------------------------------------
     646             :  *                      redistribute
     647             :  *-----------------------------------------------------------------------*/
     648             : 
     649             : #define VNC_REDIST_ENABLE(bgp, afi, type)                                      \
     650             :         do {                                                                   \
     651             :                 switch (type) {                                                \
     652             :                 case ZEBRA_ROUTE_BGP_DIRECT:                                   \
     653             :                         vnc_import_bgp_redist_enable((bgp), (afi));            \
     654             :                         break;                                                 \
     655             :                 case ZEBRA_ROUTE_BGP_DIRECT_EXT:                               \
     656             :                         vnc_import_bgp_exterior_redist_enable((bgp), (afi));   \
     657             :                         break;                                                 \
     658             :                 default:                                                       \
     659             :                         if ((type) < ZEBRA_ROUTE_MAX)                               \
     660             :                                 vnc_redistribute_set((bgp), (afi), (type));    \
     661             :                         break;                                                 \
     662             :                 }                                                              \
     663             :         } while (0)
     664             : 
     665             : #define VNC_REDIST_DISABLE(bgp, afi, type)                                     \
     666             :         do {                                                                   \
     667             :                 switch (type) {                                                \
     668             :                 case ZEBRA_ROUTE_BGP_DIRECT:                                   \
     669             :                         vnc_import_bgp_redist_disable((bgp), (afi));           \
     670             :                         break;                                                 \
     671             :                 case ZEBRA_ROUTE_BGP_DIRECT_EXT:                               \
     672             :                         vnc_import_bgp_exterior_redist_disable((bgp), (afi));  \
     673             :                         break;                                                 \
     674             :                 default:                                                       \
     675             :                         if ((type) < ZEBRA_ROUTE_MAX)                               \
     676             :                                 vnc_redistribute_unset((bgp), (afi), (type));  \
     677             :                         break;                                                 \
     678             :                 }                                                              \
     679             :         } while (0)
     680             : 
     681             : static uint8_t redist_was_enabled[AFI_MAX][ZEBRA_ROUTE_MAX];
     682             : 
     683           1 : static void vnc_redistribute_prechange(struct bgp *bgp)
     684             : {
     685           1 :         afi_t afi;
     686           1 :         int type;
     687             : 
     688           1 :         vnc_zlog_debug_verbose("%s: entry", __func__);
     689           1 :         memset(redist_was_enabled, 0, sizeof(redist_was_enabled));
     690             : 
     691             :         /*
     692             :          * Look to see if we have any redistribution enabled. If so, flush
     693             :          * the corresponding routes and turn off redistribution temporarily.
     694             :          * We need to do it because the RD's used for the redistributed
     695             :          * routes depend on the nve group.
     696             :          */
     697           4 :         for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
     698          96 :                 for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
     699          93 :                         if (bgp->rfapi_cfg->redist[afi][type]) {
     700           0 :                                 redist_was_enabled[afi][type] = 1;
     701          93 :                                 VNC_REDIST_DISABLE(bgp, afi, type);
     702             :                         }
     703             :                 }
     704             :         }
     705           1 :         vnc_zlog_debug_verbose("%s: return", __func__);
     706           1 : }
     707             : 
     708           1 : static void vnc_redistribute_postchange(struct bgp *bgp)
     709             : {
     710           1 :         afi_t afi;
     711           1 :         int type;
     712             : 
     713           1 :         vnc_zlog_debug_verbose("%s: entry", __func__);
     714             :         /*
     715             :          * If we turned off redistribution above, turn it back on. Doing so
     716             :          * will tell zebra to resend the routes to us
     717             :          */
     718           4 :         for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
     719          96 :                 for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
     720          93 :                         if (redist_was_enabled[afi][type]) {
     721          93 :                                 VNC_REDIST_ENABLE(bgp, afi, type);
     722             :                         }
     723             :                 }
     724             :         }
     725           1 :         vnc_zlog_debug_verbose("%s: return", __func__);
     726           1 : }
     727             : 
     728           0 : DEFUN (vnc_redistribute_rh_roo_localadmin,
     729             :        vnc_redistribute_rh_roo_localadmin_cmd,
     730             :        "vnc redistribute resolve-nve roo-ec-local-admin (0-65535)",
     731             :        VNC_CONFIG_STR
     732             :        "Redistribute routes into VNC\n"
     733             :        "Resolve-NVE mode\n"
     734             :        "Route Origin Extended Community Local Admin Field\n" "Field value\n")
     735             : {
     736           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     737           0 :         uint32_t localadmin;
     738           0 :         char *endptr;
     739             : 
     740           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     741             : 
     742           0 :         localadmin = strtoul(argv[4]->arg, &endptr, 0);
     743           0 :         if (!argv[4]->arg[0] || *endptr) {
     744           0 :                 vty_out(vty, "%% Malformed value\n");
     745           0 :                 return CMD_WARNING_CONFIG_FAILED;
     746             :         }
     747             : 
     748           0 :         if (localadmin > 0xffff) {
     749           0 :                 vty_out(vty, "%% Value out of range (0-%d)\n", 0xffff);
     750           0 :                 return CMD_WARNING_CONFIG_FAILED;
     751             :         }
     752             : 
     753           0 :         if (bgp->rfapi_cfg->resolve_nve_roo_local_admin == localadmin)
     754             :                 return CMD_SUCCESS;
     755             : 
     756           0 :         if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)
     757             :             == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) {
     758             : 
     759           0 :                 vnc_export_bgp_prechange(bgp);
     760             :         }
     761           0 :         vnc_redistribute_prechange(bgp);
     762             : 
     763           0 :         bgp->rfapi_cfg->resolve_nve_roo_local_admin = localadmin;
     764             : 
     765           0 :         if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)
     766             :             == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) {
     767             : 
     768           0 :                 vnc_export_bgp_postchange(bgp);
     769             :         }
     770           0 :         vnc_redistribute_postchange(bgp);
     771             : 
     772           0 :         return CMD_SUCCESS;
     773             : }
     774             : 
     775             : 
     776           0 : DEFUN (vnc_redistribute_mode,
     777             :        vnc_redistribute_mode_cmd,
     778             :        "vnc redistribute mode <nve-group|plain|resolve-nve>",
     779             :        VNC_CONFIG_STR
     780             :        "Redistribute routes into VNC\n"
     781             :        "Redistribution mode\n"
     782             :        "Based on redistribute nve-group\n"
     783             :        "Unmodified\n" "Resolve each nexthop to connected NVEs\n")
     784             : {
     785           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     786           0 :         vnc_redist_mode_t newmode;
     787             : 
     788           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     789             : 
     790           0 :         switch (argv[3]->arg[0]) {
     791             :         case 'n':
     792             :                 newmode = VNC_REDIST_MODE_RFG;
     793             :                 break;
     794             : 
     795           0 :         case 'p':
     796           0 :                 newmode = VNC_REDIST_MODE_PLAIN;
     797           0 :                 break;
     798             : 
     799           0 :         case 'r':
     800           0 :                 newmode = VNC_REDIST_MODE_RESOLVE_NVE;
     801           0 :                 break;
     802             : 
     803           0 :         default:
     804           0 :                 vty_out(vty, "unknown redistribute mode\n");
     805           0 :                 return CMD_WARNING_CONFIG_FAILED;
     806             :         }
     807             : 
     808           0 :         if (newmode != bgp->rfapi_cfg->redist_mode) {
     809           0 :                 vnc_redistribute_prechange(bgp);
     810           0 :                 bgp->rfapi_cfg->redist_mode = newmode;
     811           0 :                 vnc_redistribute_postchange(bgp);
     812             :         }
     813             : 
     814             :         return CMD_SUCCESS;
     815             : }
     816             : 
     817           0 : DEFUN (vnc_redistribute_protocol,
     818             :        vnc_redistribute_protocol_cmd,
     819             :        "vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
     820             :        VNC_CONFIG_STR
     821             :        "Redistribute routes into VNC\n"
     822             :        "IPv4 routes\n"
     823             :        "IPv6 routes\n"
     824             :        "From BGP\n"
     825             :        "From BGP without Zebra\n"
     826             :        "From BGP without Zebra, only to configured NVE groups\n"
     827             :        "Connected interfaces\n"
     828             :        "From kernel routes\n"
     829             :        "From Open Shortest Path First (OSPF)\n"
     830             :        "From Routing Information Protocol (RIP)\n" "From Static routes\n")
     831             : {
     832           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     833           0 :         int type = ZEBRA_ROUTE_MAX; /* init to bogus value */
     834           0 :         afi_t afi;
     835             : 
     836           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     837             : 
     838           0 :         if (rfapi_str2route_type(argv[2]->arg, argv[3]->arg, &afi, &type)) {
     839           0 :                 vty_out(vty, "%% Invalid route type\n");
     840           0 :                 return CMD_WARNING_CONFIG_FAILED;
     841             :         }
     842             : 
     843           0 :         if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
     844           0 :                 if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) {
     845           0 :                         VNC_REDIST_DISABLE(bgp, afi,
     846             :                                            type); /* disabled view implicitly */
     847           0 :                         free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
     848           0 :                         bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL;
     849             :                 }
     850           0 :                 bgp->rfapi_cfg->redist_bgp_exterior_view = bgp;
     851             :         }
     852             : 
     853           0 :         VNC_REDIST_ENABLE(bgp, afi, type);
     854             : 
     855             :         return CMD_SUCCESS;
     856             : }
     857             : 
     858           0 : DEFUN (vnc_no_redistribute_protocol,
     859             :        vnc_no_redistribute_protocol_cmd,
     860             :        "no vnc redistribute <ipv4|ipv6> <bgp|bgp-direct|bgp-direct-to-nve-groups|connected|kernel|ospf|rip|static>",
     861             :        NO_STR
     862             :        VNC_CONFIG_STR
     863             :        "Redistribute from other protocol\n"
     864             :        "IPv4 routes\n"
     865             :        "IPv6 routes\n"
     866             :        "From BGP\n"
     867             :        "From BGP without Zebra\n"
     868             :        "From BGP without Zebra, only to configured NVE groups\n"
     869             :        "Connected interfaces\n"
     870             :        "From kernel routes\n"
     871             :        "From Open Shortest Path First (OSPF)\n"
     872             :        "From Routing Information Protocol (RIP)\n" "From Static routes\n")
     873             : {
     874           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     875           0 :         int type;
     876           0 :         afi_t afi;
     877             : 
     878           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     879             : 
     880           0 :         if (rfapi_str2route_type(argv[3]->arg, argv[4]->arg, &afi, &type)) {
     881           0 :                 vty_out(vty, "%% Invalid route type\n");
     882           0 :                 return CMD_WARNING_CONFIG_FAILED;
     883             :         }
     884             : 
     885           0 :         VNC_REDIST_DISABLE(bgp, afi, type);
     886             : 
     887           0 :         if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
     888           0 :                 if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) {
     889           0 :                         free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
     890           0 :                         bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL;
     891             :                 }
     892           0 :                 bgp->rfapi_cfg->redist_bgp_exterior_view = NULL;
     893             :         }
     894             : 
     895             :         return CMD_SUCCESS;
     896             : }
     897             : 
     898           0 : DEFUN (vnc_redistribute_bgp_exterior,
     899             :        vnc_redistribute_bgp_exterior_cmd,
     900             :        "vnc redistribute <ipv4|ipv6> bgp-direct-to-nve-groups view NAME",
     901             :        VNC_CONFIG_STR
     902             :        "Redistribute routes into VNC\n"
     903             :        "IPv4 routes\n"
     904             :        "IPv6 routes\n"
     905             :        "From BGP without Zebra, only to configured NVE groups\n"
     906             :        "From BGP view\n" "BGP view name\n")
     907             : {
     908           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     909           0 :         int type;
     910           0 :         afi_t afi;
     911             : 
     912           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     913             : 
     914           0 :         if (rfapi_str2route_type(argv[2]->arg, "bgp-direct-to-nve-groups", &afi,
     915             :                                  &type)) {
     916           0 :                 vty_out(vty, "%% Invalid route type\n");
     917           0 :                 return CMD_WARNING_CONFIG_FAILED;
     918             :         }
     919             : 
     920           0 :         if (bgp->rfapi_cfg->redist_bgp_exterior_view_name)
     921           0 :                 free(bgp->rfapi_cfg->redist_bgp_exterior_view_name);
     922           0 :         bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup(argv[5]->arg);
     923             :         /* could be NULL if name is not defined yet */
     924           0 :         bgp->rfapi_cfg->redist_bgp_exterior_view =
     925           0 :                 bgp_lookup_by_name(argv[5]->arg);
     926             : 
     927           0 :         VNC_REDIST_ENABLE(bgp, afi, type);
     928             : 
     929             :         return CMD_SUCCESS;
     930             : }
     931             : 
     932           0 : DEFUN (vnc_redistribute_nvegroup,
     933             :        vnc_redistribute_nvegroup_cmd,
     934             :        "vnc redistribute nve-group NAME",
     935             :        VNC_CONFIG_STR
     936             :        "Assign a NVE group to routes redistributed from another routing protocol\n"
     937             :        "NVE group\n" "Group name\n")
     938             : {
     939           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     940           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     941             : 
     942           0 :         vnc_redistribute_prechange(bgp);
     943             : 
     944             :         /*
     945             :          * OK if nve group doesn't exist yet; we'll set the pointer
     946             :          * when the group is defined later
     947             :          */
     948           0 :         bgp->rfapi_cfg->rfg_redist = bgp_rfapi_cfg_match_byname(
     949           0 :                 bgp, argv[3]->arg, RFAPI_GROUP_CFG_NVE);
     950           0 :         if (bgp->rfapi_cfg->rfg_redist_name)
     951           0 :                 free(bgp->rfapi_cfg->rfg_redist_name);
     952           0 :         bgp->rfapi_cfg->rfg_redist_name = strdup(argv[3]->arg);
     953             : 
     954           0 :         vnc_redistribute_postchange(bgp);
     955             : 
     956           0 :         return CMD_SUCCESS;
     957             : }
     958             : 
     959           0 : DEFUN (vnc_redistribute_no_nvegroup,
     960             :        vnc_redistribute_no_nvegroup_cmd,
     961             :        "no vnc redistribute nve-group",
     962             :        NO_STR
     963             :        VNC_CONFIG_STR
     964             :        "Redistribute from other protocol\n"
     965             :        "Assign a NVE group to routes redistributed from another routing protocol\n")
     966             : {
     967           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     968             : 
     969           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     970             : 
     971           0 :         vnc_redistribute_prechange(bgp);
     972             : 
     973           0 :         bgp->rfapi_cfg->rfg_redist = NULL;
     974           0 :         if (bgp->rfapi_cfg->rfg_redist_name)
     975           0 :                 free(bgp->rfapi_cfg->rfg_redist_name);
     976           0 :         bgp->rfapi_cfg->rfg_redist_name = NULL;
     977             : 
     978           0 :         vnc_redistribute_postchange(bgp);
     979             : 
     980           0 :         return CMD_SUCCESS;
     981             : }
     982             : 
     983             : 
     984           0 : DEFUN (vnc_redistribute_lifetime,
     985             :        vnc_redistribute_lifetime_cmd,
     986             :        "vnc redistribute lifetime <LIFETIME|infinite>",
     987             :        VNC_CONFIG_STR
     988             :        "Redistribute\n"
     989             :        "Assign a lifetime to routes redistributed from another routing protocol\n"
     990             :        "lifetime value (32 bit)\n"
     991             :        "Allow lifetime to never expire\n")
     992             : {
     993           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
     994           0 :         VNC_VTY_CONFIG_CHECK(bgp);
     995             : 
     996           0 :         vnc_redistribute_prechange(bgp);
     997             : 
     998           0 :         if (strmatch(argv[3]->text, "infinite")) {
     999           0 :                 bgp->rfapi_cfg->redist_lifetime = RFAPI_INFINITE_LIFETIME;
    1000             :         } else {
    1001           0 :                 bgp->rfapi_cfg->redist_lifetime =
    1002           0 :                         strtoul(argv[3]->arg, NULL, 10);
    1003             :         }
    1004             : 
    1005           0 :         vnc_redistribute_postchange(bgp);
    1006             : 
    1007           0 :         return CMD_SUCCESS;
    1008             : }
    1009             : 
    1010             : /*-- redist policy, non-nvegroup start --*/
    1011             : 
    1012           0 : DEFUN (vnc_redist_bgpdirect_no_prefixlist,
    1013             :        vnc_redist_bgpdirect_no_prefixlist_cmd,
    1014             :        "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list",
    1015             :        NO_STR
    1016             :        VNC_CONFIG_STR
    1017             :        "Redistribute from other protocol\n"
    1018             :        "Redistribute from BGP directly\n"
    1019             :        "Redistribute from BGP without Zebra, only to configured NVE groups\n"
    1020             :        "IPv4 routes\n"
    1021             :        "IPv6 routes\n" "Prefix-list for filtering redistributed routes\n")
    1022             : {
    1023           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1024           0 :         afi_t afi;
    1025           0 :         struct rfapi_cfg *hc;
    1026           0 :         uint8_t route_type = 0;
    1027             : 
    1028           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1029           0 :         hc = bgp->rfapi_cfg;
    1030             : 
    1031           0 :         if (strmatch(argv[3]->text, "bgp-direct")) {
    1032             :                 route_type = ZEBRA_ROUTE_BGP_DIRECT;
    1033             :         } else {
    1034           0 :                 route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
    1035             :         }
    1036             : 
    1037           0 :         if (strmatch(argv[4]->text, "ipv4")) {
    1038             :                 afi = AFI_IP;
    1039             :         } else {
    1040           0 :                 afi = AFI_IP6;
    1041             :         }
    1042             : 
    1043           0 :         vnc_redistribute_prechange(bgp);
    1044             : 
    1045           0 :         if (hc->plist_redist_name[route_type][afi])
    1046           0 :                 free(hc->plist_redist_name[route_type][afi]);
    1047           0 :         hc->plist_redist_name[route_type][afi] = NULL;
    1048           0 :         hc->plist_redist[route_type][afi] = NULL;
    1049             : 
    1050           0 :         vnc_redistribute_postchange(bgp);
    1051             : 
    1052           0 :         return CMD_SUCCESS;
    1053             : }
    1054             : 
    1055           0 : DEFUN (vnc_redist_bgpdirect_prefixlist,
    1056             :        vnc_redist_bgpdirect_prefixlist_cmd,
    1057             :        "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> <ipv4|ipv6> prefix-list NAME",
    1058             :        VNC_CONFIG_STR
    1059             :        "Redistribute from other protocol\n"
    1060             :        "Redistribute from BGP directly\n"
    1061             :        "Redistribute from BGP without Zebra, only to configured NVE groups\n"
    1062             :        "IPv4 routes\n"
    1063             :        "IPv6 routes\n"
    1064             :        "Prefix-list for filtering redistributed routes\n"
    1065             :        "prefix list name\n")
    1066             : {
    1067           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1068           0 :         struct rfapi_cfg *hc;
    1069           0 :         afi_t afi;
    1070           0 :         uint8_t route_type = 0;
    1071             : 
    1072           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1073           0 :         hc = bgp->rfapi_cfg;
    1074             : 
    1075           0 :         if (strmatch(argv[2]->text, "bgp-direct")) {
    1076             :                 route_type = ZEBRA_ROUTE_BGP_DIRECT;
    1077             :         } else {
    1078           0 :                 route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
    1079             :         }
    1080             : 
    1081           0 :         if (strmatch(argv[3]->text, "ipv4")) {
    1082             :                 afi = AFI_IP;
    1083             :         } else {
    1084           0 :                 afi = AFI_IP6;
    1085             :         }
    1086             : 
    1087           0 :         vnc_redistribute_prechange(bgp);
    1088             : 
    1089           0 :         if (hc->plist_redist_name[route_type][afi])
    1090           0 :                 free(hc->plist_redist_name[route_type][afi]);
    1091           0 :         hc->plist_redist_name[route_type][afi] = strdup(argv[5]->arg);
    1092           0 :         hc->plist_redist[route_type][afi] =
    1093           0 :                 prefix_list_lookup(afi, argv[5]->arg);
    1094             : 
    1095           0 :         vnc_redistribute_postchange(bgp);
    1096             : 
    1097           0 :         return CMD_SUCCESS;
    1098             : }
    1099             : 
    1100           0 : DEFUN (vnc_redist_bgpdirect_no_routemap,
    1101             :        vnc_redist_bgpdirect_no_routemap_cmd,
    1102             :        "no vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map",
    1103             :        NO_STR
    1104             :        VNC_CONFIG_STR
    1105             :        "Redistribute from other protocols\n"
    1106             :        "Redistribute from BGP directly\n"
    1107             :        "Redistribute from BGP without Zebra, only to configured NVE groups\n"
    1108             :        "Route-map for filtering redistributed routes\n")
    1109             : {
    1110           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1111           0 :         struct rfapi_cfg *hc;
    1112           0 :         uint8_t route_type = 0;
    1113             : 
    1114           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1115           0 :         hc = bgp->rfapi_cfg;
    1116             : 
    1117           0 :         if (strmatch(argv[3]->text, "bgp-direct")) {
    1118             :                 route_type = ZEBRA_ROUTE_BGP_DIRECT;
    1119             :         } else {
    1120           0 :                 route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
    1121             :         }
    1122             : 
    1123           0 :         vnc_redistribute_prechange(bgp);
    1124             : 
    1125           0 :         if (hc->routemap_redist_name[route_type])
    1126           0 :                 free(hc->routemap_redist_name[route_type]);
    1127           0 :         hc->routemap_redist_name[route_type] = NULL;
    1128           0 :         hc->routemap_redist[route_type] = NULL;
    1129             : 
    1130           0 :         vnc_redistribute_postchange(bgp);
    1131             : 
    1132           0 :         return CMD_SUCCESS;
    1133             : }
    1134             : 
    1135           0 : DEFUN (vnc_redist_bgpdirect_routemap,
    1136             :        vnc_redist_bgpdirect_routemap_cmd,
    1137             :        "vnc redistribute <bgp-direct|bgp-direct-to-nve-groups> route-map NAME",
    1138             :        VNC_CONFIG_STR
    1139             :        "Redistribute from other protocols\n"
    1140             :        "Redistribute from BGP directly\n"
    1141             :        "Redistribute from BGP without Zebra, only to configured NVE groups\n"
    1142             :        "Route-map for filtering exported routes\n" "route map name\n")
    1143             : {
    1144           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1145           0 :         struct rfapi_cfg *hc;
    1146           0 :         uint8_t route_type = 0;
    1147             : 
    1148           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1149           0 :         hc = bgp->rfapi_cfg;
    1150             : 
    1151           0 :         if (strmatch(argv[2]->text, "bgp-direct")) {
    1152             :                 route_type = ZEBRA_ROUTE_BGP_DIRECT;
    1153             :         } else {
    1154           0 :                 route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT;
    1155             :         }
    1156             : 
    1157           0 :         vnc_redistribute_prechange(bgp);
    1158             : 
    1159           0 :         if (hc->routemap_redist_name[route_type])
    1160           0 :                 free(hc->routemap_redist_name[route_type]);
    1161             : 
    1162             :         /* If the old route map config overwrite with new
    1163             :          * route map config , old routemap counter have to be
    1164             :          * reduced.
    1165             :          */
    1166           0 :         route_map_counter_decrement(hc->routemap_redist[route_type]);
    1167           0 :         hc->routemap_redist_name[route_type] = strdup(argv[4]->arg);
    1168           0 :         hc->routemap_redist[route_type] =
    1169           0 :                 route_map_lookup_by_name(argv[4]->arg);
    1170           0 :         route_map_counter_increment(hc->routemap_redist[route_type]);
    1171             : 
    1172           0 :         vnc_redistribute_postchange(bgp);
    1173             : 
    1174           0 :         return CMD_SUCCESS;
    1175             : }
    1176             : 
    1177             : /*-- redist policy, non-nvegroup end --*/
    1178             : 
    1179             : /*-- redist policy, nvegroup start --*/
    1180             : 
    1181           0 : DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist,
    1182             :        vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd,
    1183             :        "no redistribute bgp-direct <ipv4|ipv6> prefix-list",
    1184             :        NO_STR
    1185             :        "Redistribute from other protocol\n"
    1186             :        "Redistribute from BGP directly\n"
    1187             :        "IPv4 routes\n"
    1188             :        "IPv6 routes\n"
    1189             :        "Prefix-list for filtering redistributed routes\n")
    1190             : {
    1191           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1192           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg)
    1193           0 :         afi_t afi;
    1194             : 
    1195           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1196             : 
    1197             :         /* make sure it's still in list */
    1198           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    1199             :                 /* Not in list anymore */
    1200           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    1201           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1202             :         }
    1203             : 
    1204           0 :         if (strmatch(argv[3]->text, "ipv4")) {
    1205             :                 afi = AFI_IP;
    1206             :         } else {
    1207           0 :                 afi = AFI_IP6;
    1208             :         }
    1209             : 
    1210           0 :         vnc_redistribute_prechange(bgp);
    1211             : 
    1212           0 :         if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi])
    1213           0 :                 free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]);
    1214           0 :         rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL;
    1215           0 :         rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL;
    1216             : 
    1217           0 :         vnc_redistribute_postchange(bgp);
    1218             : 
    1219           0 :         return CMD_SUCCESS;
    1220             : }
    1221             : 
    1222           0 : DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist,
    1223             :        vnc_nve_group_redist_bgpdirect_prefixlist_cmd,
    1224             :        "redistribute bgp-direct <ipv4|ipv6> prefix-list NAME",
    1225             :        "Redistribute from other protocol\n"
    1226             :        "Redistribute from BGP directly\n"
    1227             :        "IPv4 routes\n"
    1228             :        "IPv6 routes\n"
    1229             :        "Prefix-list for filtering redistributed routes\n"
    1230             :        "prefix list name\n")
    1231             : {
    1232           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1233           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    1234           0 :         afi_t afi;
    1235             : 
    1236           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1237             : 
    1238             :         /* make sure it's still in list */
    1239           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    1240             :                 /* Not in list anymore */
    1241           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    1242           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1243             :         }
    1244             : 
    1245           0 :         if (strmatch(argv[2]->text, "ipv4")) {
    1246             :                 afi = AFI_IP;
    1247             :         } else {
    1248           0 :                 afi = AFI_IP6;
    1249             :         }
    1250             : 
    1251           0 :         vnc_redistribute_prechange(bgp);
    1252             : 
    1253           0 :         if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi])
    1254           0 :                 free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]);
    1255           0 :         rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] =
    1256           0 :                 strdup(argv[4]->arg);
    1257           0 :         rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] =
    1258           0 :                 prefix_list_lookup(afi, argv[4]->arg);
    1259             : 
    1260           0 :         vnc_redistribute_postchange(bgp);
    1261             : 
    1262           0 :         return CMD_SUCCESS;
    1263             : }
    1264             : 
    1265           0 : DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap,
    1266             :        vnc_nve_group_redist_bgpdirect_no_routemap_cmd,
    1267             :        "no redistribute bgp-direct route-map",
    1268             :        NO_STR
    1269             :        "Redistribute from other protocols\n"
    1270             :        "Redistribute from BGP directly\n"
    1271             :        "Route-map for filtering redistributed routes\n")
    1272             : {
    1273           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1274           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    1275             : 
    1276           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1277             : 
    1278             :         /* make sure it's still in list */
    1279           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    1280             :                 /* Not in list anymore */
    1281           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    1282           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1283             :         }
    1284             : 
    1285           0 :         vnc_redistribute_prechange(bgp);
    1286             : 
    1287           0 :         if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT])
    1288           0 :                 free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
    1289           0 :         route_map_counter_decrement(
    1290             :                 rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
    1291           0 :         rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = NULL;
    1292           0 :         rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = NULL;
    1293             : 
    1294           0 :         vnc_redistribute_postchange(bgp);
    1295             : 
    1296           0 :         return CMD_SUCCESS;
    1297             : }
    1298             : 
    1299           0 : DEFUN (vnc_nve_group_redist_bgpdirect_routemap,
    1300             :        vnc_nve_group_redist_bgpdirect_routemap_cmd,
    1301             :        "redistribute bgp-direct route-map NAME",
    1302             :        "Redistribute from other protocols\n"
    1303             :        "Redistribute from BGP directly\n"
    1304             :        "Route-map for filtering exported routes\n" "route map name\n")
    1305             : {
    1306           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1307           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    1308             : 
    1309           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1310             : 
    1311             :         /* make sure it's still in list */
    1312           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    1313             :                 /* Not in list anymore */
    1314           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    1315           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1316             :         }
    1317             : 
    1318           0 :         vnc_redistribute_prechange(bgp);
    1319             : 
    1320           0 :         if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT])
    1321           0 :                 free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
    1322           0 :         route_map_counter_decrement(
    1323             :                 rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
    1324           0 :         rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] =
    1325           0 :                 strdup(argv[3]->arg);
    1326           0 :         rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] =
    1327           0 :                 route_map_lookup_by_name(argv[3]->arg);
    1328           0 :         route_map_counter_increment(
    1329             :                 rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]);
    1330             : 
    1331           0 :         vnc_redistribute_postchange(bgp);
    1332             : 
    1333           0 :         return CMD_SUCCESS;
    1334             : }
    1335             : 
    1336             : /*-- redist policy, nvegroup end --*/
    1337             : 
    1338             : /*-------------------------------------------------------------------------
    1339             :  *                      export
    1340             :  *-----------------------------------------------------------------------*/
    1341             : 
    1342           0 : DEFUN (vnc_export_mode,
    1343             :        vnc_export_mode_cmd,
    1344             :        "vnc export <bgp|zebra> mode <group-nve|ce|none|registering-nve>",
    1345             :        VNC_CONFIG_STR
    1346             :        "Export to other protocols\n"
    1347             :        "Export to BGP\n"
    1348             :        "Export to Zebra (experimental)\n"
    1349             :        "Select export mode\n"
    1350             :        "Export routes with nve-group next-hops\n"
    1351             :        "Export routes with NVE connected router next-hops\n"
    1352             :        "Disable export\n" "Export routes with registering NVE as next-hop\n")
    1353             : {
    1354           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1355           0 :         uint32_t oldmode = 0;
    1356           0 :         uint32_t newmode = 0;
    1357             : 
    1358           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1359             : 
    1360           0 :         if (argv[2]->arg[0] == 'b') {
    1361           0 :                 oldmode = bgp->rfapi_cfg->flags
    1362             :                           & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS;
    1363           0 :                 switch (argv[4]->arg[0]) {
    1364             :                 case 'g':
    1365             :                         newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP;
    1366             :                         break;
    1367           0 :                 case 'c':
    1368           0 :                         newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE;
    1369           0 :                         break;
    1370           0 :                 case 'n':
    1371           0 :                         newmode = 0;
    1372           0 :                         break;
    1373           0 :                 case 'r':
    1374           0 :                         newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH;
    1375           0 :                         break;
    1376           0 :                 default:
    1377           0 :                         vty_out(vty, "Invalid mode specified\n");
    1378           0 :                         return CMD_WARNING_CONFIG_FAILED;
    1379             :                 }
    1380             : 
    1381           0 :                 if (newmode == oldmode) {
    1382           0 :                         vty_out(vty, "Mode unchanged\n");
    1383           0 :                         return CMD_SUCCESS;
    1384             :                 }
    1385             : 
    1386           0 :                 vnc_export_bgp_prechange(bgp);
    1387             : 
    1388           0 :                 bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS;
    1389           0 :                 bgp->rfapi_cfg->flags |= newmode;
    1390             : 
    1391           0 :                 vnc_export_bgp_postchange(bgp);
    1392             : 
    1393             : 
    1394             :         } else {
    1395             :                 /*
    1396             :                  * export to zebra with RH mode is not yet implemented
    1397             :                  */
    1398           0 :                 vty_out(vty,
    1399             :                         "Changing modes for zebra export not implemented yet\n");
    1400           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1401             :         }
    1402             : 
    1403           0 :         return CMD_SUCCESS;
    1404             : }
    1405             : 
    1406           0 : static struct rfapi_rfg_name *rfgn_new(void)
    1407             : {
    1408           0 :         return XCALLOC(MTYPE_RFAPI_RFG_NAME, sizeof(struct rfapi_rfg_name));
    1409             : }
    1410             : 
    1411           0 : static void rfgn_free(struct rfapi_rfg_name *rfgn)
    1412             : {
    1413           0 :         XFREE(MTYPE_RFAPI_RFG_NAME, rfgn);
    1414           0 : }
    1415             : 
    1416           0 : DEFUN (vnc_export_nvegroup,
    1417             :        vnc_export_nvegroup_cmd,
    1418             :        "vnc export <bgp|zebra> group-nve group NAME",
    1419             :        VNC_CONFIG_STR
    1420             :        "Export to other protocols\n"
    1421             :        "Export to BGP\n"
    1422             :        "Export to Zebra (experimental)\n"
    1423             :        "NVE group, used in 'group-nve' export mode\n"
    1424             :        "NVE group\n" "Group name\n")
    1425             : {
    1426           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1427           0 :         struct rfapi_nve_group_cfg *rfg_new;
    1428             : 
    1429           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1430             : 
    1431           0 :         rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg,
    1432             :                                              RFAPI_GROUP_CFG_NVE);
    1433           0 :         if (rfg_new == NULL) {
    1434           0 :                 rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg,
    1435             :                                                      RFAPI_GROUP_CFG_VRF);
    1436           0 :                 if (rfg_new)
    1437           0 :                         vnc_add_vrf_opener(bgp, rfg_new);
    1438             :         }
    1439             : 
    1440           0 :         if (rfg_new == NULL) {
    1441           0 :                 vty_out(vty, "Can't find group named \"%s\".\n", argv[5]->arg);
    1442           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1443             :         }
    1444             : 
    1445           0 :         if (argv[2]->arg[0] == 'b') {
    1446             : 
    1447           0 :                 struct listnode *node;
    1448           0 :                 struct rfapi_rfg_name *rfgn;
    1449             : 
    1450             :                 /*
    1451             :                  * Set group for export to BGP Direct
    1452             :                  */
    1453             : 
    1454             :                 /* see if group is already included in export list */
    1455           0 :                 for (ALL_LIST_ELEMENTS_RO(
    1456             :                              bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
    1457             :                              rfgn)) {
    1458             : 
    1459           0 :                         if (!strcmp(rfgn->name, argv[5]->arg)) {
    1460             :                                 /* already in the list: we're done */
    1461             :                                 return CMD_SUCCESS;
    1462             :                         }
    1463             :                 }
    1464             : 
    1465           0 :                 rfgn = rfgn_new();
    1466           0 :                 rfgn->name = strdup(argv[5]->arg);
    1467           0 :                 rfgn->rfg = rfg_new; /* OK if not set yet */
    1468             : 
    1469           0 :                 listnode_add(bgp->rfapi_cfg->rfg_export_direct_bgp_l, rfgn);
    1470             : 
    1471           0 :                 vnc_zlog_debug_verbose("%s: testing rfg_new", __func__);
    1472           0 :                 if (rfg_new) {
    1473           0 :                         vnc_zlog_debug_verbose(
    1474             :                                 "%s: testing bgp grp mode enabled", __func__);
    1475           0 :                         if (VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg))
    1476           0 :                                 vnc_zlog_debug_verbose(
    1477             :                                         "%s: calling vnc_direct_bgp_add_group",
    1478             :                                         __func__);
    1479           0 :                         vnc_direct_bgp_add_group(bgp, rfg_new);
    1480             :                 }
    1481             : 
    1482             :         } else {
    1483             : 
    1484           0 :                 struct listnode *node;
    1485           0 :                 struct rfapi_rfg_name *rfgn;
    1486             : 
    1487             :                 /*
    1488             :                  * Set group for export to Zebra
    1489             :                  */
    1490             : 
    1491             :                 /* see if group is already included in export list */
    1492           0 :                 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l,
    1493             :                                           node, rfgn)) {
    1494             : 
    1495           0 :                         if (!strcmp(rfgn->name, argv[5]->arg)) {
    1496             :                                 /* already in the list: we're done */
    1497             :                                 return CMD_SUCCESS;
    1498             :                         }
    1499             :                 }
    1500             : 
    1501           0 :                 rfgn = rfgn_new();
    1502           0 :                 rfgn->name = strdup(argv[5]->arg);
    1503           0 :                 rfgn->rfg = rfg_new; /* OK if not set yet */
    1504             : 
    1505           0 :                 listnode_add(bgp->rfapi_cfg->rfg_export_zebra_l, rfgn);
    1506             : 
    1507           0 :                 if (rfg_new) {
    1508           0 :                         if (VNC_EXPORT_ZEBRA_GRP_ENABLED(bgp->rfapi_cfg))
    1509           0 :                                 vnc_zebra_add_group(bgp, rfg_new);
    1510             :                 }
    1511             :         }
    1512             : 
    1513             :         return CMD_SUCCESS;
    1514             : }
    1515             : 
    1516             : /*
    1517             :  * This command applies to routes exported from VNC to BGP directly
    1518             :  * without going though zebra
    1519             :  */
    1520           0 : DEFUN (vnc_no_export_nvegroup,
    1521             :        vnc_no_export_nvegroup_cmd,
    1522             :        "vnc export <bgp|zebra> group-nve no group NAME",
    1523             :        VNC_CONFIG_STR
    1524             :        "Export to other protocols\n"
    1525             :        "Export to BGP\n"
    1526             :        "Export to Zebra (experimental)\n"
    1527             :        "NVE group, used in 'group-nve' export mode\n"
    1528             :        "Disable export of VNC routes\n" "NVE group\n" "Group name\n")
    1529             : {
    1530           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1531           0 :         struct listnode *node, *nnode;
    1532           0 :         struct rfapi_rfg_name *rfgn;
    1533             : 
    1534           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1535             : 
    1536           0 :         if (argv[2]->arg[0] == 'b') {
    1537           0 :                 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l,
    1538             :                                        node, nnode, rfgn)) {
    1539             : 
    1540           0 :                         if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) {
    1541           0 :                                 vnc_zlog_debug_verbose("%s: matched \"%s\"",
    1542             :                                                        __func__, rfgn->name);
    1543           0 :                                 if (rfgn->rfg)
    1544           0 :                                         vnc_direct_bgp_del_group(bgp,
    1545             :                                                                  rfgn->rfg);
    1546           0 :                                 free(rfgn->name);
    1547           0 :                                 list_delete_node(
    1548           0 :                                         bgp->rfapi_cfg->rfg_export_direct_bgp_l,
    1549             :                                         node);
    1550           0 :                                 rfgn_free(rfgn);
    1551             :                                 break;
    1552             :                         }
    1553             :                 }
    1554             :         } else {
    1555           0 :                 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node,
    1556             :                                        nnode, rfgn)) {
    1557             : 
    1558           0 :                         vnc_zlog_debug_verbose("does rfg \"%s\" match?",
    1559             :                                                rfgn->name);
    1560           0 :                         if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) {
    1561           0 :                                 if (rfgn->rfg)
    1562           0 :                                         vnc_zebra_del_group(bgp, rfgn->rfg);
    1563           0 :                                 free(rfgn->name);
    1564           0 :                                 list_delete_node(
    1565           0 :                                         bgp->rfapi_cfg->rfg_export_zebra_l,
    1566             :                                         node);
    1567           0 :                                 rfgn_free(rfgn);
    1568             :                                 break;
    1569             :                         }
    1570             :                 }
    1571             :         }
    1572             :         return CMD_SUCCESS;
    1573             : }
    1574             : 
    1575           0 : DEFUN (vnc_nve_group_export_no_prefixlist,
    1576             :        vnc_nve_group_export_no_prefixlist_cmd,
    1577             :        "no export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
    1578             :        NO_STR
    1579             :        "Export to other protocols\n"
    1580             :        "Export to BGP\n"
    1581             :        "Export to Zebra (experimental)\n"
    1582             :        "IPv4 routes\n"
    1583             :        "IPv6 routes\n"
    1584             :        "Prefix-list for filtering exported routes\n" "prefix list name\n")
    1585             : {
    1586           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1587           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    1588           0 :         int idx = 0;
    1589           0 :         int is_bgp = 1;
    1590           0 :         afi_t afi;
    1591             : 
    1592           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1593             : 
    1594             :         /* make sure it's still in list */
    1595           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    1596             :                 /* Not in list anymore */
    1597           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    1598           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1599             :         }
    1600             : 
    1601           0 :         if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
    1602           0 :                 vty_out(vty, "%% Malformed Address Family\n");
    1603           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1604             :         }
    1605             : 
    1606           0 :         if (argv[idx - 1]->text[0] == 'z')
    1607           0 :                 is_bgp = 0;
    1608           0 :         idx += 2; /* skip afi and keyword */
    1609             : 
    1610           0 :         if (is_bgp) {
    1611           0 :                 if (idx == argc
    1612           0 :                     || (rfg->plist_export_bgp_name[afi]
    1613           0 :                         && strmatch(argv[idx]->arg,
    1614             :                                     rfg->plist_export_bgp_name[afi]))) {
    1615           0 :                         if (rfg->plist_export_bgp_name[afi])
    1616           0 :                                 free(rfg->plist_export_bgp_name[afi]);
    1617           0 :                         rfg->plist_export_bgp_name[afi] = NULL;
    1618           0 :                         rfg->plist_export_bgp[afi] = NULL;
    1619             : 
    1620           0 :                         vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
    1621             :                 }
    1622             :         } else {
    1623           0 :                 if (idx == argc
    1624           0 :                     || (rfg->plist_export_zebra_name[afi]
    1625           0 :                         && strmatch(argv[idx]->arg,
    1626             :                                     rfg->plist_export_zebra_name[afi]))) {
    1627           0 :                         if (rfg->plist_export_zebra_name[afi])
    1628           0 :                                 free(rfg->plist_export_zebra_name[afi]);
    1629           0 :                         rfg->plist_export_zebra_name[afi] = NULL;
    1630           0 :                         rfg->plist_export_zebra[afi] = NULL;
    1631             : 
    1632           0 :                         vnc_zebra_reexport_group_afi(bgp, rfg, afi);
    1633             :                 }
    1634             :         }
    1635             :         return CMD_SUCCESS;
    1636             : }
    1637             : 
    1638             : ALIAS (vnc_nve_group_export_no_prefixlist,
    1639             :        vnc_vrf_policy_export_no_prefixlist_cmd,
    1640             :        "no export <ipv4|ipv6> prefix-list [NAME]",
    1641             :        NO_STR
    1642             :        "Export to VRF\n"
    1643             :        "IPv4 routes\n"
    1644             :        "IPv6 routes\n"
    1645             :        "Prefix-list for filtering exported routes\n" "prefix list name\n")
    1646             : 
    1647           0 : DEFUN (vnc_nve_group_export_prefixlist,
    1648             :        vnc_nve_group_export_prefixlist_cmd,
    1649             :        "export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
    1650             :        "Export to other protocols\n"
    1651             :        "Export to BGP\n"
    1652             :        "Export to Zebra (experimental)\n"
    1653             :        "IPv4 routes\n"
    1654             :        "IPv6 routes\n"
    1655             :        "Prefix-list for filtering exported routes\n" "prefix list name\n")
    1656             : {
    1657           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1658           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    1659           0 :         int idx = 0;
    1660           0 :         int is_bgp = 1;
    1661           0 :         afi_t afi;
    1662             : 
    1663           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1664             : 
    1665             :         /* make sure it's still in list */
    1666           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    1667             :                 /* Not in list anymore */
    1668           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    1669           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1670             :         }
    1671             : 
    1672           0 :         if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
    1673           0 :                 vty_out(vty, "%% Malformed Address Family\n");
    1674           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1675             :         }
    1676             : 
    1677           0 :         if (argv[idx - 1]->text[0] == 'z')
    1678           0 :                 is_bgp = 0;
    1679           0 :         idx = argc - 1;
    1680             : 
    1681           0 :         if (is_bgp) {
    1682           0 :                 if (rfg->plist_export_bgp_name[afi])
    1683           0 :                         free(rfg->plist_export_bgp_name[afi]);
    1684           0 :                 rfg->plist_export_bgp_name[afi] = strdup(argv[idx]->arg);
    1685           0 :                 rfg->plist_export_bgp[afi] =
    1686           0 :                         prefix_list_lookup(afi, argv[idx]->arg);
    1687             : 
    1688           0 :                 vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
    1689             : 
    1690             :         } else {
    1691           0 :                 if (rfg->plist_export_zebra_name[afi])
    1692           0 :                         free(rfg->plist_export_zebra_name[afi]);
    1693           0 :                 rfg->plist_export_zebra_name[afi] = strdup(argv[idx]->arg);
    1694           0 :                 rfg->plist_export_zebra[afi] =
    1695           0 :                         prefix_list_lookup(afi, argv[idx]->arg);
    1696             : 
    1697           0 :                 vnc_zebra_reexport_group_afi(bgp, rfg, afi);
    1698             :         }
    1699             :         return CMD_SUCCESS;
    1700             : }
    1701             : 
    1702             : ALIAS (vnc_nve_group_export_prefixlist,
    1703             :        vnc_vrf_policy_export_prefixlist_cmd,
    1704             :        "export <ipv4|ipv6> prefix-list NAME",
    1705             :        "Export to VRF\n"
    1706             :        "IPv4 routes\n"
    1707             :        "IPv6 routes\n"
    1708             :        "Prefix-list for filtering exported routes\n" "prefix list name\n")
    1709             : 
    1710           0 : DEFUN (vnc_nve_group_export_no_routemap,
    1711             :        vnc_nve_group_export_no_routemap_cmd,
    1712             :        "no export <bgp|zebra> route-map [NAME]",
    1713             :        NO_STR
    1714             :        "Export to other protocols\n"
    1715             :        "Export to BGP\n"
    1716             :        "Export to Zebra (experimental)\n"
    1717             :        "Route-map for filtering exported routes\n" "route map name\n")
    1718             : {
    1719           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1720           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    1721           0 :         int idx = 2;
    1722           0 :         int is_bgp = 1;
    1723             : 
    1724           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1725             : 
    1726             :         /* make sure it's still in list */
    1727           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    1728             :                 /* Not in list anymore */
    1729           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    1730           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1731             :         }
    1732           0 :         switch (argv[idx]->text[0]) {
    1733             :         case 'z':
    1734           0 :                 is_bgp = 0;
    1735             :         /* fall thru */
    1736             :         case 'b':
    1737           0 :                 idx += 2;
    1738           0 :                 break;
    1739             :         default: /* route-map */
    1740             :                 idx++;
    1741             :                 break;
    1742             :         }
    1743             : 
    1744           0 :         if (is_bgp) {
    1745           0 :                 if (idx == argc
    1746           0 :                     || (rfg->routemap_export_bgp_name
    1747           0 :                         && strmatch(argv[idx]->arg,
    1748             :                                     rfg->routemap_export_bgp_name))) {
    1749           0 :                         if (rfg->routemap_export_bgp_name)
    1750           0 :                                 free(rfg->routemap_export_bgp_name);
    1751           0 :                         route_map_counter_decrement(rfg->routemap_export_bgp);
    1752           0 :                         rfg->routemap_export_bgp_name = NULL;
    1753           0 :                         rfg->routemap_export_bgp = NULL;
    1754             : 
    1755           0 :                         vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
    1756           0 :                         vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
    1757             :                 }
    1758             :         } else {
    1759           0 :                 if (idx == argc
    1760           0 :                     || (rfg->routemap_export_zebra_name
    1761           0 :                         && strmatch(argv[idx]->arg,
    1762             :                                     rfg->routemap_export_zebra_name))) {
    1763           0 :                         if (rfg->routemap_export_zebra_name)
    1764           0 :                                 free(rfg->routemap_export_zebra_name);
    1765           0 :                         route_map_counter_decrement(rfg->routemap_export_zebra);
    1766           0 :                         rfg->routemap_export_zebra_name = NULL;
    1767           0 :                         rfg->routemap_export_zebra = NULL;
    1768             : 
    1769           0 :                         vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP);
    1770           0 :                         vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6);
    1771             :                 }
    1772             :         }
    1773             :         return CMD_SUCCESS;
    1774             : }
    1775             : 
    1776             : ALIAS (vnc_nve_group_export_no_routemap,
    1777             :        vnc_vrf_policy_export_no_routemap_cmd,
    1778             :        "no export route-map [NAME]",
    1779             :        NO_STR
    1780             :        "Export to VRF\n"
    1781             :        "Route-map for filtering exported routes\n" "route map name\n")
    1782             : 
    1783           0 : DEFUN (vnc_nve_group_export_routemap,
    1784             :        vnc_nve_group_export_routemap_cmd,
    1785             :        "export <bgp|zebra> route-map NAME",
    1786             :        "Export to other protocols\n"
    1787             :        "Export to BGP\n"
    1788             :        "Export to Zebra (experimental)\n"
    1789             :        "Route-map for filtering exported routes\n" "route map name\n")
    1790             : {
    1791           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1792           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    1793           0 :         int idx = 0;
    1794           0 :         int is_bgp = 1;
    1795             : 
    1796           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1797             : 
    1798             :         /* make sure it's still in list */
    1799           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    1800             :                 /* Not in list anymore */
    1801           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    1802           0 :                 return CMD_WARNING_CONFIG_FAILED;
    1803             :         }
    1804             : 
    1805           0 :         if (argv[1]->text[0] == 'z')
    1806           0 :                 is_bgp = 0;
    1807           0 :         idx = argc - 1;
    1808             : 
    1809           0 :         if (is_bgp) {
    1810           0 :                 if (rfg->routemap_export_bgp_name)
    1811           0 :                         free(rfg->routemap_export_bgp_name);
    1812           0 :                 route_map_counter_decrement(rfg->routemap_export_bgp);
    1813           0 :                 rfg->routemap_export_bgp_name = strdup(argv[idx]->arg);
    1814           0 :                 rfg->routemap_export_bgp =
    1815           0 :                         route_map_lookup_by_name(argv[idx]->arg);
    1816           0 :                 route_map_counter_increment(rfg->routemap_export_bgp);
    1817           0 :                 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
    1818           0 :                 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
    1819             :         } else {
    1820           0 :                 if (rfg->routemap_export_zebra_name)
    1821           0 :                         free(rfg->routemap_export_zebra_name);
    1822           0 :                 route_map_counter_decrement(rfg->routemap_export_zebra);
    1823           0 :                 rfg->routemap_export_zebra_name = strdup(argv[idx]->arg);
    1824           0 :                 rfg->routemap_export_zebra =
    1825           0 :                         route_map_lookup_by_name(argv[idx]->arg);
    1826           0 :                 route_map_counter_increment(rfg->routemap_export_zebra);
    1827           0 :                 vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP);
    1828           0 :                 vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6);
    1829             :         }
    1830             :         return CMD_SUCCESS;
    1831             : }
    1832             : 
    1833             : ALIAS (vnc_nve_group_export_routemap,
    1834             :        vnc_vrf_policy_export_routemap_cmd,
    1835             :        "export route-map NAME",
    1836             :        "Export to VRF\n"
    1837             :        "Route-map for filtering exported routes\n" "route map name\n")
    1838             : 
    1839           0 : DEFUN (vnc_nve_export_no_prefixlist,
    1840             :        vnc_nve_export_no_prefixlist_cmd,
    1841             :        "no vnc export <bgp|zebra> <ipv4|ipv6> prefix-list [NAME]",
    1842             :        NO_STR
    1843             :        VNC_CONFIG_STR
    1844             :        "Export to other protocols\n"
    1845             :        "Export to BGP\n"
    1846             :        "Export to Zebra (experimental)\n"
    1847             :        "IPv4 prefixes\n"
    1848             :        "IPv6 prefixes\n"
    1849             :        "Prefix-list for filtering exported routes\n" "Prefix list name\n")
    1850             : {
    1851           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1852           0 :         struct rfapi_cfg *hc;
    1853           0 :         afi_t afi;
    1854             : 
    1855           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1856           0 :         hc = bgp->rfapi_cfg;
    1857             : 
    1858           0 :         if (strmatch(argv[4]->text, "ipv4")) {
    1859             :                 afi = AFI_IP;
    1860             :         } else {
    1861           0 :                 afi = AFI_IP6;
    1862             :         }
    1863             : 
    1864           0 :         if (argv[3]->arg[0] == 'b') {
    1865           0 :                 if (((argc > 6) && hc->plist_export_bgp_name[afi]
    1866           0 :                      && strmatch(argv[6]->text, hc->plist_export_bgp_name[afi]))
    1867             :                     || (argc <= 6)) {
    1868             : 
    1869           0 :                         free(hc->plist_export_bgp_name[afi]);
    1870           0 :                         hc->plist_export_bgp_name[afi] = NULL;
    1871           0 :                         hc->plist_export_bgp[afi] = NULL;
    1872           0 :                         vnc_direct_bgp_reexport(bgp, afi);
    1873             :                 }
    1874             :         } else {
    1875           0 :                 if (((argc > 6) && hc->plist_export_zebra_name[afi]
    1876           0 :                      && strmatch(argv[6]->text,
    1877             :                                  hc->plist_export_zebra_name[afi]))
    1878             :                     || (argc <= 6)) {
    1879             : 
    1880           0 :                         free(hc->plist_export_zebra_name[afi]);
    1881           0 :                         hc->plist_export_zebra_name[afi] = NULL;
    1882           0 :                         hc->plist_export_zebra[afi] = NULL;
    1883             :                         /* TBD vnc_zebra_rh_reexport(bgp, afi); */
    1884             :                 }
    1885             :         }
    1886             :         return CMD_SUCCESS;
    1887             : }
    1888             : 
    1889           0 : DEFUN (vnc_nve_export_prefixlist,
    1890             :        vnc_nve_export_prefixlist_cmd,
    1891             :        "vnc export <bgp|zebra> <ipv4|ipv6> prefix-list NAME",
    1892             :        VNC_CONFIG_STR
    1893             :        "Export to other protocols\n"
    1894             :        "Export to BGP\n"
    1895             :        "Export to Zebra (experimental)\n"
    1896             :        "IPv4 prefixes\n"
    1897             :        "IPv6 prefixes\n"
    1898             :        "Prefix-list for filtering exported routes\n" "Prefix list name\n")
    1899             : {
    1900           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1901           0 :         struct rfapi_cfg *hc;
    1902           0 :         afi_t afi;
    1903             : 
    1904           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1905           0 :         hc = bgp->rfapi_cfg;
    1906             : 
    1907           0 :         if (strmatch(argv[3]->text, "ipv4")) {
    1908             :                 afi = AFI_IP;
    1909             :         } else {
    1910           0 :                 afi = AFI_IP6;
    1911             :         }
    1912             : 
    1913           0 :         if (argv[2]->arg[0] == 'b') {
    1914           0 :                 if (hc->plist_export_bgp_name[afi])
    1915           0 :                         free(hc->plist_export_bgp_name[afi]);
    1916           0 :                 hc->plist_export_bgp_name[afi] = strdup(argv[5]->arg);
    1917           0 :                 hc->plist_export_bgp[afi] =
    1918           0 :                         prefix_list_lookup(afi, argv[5]->arg);
    1919           0 :                 vnc_direct_bgp_reexport(bgp, afi);
    1920             :         } else {
    1921           0 :                 if (hc->plist_export_zebra_name[afi])
    1922           0 :                         free(hc->plist_export_zebra_name[afi]);
    1923           0 :                 hc->plist_export_zebra_name[afi] = strdup(argv[5]->arg);
    1924           0 :                 hc->plist_export_zebra[afi] =
    1925           0 :                         prefix_list_lookup(afi, argv[5]->arg);
    1926             :                 /* TBD vnc_zebra_rh_reexport(bgp, afi); */
    1927             :         }
    1928             :         return CMD_SUCCESS;
    1929             : }
    1930             : 
    1931           0 : DEFUN (vnc_nve_export_no_routemap,
    1932             :        vnc_nve_export_no_routemap_cmd,
    1933             :        "no vnc export <bgp|zebra> route-map [NAME]",
    1934             :        NO_STR
    1935             :        VNC_CONFIG_STR
    1936             :        "Export to other protocols\n"
    1937             :        "Export to BGP\n"
    1938             :        "Export to Zebra (experimental)\n"
    1939             :        "Route-map for filtering exported routes\n" "Route map name\n")
    1940             : {
    1941           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1942           0 :         struct rfapi_cfg *hc;
    1943             : 
    1944           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1945           0 :         hc = bgp->rfapi_cfg;
    1946             : 
    1947           0 :         if (argv[3]->arg[0] == 'b') {
    1948           0 :                 if (((argc > 5) && hc->routemap_export_bgp_name
    1949           0 :                      && strmatch(argv[5]->text, hc->routemap_export_bgp_name))
    1950             :                     || (argc <= 5)) {
    1951             : 
    1952           0 :                         free(hc->routemap_export_bgp_name);
    1953           0 :                         route_map_counter_decrement(hc->routemap_export_bgp);
    1954           0 :                         hc->routemap_export_bgp_name = NULL;
    1955           0 :                         hc->routemap_export_bgp = NULL;
    1956           0 :                         vnc_direct_bgp_reexport(bgp, AFI_IP);
    1957           0 :                         vnc_direct_bgp_reexport(bgp, AFI_IP6);
    1958             :                 }
    1959             :         } else {
    1960           0 :                 if (((argc > 5) && hc->routemap_export_zebra_name
    1961           0 :                      && strmatch(argv[5]->text, hc->routemap_export_zebra_name))
    1962             :                     || (argc <= 5)) {
    1963             : 
    1964           0 :                         free(hc->routemap_export_zebra_name);
    1965           0 :                         route_map_counter_decrement(hc->routemap_export_zebra);
    1966           0 :                         hc->routemap_export_zebra_name = NULL;
    1967           0 :                         hc->routemap_export_zebra = NULL;
    1968             :                         /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
    1969             :                         /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
    1970             :                 }
    1971             :         }
    1972             :         return CMD_SUCCESS;
    1973             : }
    1974             : 
    1975           0 : DEFUN (vnc_nve_export_routemap,
    1976             :        vnc_nve_export_routemap_cmd,
    1977             :        "vnc export <bgp|zebra> route-map NAME",
    1978             :        VNC_CONFIG_STR
    1979             :        "Export to other protocols\n"
    1980             :        "Export to BGP\n"
    1981             :        "Export to Zebra (experimental)\n"
    1982             :        "Route-map for filtering exported routes\n" "Route map name\n")
    1983             : {
    1984           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    1985           0 :         struct rfapi_cfg *hc;
    1986             : 
    1987           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    1988           0 :         hc = bgp->rfapi_cfg;
    1989             : 
    1990           0 :         if (argv[2]->arg[0] == 'b') {
    1991           0 :                 if (hc->routemap_export_bgp_name)
    1992           0 :                         free(hc->routemap_export_bgp_name);
    1993           0 :                 route_map_counter_decrement(hc->routemap_export_bgp);
    1994           0 :                 hc->routemap_export_bgp_name = strdup(argv[4]->arg);
    1995           0 :                 hc->routemap_export_bgp =
    1996           0 :                         route_map_lookup_by_name(argv[4]->arg);
    1997           0 :                 route_map_counter_increment(hc->routemap_export_bgp);
    1998           0 :                 vnc_direct_bgp_reexport(bgp, AFI_IP);
    1999           0 :                 vnc_direct_bgp_reexport(bgp, AFI_IP6);
    2000             :         } else {
    2001           0 :                 if (hc->routemap_export_zebra_name)
    2002           0 :                         free(hc->routemap_export_zebra_name);
    2003           0 :                 route_map_counter_decrement(hc->routemap_export_zebra);
    2004           0 :                 hc->routemap_export_zebra_name = strdup(argv[4]->arg);
    2005           0 :                 hc->routemap_export_zebra =
    2006           0 :                         route_map_lookup_by_name(argv[4]->arg);
    2007           0 :                 route_map_counter_increment(hc->routemap_export_zebra);
    2008             :                 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
    2009             :                 /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
    2010             :         }
    2011             :         return CMD_SUCCESS;
    2012             : }
    2013             : 
    2014             : 
    2015             : /*
    2016             :  * respond to changes in the global prefix list configuration
    2017             :  */
    2018           0 : void vnc_prefix_list_update(struct bgp *bgp)
    2019             : {
    2020           0 :         afi_t afi;
    2021           0 :         struct listnode *n;
    2022           0 :         struct rfapi_nve_group_cfg *rfg;
    2023           0 :         struct rfapi_cfg *hc;
    2024           0 :         int i;
    2025             : 
    2026           0 :         if (!bgp) {
    2027           0 :                 vnc_zlog_debug_verbose("%s: No BGP process is configured",
    2028             :                                        __func__);
    2029           0 :                 return;
    2030             :         }
    2031             : 
    2032           0 :         if (!(hc = bgp->rfapi_cfg)) {
    2033           0 :                 vnc_zlog_debug_verbose("%s: rfapi not configured", __func__);
    2034           0 :                 return;
    2035             :         }
    2036             : 
    2037           0 :         for (afi = AFI_IP; afi < AFI_MAX; afi++) {
    2038             :                 /*
    2039             :                  * Loop over nve groups
    2040             :                  */
    2041           0 :                 for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential,
    2042             :                                           n, rfg)) {
    2043             : 
    2044           0 :                         if (rfg->plist_export_bgp_name[afi]) {
    2045           0 :                                 rfg->plist_export_bgp[afi] = prefix_list_lookup(
    2046             :                                         afi, rfg->plist_export_bgp_name[afi]);
    2047             :                         }
    2048           0 :                         if (rfg->plist_export_zebra_name[afi]) {
    2049           0 :                                 rfg->plist_export_zebra
    2050           0 :                                         [afi] = prefix_list_lookup(
    2051             :                                         afi, rfg->plist_export_zebra_name[afi]);
    2052             :                         }
    2053           0 :                         for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
    2054           0 :                                 if (rfg->plist_redist_name[i][afi]) {
    2055           0 :                                         rfg->plist_redist
    2056           0 :                                                 [i][afi] = prefix_list_lookup(
    2057             :                                                 afi,
    2058             :                                                 rfg->plist_redist_name[i][afi]);
    2059             :                                 }
    2060             :                         }
    2061             : 
    2062           0 :                         vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
    2063             :                         /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */
    2064             :                 }
    2065             : 
    2066             :                 /*
    2067             :                  * RH config, too
    2068             :                  */
    2069           0 :                 if (hc->plist_export_bgp_name[afi]) {
    2070           0 :                         hc->plist_export_bgp[afi] = prefix_list_lookup(
    2071             :                                 afi, hc->plist_export_bgp_name[afi]);
    2072             :                 }
    2073           0 :                 if (hc->plist_export_zebra_name[afi]) {
    2074           0 :                         hc->plist_export_zebra[afi] = prefix_list_lookup(
    2075             :                                 afi, hc->plist_export_zebra_name[afi]);
    2076             :                 }
    2077             : 
    2078           0 :                 for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
    2079           0 :                         if (hc->plist_redist_name[i][afi]) {
    2080           0 :                                 hc->plist_redist[i][afi] = prefix_list_lookup(
    2081             :                                         afi, hc->plist_redist_name[i][afi]);
    2082             :                         }
    2083             :                 }
    2084             :         }
    2085             : 
    2086           0 :         vnc_direct_bgp_reexport(bgp, AFI_IP);
    2087           0 :         vnc_direct_bgp_reexport(bgp, AFI_IP6);
    2088             : 
    2089             :         /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
    2090             :         /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
    2091             : 
    2092           0 :         vnc_redistribute_prechange(bgp);
    2093           0 :         vnc_redistribute_postchange(bgp);
    2094             : }
    2095             : 
    2096             : /*
    2097             :  * respond to changes in the global route map configuration
    2098             :  */
    2099           0 : void vnc_routemap_update(struct bgp *bgp, const char *unused)
    2100             : {
    2101           0 :         struct listnode *n;
    2102           0 :         struct rfapi_nve_group_cfg *rfg;
    2103           0 :         struct rfapi_cfg *hc;
    2104           0 :         int i;
    2105           0 :         struct route_map *old = NULL;
    2106             : 
    2107           0 :         vnc_zlog_debug_verbose("%s(arg=%s)", __func__, unused);
    2108             : 
    2109           0 :         if (!bgp) {
    2110           0 :                 vnc_zlog_debug_verbose("%s: No BGP process is configured",
    2111             :                                        __func__);
    2112           0 :                 return;
    2113             :         }
    2114             : 
    2115           0 :         if (!(hc = bgp->rfapi_cfg)) {
    2116           0 :                 vnc_zlog_debug_verbose("%s: rfapi not configured", __func__);
    2117           0 :                 return;
    2118             :         }
    2119             : 
    2120             :         /*
    2121             :          * Loop over nve groups
    2122             :          */
    2123           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, n,
    2124             :                                   rfg)) {
    2125             : 
    2126           0 :                 if (rfg->routemap_export_bgp_name) {
    2127           0 :                         old = rfg->routemap_export_bgp;
    2128           0 :                         rfg->routemap_export_bgp = route_map_lookup_by_name(
    2129             :                                 rfg->routemap_export_bgp_name);
    2130             :                         /* old is NULL. i.e Route map creation event.
    2131             :                          * So update applied_counter.
    2132             :                          * If Old is not NULL, i.e It may be routemap
    2133             :                          * updation or deletion.
    2134             :                          * So no need to update the counter.
    2135             :                          */
    2136           0 :                         if (!old)
    2137           0 :                                 route_map_counter_increment(
    2138             :                                         rfg->routemap_export_bgp);
    2139             :                 }
    2140           0 :                 if (rfg->routemap_export_zebra_name) {
    2141           0 :                         old = rfg->routemap_export_bgp;
    2142           0 :                         rfg->routemap_export_bgp = route_map_lookup_by_name(
    2143             :                                 rfg->routemap_export_zebra_name);
    2144           0 :                         if (!old)
    2145           0 :                                 route_map_counter_increment(
    2146             :                                         rfg->routemap_export_bgp);
    2147             :                 }
    2148           0 :                 for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
    2149           0 :                         if (rfg->routemap_redist_name[i]) {
    2150           0 :                                 old = rfg->routemap_redist[i];
    2151           0 :                                 rfg->routemap_redist[i] =
    2152           0 :                                         route_map_lookup_by_name(
    2153             :                                                 rfg->routemap_redist_name[i]);
    2154           0 :                                 if (!old)
    2155           0 :                                         route_map_counter_increment(
    2156             :                                                 rfg->routemap_redist[i]);
    2157             :                         }
    2158             :                 }
    2159             : 
    2160           0 :                 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP);
    2161           0 :                 vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
    2162             :                 /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */
    2163             :         }
    2164             : 
    2165             :         /*
    2166             :          * RH config, too
    2167             :          */
    2168           0 :         if (hc->routemap_export_bgp_name) {
    2169           0 :                 old = hc->routemap_export_bgp;
    2170           0 :                 hc->routemap_export_bgp =
    2171           0 :                         route_map_lookup_by_name(hc->routemap_export_bgp_name);
    2172           0 :                 if (!old)
    2173           0 :                         route_map_counter_increment(hc->routemap_export_bgp);
    2174             :         }
    2175           0 :         if (hc->routemap_export_zebra_name) {
    2176           0 :                 old  = hc->routemap_export_bgp;
    2177           0 :                 hc->routemap_export_bgp = route_map_lookup_by_name(
    2178             :                         hc->routemap_export_zebra_name);
    2179           0 :                 if (!old)
    2180           0 :                         route_map_counter_increment(hc->routemap_export_bgp);
    2181             :         }
    2182           0 :         for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) {
    2183           0 :                 if (hc->routemap_redist_name[i]) {
    2184           0 :                         old = hc->routemap_redist[i];
    2185           0 :                         hc->routemap_redist[i] = route_map_lookup_by_name(
    2186             :                                 hc->routemap_redist_name[i]);
    2187           0 :                         if (!old)
    2188           0 :                                 route_map_counter_increment(
    2189             :                                         hc->routemap_redist[i]);
    2190             :                 }
    2191             :         }
    2192             : 
    2193           0 :         vnc_direct_bgp_reexport(bgp, AFI_IP);
    2194           0 :         vnc_direct_bgp_reexport(bgp, AFI_IP6);
    2195             : 
    2196             :         /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */
    2197             :         /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */
    2198             : 
    2199           0 :         vnc_redistribute_prechange(bgp);
    2200           0 :         vnc_redistribute_postchange(bgp);
    2201             : 
    2202           0 :         vnc_zlog_debug_verbose("%s done", __func__);
    2203             : }
    2204             : 
    2205             : /*-------------------------------------------------------------------------
    2206             :  *                      nve-group
    2207             :  *-----------------------------------------------------------------------*/
    2208             : 
    2209             : 
    2210           0 : DEFUN_NOSH (vnc_nve_group,
    2211             :        vnc_nve_group_cmd,
    2212             :        "vnc nve-group NAME",
    2213             :        VNC_CONFIG_STR "Configure a NVE group\n" "Group name\n")
    2214             : {
    2215           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2216           0 :         struct rfapi_nve_group_cfg *rfg;
    2217           0 :         struct listnode *node, *nnode;
    2218           0 :         struct rfapi_rfg_name *rfgn;
    2219             : 
    2220           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    2221             : 
    2222             :         /* Search for name */
    2223           0 :         rfg = bgp_rfapi_cfg_match_byname(bgp, argv[2]->arg,
    2224             :                                          RFAPI_GROUP_CFG_NVE);
    2225             : 
    2226           0 :         if (!rfg) {
    2227           0 :                 rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_NVE, argv[2]->arg);
    2228           0 :                 if (!rfg) {
    2229             :                         /* Error out of memory */
    2230           0 :                         vty_out(vty, "Can't allocate memory for NVE group\n");
    2231           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2232             :                 }
    2233             : 
    2234             :                 /* Copy defaults from struct rfapi_cfg */
    2235           0 :                 rfg->rd = bgp->rfapi_cfg->default_rd;
    2236           0 :                 if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_L2RD) {
    2237           0 :                         rfg->l2rd = bgp->rfapi_cfg->default_l2rd;
    2238           0 :                         rfg->flags |= RFAPI_RFG_L2RD;
    2239             :                 }
    2240           0 :                 rfg->rd = bgp->rfapi_cfg->default_rd;
    2241           0 :                 rfg->response_lifetime =
    2242           0 :                         bgp->rfapi_cfg->default_response_lifetime;
    2243             : 
    2244           0 :                 if (bgp->rfapi_cfg->default_rt_export_list) {
    2245           0 :                         rfg->rt_export_list = ecommunity_dup(
    2246             :                                 bgp->rfapi_cfg->default_rt_export_list);
    2247             :                 }
    2248             : 
    2249           0 :                 if (bgp->rfapi_cfg->default_rt_import_list) {
    2250           0 :                         rfg->rt_import_list = ecommunity_dup(
    2251             :                                 bgp->rfapi_cfg->default_rt_import_list);
    2252           0 :                         rfg->rfapi_import_table = rfapiImportTableRefAdd(
    2253             :                                 bgp, rfg->rt_import_list, rfg);
    2254             :                 }
    2255             : 
    2256             :                 /*
    2257             :                  * If a redist nve group was named but the group was not
    2258             :                  * defined,
    2259             :                  * make the linkage now
    2260             :                  */
    2261           0 :                 if (!bgp->rfapi_cfg->rfg_redist) {
    2262           0 :                         if (bgp->rfapi_cfg->rfg_redist_name
    2263           0 :                             && !strcmp(bgp->rfapi_cfg->rfg_redist_name,
    2264           0 :                                        rfg->name)) {
    2265             : 
    2266           0 :                                 vnc_redistribute_prechange(bgp);
    2267           0 :                                 bgp->rfapi_cfg->rfg_redist = rfg;
    2268           0 :                                 vnc_redistribute_postchange(bgp);
    2269             :                         }
    2270             :                 }
    2271             : 
    2272             :                 /*
    2273             :                  * Same treatment for bgp-direct export group
    2274             :                  */
    2275           0 :                 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l,
    2276             :                                        node, nnode, rfgn)) {
    2277             : 
    2278           0 :                         if (!strcmp(rfgn->name, rfg->name)) {
    2279           0 :                                 rfgn->rfg = rfg;
    2280           0 :                                 vnc_direct_bgp_add_group(bgp, rfg);
    2281           0 :                                 break;
    2282             :                         }
    2283             :                 }
    2284             : 
    2285             :                 /*
    2286             :                  * Same treatment for zebra export group
    2287             :                  */
    2288           0 :                 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node,
    2289             :                                        nnode, rfgn)) {
    2290             : 
    2291           0 :                         vnc_zlog_debug_verbose(
    2292             :                                 "%s: ezport zebra: checking if \"%s\" == \"%s\"",
    2293             :                                 __func__, rfgn->name, rfg->name);
    2294           0 :                         if (!strcmp(rfgn->name, rfg->name)) {
    2295           0 :                                 rfgn->rfg = rfg;
    2296           0 :                                 vnc_zebra_add_group(bgp, rfg);
    2297           0 :                                 break;
    2298             :                         }
    2299             :                 }
    2300             :         }
    2301             : 
    2302             :         /*
    2303             :          * XXX subsequent calls will need to make sure this item is still
    2304             :          * in the linked list and has the same name
    2305             :          */
    2306           0 :         VTY_PUSH_CONTEXT_SUB(BGP_VNC_NVE_GROUP_NODE, rfg);
    2307             : 
    2308           0 :         return CMD_SUCCESS;
    2309             : }
    2310             : 
    2311           0 : static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */
    2312             :                                        struct bgp *bgp,
    2313             :                                        struct rfapi_nve_group_cfg *rfg)
    2314             : {
    2315           0 :         struct list *orphaned_nves = NULL;
    2316           0 :         struct listnode *node, *nnode;
    2317             : 
    2318             :         /*
    2319             :          * If there are currently-open NVEs that belong to this group,
    2320             :          * zero out their references to this group structure.
    2321             :          */
    2322           0 :         if (rfg->nves) {
    2323           0 :                 struct rfapi_descriptor *rfd;
    2324           0 :                 orphaned_nves = list_new();
    2325           0 :                 while ((rfd = listnode_head(rfg->nves))) {
    2326           0 :                         rfd->rfg = NULL;
    2327           0 :                         listnode_delete(rfg->nves, rfd);
    2328           0 :                         listnode_add(orphaned_nves, rfd);
    2329             :                 }
    2330           0 :                 list_delete(&rfg->nves);
    2331             :         }
    2332             : 
    2333             :         /* delete it */
    2334           0 :         free(rfg->name);
    2335           0 :         if (rfg->rfapi_import_table)
    2336           0 :                 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
    2337           0 :         if (rfg->rt_import_list)
    2338           0 :                 ecommunity_free(&rfg->rt_import_list);
    2339           0 :         if (rfg->rt_export_list)
    2340           0 :                 ecommunity_free(&rfg->rt_export_list);
    2341             : 
    2342           0 :         if (rfg->vn_node) {
    2343           0 :                 rfg->vn_node->info = NULL;
    2344           0 :                 agg_unlock_node(rfg->vn_node); /* frees */
    2345             :         }
    2346           0 :         if (rfg->un_node) {
    2347           0 :                 rfg->un_node->info = NULL;
    2348           0 :                 agg_unlock_node(rfg->un_node); /* frees */
    2349             :         }
    2350           0 :         if (rfg->rfp_cfg)
    2351           0 :                 XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
    2352           0 :         listnode_delete(bgp->rfapi_cfg->nve_groups_sequential, rfg);
    2353             : 
    2354           0 :         QOBJ_UNREG(rfg);
    2355           0 :         XFREE(MTYPE_RFAPI_GROUP_CFG, rfg);
    2356             : 
    2357             :         /*
    2358             :          * Attempt to reassign the orphaned nves to a new group. If
    2359             :          * a NVE can not be reassigned, its rfd->rfg will remain NULL
    2360             :          * and it will become a zombie until released by rfapi_close().
    2361             :          */
    2362           0 :         if (orphaned_nves) {
    2363           0 :                 struct rfapi_descriptor *rfd;
    2364             : 
    2365           0 :                 for (ALL_LIST_ELEMENTS(orphaned_nves, node, nnode, rfd)) {
    2366             :                         /*
    2367             :                          * 1. rfapi_close() equivalent except:
    2368             :                          *          a. don't free original descriptor
    2369             :                          *          b. remember query list
    2370             :                          *          c. remember advertised route list
    2371             :                          * 2. rfapi_open() equivalent except:
    2372             :                          *          a. reuse original descriptor
    2373             :                          * 3. rfapi_register() on remembered advertised route
    2374             :                          * list
    2375             :                          * 4. rfapi_query on rememebred query list
    2376             :                          */
    2377             : 
    2378           0 :                         int rc;
    2379             : 
    2380           0 :                         rc = rfapi_reopen(rfd, bgp);
    2381             : 
    2382           0 :                         if (!rc) {
    2383           0 :                                 list_delete_node(orphaned_nves, node);
    2384           0 :                                 if (vty)
    2385           0 :                                         vty_out(vty,
    2386             :                                                 "WARNING: reassigned NVE vn=");
    2387           0 :                                 rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
    2388           0 :                                 if (vty)
    2389           0 :                                         vty_out(vty, " un=");
    2390           0 :                                 rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
    2391           0 :                                 if (vty)
    2392           0 :                                         vty_out(vty, " to new group \"%s\"\n",
    2393           0 :                                                 rfd->rfg->name);
    2394             :                         }
    2395             :                 }
    2396             : 
    2397           0 :                 for (ALL_LIST_ELEMENTS_RO(orphaned_nves, node, rfd)) {
    2398           0 :                         if (vty)
    2399           0 :                                 vty_out(vty, "WARNING: orphaned NVE vn=");
    2400           0 :                         rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
    2401           0 :                         if (vty)
    2402           0 :                                 vty_out(vty, " un=");
    2403           0 :                         rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
    2404           0 :                         if (vty)
    2405           0 :                                 vty_out(vty, "\n");
    2406             :                 }
    2407           0 :                 list_delete(&orphaned_nves);
    2408             :         }
    2409           0 : }
    2410             : 
    2411             : static int
    2412           1 : bgp_rfapi_delete_named_nve_group(struct vty *vty, /* NULL = no output */
    2413             :                                  struct bgp *bgp,
    2414             :                                  const char *rfg_name,  /* NULL = any */
    2415             :                                  rfapi_group_cfg_type_t type) /* _MAX = any */
    2416             : {
    2417           1 :         struct rfapi_nve_group_cfg *rfg = NULL;
    2418           1 :         struct listnode *node, *nnode;
    2419           1 :         struct rfapi_rfg_name *rfgn;
    2420             : 
    2421             :         /* Search for name */
    2422           1 :         if (rfg_name) {
    2423           0 :                 rfg = bgp_rfapi_cfg_match_byname(bgp, rfg_name, type);
    2424           0 :                 if (!rfg) {
    2425           0 :                         if (vty)
    2426           0 :                                 vty_out(vty, "No NVE group named \"%s\"\n",
    2427             :                                         rfg_name);
    2428           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2429             :                 }
    2430             :         }
    2431             : 
    2432             :         /*
    2433             :          * If this group is the redist nve group, unlink it
    2434             :          */
    2435           0 :         if (rfg_name == NULL || bgp->rfapi_cfg->rfg_redist == rfg) {
    2436           1 :                 vnc_redistribute_prechange(bgp);
    2437           1 :                 bgp->rfapi_cfg->rfg_redist = NULL;
    2438           1 :                 vnc_redistribute_postchange(bgp);
    2439             :         }
    2440             : 
    2441             : 
    2442             :         /*
    2443             :          * remove reference from bgp direct export list
    2444             :          */
    2445           2 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
    2446             :                                   rfgn)) {
    2447           0 :                 if (rfgn->rfg == rfg) {
    2448           0 :                         rfgn->rfg = NULL;
    2449             :                         /* remove exported routes from this group */
    2450           0 :                         vnc_direct_bgp_del_group(bgp, rfg);
    2451           0 :                         break;
    2452             :                 }
    2453             :         }
    2454             : 
    2455             :         /*
    2456             :          * remove reference from zebra export list
    2457             :          */
    2458           2 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
    2459             :                                   rfgn)) {
    2460           0 :                 if (rfgn->rfg == rfg) {
    2461           0 :                         rfgn->rfg = NULL;
    2462             :                         /* remove exported routes from this group */
    2463           0 :                         vnc_zebra_del_group(bgp, rfg);
    2464           0 :                         break;
    2465             :                 }
    2466             :         }
    2467           1 :         if (rfg) {
    2468           0 :                 if (rfg->rfd)
    2469           0 :                         clear_vnc_vrf_closer(rfg);
    2470           0 :                 bgp_rfapi_delete_nve_group(vty, bgp, rfg);
    2471             :         } else /* must be delete all */
    2472           2 :                 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential,
    2473             :                                        node, nnode, rfg)) {
    2474           0 :                         if (rfg->rfd)
    2475           0 :                                 clear_vnc_vrf_closer(rfg);
    2476           0 :                         bgp_rfapi_delete_nve_group(vty, bgp, rfg);
    2477             :                 }
    2478             :         return CMD_SUCCESS;
    2479             : }
    2480             : 
    2481           0 : DEFUN (vnc_no_nve_group,
    2482             :        vnc_no_nve_group_cmd,
    2483             :        "no vnc nve-group NAME",
    2484             :        NO_STR
    2485             :        VNC_CONFIG_STR
    2486             :        "Configure a NVE group\n"
    2487             :        "Group name\n")
    2488             : {
    2489           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2490             : 
    2491           0 :         return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[3]->arg,
    2492             :                                                 RFAPI_GROUP_CFG_NVE);
    2493             : }
    2494             : 
    2495           0 : DEFUN (vnc_nve_group_prefix,
    2496             :        vnc_nve_group_prefix_cmd,
    2497             :        "prefix <vn|un> <A.B.C.D/M|X:X::X:X/M>",
    2498             :        "Specify prefixes matching NVE VN or UN interfaces\n"
    2499             :        "VN prefix\n"
    2500             :        "UN prefix\n"
    2501             :        "IPv4 prefix\n"
    2502             :        "IPv6 prefix\n")
    2503             : {
    2504           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2505           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    2506           0 :         struct prefix p;
    2507           0 :         afi_t afi;
    2508           0 :         struct agg_table *rt;
    2509           0 :         struct agg_node *rn;
    2510           0 :         int is_un_prefix = 0;
    2511             : 
    2512             :         /* make sure it's still in list */
    2513           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    2514             :                 /* Not in list anymore */
    2515           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    2516           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2517             :         }
    2518             : 
    2519           0 :         if (!str2prefix(argv[2]->arg, &p)) {
    2520           0 :                 vty_out(vty, "Malformed prefix \"%s\"\n", argv[2]->arg);
    2521           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2522             :         }
    2523             : 
    2524           0 :         afi = family2afi(p.family);
    2525           0 :         if (!afi) {
    2526           0 :                 vty_out(vty, "Unsupported address family\n");
    2527           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2528             :         }
    2529             : 
    2530           0 :         if (argv[1]->arg[0] == 'u') {
    2531           0 :                 rt = bgp->rfapi_cfg->nve_groups_un[afi];
    2532           0 :                 is_un_prefix = 1;
    2533             :         } else {
    2534           0 :                 rt = bgp->rfapi_cfg->nve_groups_vn[afi];
    2535             :         }
    2536             : 
    2537           0 :         rn = agg_node_get(rt, &p); /* NB locks node */
    2538           0 :         if (rn->info) {
    2539             :                 /*
    2540             :                  * There is already a group with this prefix
    2541             :                  */
    2542           0 :                 agg_unlock_node(rn);
    2543           0 :                 if (rn->info != rfg) {
    2544             :                         /*
    2545             :                          * different group name: fail
    2546             :                          */
    2547           0 :                         vty_out(vty,
    2548             :                                 "nve group \"%s\" already has \"%s\" prefix %s\n",
    2549             :                                 ((struct rfapi_nve_group_cfg *)(rn->info))
    2550             :                                         ->name,
    2551           0 :                                 argv[1]->arg, argv[2]->arg);
    2552           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2553             :                 } else {
    2554             :                         /*
    2555             :                          * same group name: it's already in the correct place
    2556             :                          * in the table, so we're done.
    2557             :                          *
    2558             :                          * Implies rfg->(vn|un)_prefix is already correct.
    2559             :                          */
    2560             :                         return CMD_SUCCESS;
    2561             :                 }
    2562             :         }
    2563             : 
    2564           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    2565           0 :                 vnc_redistribute_prechange(bgp);
    2566             :         }
    2567             : 
    2568             :         /* New prefix, new node */
    2569             : 
    2570           0 :         if (is_un_prefix) {
    2571             : 
    2572             :                 /* detach rfg from previous route table location */
    2573           0 :                 if (rfg->un_node) {
    2574           0 :                         rfg->un_node->info = NULL;
    2575           0 :                         agg_unlock_node(rfg->un_node); /* frees */
    2576             :                 }
    2577           0 :                 rfg->un_node = rn; /* back ref */
    2578           0 :                 rfg->un_prefix = p;
    2579             : 
    2580             :         } else {
    2581             : 
    2582             :                 /* detach rfg from previous route table location */
    2583           0 :                 if (rfg->vn_node) {
    2584           0 :                         rfg->vn_node->info = NULL;
    2585           0 :                         agg_unlock_node(rfg->vn_node); /* frees */
    2586             :                 }
    2587           0 :                 rfg->vn_node = rn; /* back ref */
    2588           0 :                 rfg->vn_prefix = p;
    2589             :         }
    2590             : 
    2591             :         /* attach */
    2592           0 :         rn->info = rfg;
    2593             : 
    2594           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    2595           0 :                 vnc_redistribute_postchange(bgp);
    2596             :         }
    2597             : 
    2598             :         return CMD_SUCCESS;
    2599             : }
    2600             : 
    2601           0 : DEFUN (vnc_nve_group_rt_import,
    2602             :        vnc_nve_group_rt_import_cmd,
    2603             :        "rt import RTLIST...",
    2604             :        "Specify route targets\n"
    2605             :        "Import filter\n"
    2606             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
    2607             : {
    2608           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2609           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    2610           0 :         int rc;
    2611           0 :         struct listnode *node;
    2612           0 :         struct rfapi_rfg_name *rfgn;
    2613           0 :         int is_export_bgp = 0;
    2614           0 :         int is_export_zebra = 0;
    2615             : 
    2616             :         /* make sure it's still in list */
    2617           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    2618             :                 /* Not in list anymore */
    2619           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    2620           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2621             :         }
    2622             : 
    2623           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
    2624           0 :         if (rc != CMD_SUCCESS)
    2625             :                 return rc;
    2626             : 
    2627           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
    2628             :                                   rfgn)) {
    2629             : 
    2630           0 :                 if (rfgn->rfg == rfg) {
    2631             :                         is_export_bgp = 1;
    2632             :                         break;
    2633             :                 }
    2634             :         }
    2635             : 
    2636           0 :         if (is_export_bgp)
    2637           0 :                 vnc_direct_bgp_del_group(bgp, rfg);
    2638             : 
    2639           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
    2640             :                                   rfgn)) {
    2641             : 
    2642           0 :                 if (rfgn->rfg == rfg) {
    2643             :                         is_export_zebra = 1;
    2644             :                         break;
    2645             :                 }
    2646             :         }
    2647             : 
    2648           0 :         if (is_export_zebra)
    2649           0 :                 vnc_zebra_del_group(bgp, rfg);
    2650             : 
    2651             :         /*
    2652             :          * stop referencing old import table, now reference new one
    2653             :          */
    2654           0 :         if (rfg->rfapi_import_table)
    2655           0 :                 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
    2656           0 :         rfg->rfapi_import_table =
    2657           0 :                 rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
    2658             : 
    2659           0 :         if (is_export_bgp)
    2660           0 :                 vnc_direct_bgp_add_group(bgp, rfg);
    2661             : 
    2662           0 :         if (is_export_zebra)
    2663           0 :                 vnc_zebra_add_group(bgp, rfg);
    2664             : 
    2665             :         return CMD_SUCCESS;
    2666             : }
    2667             : 
    2668           0 : DEFUN (vnc_nve_group_rt_export,
    2669             :        vnc_nve_group_rt_export_cmd,
    2670             :        "rt export RTLIST...",
    2671             :        "Specify route targets\n"
    2672             :        "Export filter\n"
    2673             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
    2674             : {
    2675           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2676           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    2677           0 :         int rc;
    2678             : 
    2679             :         /* make sure it's still in list */
    2680           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    2681             :                 /* Not in list anymore */
    2682           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    2683           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2684             :         }
    2685             : 
    2686           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    2687           0 :                 vnc_redistribute_prechange(bgp);
    2688             :         }
    2689             : 
    2690           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
    2691             : 
    2692           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    2693           0 :                 vnc_redistribute_postchange(bgp);
    2694             :         }
    2695             : 
    2696             :         return rc;
    2697             : }
    2698             : 
    2699           0 : DEFUN (vnc_nve_group_rt_both,
    2700             :        vnc_nve_group_rt_both_cmd,
    2701             :        "rt both RTLIST...",
    2702             :        "Specify route targets\n"
    2703             :        "Export+import filters\n"
    2704             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
    2705             : {
    2706           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2707           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    2708           0 :         int rc;
    2709           0 :         int is_export_bgp = 0;
    2710           0 :         int is_export_zebra = 0;
    2711           0 :         struct listnode *node;
    2712           0 :         struct rfapi_rfg_name *rfgn;
    2713             : 
    2714             :         /* make sure it's still in list */
    2715           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    2716             :                 /* Not in list anymore */
    2717           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    2718           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2719             :         }
    2720             : 
    2721           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
    2722           0 :         if (rc != CMD_SUCCESS)
    2723             :                 return rc;
    2724             : 
    2725           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
    2726             :                                   rfgn)) {
    2727             : 
    2728           0 :                 if (rfgn->rfg == rfg) {
    2729             :                         is_export_bgp = 1;
    2730             :                         break;
    2731             :                 }
    2732             :         }
    2733             : 
    2734           0 :         if (is_export_bgp)
    2735           0 :                 vnc_direct_bgp_del_group(bgp, rfg);
    2736             : 
    2737           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
    2738             :                                   rfgn)) {
    2739             : 
    2740           0 :                 if (rfgn->rfg == rfg) {
    2741             :                         is_export_zebra = 1;
    2742             :                         break;
    2743             :                 }
    2744             :         }
    2745             : 
    2746           0 :         if (is_export_zebra) {
    2747           0 :                 vnc_zlog_debug_verbose("%s: is_export_zebra", __func__);
    2748           0 :                 vnc_zebra_del_group(bgp, rfg);
    2749             :         }
    2750             : 
    2751             :         /*
    2752             :          * stop referencing old import table, now reference new one
    2753             :          */
    2754           0 :         if (rfg->rfapi_import_table)
    2755           0 :                 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
    2756           0 :         rfg->rfapi_import_table =
    2757           0 :                 rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
    2758             : 
    2759           0 :         if (is_export_bgp)
    2760           0 :                 vnc_direct_bgp_add_group(bgp, rfg);
    2761             : 
    2762           0 :         if (is_export_zebra)
    2763           0 :                 vnc_zebra_add_group(bgp, rfg);
    2764             : 
    2765           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    2766           0 :                 vnc_redistribute_prechange(bgp);
    2767             :         }
    2768             : 
    2769           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
    2770             : 
    2771           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    2772           0 :                 vnc_redistribute_postchange(bgp);
    2773             :         }
    2774             : 
    2775             :         return rc;
    2776             : }
    2777             : 
    2778           0 : DEFUN (vnc_nve_group_l2rd,
    2779             :        vnc_nve_group_l2rd_cmd,
    2780             :        "l2rd <(1-255)|auto-vn>",
    2781             :        "Specify default Local Nve ID value to use in RD for L2 routes\n"
    2782             :        "Fixed value 1-255\n"
    2783             :        "use the low-order octet of the NVE's VN address\n")
    2784             : {
    2785           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2786           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    2787             : 
    2788             :         /* make sure it's still in list */
    2789           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    2790             :                 /* Not in list anymore */
    2791           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    2792           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2793             :         }
    2794             : 
    2795           0 :         if (strmatch(argv[1]->text, "auto:vn")) {
    2796           0 :                 rfg->l2rd = 0;
    2797             :         } else {
    2798           0 :                 char *end = NULL;
    2799           0 :                 unsigned long value_l = strtoul(argv[1]->arg, &end, 10);
    2800           0 :                 uint8_t value = value_l & 0xff;
    2801             : 
    2802           0 :                 if (!argv[1]->arg[0] || *end) {
    2803           0 :                         vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n",
    2804             :                                 argv[1]->arg);
    2805           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2806             :                 }
    2807           0 :                 if ((value_l < 1) || (value_l > 0xff)) {
    2808           0 :                         vty_out(vty,
    2809             :                                 "%% Malformed l2 nve id (must be greater than 0 and less than %u\n",
    2810             :                                 0x100);
    2811           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2812             :                 }
    2813             : 
    2814           0 :                 rfg->l2rd = value;
    2815             :         }
    2816           0 :         rfg->flags |= RFAPI_RFG_L2RD;
    2817             : 
    2818           0 :         return CMD_SUCCESS;
    2819             : }
    2820             : 
    2821           0 : DEFUN (vnc_nve_group_no_l2rd,
    2822             :        vnc_nve_group_no_l2rd_cmd,
    2823             :        "no l2rd",
    2824             :        NO_STR
    2825             :        "Specify default Local Nve ID value to use in RD for L2 routes\n")
    2826             : {
    2827           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2828           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    2829             : 
    2830             :         /* make sure it's still in list */
    2831           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    2832             :                 /* Not in list anymore */
    2833           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    2834           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2835             :         }
    2836             : 
    2837           0 :         rfg->l2rd = 0;
    2838           0 :         rfg->flags &= ~RFAPI_RFG_L2RD;
    2839             : 
    2840           0 :         return CMD_SUCCESS;
    2841             : }
    2842             : 
    2843           0 : DEFUN (vnc_nve_group_rd,
    2844             :        vnc_nve_group_rd_cmd,
    2845             :        "rd ASN:NN_OR_IP-ADDRESS:NN",
    2846             :        "Specify route distinguisher\n"
    2847             :        "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
    2848             : {
    2849           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2850           0 :         int ret;
    2851           0 :         struct prefix_rd prd;
    2852           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    2853             : 
    2854             :         /* make sure it's still in list */
    2855           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    2856             :                 /* Not in list anymore */
    2857           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    2858           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2859             :         }
    2860             : 
    2861           0 :         if (!strncmp(argv[1]->arg, "auto:vn:", 8)) {
    2862             :                 /*
    2863             :                  * use AF_UNIX to designate automatically-assigned RD
    2864             :                  * auto:vn:nn where nn is a 2-octet quantity
    2865             :                  */
    2866           0 :                 char *end = NULL;
    2867           0 :                 uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
    2868           0 :                 uint16_t value = value32 & 0xffff;
    2869             : 
    2870           0 :                 if (!argv[1]->arg[8] || *end) {
    2871           0 :                         vty_out(vty, "%% Malformed rd\n");
    2872           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2873             :                 }
    2874           0 :                 if (value32 > 0xffff) {
    2875           0 :                         vty_out(vty, "%% Malformed rd (must be less than %u\n",
    2876             :                                 0x0ffff);
    2877           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2878             :                 }
    2879             : 
    2880           0 :                 memset(&prd, 0, sizeof(prd));
    2881           0 :                 prd.family = AF_UNIX;
    2882           0 :                 prd.prefixlen = 64;
    2883           0 :                 prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
    2884           0 :                 prd.val[1] = RD_TYPE_IP & 0x0ff;
    2885           0 :                 prd.val[6] = (value >> 8) & 0x0ff;
    2886           0 :                 prd.val[7] = value & 0x0ff;
    2887             : 
    2888             :         } else {
    2889             : 
    2890           0 :                 ret = str2prefix_rd(argv[1]->arg, &prd);
    2891           0 :                 if (!ret) {
    2892           0 :                         vty_out(vty, "%% Malformed rd\n");
    2893           0 :                         return CMD_WARNING_CONFIG_FAILED;
    2894             :                 }
    2895             :         }
    2896             : 
    2897           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    2898           0 :                 vnc_redistribute_prechange(bgp);
    2899             :         }
    2900             : 
    2901           0 :         rfg->rd = prd;
    2902             : 
    2903           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    2904           0 :                 vnc_redistribute_postchange(bgp);
    2905             :         }
    2906             :         return CMD_SUCCESS;
    2907             : }
    2908             : 
    2909           0 : DEFUN (vnc_nve_group_responselifetime,
    2910             :        vnc_nve_group_responselifetime_cmd,
    2911             :        "response-lifetime <LIFETIME|infinite>",
    2912             :        "Specify response lifetime\n"
    2913             :        "Response lifetime in seconds\n" "Infinite response lifetime\n")
    2914             : {
    2915           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2916           0 :         unsigned int rspint;
    2917           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    2918           0 :         struct rfapi_descriptor *rfd;
    2919           0 :         struct listnode *hdnode;
    2920             : 
    2921             :         /* make sure it's still in list */
    2922           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    2923             :                 /* Not in list anymore */
    2924           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    2925           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2926             :         }
    2927             : 
    2928           0 :         if (strmatch(argv[1]->text, "infinite")) {
    2929             :                 rspint = RFAPI_INFINITE_LIFETIME;
    2930             :         } else {
    2931           0 :                 rspint = strtoul(argv[1]->arg, NULL, 10);
    2932             :         }
    2933             : 
    2934           0 :         rfg->response_lifetime = rspint;
    2935           0 :         rfg->flags |= RFAPI_RFG_RESPONSE_LIFETIME;
    2936           0 :         if (rfg->nves)
    2937           0 :                 for (ALL_LIST_ELEMENTS_RO(rfg->nves, hdnode, rfd))
    2938           0 :                         rfd->response_lifetime = rspint;
    2939             :         return CMD_SUCCESS;
    2940             : }
    2941             : 
    2942             : /*
    2943             :  * Sigh. This command, like exit-address-family, is a hack to deal
    2944             :  * with the lack of rigorous level control in the command handler.
    2945             :  * TBD fix command handler.
    2946             :  */
    2947           0 : DEFUN_NOSH (exit_vnc,
    2948             :        exit_vnc_cmd,
    2949             :        "exit-vnc",
    2950             :        "Exit VNC configuration mode\n")
    2951             : {
    2952           0 :         if (vty->node == BGP_VNC_DEFAULTS_NODE
    2953             :             || vty->node == BGP_VNC_NVE_GROUP_NODE
    2954           0 :             || vty->node == BGP_VNC_L2_GROUP_NODE) {
    2955             : 
    2956           0 :                 vty->node = BGP_NODE;
    2957             :         }
    2958           0 :         return CMD_SUCCESS;
    2959             : }
    2960             : 
    2961             : static struct cmd_node bgp_vnc_defaults_node = {
    2962             :         .name = "bgp vnc defaults",
    2963             :         .node = BGP_VNC_DEFAULTS_NODE,
    2964             :         .parent_node = BGP_NODE,
    2965             :         .prompt = "%s(config-router-vnc-defaults)# ",
    2966             : };
    2967             : 
    2968             : static struct cmd_node bgp_vnc_nve_group_node = {
    2969             :         .name = "bgp vnc nve",
    2970             :         .node = BGP_VNC_NVE_GROUP_NODE,
    2971             :         .parent_node = BGP_NODE,
    2972             :         .prompt = "%s(config-router-vnc-nve-group)# ",
    2973             : };
    2974             : 
    2975             : /*-------------------------------------------------------------------------
    2976             :  *                      VNC nve-group
    2977             :  * Note there are two types of NVEs, one for VPNs one for RFP NVEs
    2978             :  *-----------------------------------------------------------------------*/
    2979             : 
    2980           0 : DEFUN_NOSH (vnc_vrf_policy,
    2981             :        vnc_vrf_policy_cmd,
    2982             :        "vrf-policy NAME",
    2983             :        "Configure a VRF policy group\n"
    2984             :        "VRF name\n")
    2985             : {
    2986           0 :         struct rfapi_nve_group_cfg *rfg;
    2987           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    2988             : 
    2989           0 :         if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
    2990           0 :                 vty_out(vty,
    2991             :                         "Can't configure vrf-policy within a BGP VRF instance\n");
    2992           0 :                 return CMD_WARNING_CONFIG_FAILED;
    2993             :         }
    2994             : 
    2995             :         /* Search for name */
    2996           0 :         rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg,
    2997             :                                          RFAPI_GROUP_CFG_VRF);
    2998             : 
    2999           0 :         if (!rfg) {
    3000           0 :                 rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_VRF, argv[1]->arg);
    3001           0 :                 if (!rfg) {
    3002             :                         /* Error out of memory */
    3003           0 :                         vty_out(vty, "Can't allocate memory for NVE group\n");
    3004           0 :                         return CMD_WARNING_CONFIG_FAILED;
    3005             :                 }
    3006             :         }
    3007             :         /*
    3008             :          * XXX subsequent calls will need to make sure this item is still
    3009             :          * in the linked list and has the same name
    3010             :          */
    3011           0 :         VTY_PUSH_CONTEXT_SUB(BGP_VRF_POLICY_NODE, rfg);
    3012             : 
    3013           0 :         return CMD_SUCCESS;
    3014             : }
    3015             : 
    3016           0 : DEFUN (vnc_no_vrf_policy,
    3017             :        vnc_no_vrf_policy_cmd,
    3018             :        "no vrf-policy NAME",
    3019             :        NO_STR
    3020             :        "Remove a VRF policy group\n"
    3021             :        "VRF name\n")
    3022             : {
    3023           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3024             : 
    3025             :         /* silently return */
    3026           0 :         if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
    3027             :                 return CMD_SUCCESS;
    3028             : 
    3029           0 :         return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[2]->arg,
    3030             :                                                 RFAPI_GROUP_CFG_VRF);
    3031             : }
    3032             : 
    3033           0 : DEFUN (vnc_vrf_policy_label,
    3034             :        vnc_vrf_policy_label_cmd,
    3035             :        "label (0-1048575)",
    3036             :        "Default label value for VRF\n"
    3037             :        "Label Value <0-1048575>\n")
    3038             : {
    3039           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    3040             : 
    3041           0 :         uint32_t label;
    3042           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3043             : 
    3044             :         /* make sure it's still in list */
    3045           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    3046             :                 /* Not in list anymore */
    3047           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    3048           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3049             :         }
    3050             : 
    3051           0 :         label = strtoul(argv[1]->arg, NULL, 10);
    3052             : 
    3053           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3054           0 :                 vnc_redistribute_prechange(bgp);
    3055             :         }
    3056             : 
    3057           0 :         rfg->label = label;
    3058             : 
    3059           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3060           0 :                 vnc_redistribute_postchange(bgp);
    3061             :         }
    3062             :         return CMD_SUCCESS;
    3063             : }
    3064             : 
    3065           0 : DEFUN (vnc_vrf_policy_no_label,
    3066             :        vnc_vrf_policy_no_label_cmd,
    3067             :        "no label",
    3068             :        NO_STR
    3069             :        "Remove VRF default label\n")
    3070             : {
    3071           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    3072           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3073             : 
    3074             :         /* make sure it's still in list */
    3075           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    3076             :                 /* Not in list anymore */
    3077           0 :                 vty_out(vty, "Current VRF group no longer exists\n");
    3078           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3079             :         }
    3080             : 
    3081           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3082           0 :                 vnc_redistribute_prechange(bgp);
    3083             :         }
    3084             : 
    3085           0 :         rfg->label = MPLS_LABEL_NONE;
    3086             : 
    3087           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3088           0 :                 vnc_redistribute_postchange(bgp);
    3089             :         }
    3090             :         return CMD_SUCCESS;
    3091             : }
    3092             : 
    3093           0 : DEFUN (vnc_vrf_policy_nexthop,
    3094             :        vnc_vrf_policy_nexthop_cmd,
    3095             :        "nexthop <A.B.C.D|X:X::X:X|self>",
    3096             :        "Specify next hop to use for VRF advertised prefixes\n"
    3097             :        "IPv4 prefix\n"
    3098             :        "IPv6 prefix\n"
    3099             :        "Use configured router-id (default)\n")
    3100             : {
    3101           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    3102           0 :         struct prefix p;
    3103             : 
    3104           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3105             : 
    3106             :         /* make sure it's still in list */
    3107           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    3108             :                 /* Not in list anymore */
    3109           0 :                 vty_out(vty, "Current VRF no longer exists\n");
    3110           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3111             :         }
    3112             : 
    3113           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3114           0 :                 vnc_redistribute_prechange(bgp);
    3115             :         }
    3116             : 
    3117           0 :         if (!str2prefix(argv[1]->arg, &p) && p.family) {
    3118             :                 // vty_out (vty, "Nexthop set to self\n");
    3119           0 :                 SET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF);
    3120           0 :                 memset(&rfg->vn_prefix, 0, sizeof(struct prefix));
    3121             :         } else {
    3122           0 :                 UNSET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF);
    3123           0 :                 rfg->vn_prefix = p;
    3124           0 :                 rfg->un_prefix = p;
    3125             :         }
    3126             : 
    3127             :         /* TBD handle router-id/ nexthop changes when have advertised prefixes
    3128             :          */
    3129             : 
    3130           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3131           0 :                 vnc_redistribute_postchange(bgp);
    3132             :         }
    3133             : 
    3134             :         return CMD_SUCCESS;
    3135             : }
    3136             : 
    3137             : /* The RT code should be refactored/simplified with above... */
    3138           0 : DEFUN (vnc_vrf_policy_rt_import,
    3139             :        vnc_vrf_policy_rt_import_cmd,
    3140             :        "rt import RTLIST...",
    3141             :        "Specify route targets\n"
    3142             :        "Import filter\n"
    3143             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
    3144             : {
    3145           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    3146           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3147           0 :         int rc;
    3148           0 :         struct listnode *node;
    3149           0 :         struct rfapi_rfg_name *rfgn;
    3150           0 :         int is_export_bgp = 0;
    3151           0 :         int is_export_zebra = 0;
    3152             : 
    3153             :         /* make sure it's still in list */
    3154           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    3155             :                 /* Not in list anymore */
    3156           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    3157           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3158             :         }
    3159             : 
    3160           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
    3161           0 :         if (rc != CMD_SUCCESS)
    3162             :                 return rc;
    3163             : 
    3164           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
    3165             :                                   rfgn)) {
    3166             : 
    3167           0 :                 if (rfgn->rfg == rfg) {
    3168             :                         is_export_bgp = 1;
    3169             :                         break;
    3170             :                 }
    3171             :         }
    3172             : 
    3173           0 :         if (is_export_bgp)
    3174           0 :                 vnc_direct_bgp_del_group(bgp, rfg);
    3175             : 
    3176           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
    3177             :                                   rfgn)) {
    3178             : 
    3179           0 :                 if (rfgn->rfg == rfg) {
    3180             :                         is_export_zebra = 1;
    3181             :                         break;
    3182             :                 }
    3183             :         }
    3184             : 
    3185           0 :         if (is_export_zebra)
    3186           0 :                 vnc_zebra_del_group(bgp, rfg);
    3187             : 
    3188             :         /*
    3189             :          * stop referencing old import table, now reference new one
    3190             :          */
    3191           0 :         if (rfg->rfapi_import_table)
    3192           0 :                 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
    3193           0 :         rfg->rfapi_import_table =
    3194           0 :                 rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
    3195             : 
    3196           0 :         if (is_export_bgp)
    3197           0 :                 vnc_direct_bgp_add_group(bgp, rfg);
    3198             : 
    3199           0 :         if (is_export_zebra)
    3200           0 :                 vnc_zebra_add_group(bgp, rfg);
    3201             : 
    3202             :         return CMD_SUCCESS;
    3203             : }
    3204             : 
    3205           0 : DEFUN (vnc_vrf_policy_rt_export,
    3206             :        vnc_vrf_policy_rt_export_cmd,
    3207             :        "rt export RTLIST...",
    3208             :        "Specify route targets\n"
    3209             :        "Export filter\n"
    3210             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
    3211             : {
    3212           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    3213           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3214           0 :         int rc;
    3215             : 
    3216             :         /* make sure it's still in list */
    3217           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    3218             :                 /* Not in list anymore */
    3219           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    3220           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3221             :         }
    3222             : 
    3223           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3224           0 :                 vnc_redistribute_prechange(bgp);
    3225             :         }
    3226             : 
    3227           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
    3228             : 
    3229           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3230           0 :                 vnc_redistribute_postchange(bgp);
    3231             :         }
    3232             : 
    3233             :         return rc;
    3234             : }
    3235             : 
    3236           0 : DEFUN (vnc_vrf_policy_rt_both,
    3237             :        vnc_vrf_policy_rt_both_cmd,
    3238             :        "rt both RTLIST...",
    3239             :        "Specify route targets\n"
    3240             :        "Export+import filters\n"
    3241             :        "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
    3242             : {
    3243           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    3244           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3245           0 :         int rc;
    3246           0 :         int is_export_bgp = 0;
    3247           0 :         int is_export_zebra = 0;
    3248           0 :         struct listnode *node;
    3249           0 :         struct rfapi_rfg_name *rfgn;
    3250             : 
    3251             :         /* make sure it's still in list */
    3252           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    3253             :                 /* Not in list anymore */
    3254           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    3255           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3256             :         }
    3257             : 
    3258           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list);
    3259           0 :         if (rc != CMD_SUCCESS)
    3260             :                 return rc;
    3261             : 
    3262           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node,
    3263             :                                   rfgn)) {
    3264             : 
    3265           0 :                 if (rfgn->rfg == rfg) {
    3266             :                         is_export_bgp = 1;
    3267             :                         break;
    3268             :                 }
    3269             :         }
    3270             : 
    3271           0 :         if (is_export_bgp)
    3272           0 :                 vnc_direct_bgp_del_group(bgp, rfg);
    3273             : 
    3274           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node,
    3275             :                                   rfgn)) {
    3276             : 
    3277           0 :                 if (rfgn->rfg == rfg) {
    3278             :                         is_export_zebra = 1;
    3279             :                         break;
    3280             :                 }
    3281             :         }
    3282             : 
    3283           0 :         if (is_export_zebra) {
    3284           0 :                 vnc_zlog_debug_verbose("%s: is_export_zebra", __func__);
    3285           0 :                 vnc_zebra_del_group(bgp, rfg);
    3286             :         }
    3287             : 
    3288             :         /*
    3289             :          * stop referencing old import table, now reference new one
    3290             :          */
    3291           0 :         if (rfg->rfapi_import_table)
    3292           0 :                 rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table);
    3293           0 :         rfg->rfapi_import_table =
    3294           0 :                 rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg);
    3295             : 
    3296           0 :         if (is_export_bgp)
    3297           0 :                 vnc_direct_bgp_add_group(bgp, rfg);
    3298             : 
    3299           0 :         if (is_export_zebra)
    3300           0 :                 vnc_zebra_add_group(bgp, rfg);
    3301             : 
    3302           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3303           0 :                 vnc_redistribute_prechange(bgp);
    3304             :         }
    3305             : 
    3306           0 :         rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list);
    3307             : 
    3308           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3309           0 :                 vnc_redistribute_postchange(bgp);
    3310             :         }
    3311             : 
    3312             :         return rc;
    3313             : }
    3314             : 
    3315           0 : DEFUN (vnc_vrf_policy_rd,
    3316             :        vnc_vrf_policy_rd_cmd,
    3317             :        "rd ASN:NN_OR_IP-ADDRESS:NN",
    3318             :        "Specify default VRF route distinguisher\n"
    3319             :        "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:nh:<number> )\n")
    3320             : {
    3321           0 :         int ret;
    3322           0 :         struct prefix_rd prd;
    3323           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg);
    3324           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3325             : 
    3326             :         /* make sure it's still in list */
    3327           0 :         if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) {
    3328             :                 /* Not in list anymore */
    3329           0 :                 vty_out(vty, "Current NVE group no longer exists\n");
    3330           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3331             :         }
    3332             : 
    3333           0 :         if (!strncmp(argv[1]->arg, "auto:nh:", 8)) {
    3334             :                 /*
    3335             :                  * use AF_UNIX to designate automatically-assigned RD
    3336             :                  * auto:vn:nn where nn is a 2-octet quantity
    3337             :                  */
    3338           0 :                 char *end = NULL;
    3339           0 :                 uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10);
    3340           0 :                 uint16_t value = value32 & 0xffff;
    3341             : 
    3342           0 :                 if (!*(argv[1]->arg + 5) || *end) {
    3343           0 :                         vty_out(vty, "%% Malformed rd\n");
    3344           0 :                         return CMD_WARNING_CONFIG_FAILED;
    3345             :                 }
    3346           0 :                 if (value32 > 0xffff) {
    3347           0 :                         vty_out(vty, "%% Malformed rd (must be less than %u\n",
    3348             :                                 0x0ffff);
    3349           0 :                         return CMD_WARNING_CONFIG_FAILED;
    3350             :                 }
    3351             : 
    3352           0 :                 memset(&prd, 0, sizeof(prd));
    3353           0 :                 prd.family = AF_UNIX;
    3354           0 :                 prd.prefixlen = 64;
    3355           0 :                 prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff;
    3356           0 :                 prd.val[1] = RD_TYPE_IP & 0x0ff;
    3357           0 :                 prd.val[6] = (value >> 8) & 0x0ff;
    3358           0 :                 prd.val[7] = value & 0x0ff;
    3359             : 
    3360             :         } else {
    3361             : 
    3362           0 :                 ret = str2prefix_rd(argv[1]->arg, &prd);
    3363           0 :                 if (!ret) {
    3364           0 :                         vty_out(vty, "%% Malformed rd\n");
    3365           0 :                         return CMD_WARNING_CONFIG_FAILED;
    3366             :                 }
    3367             :         }
    3368             : 
    3369           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3370           0 :                 vnc_redistribute_prechange(bgp);
    3371             :         }
    3372             : 
    3373           0 :         rfg->rd = prd;
    3374             : 
    3375           0 :         if (bgp->rfapi_cfg->rfg_redist == rfg) {
    3376           0 :                 vnc_redistribute_postchange(bgp);
    3377             :         }
    3378             :         return CMD_SUCCESS;
    3379             : }
    3380             : 
    3381           0 : DEFUN_NOSH (exit_vrf_policy,
    3382             :        exit_vrf_policy_cmd,
    3383             :        "exit-vrf-policy",
    3384             :        "Exit VRF policy configuration mode\n")
    3385             : {
    3386           0 :         if (vty->node == BGP_VRF_POLICY_NODE) {
    3387           0 :                 vty->node = BGP_NODE;
    3388             :         }
    3389           0 :         return CMD_SUCCESS;
    3390             : }
    3391             : 
    3392             : static struct cmd_node bgp_vrf_policy_node = {
    3393             :         .name = "bgp vrf policy",
    3394             :         .node = BGP_VRF_POLICY_NODE,
    3395             :         .parent_node = BGP_NODE,
    3396             :         .prompt = "%s(config-router-vrf-policy)# ",
    3397             : };
    3398             : 
    3399             : /*-------------------------------------------------------------------------
    3400             :  *                      vnc-l2-group
    3401             :  *-----------------------------------------------------------------------*/
    3402             : 
    3403             : 
    3404           0 : DEFUN_NOSH (vnc_l2_group,
    3405             :        vnc_l2_group_cmd,
    3406             :        "vnc l2-group NAME",
    3407             :        VNC_CONFIG_STR "Configure a L2 group\n" "Group name\n")
    3408             : {
    3409           0 :         struct rfapi_l2_group_cfg *rfg;
    3410           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3411           0 :         VNC_VTY_CONFIG_CHECK(bgp);
    3412             : 
    3413             :         /* Search for name */
    3414           0 :         rfg = rfapi_l2_group_lookup_byname(bgp, argv[2]->arg);
    3415             : 
    3416           0 :         if (!rfg) {
    3417           0 :                 rfg = rfapi_l2_group_new();
    3418           0 :                 if (!rfg) {
    3419             :                         /* Error out of memory */
    3420           0 :                         vty_out(vty, "Can't allocate memory for L2 group\n");
    3421           0 :                         return CMD_WARNING_CONFIG_FAILED;
    3422             :                 }
    3423           0 :                 rfg->name = strdup(argv[2]->arg);
    3424             :                 /* add to tail of list */
    3425           0 :                 listnode_add(bgp->rfapi_cfg->l2_groups, rfg);
    3426             :         }
    3427             : 
    3428             :         /*
    3429             :          * XXX subsequent calls will need to make sure this item is still
    3430             :          * in the linked list and has the same name
    3431             :          */
    3432           0 :         VTY_PUSH_CONTEXT_SUB(BGP_VNC_L2_GROUP_NODE, rfg);
    3433           0 :         return CMD_SUCCESS;
    3434             : }
    3435             : 
    3436           0 : static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */
    3437             :                                       struct bgp *bgp,
    3438             :                                       struct rfapi_l2_group_cfg *rfg)
    3439             : {
    3440             :         /* delete it */
    3441           0 :         free(rfg->name);
    3442           0 :         if (rfg->rt_import_list)
    3443           0 :                 ecommunity_free(&rfg->rt_import_list);
    3444           0 :         if (rfg->rt_export_list)
    3445           0 :                 ecommunity_free(&rfg->rt_export_list);
    3446           0 :         if (rfg->labels)
    3447           0 :                 list_delete(&rfg->labels);
    3448           0 :         XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
    3449           0 :         listnode_delete(bgp->rfapi_cfg->l2_groups, rfg);
    3450             : 
    3451           0 :         rfapi_l2_group_del(rfg);
    3452           0 : }
    3453             : 
    3454             : static int
    3455           1 : bgp_rfapi_delete_named_l2_group(struct vty *vty, /* NULL = no output */
    3456             :                                 struct bgp *bgp,
    3457             :                                 const char *rfg_name) /* NULL = any */
    3458             : {
    3459           1 :         struct rfapi_l2_group_cfg *rfg = NULL;
    3460           1 :         struct listnode *node, *nnode;
    3461             : 
    3462             :         /* Search for name */
    3463           1 :         if (rfg_name) {
    3464           0 :                 rfg = rfapi_l2_group_lookup_byname(bgp, rfg_name);
    3465           0 :                 if (!rfg) {
    3466           0 :                         if (vty)
    3467           0 :                                 vty_out(vty, "No L2 group named \"%s\"\n",
    3468             :                                         rfg_name);
    3469           0 :                         return CMD_WARNING_CONFIG_FAILED;
    3470             :                 }
    3471             :         }
    3472             : 
    3473           1 :         if (rfg)
    3474           0 :                 bgp_rfapi_delete_l2_group(vty, bgp, rfg);
    3475             :         else /* must be delete all */
    3476           2 :                 for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode,
    3477             :                                        rfg))
    3478           0 :                         bgp_rfapi_delete_l2_group(vty, bgp, rfg);
    3479             :         return CMD_SUCCESS;
    3480             : }
    3481             : 
    3482           0 : DEFUN (vnc_no_l2_group,
    3483             :        vnc_no_l2_group_cmd,
    3484             :        "no vnc l2-group NAME",
    3485             :        NO_STR
    3486             :        VNC_CONFIG_STR
    3487             :        "Configure a L2 group\n"
    3488             :        "Group name\n")
    3489             : {
    3490           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3491             : 
    3492           0 :         return bgp_rfapi_delete_named_l2_group(vty, bgp, argv[3]->arg);
    3493             : }
    3494             : 
    3495             : 
    3496           0 : DEFUN (vnc_l2_group_lni,
    3497             :        vnc_l2_group_lni_cmd,
    3498             :        "logical-network-id (0-4294967295)",
    3499             :        "Specify Logical Network ID associated with group\n"
    3500             :        "value\n")
    3501             : {
    3502           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
    3503           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3504             : 
    3505             :         /* make sure it's still in list */
    3506           0 :         if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
    3507             :                 /* Not in list anymore */
    3508           0 :                 vty_out(vty, "Current L2 group no longer exists\n");
    3509           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3510             :         }
    3511             : 
    3512           0 :         rfg->logical_net_id = strtoul(argv[1]->arg, NULL, 10);
    3513             : 
    3514           0 :         return CMD_SUCCESS;
    3515             : }
    3516             : 
    3517           0 : DEFUN (vnc_l2_group_labels,
    3518             :        vnc_l2_group_labels_cmd,
    3519             :        "labels (0-1048575)...",
    3520             :        "Specify label values associated with group\n"
    3521             :        "Space separated list of label values <0-1048575>\n")
    3522             : {
    3523           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
    3524           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3525           0 :         struct list *ll;
    3526             : 
    3527             :         /* make sure it's still in list */
    3528           0 :         if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
    3529             :                 /* Not in list anymore */
    3530           0 :                 vty_out(vty, "Current L2 group no longer exists\n");
    3531           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3532             :         }
    3533             : 
    3534           0 :         ll = rfg->labels;
    3535           0 :         if (ll == NULL) {
    3536           0 :                 ll = list_new();
    3537           0 :                 rfg->labels = ll;
    3538             :         }
    3539           0 :         argc--;
    3540           0 :         argv++;
    3541           0 :         for (; argc; --argc, ++argv) {
    3542           0 :                 uint32_t label;
    3543           0 :                 label = strtoul(argv[0]->arg, NULL, 10);
    3544           0 :                 if (!listnode_lookup(ll, (void *)(uintptr_t)label))
    3545           0 :                         listnode_add(ll, (void *)(uintptr_t)label);
    3546             :         }
    3547             : 
    3548             :         return CMD_SUCCESS;
    3549             : }
    3550             : 
    3551           0 : DEFUN (vnc_l2_group_no_labels,
    3552             :        vnc_l2_group_no_labels_cmd,
    3553             :        "no labels (0-1048575)...",
    3554             :        NO_STR
    3555             :        "Specify label values associated with L2 group\n"
    3556             :        "Space separated list of label values <0-1048575>\n")
    3557             : {
    3558           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
    3559           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3560           0 :         struct list *ll;
    3561             : 
    3562             :         /* make sure it's still in list */
    3563           0 :         if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
    3564             :                 /* Not in list anymore */
    3565           0 :                 vty_out(vty, "Current L2 group no longer exists\n");
    3566           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3567             :         }
    3568             : 
    3569           0 :         ll = rfg->labels;
    3570           0 :         if (ll == NULL) {
    3571           0 :                 vty_out(vty, "Label no longer associated with group\n");
    3572           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3573             :         }
    3574             : 
    3575           0 :         argc -= 2;
    3576           0 :         argv += 2;
    3577           0 :         for (; argc; --argc, ++argv) {
    3578           0 :                 uint32_t label;
    3579           0 :                 label = strtoul(argv[0]->arg, NULL, 10);
    3580           0 :                 listnode_delete(ll, (void *)(uintptr_t)label);
    3581             :         }
    3582             : 
    3583             :         return CMD_SUCCESS;
    3584             : }
    3585             : 
    3586           0 : DEFUN (vnc_l2_group_rt,
    3587             :        vnc_l2_group_rt_cmd,
    3588             :        "rt <both|export|import> ASN:NN_OR_IP-ADDRESS:NN",
    3589             :        "Specify route targets\n"
    3590             :        "Export+import filters\n"
    3591             :        "Export filters\n"
    3592             :        "Import filters\n"
    3593             :        "A route target\n")
    3594             : {
    3595           0 :         VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg);
    3596           0 :         VTY_DECLVAR_CONTEXT(bgp, bgp);
    3597           0 :         int rc = CMD_SUCCESS;
    3598           0 :         int do_import = 0;
    3599           0 :         int do_export = 0;
    3600             : 
    3601           0 :         switch (argv[1]->arg[0]) {
    3602           0 :         case 'b':
    3603           0 :                 do_export = 1; /* fall through */
    3604             :         case 'i':
    3605             :                 do_import = 1;
    3606             :                 break;
    3607             :         case 'e':
    3608             :                 do_export = 1;
    3609             :                 break;
    3610           0 :         default:
    3611           0 :                 vty_out(vty, "Unknown option, %s\n", argv[1]->arg);
    3612           0 :                 return CMD_ERR_NO_MATCH;
    3613             :         }
    3614             : 
    3615             :         /* make sure it's still in list */
    3616           0 :         if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) {
    3617             :                 /* Not in list anymore */
    3618           0 :                 vty_out(vty, "Current L2 group no longer exists\n");
    3619           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3620             :         }
    3621             : 
    3622           0 :         if (do_import)
    3623           0 :                 rc = set_ecom_list(vty, argc - 2, argv + 2,
    3624             :                                    &rfg->rt_import_list);
    3625           0 :         if (rc == CMD_SUCCESS && do_export)
    3626           0 :                 rc = set_ecom_list(vty, argc - 2, argv + 2,
    3627             :                                    &rfg->rt_export_list);
    3628             :         return rc;
    3629             : }
    3630             : 
    3631             : 
    3632             : static struct cmd_node bgp_vnc_l2_group_node = {
    3633             :         .name = "bgp vnc l2",
    3634             :         .node = BGP_VNC_L2_GROUP_NODE,
    3635             :         .parent_node = BGP_NODE,
    3636             :         .prompt = "%s(config-router-vnc-l2-group)# ",
    3637             : };
    3638             : 
    3639             : struct rfapi_l2_group_cfg *
    3640           0 : bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id,
    3641             :                                  uint32_t label)
    3642             : {
    3643           0 :         struct rfapi_l2_group_cfg *rfg;
    3644           0 :         struct listnode *node;
    3645             : 
    3646           0 :         if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */
    3647             :                 return NULL;
    3648             : 
    3649           0 :         label = label & 0xfffff; /* label is 20 bits! */
    3650             : 
    3651           0 :         for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->l2_groups, node, rfg)) {
    3652           0 :                 if (rfg->logical_net_id == logical_net_id) {
    3653           0 :                         struct listnode *lnode;
    3654           0 :                         void *data;
    3655           0 :                         for (ALL_LIST_ELEMENTS_RO(rfg->labels, lnode, data))
    3656           0 :                                 if (((uint32_t)((uintptr_t)data))
    3657             :                                     == label) { /* match! */
    3658           0 :                                         return rfg;
    3659             :                                 }
    3660             :                 }
    3661             :         }
    3662             :         return NULL;
    3663             : }
    3664             : 
    3665           0 : struct list *bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp,
    3666             :                                                   uint32_t logical_net_id,
    3667             :                                                   uint32_t label)
    3668             : {
    3669           0 :         struct rfapi_l2_group_cfg *rfg;
    3670           0 :         rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label);
    3671           0 :         if (rfg) {
    3672           0 :                 return rfg->labels;
    3673             :         }
    3674             :         return NULL;
    3675             : }
    3676             : 
    3677             : struct ecommunity *
    3678           0 : bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import,
    3679             :                                       uint32_t logical_net_id, uint32_t label)
    3680             : {
    3681           0 :         struct rfapi_l2_group_cfg *rfg;
    3682           0 :         rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label);
    3683           0 :         if (rfg) {
    3684           0 :                 if (is_import)
    3685           0 :                         return rfg->rt_import_list;
    3686             :                 else
    3687           0 :                         return rfg->rt_export_list;
    3688             :         }
    3689             :         return NULL;
    3690             : }
    3691             : 
    3692           3 : void bgp_rfapi_cfg_init(void)
    3693             : {
    3694           3 :         install_node(&bgp_vnc_defaults_node);
    3695           3 :         install_node(&bgp_vnc_nve_group_node);
    3696           3 :         install_node(&bgp_vrf_policy_node);
    3697           3 :         install_node(&bgp_vnc_l2_group_node);
    3698           3 :         install_default(BGP_VRF_POLICY_NODE);
    3699           3 :         install_default(BGP_VNC_DEFAULTS_NODE);
    3700           3 :         install_default(BGP_VNC_NVE_GROUP_NODE);
    3701           3 :         install_default(BGP_VNC_L2_GROUP_NODE);
    3702             : 
    3703             :         /*
    3704             :          * Add commands
    3705             :          */
    3706           3 :         install_element(BGP_NODE, &vnc_defaults_cmd);
    3707           3 :         install_element(BGP_NODE, &vnc_nve_group_cmd);
    3708           3 :         install_element(BGP_NODE, &vnc_no_nve_group_cmd);
    3709           3 :         install_element(BGP_NODE, &vnc_vrf_policy_cmd);
    3710           3 :         install_element(BGP_NODE, &vnc_no_vrf_policy_cmd);
    3711           3 :         install_element(BGP_NODE, &vnc_l2_group_cmd);
    3712           3 :         install_element(BGP_NODE, &vnc_no_l2_group_cmd);
    3713           3 :         install_element(BGP_NODE, &vnc_advertise_un_method_cmd);
    3714           3 :         install_element(BGP_NODE, &vnc_export_mode_cmd);
    3715             : 
    3716           3 :         install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_import_cmd);
    3717           3 :         install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_export_cmd);
    3718           3 :         install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_both_cmd);
    3719           3 :         install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rd_cmd);
    3720           3 :         install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_l2rd_cmd);
    3721           3 :         install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_no_l2rd_cmd);
    3722           3 :         install_element(BGP_VNC_DEFAULTS_NODE,
    3723             :                         &vnc_defaults_responselifetime_cmd);
    3724           3 :         install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_cmd);
    3725             : 
    3726           3 :         install_element(BGP_NODE, &vnc_redistribute_protocol_cmd);
    3727           3 :         install_element(BGP_NODE, &vnc_no_redistribute_protocol_cmd);
    3728           3 :         install_element(BGP_NODE, &vnc_redistribute_nvegroup_cmd);
    3729           3 :         install_element(BGP_NODE, &vnc_redistribute_no_nvegroup_cmd);
    3730           3 :         install_element(BGP_NODE, &vnc_redistribute_lifetime_cmd);
    3731           3 :         install_element(BGP_NODE, &vnc_redistribute_rh_roo_localadmin_cmd);
    3732           3 :         install_element(BGP_NODE, &vnc_redistribute_mode_cmd);
    3733           3 :         install_element(BGP_NODE, &vnc_redistribute_bgp_exterior_cmd);
    3734             : 
    3735           3 :         install_element(BGP_NODE, &vnc_redist_bgpdirect_no_prefixlist_cmd);
    3736           3 :         install_element(BGP_NODE, &vnc_redist_bgpdirect_prefixlist_cmd);
    3737           3 :         install_element(BGP_NODE, &vnc_redist_bgpdirect_no_routemap_cmd);
    3738           3 :         install_element(BGP_NODE, &vnc_redist_bgpdirect_routemap_cmd);
    3739             : 
    3740           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3741             :                         &vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd);
    3742           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3743             :                         &vnc_nve_group_redist_bgpdirect_prefixlist_cmd);
    3744           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3745             :                         &vnc_nve_group_redist_bgpdirect_no_routemap_cmd);
    3746           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3747             :                         &vnc_nve_group_redist_bgpdirect_routemap_cmd);
    3748             : 
    3749           3 :         install_element(BGP_NODE, &vnc_export_nvegroup_cmd);
    3750           3 :         install_element(BGP_NODE, &vnc_no_export_nvegroup_cmd);
    3751           3 :         install_element(BGP_NODE, &vnc_nve_export_prefixlist_cmd);
    3752           3 :         install_element(BGP_NODE, &vnc_nve_export_routemap_cmd);
    3753           3 :         install_element(BGP_NODE, &vnc_nve_export_no_prefixlist_cmd);
    3754           3 :         install_element(BGP_NODE, &vnc_nve_export_no_routemap_cmd);
    3755             : 
    3756           3 :         install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_l2rd_cmd);
    3757           3 :         install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_no_l2rd_cmd);
    3758           3 :         install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_prefix_cmd);
    3759           3 :         install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_import_cmd);
    3760           3 :         install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_export_cmd);
    3761           3 :         install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_both_cmd);
    3762           3 :         install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rd_cmd);
    3763           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3764             :                         &vnc_nve_group_responselifetime_cmd);
    3765           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3766             :                         &vnc_nve_group_export_prefixlist_cmd);
    3767           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3768             :                         &vnc_nve_group_export_routemap_cmd);
    3769           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3770             :                         &vnc_nve_group_export_no_prefixlist_cmd);
    3771           3 :         install_element(BGP_VNC_NVE_GROUP_NODE,
    3772             :                         &vnc_nve_group_export_no_routemap_cmd);
    3773           3 :         install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_cmd);
    3774             : 
    3775           3 :         install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_label_cmd);
    3776           3 :         install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_no_label_cmd);
    3777             :         // Reenable to support VRF controller use case and testing
    3778           3 :         install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_nexthop_cmd);
    3779           3 :         install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_import_cmd);
    3780           3 :         install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_export_cmd);
    3781           3 :         install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_both_cmd);
    3782           3 :         install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rd_cmd);
    3783           3 :         install_element(BGP_VRF_POLICY_NODE,
    3784             :                         &vnc_vrf_policy_export_prefixlist_cmd);
    3785           3 :         install_element(BGP_VRF_POLICY_NODE,
    3786             :                         &vnc_vrf_policy_export_routemap_cmd);
    3787           3 :         install_element(BGP_VRF_POLICY_NODE,
    3788             :                         &vnc_vrf_policy_export_no_prefixlist_cmd);
    3789           3 :         install_element(BGP_VRF_POLICY_NODE,
    3790             :                         &vnc_vrf_policy_export_no_routemap_cmd);
    3791           3 :         install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd);
    3792             : 
    3793           3 :         install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_lni_cmd);
    3794           3 :         install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_labels_cmd);
    3795           3 :         install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_no_labels_cmd);
    3796           3 :         install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_rt_cmd);
    3797           3 :         install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_cmd);
    3798           3 : }
    3799             : 
    3800           1 : struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)
    3801             : {
    3802           1 :         struct rfapi_cfg *h;
    3803           1 :         afi_t afi;
    3804             : 
    3805           1 :         h = XCALLOC(MTYPE_RFAPI_CFG, sizeof(struct rfapi_cfg));
    3806           1 :         assert(h);
    3807             : 
    3808           1 :         h->nve_groups_sequential = list_new();
    3809           1 :         assert(h->nve_groups_sequential);
    3810           4 :         for (afi = AFI_IP; afi < AFI_MAX; afi++) {
    3811           3 :                 h->nve_groups_vn[afi] = agg_table_init();
    3812           3 :                 h->nve_groups_un[afi] = agg_table_init();
    3813             :         }
    3814           1 :         h->default_response_lifetime =
    3815             :                 BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;
    3816           1 :         h->rfg_export_direct_bgp_l = list_new();
    3817           1 :         h->rfg_export_zebra_l = list_new();
    3818           1 :         h->resolve_nve_roo_local_admin =
    3819             :                 BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT;
    3820             : 
    3821           1 :         SET_FLAG(h->flags, BGP_VNC_CONFIG_FLAGS_DEFAULT);
    3822             : 
    3823           1 :         if (cfg == NULL) {
    3824           0 :                 h->rfp_cfg.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL;
    3825           0 :                 h->rfp_cfg.ftd_advertisement_interval =
    3826             :                         RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL;
    3827           0 :                 h->rfp_cfg.holddown_factor =
    3828             :                         RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR;
    3829           0 :                 h->rfp_cfg.use_updated_response = 0;
    3830           0 :                 h->rfp_cfg.use_removes = 0;
    3831             :         } else {
    3832           1 :                 h->rfp_cfg.download_type = cfg->download_type;
    3833           1 :                 h->rfp_cfg.ftd_advertisement_interval =
    3834           1 :                         cfg->ftd_advertisement_interval;
    3835           1 :                 h->rfp_cfg.holddown_factor = cfg->holddown_factor;
    3836           1 :                 h->rfp_cfg.use_updated_response = cfg->use_updated_response;
    3837           1 :                 h->rfp_cfg.use_removes = cfg->use_removes;
    3838           1 :                 if (cfg->use_updated_response)
    3839           1 :                         h->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE;
    3840             :                 else
    3841             :                         h->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE;
    3842           1 :                 if (cfg->use_removes)
    3843           1 :                         h->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;
    3844             :                 else
    3845           0 :                         h->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;
    3846             :         }
    3847           1 :         return h;
    3848             : }
    3849             : 
    3850           0 : static void bgp_rfapi_rfgn_list_delete(void *data)
    3851             : {
    3852           0 :         struct rfapi_rfg_name *rfgn = data;
    3853           0 :         free(rfgn->name);
    3854           0 :         rfgn_free(rfgn);
    3855           0 : }
    3856             : 
    3857           1 : void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
    3858             : {
    3859           1 :         afi_t afi;
    3860           1 :         if (h == NULL)
    3861             :                 return;
    3862             : 
    3863           1 :         bgp_rfapi_delete_named_nve_group(NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX);
    3864           1 :         bgp_rfapi_delete_named_l2_group(NULL, bgp, NULL);
    3865           1 :         if (h->l2_groups != NULL)
    3866           0 :                 list_delete(&h->l2_groups);
    3867           1 :         list_delete(&h->nve_groups_sequential);
    3868             : 
    3869           1 :         h->rfg_export_direct_bgp_l->del = bgp_rfapi_rfgn_list_delete;
    3870           1 :         list_delete(&h->rfg_export_direct_bgp_l);
    3871             : 
    3872           1 :         h->rfg_export_zebra_l->del = bgp_rfapi_rfgn_list_delete;
    3873           1 :         list_delete(&h->rfg_export_zebra_l);
    3874             : 
    3875           1 :         if (h->default_rt_export_list)
    3876           0 :                 ecommunity_free(&h->default_rt_export_list);
    3877           1 :         if (h->default_rt_import_list)
    3878           0 :                 ecommunity_free(&h->default_rt_import_list);
    3879           1 :         XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg);
    3880           4 :         for (afi = AFI_IP; afi < AFI_MAX; afi++) {
    3881           3 :                 agg_table_finish(h->nve_groups_vn[afi]);
    3882           3 :                 agg_table_finish(h->nve_groups_un[afi]);
    3883             :         }
    3884           1 :         XFREE(MTYPE_RFAPI_CFG, h);
    3885             : }
    3886             : 
    3887           0 : int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
    3888             : {
    3889           0 :         struct listnode *node, *nnode;
    3890           0 :         struct rfapi_nve_group_cfg *rfg;
    3891           0 :         struct rfapi_cfg *hc = bgp->rfapi_cfg;
    3892           0 :         struct rfapi_rfg_name *rfgn;
    3893           0 :         int write = 0;
    3894           0 :         afi_t afi;
    3895           0 :         int type;
    3896           0 :         if (bgp->rfapi == NULL || hc == NULL)
    3897             :                 return write;
    3898             : 
    3899           0 :         vty_out(vty, "!\n");
    3900           0 :         for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg))
    3901           0 :                 if (rfg->type == RFAPI_GROUP_CFG_VRF) {
    3902           0 :                         ++write;
    3903           0 :                         vty_out(vty, " vrf-policy %s\n", rfg->name);
    3904           0 :                         if (rfg->label <= MPLS_LABEL_MAX) {
    3905           0 :                                 vty_out(vty, "  label %u\n", rfg->label);
    3906             :                         }
    3907           0 :                         if (CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) {
    3908           0 :                                 vty_out(vty, "  nexthop self\n");
    3909             : 
    3910             :                         } else {
    3911           0 :                                 if (rfg->vn_prefix.family) {
    3912           0 :                                         char buf[BUFSIZ];
    3913           0 :                                         buf[0] = buf[BUFSIZ - 1] = 0;
    3914           0 :                                         inet_ntop(rfg->vn_prefix.family,
    3915           0 :                                                   &rfg->vn_prefix.u.prefix, buf,
    3916             :                                                   sizeof(buf));
    3917           0 :                                         if (!buf[0] || buf[BUFSIZ - 1]) {
    3918             :                                                 // vty_out (vty, "nexthop
    3919             :                                                 // self\n");
    3920             :                                         } else {
    3921           0 :                                                 vty_out(vty, "  nexthop %s\n",
    3922             :                                                         buf);
    3923             :                                         }
    3924             :                                 }
    3925             :                         }
    3926             : 
    3927           0 :                         if (rfg->rd.prefixlen) {
    3928           0 :                                 if (AF_UNIX == rfg->rd.family) {
    3929             : 
    3930           0 :                                         uint16_t value = 0;
    3931             : 
    3932           0 :                                         value = ((rfg->rd.val[6] << 8)
    3933             :                                                  & 0x0ff00)
    3934           0 :                                                 | (rfg->rd.val[7] & 0x0ff);
    3935             : 
    3936           0 :                                         vty_out(vty, "  rd auto:nh:%d\n",
    3937             :                                                 value);
    3938             : 
    3939             :                                 } else
    3940           0 :                                         vty_out(vty, "  rd %pRD\n", &rfg->rd);
    3941             :                         }
    3942             : 
    3943           0 :                         if (rfg->rt_import_list && rfg->rt_export_list
    3944           0 :                             && ecommunity_cmp(rfg->rt_import_list,
    3945           0 :                                               rfg->rt_export_list)) {
    3946           0 :                                 char *b = ecommunity_ecom2str(
    3947             :                                         rfg->rt_import_list,
    3948             :                                         ECOMMUNITY_FORMAT_ROUTE_MAP,
    3949             :                                         ECOMMUNITY_ROUTE_TARGET);
    3950           0 :                                 vty_out(vty, "  rt both %s\n", b);
    3951           0 :                                 XFREE(MTYPE_ECOMMUNITY_STR, b);
    3952             :                         } else {
    3953           0 :                                 if (rfg->rt_import_list) {
    3954           0 :                                         char *b = ecommunity_ecom2str(
    3955             :                                                 rfg->rt_import_list,
    3956             :                                                 ECOMMUNITY_FORMAT_ROUTE_MAP,
    3957             :                                                 ECOMMUNITY_ROUTE_TARGET);
    3958           0 :                                         vty_out(vty, "  rt import %s\n", b);
    3959           0 :                                         XFREE(MTYPE_ECOMMUNITY_STR, b);
    3960             :                                 }
    3961           0 :                                 if (rfg->rt_export_list) {
    3962           0 :                                         char *b = ecommunity_ecom2str(
    3963             :                                                 rfg->rt_export_list,
    3964             :                                                 ECOMMUNITY_FORMAT_ROUTE_MAP,
    3965             :                                                 ECOMMUNITY_ROUTE_TARGET);
    3966           0 :                                         vty_out(vty, "  rt export %s\n", b);
    3967           0 :                                         XFREE(MTYPE_ECOMMUNITY_STR, b);
    3968             :                                 }
    3969             :                         }
    3970             : 
    3971             :                         /*
    3972             :                          * route filtering: prefix-lists and route-maps
    3973             :                          */
    3974           0 :                         for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
    3975             : 
    3976           0 :                                 const char *afistr =
    3977           0 :                                         (afi == AFI_IP) ? "ipv4" : "ipv6";
    3978             : 
    3979           0 :                                 if (rfg->plist_export_bgp_name[afi]) {
    3980           0 :                                         vty_out(vty,
    3981             :                                                 "  export %s%s prefix-list %s\n",
    3982           0 :                                                 (rfg->type == RFAPI_GROUP_CFG_VRF
    3983             :                                                          ? ""
    3984             :                                                          : "bgp "),
    3985             :                                                 afistr,
    3986             :                                                 rfg->plist_export_bgp_name
    3987             :                                                         [afi]);
    3988             :                                 }
    3989           0 :                                 if (rfg->plist_export_zebra_name[afi]) {
    3990           0 :                                         vty_out(vty,
    3991             :                                                 "  export %s%s prefix-list %s\n",
    3992           0 :                                                 (rfg->type == RFAPI_GROUP_CFG_VRF
    3993             :                                                          ? ""
    3994             :                                                          : "zebra "),
    3995             :                                                 afistr,
    3996             :                                                 rfg->plist_export_zebra_name
    3997             :                                                         [afi]);
    3998             :                                 }
    3999             :                                 /*
    4000             :                                  * currently we only support redist plists for
    4001             :                                  * bgp-direct.
    4002             :                                  * If we later add plist support for
    4003             :                                  * redistributing other
    4004             :                                  * protocols, we'll need to loop over protocols
    4005             :                                  * here
    4006             :                                  */
    4007           0 :                                 if (rfg->plist_redist_name
    4008           0 :                                             [ZEBRA_ROUTE_BGP_DIRECT][afi]) {
    4009           0 :                                         vty_out(vty,
    4010             :                                                 "  redistribute bgp-direct %s prefix-list %s\n",
    4011             :                                                 afistr,
    4012             :                                                 rfg->plist_redist_name
    4013             :                                                         [ZEBRA_ROUTE_BGP_DIRECT]
    4014             :                                                         [afi]);
    4015             :                                 }
    4016           0 :                                 if (rfg->plist_redist_name
    4017           0 :                                             [ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) {
    4018           0 :                                         vty_out(vty,
    4019             :                                                 "  redistribute bgp-direct-to-nve-groups %s prefix-list %s\n",
    4020             :                                                 afistr,
    4021             :                                                 rfg->plist_redist_name
    4022             :                                                         [ZEBRA_ROUTE_BGP_DIRECT_EXT]
    4023             :                                                         [afi]);
    4024             :                                 }
    4025             :                         }
    4026             : 
    4027           0 :                         if (rfg->routemap_export_bgp_name) {
    4028           0 :                                 vty_out(vty, "  export %sroute-map %s\n",
    4029           0 :                                         (rfg->type == RFAPI_GROUP_CFG_VRF
    4030             :                                                  ? ""
    4031             :                                                  : "bgp "),
    4032             :                                         rfg->routemap_export_bgp_name);
    4033             :                         }
    4034           0 :                         if (rfg->routemap_export_zebra_name) {
    4035           0 :                                 vty_out(vty, "  export %sroute-map %s\n",
    4036           0 :                                         (rfg->type == RFAPI_GROUP_CFG_VRF
    4037             :                                                  ? ""
    4038             :                                                  : "zebra "),
    4039             :                                         rfg->routemap_export_zebra_name);
    4040             :                         }
    4041           0 :                         if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) {
    4042           0 :                                 vty_out(vty,
    4043             :                                         "  redistribute bgp-direct route-map %s\n",
    4044             :                                         rfg->routemap_redist_name
    4045             :                                                 [ZEBRA_ROUTE_BGP_DIRECT]);
    4046             :                         }
    4047           0 :                         if (rfg->routemap_redist_name
    4048           0 :                                     [ZEBRA_ROUTE_BGP_DIRECT_EXT]) {
    4049           0 :                                 vty_out(vty,
    4050             :                                         "  redistribute bgp-direct-to-nve-groups route-map %s\n",
    4051             :                                         rfg->routemap_redist_name
    4052             :                                                 [ZEBRA_ROUTE_BGP_DIRECT_EXT]);
    4053             :                         }
    4054           0 :                         vty_out(vty, " exit-vrf-policy\n");
    4055           0 :                         vty_out(vty, "!\n");
    4056             :                 }
    4057           0 :         if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) {
    4058           0 :                 vty_out(vty, " vnc advertise-un-method encap-safi\n");
    4059           0 :                 write++;
    4060             :         }
    4061             : 
    4062             :         { /* was based on listen ports */
    4063             :                 /* for now allow both old and new */
    4064           0 :                 if (bgp->rfapi->rfp_methods.cfg_cb)
    4065           0 :                         write += (bgp->rfapi->rfp_methods.cfg_cb)(
    4066             :                                 vty, bgp->rfapi->rfp);
    4067             : 
    4068           0 :                 if (write)
    4069           0 :                         vty_out(vty, "!\n");
    4070             : 
    4071           0 :                 if (hc->l2_groups) {
    4072           0 :                         struct rfapi_l2_group_cfg *rfgc = NULL;
    4073           0 :                         struct listnode *gnode;
    4074           0 :                         for (ALL_LIST_ELEMENTS_RO(hc->l2_groups, gnode, rfgc)) {
    4075           0 :                                 struct listnode *lnode;
    4076           0 :                                 void *data;
    4077           0 :                                 ++write;
    4078           0 :                                 vty_out(vty, " vnc l2-group %s\n", rfgc->name);
    4079           0 :                                 if (rfgc->logical_net_id != 0)
    4080           0 :                                         vty_out(vty,
    4081             :                                                 "   logical-network-id %u\n",
    4082             :                                                 rfgc->logical_net_id);
    4083           0 :                                 if (rfgc->labels != NULL
    4084           0 :                                     && listhead(rfgc->labels) != NULL) {
    4085           0 :                                         vty_out(vty, "   labels ");
    4086           0 :                                         for (ALL_LIST_ELEMENTS_RO(rfgc->labels,
    4087             :                                                                   lnode,
    4088             :                                                                   data)) {
    4089           0 :                                                 vty_out(vty, "%hu ",
    4090           0 :                                                         (uint16_t)(
    4091             :                                                                 (uintptr_t)
    4092             :                                                                         data));
    4093             :                                         }
    4094           0 :                                         vty_out(vty, "\n");
    4095             :                                 }
    4096             : 
    4097           0 :                                 if (rfgc->rt_import_list && rfgc->rt_export_list
    4098           0 :                                     && ecommunity_cmp(rfgc->rt_import_list,
    4099           0 :                                                       rfgc->rt_export_list)) {
    4100           0 :                                         char *b = ecommunity_ecom2str(
    4101             :                                                 rfgc->rt_import_list,
    4102             :                                                 ECOMMUNITY_FORMAT_ROUTE_MAP,
    4103             :                                                 ECOMMUNITY_ROUTE_TARGET);
    4104           0 :                                         vty_out(vty, "   rt both %s\n", b);
    4105           0 :                                         XFREE(MTYPE_ECOMMUNITY_STR, b);
    4106             :                                 } else {
    4107           0 :                                         if (rfgc->rt_import_list) {
    4108           0 :                                                 char *b = ecommunity_ecom2str(
    4109             :                                                         rfgc->rt_import_list,
    4110             :                                                         ECOMMUNITY_FORMAT_ROUTE_MAP,
    4111             :                                                         ECOMMUNITY_ROUTE_TARGET);
    4112           0 :                                                 vty_out(vty, "  rt import %s\n",
    4113             :                                                         b);
    4114           0 :                                                 XFREE(MTYPE_ECOMMUNITY_STR, b);
    4115             :                                         }
    4116           0 :                                         if (rfgc->rt_export_list) {
    4117           0 :                                                 char *b = ecommunity_ecom2str(
    4118             :                                                         rfgc->rt_export_list,
    4119             :                                                         ECOMMUNITY_FORMAT_ROUTE_MAP,
    4120             :                                                         ECOMMUNITY_ROUTE_TARGET);
    4121           0 :                                                 vty_out(vty, "  rt export %s\n",
    4122             :                                                         b);
    4123           0 :                                                 XFREE(MTYPE_ECOMMUNITY_STR, b);
    4124             :                                         }
    4125             :                                 }
    4126           0 :                                 if (bgp->rfapi->rfp_methods.cfg_group_cb)
    4127           0 :                                         write += (bgp->rfapi->rfp_methods
    4128           0 :                                                           .cfg_group_cb)(
    4129             :                                                 vty, bgp->rfapi->rfp,
    4130             :                                                 RFAPI_RFP_CFG_GROUP_L2,
    4131           0 :                                                 rfgc->name, rfgc->rfp_cfg);
    4132           0 :                                 vty_out(vty, " exit-vnc\n");
    4133           0 :                                 vty_out(vty, "!\n");
    4134             :                         }
    4135             :                 }
    4136             : 
    4137           0 :                 if (hc->default_rd.prefixlen
    4138           0 :                     || hc->default_response_lifetime
    4139             :                                != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT
    4140           0 :                     || hc->default_rt_import_list || hc->default_rt_export_list
    4141           0 :                     || hc->nve_groups_sequential->count) {
    4142             : 
    4143             : 
    4144           0 :                         ++write;
    4145           0 :                         vty_out(vty, " vnc defaults\n");
    4146             : 
    4147           0 :                         if (hc->default_rd.prefixlen) {
    4148           0 :                                 if (AF_UNIX == hc->default_rd.family) {
    4149           0 :                                         uint16_t value = 0;
    4150             : 
    4151           0 :                                         value = ((hc->default_rd.val[6] << 8)
    4152             :                                                  & 0x0ff00)
    4153           0 :                                                 | (hc->default_rd.val[7]
    4154             :                                                    & 0x0ff);
    4155             : 
    4156           0 :                                         vty_out(vty, "  rd auto:vn:%d\n",
    4157             :                                                 value);
    4158             : 
    4159             :                                 } else
    4160           0 :                                         vty_out(vty, "  rd %pRD\n",
    4161             :                                                 &hc->default_rd);
    4162             :                         }
    4163           0 :                         if (hc->default_response_lifetime
    4164             :                             != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT) {
    4165           0 :                                 vty_out(vty, "  response-lifetime ");
    4166           0 :                                 if (hc->default_response_lifetime != UINT32_MAX)
    4167           0 :                                         vty_out(vty, "%d",
    4168             :                                                 hc->default_response_lifetime);
    4169             :                                 else
    4170           0 :                                         vty_out(vty, "infinite");
    4171           0 :                                 vty_out(vty, "\n");
    4172             :                         }
    4173           0 :                         if (hc->default_rt_import_list
    4174           0 :                             && hc->default_rt_export_list
    4175           0 :                             && ecommunity_cmp(hc->default_rt_import_list,
    4176           0 :                                               hc->default_rt_export_list)) {
    4177           0 :                                 char *b = ecommunity_ecom2str(
    4178             :                                         hc->default_rt_import_list,
    4179             :                                         ECOMMUNITY_FORMAT_ROUTE_MAP,
    4180             :                                         ECOMMUNITY_ROUTE_TARGET);
    4181           0 :                                 vty_out(vty, "  rt both %s\n", b);
    4182           0 :                                 XFREE(MTYPE_ECOMMUNITY_STR, b);
    4183             :                         } else {
    4184           0 :                                 if (hc->default_rt_import_list) {
    4185           0 :                                         char *b = ecommunity_ecom2str(
    4186             :                                                 hc->default_rt_import_list,
    4187             :                                                 ECOMMUNITY_FORMAT_ROUTE_MAP,
    4188             :                                                 ECOMMUNITY_ROUTE_TARGET);
    4189           0 :                                         vty_out(vty, "  rt import %s\n", b);
    4190           0 :                                         XFREE(MTYPE_ECOMMUNITY_STR, b);
    4191             :                                 }
    4192           0 :                                 if (hc->default_rt_export_list) {
    4193           0 :                                         char *b = ecommunity_ecom2str(
    4194             :                                                 hc->default_rt_export_list,
    4195             :                                                 ECOMMUNITY_FORMAT_ROUTE_MAP,
    4196             :                                                 ECOMMUNITY_ROUTE_TARGET);
    4197           0 :                                         vty_out(vty, "  rt export %s\n", b);
    4198           0 :                                         XFREE(MTYPE_ECOMMUNITY_STR, b);
    4199             :                                 }
    4200             :                         }
    4201           0 :                         if (bgp->rfapi->rfp_methods.cfg_group_cb)
    4202           0 :                                 write += (bgp->rfapi->rfp_methods.cfg_group_cb)(
    4203             :                                         vty, bgp->rfapi->rfp,
    4204             :                                         RFAPI_RFP_CFG_GROUP_DEFAULT, NULL,
    4205           0 :                                         bgp->rfapi_cfg->default_rfp_cfg);
    4206           0 :                         vty_out(vty, " exit-vnc\n");
    4207           0 :                         vty_out(vty, "!\n");
    4208             :                 }
    4209             : 
    4210           0 :                 for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode,
    4211             :                                        rfg))
    4212           0 :                         if (rfg->type == RFAPI_GROUP_CFG_NVE) {
    4213           0 :                                 ++write;
    4214           0 :                                 vty_out(vty, " vnc nve-group %s\n", rfg->name);
    4215             : 
    4216           0 :                                 if (rfg->vn_prefix.family && rfg->vn_node)
    4217           0 :                                         vty_out(vty, "  prefix %s %pFX\n", "vn",
    4218             :                                                 &rfg->vn_prefix);
    4219             : 
    4220           0 :                                 if (rfg->un_prefix.family && rfg->un_node)
    4221           0 :                                         vty_out(vty, "  prefix %s %pFX\n", "un",
    4222             :                                                 &rfg->un_prefix);
    4223             : 
    4224             : 
    4225           0 :                                 if (rfg->rd.prefixlen) {
    4226           0 :                                         if (AF_UNIX == rfg->rd.family) {
    4227             : 
    4228           0 :                                                 uint16_t value = 0;
    4229             : 
    4230           0 :                                                 value = ((rfg->rd.val[6] << 8)
    4231             :                                                          & 0x0ff00)
    4232           0 :                                                         | (rfg->rd.val[7]
    4233             :                                                            & 0x0ff);
    4234             : 
    4235           0 :                                                 vty_out(vty,
    4236             :                                                         "  rd auto:vn:%d\n",
    4237             :                                                         value);
    4238             : 
    4239             :                                         } else
    4240           0 :                                                 vty_out(vty, "  rd %pRD\n",
    4241             :                                                         &rfg->rd);
    4242             :                                 }
    4243           0 :                                 if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) {
    4244           0 :                                         vty_out(vty, "  response-lifetime ");
    4245           0 :                                         if (rfg->response_lifetime
    4246             :                                             != UINT32_MAX)
    4247           0 :                                                 vty_out(vty, "%d",
    4248             :                                                         rfg->response_lifetime);
    4249             :                                         else
    4250           0 :                                                 vty_out(vty, "infinite");
    4251           0 :                                         vty_out(vty, "\n");
    4252             :                                 }
    4253             : 
    4254           0 :                                 if (rfg->rt_import_list && rfg->rt_export_list
    4255           0 :                                     && ecommunity_cmp(rfg->rt_import_list,
    4256           0 :                                                       rfg->rt_export_list)) {
    4257           0 :                                         char *b = ecommunity_ecom2str(
    4258             :                                                 rfg->rt_import_list,
    4259             :                                                 ECOMMUNITY_FORMAT_ROUTE_MAP,
    4260             :                                                 ECOMMUNITY_ROUTE_TARGET);
    4261           0 :                                         vty_out(vty, "  rt both %s\n", b);
    4262           0 :                                         XFREE(MTYPE_ECOMMUNITY_STR, b);
    4263             :                                 } else {
    4264           0 :                                         if (rfg->rt_import_list) {
    4265           0 :                                                 char *b = ecommunity_ecom2str(
    4266             :                                                         rfg->rt_import_list,
    4267             :                                                         ECOMMUNITY_FORMAT_ROUTE_MAP,
    4268             :                                                         ECOMMUNITY_ROUTE_TARGET);
    4269           0 :                                                 vty_out(vty, "  rt import %s\n",
    4270             :                                                         b);
    4271           0 :                                                 XFREE(MTYPE_ECOMMUNITY_STR, b);
    4272             :                                         }
    4273           0 :                                         if (rfg->rt_export_list) {
    4274           0 :                                                 char *b = ecommunity_ecom2str(
    4275             :                                                         rfg->rt_export_list,
    4276             :                                                         ECOMMUNITY_FORMAT_ROUTE_MAP,
    4277             :                                                         ECOMMUNITY_ROUTE_TARGET);
    4278           0 :                                                 vty_out(vty, "  rt export %s\n",
    4279             :                                                         b);
    4280           0 :                                                 XFREE(MTYPE_ECOMMUNITY_STR, b);
    4281             :                                         }
    4282             :                                 }
    4283             : 
    4284             :                                 /*
    4285             :                                  * route filtering: prefix-lists and route-maps
    4286             :                                  */
    4287           0 :                                 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
    4288             : 
    4289           0 :                                         const char *afistr = (afi == AFI_IP)
    4290             :                                                                      ? "ipv4"
    4291           0 :                                                                      : "ipv6";
    4292             : 
    4293           0 :                                         if (rfg->plist_export_bgp_name[afi]) {
    4294           0 :                                                 vty_out(vty,
    4295             :                                                         "  export bgp %s prefix-list %s\n",
    4296             :                                                         afistr,
    4297             :                                                         rfg->plist_export_bgp_name
    4298             :                                                                 [afi]);
    4299             :                                         }
    4300           0 :                                         if (rfg->plist_export_zebra_name[afi]) {
    4301           0 :                                                 vty_out(vty,
    4302             :                                                         "  export zebra %s prefix-list %s\n",
    4303             :                                                         afistr,
    4304             :                                                         rfg->plist_export_zebra_name
    4305             :                                                                 [afi]);
    4306             :                                         }
    4307             :                                         /*
    4308             :                                          * currently we only support redist
    4309             :                                          * plists for bgp-direct.
    4310             :                                          * If we later add plist support for
    4311             :                                          * redistributing other
    4312             :                                          * protocols, we'll need to loop over
    4313             :                                          * protocols here
    4314             :                                          */
    4315           0 :                                         if (rfg->plist_redist_name
    4316             :                                                     [ZEBRA_ROUTE_BGP_DIRECT]
    4317           0 :                                                     [afi]) {
    4318           0 :                                                 vty_out(vty,
    4319             :                                                         "  redistribute bgp-direct %s prefix-list %s\n",
    4320             :                                                         afistr,
    4321             :                                                         rfg->plist_redist_name
    4322             :                                                                 [ZEBRA_ROUTE_BGP_DIRECT]
    4323             :                                                                 [afi]);
    4324             :                                         }
    4325           0 :                                         if (rfg->plist_redist_name
    4326             :                                                     [ZEBRA_ROUTE_BGP_DIRECT_EXT]
    4327           0 :                                                     [afi]) {
    4328           0 :                                                 vty_out(vty,
    4329             :                                                         "  redistribute bgp-direct-to-nve-groups %s prefix-list %s\n",
    4330             :                                                         afistr,
    4331             :                                                         rfg->plist_redist_name
    4332             :                                                                 [ZEBRA_ROUTE_BGP_DIRECT_EXT]
    4333             :                                                                 [afi]);
    4334             :                                         }
    4335             :                                 }
    4336             : 
    4337           0 :                                 if (rfg->routemap_export_bgp_name) {
    4338           0 :                                         vty_out(vty,
    4339             :                                                 "  export bgp route-map %s\n",
    4340             :                                                 rfg->routemap_export_bgp_name);
    4341             :                                 }
    4342           0 :                                 if (rfg->routemap_export_zebra_name) {
    4343           0 :                                         vty_out(vty,
    4344             :                                                 "  export zebra route-map %s\n",
    4345             :                                                 rfg->routemap_export_zebra_name);
    4346             :                                 }
    4347           0 :                                 if (rfg->routemap_redist_name
    4348           0 :                                             [ZEBRA_ROUTE_BGP_DIRECT]) {
    4349           0 :                                         vty_out(vty,
    4350             :                                                 "  redistribute bgp-direct route-map %s\n",
    4351             :                                                 rfg->routemap_redist_name
    4352             :                                                         [ZEBRA_ROUTE_BGP_DIRECT]);
    4353             :                                 }
    4354           0 :                                 if (rfg->routemap_redist_name
    4355           0 :                                             [ZEBRA_ROUTE_BGP_DIRECT_EXT]) {
    4356           0 :                                         vty_out(vty,
    4357             :                                                 "  redistribute bgp-direct-to-nve-groups route-map %s\n",
    4358             :                                                 rfg->routemap_redist_name
    4359             :                                                         [ZEBRA_ROUTE_BGP_DIRECT_EXT]);
    4360             :                                 }
    4361           0 :                                 if (bgp->rfapi->rfp_methods.cfg_group_cb)
    4362           0 :                                         write += (bgp->rfapi->rfp_methods
    4363           0 :                                                           .cfg_group_cb)(
    4364             :                                                 vty, bgp->rfapi->rfp,
    4365             :                                                 RFAPI_RFP_CFG_GROUP_NVE,
    4366           0 :                                                 rfg->name, rfg->rfp_cfg);
    4367           0 :                                 vty_out(vty, " exit-vnc\n");
    4368           0 :                                 vty_out(vty, "!\n");
    4369             :                         }
    4370             :         } /* have listen ports */
    4371             : 
    4372             :         /*
    4373             :          * route export to other protocols
    4374             :          */
    4375           0 :         if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) {
    4376           0 :                 vty_out(vty, " vnc export bgp mode group-nve\n");
    4377           0 :         } else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) {
    4378           0 :                 vty_out(vty, " vnc export bgp mode registering-nve\n");
    4379           0 :         } else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) {
    4380           0 :                 vty_out(vty, " vnc export bgp mode ce\n");
    4381             :         }
    4382             : 
    4383           0 :         if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) {
    4384           0 :                 vty_out(vty, " vnc export zebra mode group-nve\n");
    4385           0 :         } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) {
    4386           0 :                 vty_out(vty, " vnc export zebra mode registering-nve\n");
    4387             :         }
    4388             : 
    4389           0 :         if (hc->rfg_export_direct_bgp_l) {
    4390           0 :                 for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l, node, nnode,
    4391             :                                        rfgn)) {
    4392             : 
    4393           0 :                         vty_out(vty, " vnc export bgp group-nve group %s\n",
    4394             :                                 rfgn->name);
    4395             :                 }
    4396             :         }
    4397             : 
    4398           0 :         if (hc->rfg_export_zebra_l) {
    4399           0 :                 for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node, nnode,
    4400             :                                        rfgn)) {
    4401             : 
    4402           0 :                         vty_out(vty, " vnc export zebra group-nve group %s\n",
    4403             :                                 rfgn->name);
    4404             :                 }
    4405             :         }
    4406             : 
    4407             : 
    4408           0 :         if (hc->rfg_redist_name) {
    4409           0 :                 vty_out(vty, " vnc redistribute nve-group %s\n",
    4410             :                         hc->rfg_redist_name);
    4411             :         }
    4412           0 :         if (hc->redist_lifetime) {
    4413           0 :                 vty_out(vty, " vnc redistribute lifetime %d\n",
    4414             :                         hc->redist_lifetime);
    4415             :         }
    4416           0 :         if (hc->resolve_nve_roo_local_admin
    4417             :             != BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT) {
    4418             : 
    4419           0 :                 vty_out(vty,
    4420             :                         " vnc redistribute resolve-nve roo-ec-local-admin %d\n",
    4421             :                         hc->resolve_nve_roo_local_admin);
    4422             :         }
    4423             : 
    4424           0 :         if (hc->redist_mode) /* ! default */
    4425             :         {
    4426           0 :                 const char *s = "";
    4427             : 
    4428           0 :                 switch (hc->redist_mode) {
    4429             :                 case VNC_REDIST_MODE_PLAIN:
    4430             :                         s = "plain";
    4431             :                         break;
    4432             :                 case VNC_REDIST_MODE_RFG:
    4433           0 :                         s = "nve-group";
    4434           0 :                         break;
    4435             :                 case VNC_REDIST_MODE_RESOLVE_NVE:
    4436           0 :                         s = "resolve-nve";
    4437           0 :                         break;
    4438             :                 }
    4439           0 :                 if (s) {
    4440           0 :                         vty_out(vty, " vnc redistribute mode %s\n", s);
    4441             :                 }
    4442             :         }
    4443             : 
    4444             :         /*
    4445             :          * route filtering: prefix-lists and route-maps
    4446             :          */
    4447           0 :         for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
    4448             : 
    4449           0 :                 const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6";
    4450             : 
    4451           0 :                 if (hc->plist_export_bgp_name[afi]) {
    4452           0 :                         vty_out(vty, " vnc export bgp %s prefix-list %s\n",
    4453             :                                 afistr, hc->plist_export_bgp_name[afi]);
    4454             :                 }
    4455           0 :                 if (hc->plist_export_zebra_name[afi]) {
    4456           0 :                         vty_out(vty, " vnc export zebra %s prefix-list %s\n",
    4457             :                                 afistr, hc->plist_export_zebra_name[afi]);
    4458             :                 }
    4459           0 :                 if (hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) {
    4460           0 :                         vty_out(vty,
    4461             :                                 " vnc redistribute bgp-direct %s prefix-list %s\n",
    4462             :                                 afistr,
    4463             :                                 hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT]
    4464             :                                                      [afi]);
    4465             :                 }
    4466             :         }
    4467             : 
    4468           0 :         if (hc->routemap_export_bgp_name) {
    4469           0 :                 vty_out(vty, " vnc export bgp route-map %s\n",
    4470             :                         hc->routemap_export_bgp_name);
    4471             :         }
    4472           0 :         if (hc->routemap_export_zebra_name) {
    4473           0 :                 vty_out(vty, " vnc export zebra route-map %s\n",
    4474             :                         hc->routemap_export_zebra_name);
    4475             :         }
    4476           0 :         if (hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) {
    4477           0 :                 vty_out(vty, " vnc redistribute bgp-direct route-map %s\n",
    4478             :                         hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]);
    4479             :         }
    4480             : 
    4481           0 :         for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
    4482           0 :                 for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
    4483           0 :                         if (hc->redist[afi][type]) {
    4484           0 :                                 if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT
    4485           0 :                                     && hc->redist_bgp_exterior_view_name) {
    4486           0 :                                         vty_out(vty,
    4487             :                                                 " vnc redistribute %s %s view %s\n",
    4488             :                                                 ((afi == AFI_IP) ? "ipv4"
    4489             :                                                                  : "ipv6"),
    4490             :                                                 zebra_route_string(type),
    4491             :                                                 hc->redist_bgp_exterior_view_name);
    4492             :                                 } else {
    4493           0 :                                         vty_out(vty,
    4494             :                                                 " vnc redistribute %s %s\n",
    4495             :                                                 ((afi == AFI_IP) ? "ipv4"
    4496             :                                                                  : "ipv6"),
    4497             :                                                 zebra_route_string(type));
    4498             :                                 }
    4499             :                         }
    4500             :                 }
    4501             :         }
    4502             :         return write;
    4503             : }
    4504             : 
    4505           0 : void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty)
    4506             : {
    4507           0 :         struct rfapi_cfg *hc = bgp->rfapi_cfg;
    4508           0 :         afi_t afi;
    4509           0 :         int type, redist = 0;
    4510           0 :         char tmp[40];
    4511           0 :         if (hc == NULL)
    4512             :                 return;
    4513             : 
    4514           0 :         vty_out(vty, "%-39s %-19s %s\n", "VNC Advertise method:",
    4515             :                 (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
    4516             :                          ? "Encapsulation SAFI"
    4517             :                          : "Tunnel Encap attribute"),
    4518           0 :                 ((hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)
    4519             :                                  == (BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP
    4520             :                                      & BGP_VNC_CONFIG_FLAGS_DEFAULT)
    4521             :                          ? "(default)"
    4522             :                          : ""));
    4523             :         /* export */
    4524           0 :         vty_out(vty, "%-39s ", "Export from VNC:");
    4525             :         /*
    4526             :          * route export to other protocols
    4527             :          */
    4528           0 :         if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) {
    4529           0 :                 redist++;
    4530           0 :                 vty_out(vty, "ToBGP Groups={");
    4531           0 :                 if (hc->rfg_export_direct_bgp_l) {
    4532           0 :                         int cnt = 0;
    4533           0 :                         struct listnode *node, *nnode;
    4534           0 :                         struct rfapi_rfg_name *rfgn;
    4535           0 :                         for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l,
    4536             :                                                node, nnode, rfgn)) {
    4537           0 :                                 if (cnt++ != 0)
    4538           0 :                                         vty_out(vty, ",");
    4539             : 
    4540           0 :                                 vty_out(vty, "%s", rfgn->name);
    4541             :                         }
    4542             :                 }
    4543           0 :                 vty_out(vty, "}");
    4544           0 :         } else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) {
    4545           0 :                 redist++;
    4546           0 :                 vty_out(vty, "ToBGP {Registering NVE}");
    4547             :                 /* note filters, route-maps not shown */
    4548           0 :         } else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) {
    4549           0 :                 redist++;
    4550           0 :                 vty_out(vty, "ToBGP {NVE connected router:%d}",
    4551           0 :                         hc->resolve_nve_roo_local_admin);
    4552             :                 /* note filters, route-maps not shown */
    4553             :         }
    4554             : 
    4555           0 :         if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) {
    4556           0 :                 redist++;
    4557           0 :                 vty_out(vty, "%sToZebra Groups={", (redist == 1 ? "" : " "));
    4558           0 :                 if (hc->rfg_export_zebra_l) {
    4559           0 :                         int cnt = 0;
    4560           0 :                         struct listnode *node, *nnode;
    4561           0 :                         struct rfapi_rfg_name *rfgn;
    4562           0 :                         for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node,
    4563             :                                                nnode, rfgn)) {
    4564           0 :                                 if (cnt++ != 0)
    4565           0 :                                         vty_out(vty, ",");
    4566           0 :                                 vty_out(vty, "%s", rfgn->name);
    4567             :                         }
    4568             :                 }
    4569           0 :                 vty_out(vty, "}");
    4570           0 :         } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) {
    4571           0 :                 redist++;
    4572           0 :                 vty_out(vty, "%sToZebra {Registering NVE}",
    4573             :                         (redist == 1 ? "" : " "));
    4574             :                 /* note filters, route-maps not shown */
    4575             :         }
    4576           0 :         vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"),
    4577             :                 (redist ? "" : "(default)"));
    4578             : 
    4579             :         /* Redistribution */
    4580           0 :         redist = 0;
    4581           0 :         vty_out(vty, "%-39s ", "Redistribution into VNC:");
    4582           0 :         for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
    4583           0 :                 for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) {
    4584           0 :                         if (hc->redist[afi][type]) {
    4585           0 :                                 vty_out(vty, "{%s,%s} ",
    4586             :                                         ((afi == AFI_IP) ? "ipv4" : "ipv6"),
    4587             :                                         zebra_route_string(type));
    4588           0 :                                 redist++;
    4589             :                         }
    4590             :                 }
    4591             :         }
    4592           0 :         vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"),
    4593             :                 (redist ? "" : "(default)"));
    4594             : 
    4595           0 :         vty_out(vty, "%-39s %3u%-16s %s\n",
    4596             :                 "RFP Registration Hold-Down Factor:",
    4597             :                 hc->rfp_cfg.holddown_factor, "%",
    4598           0 :                 (hc->rfp_cfg.holddown_factor
    4599             :                                  == RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR
    4600             :                          ? "(default)"
    4601             :                          : ""));
    4602           0 :         vty_out(vty, "%-39s %-19s %s\n", "RFP Updated responses:",
    4603             :                 (hc->rfp_cfg.use_updated_response == 0 ? "Off" : "On"),
    4604           0 :                 (hc->rfp_cfg.use_updated_response == 0 ? "(default)" : ""));
    4605           0 :         vty_out(vty, "%-39s %-19s %s\n", "RFP Removal responses:",
    4606             :                 (hc->rfp_cfg.use_removes == 0 ? "Off" : "On"),
    4607           0 :                 (hc->rfp_cfg.use_removes == 0 ? "(default)" : ""));
    4608           0 :         vty_out(vty, "%-39s %-19s %s\n", "RFP Full table download:",
    4609             :                 (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL ? "On"
    4610             :                                                                       : "Off"),
    4611           0 :                 (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL
    4612             :                          ? "(default)"
    4613             :                          : ""));
    4614           0 :         snprintf(tmp, sizeof(tmp), "%u seconds",
    4615             :                  hc->rfp_cfg.ftd_advertisement_interval);
    4616           0 :         vty_out(vty, "%-39s %-19s %s\n", "    Advertisement Interval:", tmp,
    4617           0 :                 (hc->rfp_cfg.ftd_advertisement_interval
    4618             :                                  == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL
    4619             :                          ? "(default)"
    4620             :                          : ""));
    4621           0 :         vty_out(vty, "%-39s %d seconds\n", "Default RFP response lifetime:",
    4622             :                 hc->default_response_lifetime);
    4623           0 :         vty_out(vty, "\n");
    4624           0 :         return;
    4625             : }
    4626             : 
    4627           0 : struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp)
    4628             : {
    4629           0 :         struct rfapi_cfg *hc = NULL;
    4630           0 :         if (bgp == NULL)
    4631           0 :                 bgp = bgp_get_default();
    4632           0 :         if (bgp != NULL)
    4633           0 :                 hc = bgp->rfapi_cfg;
    4634           0 :         return hc;
    4635             : }
    4636             : 
    4637             : #endif /* ENABLE_BGP_VNC */

Generated by: LCOV version v1.16-topotato