diff options
Diffstat (limited to 'bgpd/rfapi')
34 files changed, 26046 insertions, 28472 deletions
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index d04b186dff..8a93d3984e 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -52,32 +52,32 @@ DEFINE_MGROUP(RFAPI, "rfapi") -DEFINE_MTYPE(RFAPI, RFAPI_CFG, "NVE Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG, "NVE Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG, "RFAPI L2 Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG, "RFAPI RFP Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI, "RFAPI Generic") -DEFINE_MTYPE(RFAPI, RFAPI_DESC, "RFAPI Descriptor") -DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE, "RFAPI Import Table") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR, "RFAPI Monitor VPN") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP, "RFAPI Monitor Encap") -DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP, "RFAPI Next Hop") -DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION, "RFAPI VN Option") -DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION, "RFAPI UN Option") -DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW, "RFAPI Withdraw") -DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME, "RFAPI RFGName") -DEFINE_MTYPE(RFAPI, RFAPI_ADB, "RFAPI Advertisement Data") -DEFINE_MTYPE(RFAPI, RFAPI_ETI, "RFAPI Export Table Info") -DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR, "RFAPI NVE Address") -DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG, "RFAPI Prefix Bag") -DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA, "RFAPI IT Extra") -DEFINE_MTYPE(RFAPI, RFAPI_INFO, "RFAPI Info") -DEFINE_MTYPE(RFAPI, RFAPI_ADDR, "RFAPI Addr") +DEFINE_MTYPE(RFAPI, RFAPI_CFG, "NVE Configuration") +DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG, "NVE Group Configuration") +DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG, "RFAPI L2 Group Configuration") +DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG, "RFAPI RFP Group Configuration") +DEFINE_MTYPE(RFAPI, RFAPI, "RFAPI Generic") +DEFINE_MTYPE(RFAPI, RFAPI_DESC, "RFAPI Descriptor") +DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE, "RFAPI Import Table") +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR, "RFAPI Monitor VPN") +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP, "RFAPI Monitor Encap") +DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP, "RFAPI Next Hop") +DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION, "RFAPI VN Option") +DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION, "RFAPI UN Option") +DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW, "RFAPI Withdraw") +DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME, "RFAPI RFGName") +DEFINE_MTYPE(RFAPI, RFAPI_ADB, "RFAPI Advertisement Data") +DEFINE_MTYPE(RFAPI, RFAPI_ETI, "RFAPI Export Table Info") +DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR, "RFAPI NVE Address") +DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG, "RFAPI Prefix Bag") +DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA, "RFAPI IT Extra") +DEFINE_MTYPE(RFAPI, RFAPI_INFO, "RFAPI Info") +DEFINE_MTYPE(RFAPI, RFAPI_ADDR, "RFAPI Addr") DEFINE_MTYPE(RFAPI, RFAPI_UPDATED_RESPONSE_QUEUE, "RFAPI Updated Rsp Queue") -DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE, "RFAPI Recently Deleted Route") -DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT, "RFAPI L2 Address Option") -DEFINE_MTYPE(RFAPI, RFAPI_AP, "RFAPI Advertised Prefix") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH, "RFAPI Monitor Ethernet") +DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE, "RFAPI Recently Deleted Route") +DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT, "RFAPI L2 Address Option") +DEFINE_MTYPE(RFAPI, RFAPI_AP, "RFAPI Advertised Prefix") +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH, "RFAPI Monitor Ethernet") DEFINE_QOBJ_TYPE(rfapi_nve_group_cfg) DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg) @@ -86,139 +86,127 @@ DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg) ***********************************************************************/ -/* +/* * compaitibility to old quagga_time call - * time_t value in terms of stabilised absolute time. + * time_t value in terms of stabilised absolute time. * replacement for POSIX time() */ -time_t -rfapi_time (time_t *t) +time_t rfapi_time(time_t *t) { - time_t clock = bgp_clock(); - if (t) - *t = clock; - return clock; + time_t clock = bgp_clock(); + if (t) + *t = clock; + return clock; } -void -nve_group_to_nve_list ( - struct rfapi_nve_group_cfg *rfg, - struct list **nves, - uint8_t family) /* AF_INET, AF_INET6 */ +void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg, struct list **nves, + uint8_t family) /* AF_INET, AF_INET6 */ { - struct listnode *hln; - struct rfapi_descriptor *rfd; - - /* - * loop over nves in this grp, add to list - */ - for (ALL_LIST_ELEMENTS_RO (rfg->nves, hln, rfd)) - { - if (rfd->vn_addr.addr_family == family) - { - if (!*nves) - *nves = list_new (); - listnode_add (*nves, rfd); - } - } + struct listnode *hln; + struct rfapi_descriptor *rfd; + + /* + * loop over nves in this grp, add to list + */ + for (ALL_LIST_ELEMENTS_RO(rfg->nves, hln, rfd)) { + if (rfd->vn_addr.addr_family == family) { + if (!*nves) + *nves = list_new(); + listnode_add(*nves, rfd); + } + } } -struct rfapi_nve_group_cfg * -bgp_rfapi_cfg_match_group ( - struct rfapi_cfg *hc, - struct prefix *vn, - struct prefix *un) +struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc, + struct prefix *vn, + struct prefix *un) { - struct rfapi_nve_group_cfg *rfg_vn = NULL; - struct rfapi_nve_group_cfg *rfg_un = NULL; - - struct route_table *rt_vn; - struct route_table *rt_un; - struct route_node *rn_vn; - struct route_node *rn_un; - - struct rfapi_nve_group_cfg *rfg; - struct listnode *node, *nnode; - - switch (vn->family) - { - case AF_INET: - rt_vn = &(hc->nve_groups_vn[AFI_IP]); - break; - case AF_INET6: - rt_vn = &(hc->nve_groups_vn[AFI_IP6]); - break; - default: - return NULL; - } - - switch (un->family) - { - case AF_INET: - rt_un = &(hc->nve_groups_un[AFI_IP]); - break; - case AF_INET6: - rt_un = &(hc->nve_groups_un[AFI_IP6]); - break; - default: - return NULL; - } - - rn_vn = route_node_match (rt_vn, vn); /* NB locks node */ - if (rn_vn) - { - rfg_vn = rn_vn->info; - route_unlock_node (rn_vn); - } - - rn_un = route_node_match (rt_un, un); /* NB locks node */ - if (rn_un) - { - rfg_un = rn_un->info; - route_unlock_node (rn_un); - } + struct rfapi_nve_group_cfg *rfg_vn = NULL; + struct rfapi_nve_group_cfg *rfg_un = NULL; + + struct route_table *rt_vn; + struct route_table *rt_un; + struct route_node *rn_vn; + struct route_node *rn_un; + + struct rfapi_nve_group_cfg *rfg; + struct listnode *node, *nnode; + + switch (vn->family) { + case AF_INET: + rt_vn = &(hc->nve_groups_vn[AFI_IP]); + break; + case AF_INET6: + rt_vn = &(hc->nve_groups_vn[AFI_IP6]); + break; + default: + return NULL; + } + + switch (un->family) { + case AF_INET: + rt_un = &(hc->nve_groups_un[AFI_IP]); + break; + case AF_INET6: + rt_un = &(hc->nve_groups_un[AFI_IP6]); + break; + default: + return NULL; + } + + rn_vn = route_node_match(rt_vn, vn); /* NB locks node */ + if (rn_vn) { + rfg_vn = rn_vn->info; + route_unlock_node(rn_vn); + } + + rn_un = route_node_match(rt_un, un); /* NB locks node */ + if (rn_un) { + rfg_un = rn_un->info; + route_unlock_node(rn_un); + } #if BGP_VNC_DEBUG_MATCH_GROUP - { - char buf[BUFSIZ]; + { + char buf[BUFSIZ]; - prefix2str (vn, buf, BUFSIZ); - vnc_zlog_debug_verbose ("%s: vn prefix: %s", __func__, buf); + prefix2str(vn, buf, BUFSIZ); + vnc_zlog_debug_verbose("%s: vn prefix: %s", __func__, buf); - prefix2str (un, buf, BUFSIZ); - vnc_zlog_debug_verbose ("%s: un prefix: %s", __func__, buf); + prefix2str(un, buf, BUFSIZ); + vnc_zlog_debug_verbose("%s: un prefix: %s", __func__, buf); - vnc_zlog_debug_verbose ("%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p", - __func__, rn_vn, rn_un, rfg_vn, rfg_un); - } + vnc_zlog_debug_verbose( + "%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p", + __func__, rn_vn, rn_un, rfg_vn, rfg_un); + } #endif - if (rfg_un == rfg_vn) /* same group */ - return rfg_un; - if (!rfg_un) /* un doesn't match, return vn-matched grp */ - return rfg_vn; - if (!rfg_vn) /* vn doesn't match, return un-matched grp */ - return rfg_un; - - /* - * Two different nve groups match: the group configured earlier wins. - * For now, just walk the sequential list and pick the first one. - * If this approach is too slow, then store serial numbers in the - * nve group structures as they are defined and just compare - * serial numbers. - */ - for (ALL_LIST_ELEMENTS (hc->nve_groups_sequential, node, nnode, rfg)) - { - if ((rfg == rfg_un) || (rfg == rfg_vn)) - { - return rfg; - } - } - vnc_zlog_debug_verbose ("%s: shouldn't happen, returning NULL when un and vn match", - __func__); - return NULL; /* shouldn't happen */ + if (rfg_un == rfg_vn) /* same group */ + return rfg_un; + if (!rfg_un) /* un doesn't match, return vn-matched grp */ + return rfg_vn; + if (!rfg_vn) /* vn doesn't match, return un-matched grp */ + return rfg_un; + + /* + * Two different nve groups match: the group configured earlier wins. + * For now, just walk the sequential list and pick the first one. + * If this approach is too slow, then store serial numbers in the + * nve group structures as they are defined and just compare + * serial numbers. + */ + for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg)) { + if ((rfg == rfg_un) || (rfg == rfg_vn)) { + return rfg; + } + } + vnc_zlog_debug_verbose( + "%s: shouldn't happen, returning NULL when un and vn match", + __func__); + return NULL; /* shouldn't happen */ } /*------------------------------------------ @@ -230,15 +218,14 @@ bgp_rfapi_cfg_match_group ( * void * bgp structure * * returns: - * void * + * void * *------------------------------------------*/ -void * -rfapi_get_rfp_start_val (void *bgpv) +void *rfapi_get_rfp_start_val(void *bgpv) { - struct bgp *bgp = bgpv; - if (bgp == NULL || bgp->rfapi == NULL) - return NULL; - return bgp->rfapi->rfp; + struct bgp *bgp = bgpv; + if (bgp == NULL || bgp->rfapi == NULL) + return NULL; + return bgp->rfapi->rfp; } /*------------------------------------------ @@ -246,7 +233,7 @@ rfapi_get_rfp_start_val (void *bgpv) * * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured * - * input: + * input: * bgp NULL (=use default instance) * * output: @@ -255,32 +242,28 @@ rfapi_get_rfp_start_val (void *bgpv) * 0 Success * ENXIO VNC not configured --------------------------------------------*/ -int -bgp_rfapi_is_vnc_configured (struct bgp *bgp) +int bgp_rfapi_is_vnc_configured(struct bgp *bgp) { - if (bgp == NULL) - bgp = bgp_get_default (); - - if (bgp && bgp->rfapi_cfg) - { - struct peer *peer; - struct peer_group *group; - struct listnode *node, *nnode; - /* if have configured VPN neighbors, assume running VNC */ - for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group)) - { - if (group->conf->afc[AFI_IP][SAFI_MPLS_VPN] || - group->conf->afc[AFI_IP6][SAFI_MPLS_VPN]) - return 0; - } - for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) - { - if (peer->afc[AFI_IP][SAFI_MPLS_VPN] || - peer->afc[AFI_IP6][SAFI_MPLS_VPN]) - return 0; - } - } - return ENXIO; + if (bgp == NULL) + bgp = bgp_get_default(); + + if (bgp && bgp->rfapi_cfg) { + struct peer *peer; + struct peer_group *group; + struct listnode *node, *nnode; + /* if have configured VPN neighbors, assume running VNC */ + for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) { + if (group->conf->afc[AFI_IP][SAFI_MPLS_VPN] + || group->conf->afc[AFI_IP6][SAFI_MPLS_VPN]) + return 0; + } + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + if (peer->afc[AFI_IP][SAFI_MPLS_VPN] + || peer->afc[AFI_IP6][SAFI_MPLS_VPN]) + return 0; + } + } + return ENXIO; } /*********************************************************************** @@ -295,25 +278,21 @@ DEFUN (vnc_advertise_un_method, "Method of advertising UN addresses\n" "Via Tunnel Encap attribute (in VPN SAFI)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT(bgp, bgp); - if (!bgp->rfapi_cfg) - { - vty_out (vty, "VNC not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!bgp->rfapi_cfg) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (!strncmp (argv[2]->arg, "encap-safi", 7)) - { - bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; - } - else - { - bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; - } + if (!strncmp(argv[2]->arg, "encap-safi", 7)) { + bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; + } else { + bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } /*------------------------------------------------------------------------- @@ -325,50 +304,41 @@ DEFUN_NOSH (vnc_defaults, vnc_defaults_cmd, "vnc defaults", VNC_CONFIG_STR "Configure default NVE group\n") { - vty->node = BGP_VNC_DEFAULTS_NODE; - return CMD_SUCCESS; + vty->node = BGP_VNC_DEFAULTS_NODE; + return CMD_SUCCESS; } -static int -set_ecom_list ( - struct vty *vty, - int argc, - struct cmd_token **argv, - struct ecommunity **list) +static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv, + struct ecommunity **list) { - struct ecommunity *ecom = NULL; - struct ecommunity *ecomadd; - - for (; argc; --argc, ++argv) - { - - ecomadd = ecommunity_str2com (argv[0]->arg, ECOMMUNITY_ROUTE_TARGET, 0); - if (!ecomadd) - { - vty_out (vty, "Malformed community-list value\n"); - if (ecom) - ecommunity_free (&ecom); - return CMD_WARNING_CONFIG_FAILED; - } - - if (ecom) - { - ecommunity_merge (ecom, ecomadd); - ecommunity_free (&ecomadd); - } - else - { - ecom = ecomadd; - } - } - - if (*list) - { - ecommunity_free (&*list); - } - *list = ecom; - - return CMD_SUCCESS; + struct ecommunity *ecom = NULL; + struct ecommunity *ecomadd; + + for (; argc; --argc, ++argv) { + + ecomadd = ecommunity_str2com(argv[0]->arg, + ECOMMUNITY_ROUTE_TARGET, 0); + if (!ecomadd) { + vty_out(vty, "Malformed community-list value\n"); + if (ecom) + ecommunity_free(&ecom); + return CMD_WARNING_CONFIG_FAILED; + } + + if (ecom) { + ecommunity_merge(ecom, ecomadd); + ecommunity_free(&ecomadd); + } else { + ecom = ecomadd; + } + } + + if (*list) { + ecommunity_free(&*list); + } + *list = ecom; + + return CMD_SUCCESS; } DEFUN (vnc_defaults_rt_import, @@ -378,9 +348,9 @@ DEFUN (vnc_defaults_rt_import, "Import filter\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - return set_ecom_list (vty, argc - 2, argv + 2, - &bgp->rfapi_cfg->default_rt_import_list); + VTY_DECLVAR_CONTEXT(bgp, bgp); + return set_ecom_list(vty, argc - 2, argv + 2, + &bgp->rfapi_cfg->default_rt_import_list); } DEFUN (vnc_defaults_rt_export, @@ -390,9 +360,9 @@ DEFUN (vnc_defaults_rt_export, "Export filter\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - return set_ecom_list (vty, argc - 2, argv + 2, - &bgp->rfapi_cfg->default_rt_export_list); + VTY_DECLVAR_CONTEXT(bgp, bgp); + return set_ecom_list(vty, argc - 2, argv + 2, + &bgp->rfapi_cfg->default_rt_export_list); } DEFUN (vnc_defaults_rt_both, @@ -402,15 +372,15 @@ DEFUN (vnc_defaults_rt_both, "Export+import filters\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int rc; - - rc = set_ecom_list (vty, argc - 2, argv + 2, - &bgp->rfapi_cfg->default_rt_import_list); - if (rc != CMD_SUCCESS) - return rc; - return set_ecom_list (vty, argc - 2, argv + 2, - &bgp->rfapi_cfg->default_rt_export_list); + VTY_DECLVAR_CONTEXT(bgp, bgp); + int rc; + + rc = set_ecom_list(vty, argc - 2, argv + 2, + &bgp->rfapi_cfg->default_rt_import_list); + if (rc != CMD_SUCCESS) + return rc; + return set_ecom_list(vty, argc - 2, argv + 2, + &bgp->rfapi_cfg->default_rt_export_list); } DEFUN (vnc_defaults_rd, @@ -419,54 +389,48 @@ DEFUN (vnc_defaults_rd, "Specify default route distinguisher\n" "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - struct prefix_rd prd; - - if (!strncmp (argv[1]->arg, "auto:vn:", 8)) - { - /* - * use AF_UNIX to designate automatically-assigned RD - * auto:vn:nn where nn is a 2-octet quantity - */ - char *end = NULL; - uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10); - uint16_t value = value32 & 0xffff; - - if (!argv[1]->arg[8] || *end) - { - vty_out (vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (value32 > 0xffff) - { - vty_out (vty, "%% Malformed rd (must be less than %u\n", - 0x0ffff); - return CMD_WARNING_CONFIG_FAILED; - } - - memset (&prd, 0, sizeof (prd)); - prd.family = AF_UNIX; - prd.prefixlen = 64; - prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; - prd.val[1] = RD_TYPE_IP & 0x0ff; - prd.val[6] = (value >> 8) & 0x0ff; - prd.val[7] = value & 0x0ff; - - } - else - { - - ret = str2prefix_rd (argv[1]->arg, &prd); - if (!ret) - { - vty_out (vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - bgp->rfapi_cfg->default_rd = prd; - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + int ret; + struct prefix_rd prd; + + if (!strncmp(argv[1]->arg, "auto:vn:", 8)) { + /* + * use AF_UNIX to designate automatically-assigned RD + * auto:vn:nn where nn is a 2-octet quantity + */ + char *end = NULL; + uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10); + uint16_t value = value32 & 0xffff; + + if (!argv[1]->arg[8] || *end) { + vty_out(vty, "%% Malformed rd\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (value32 > 0xffff) { + vty_out(vty, "%% Malformed rd (must be less than %u\n", + 0x0ffff); + return CMD_WARNING_CONFIG_FAILED; + } + + memset(&prd, 0, sizeof(prd)); + prd.family = AF_UNIX; + prd.prefixlen = 64; + prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; + prd.val[1] = RD_TYPE_IP & 0x0ff; + prd.val[6] = (value >> 8) & 0x0ff; + prd.val[7] = value & 0x0ff; + + } else { + + ret = str2prefix_rd(argv[1]->arg, &prd); + if (!ret) { + vty_out(vty, "%% Malformed rd\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + bgp->rfapi_cfg->default_rd = prd; + return CMD_SUCCESS; } DEFUN (vnc_defaults_l2rd, @@ -476,36 +440,32 @@ DEFUN (vnc_defaults_l2rd, "Fixed value 1-255\n" "use the low-order octet of the NVE's VN address\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - uint8_t value = 0; - - if (strmatch(argv[1]->text, "auto-vn")) - { - value = 0; - } - else - { - char *end = NULL; - unsigned long value_l = strtoul (argv[1]->arg, &end, 10); - - value = value_l & 0xff; - if (!argv[1]->arg[0] || *end) - { - vty_out (vty, "%% Malformed l2 nve ID \"%s\"\n",argv[1]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - if ((value_l < 1) || (value_l > 0xff)) - { - vty_out (vty, - "%% Malformed l2 nve id (must be greater than 0 and less than %u\n", - 0x100); - return CMD_WARNING_CONFIG_FAILED; - } - } - bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_L2RD; - bgp->rfapi_cfg->default_l2rd = value; - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + uint8_t value = 0; + + if (strmatch(argv[1]->text, "auto-vn")) { + value = 0; + } else { + char *end = NULL; + unsigned long value_l = strtoul(argv[1]->arg, &end, 10); + + value = value_l & 0xff; + if (!argv[1]->arg[0] || *end) { + vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n", + argv[1]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if ((value_l < 1) || (value_l > 0xff)) { + vty_out(vty, + "%% Malformed l2 nve id (must be greater than 0 and less than %u\n", + 0x100); + return CMD_WARNING_CONFIG_FAILED; + } + } + bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_L2RD; + bgp->rfapi_cfg->default_l2rd = value; + + return CMD_SUCCESS; } DEFUN (vnc_defaults_no_l2rd, @@ -514,12 +474,12 @@ DEFUN (vnc_defaults_no_l2rd, NO_STR "Specify default Local Nve ID value to use in RD for L2 routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp->rfapi_cfg->default_l2rd = 0; - bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_L2RD; + bgp->rfapi_cfg->default_l2rd = 0; + bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_L2RD; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (vnc_defaults_responselifetime, @@ -528,262 +488,240 @@ DEFUN (vnc_defaults_responselifetime, "Specify default response lifetime\n" "Response lifetime in seconds\n" "Infinite response lifetime\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - uint32_t rspint; - struct rfapi *h = NULL; - struct listnode *hdnode; - struct rfapi_descriptor *rfd; - - h = bgp->rfapi; - if (!h) - return CMD_WARNING_CONFIG_FAILED; - - if (strmatch(argv[1]->text, "infinite")) - { - rspint = RFAPI_INFINITE_LIFETIME; - } - else - { - rspint = strtoul(argv[1]->arg, NULL, 10); - if (rspint > INT32_MAX) - rspint = INT32_MAX; /* is really an int, not an unsigned int */ - } - - bgp->rfapi_cfg->default_response_lifetime = rspint; - - for (ALL_LIST_ELEMENTS_RO (&h->descriptors, hdnode, rfd)) - if (rfd->rfg && !(rfd->rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME)) - rfd->response_lifetime = rfd->rfg->response_lifetime = rspint; - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + uint32_t rspint; + struct rfapi *h = NULL; + struct listnode *hdnode; + struct rfapi_descriptor *rfd; + + h = bgp->rfapi; + if (!h) + return CMD_WARNING_CONFIG_FAILED; + + if (strmatch(argv[1]->text, "infinite")) { + rspint = RFAPI_INFINITE_LIFETIME; + } else { + rspint = strtoul(argv[1]->arg, NULL, 10); + if (rspint > INT32_MAX) + rspint = + INT32_MAX; /* is really an int, not an unsigned + int */ + } + + bgp->rfapi_cfg->default_response_lifetime = rspint; + + for (ALL_LIST_ELEMENTS_RO(&h->descriptors, hdnode, rfd)) + if (rfd->rfg + && !(rfd->rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME)) + rfd->response_lifetime = rfd->rfg->response_lifetime = + rspint; + + return CMD_SUCCESS; } struct rfapi_nve_group_cfg * -bgp_rfapi_cfg_match_byname (struct bgp *bgp, const char *name, - rfapi_group_cfg_type_t type) /* _MAX = any */ +bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name, + rfapi_group_cfg_type_t type) /* _MAX = any */ { - struct rfapi_nve_group_cfg *rfg; - struct listnode *node, *nnode; - - for (ALL_LIST_ELEMENTS - (bgp->rfapi_cfg->nve_groups_sequential, node, nnode, rfg)) - { - if ((type == RFAPI_GROUP_CFG_MAX || type == rfg->type) && - !strcmp (rfg->name, name)) - return rfg; - } - return NULL; + struct rfapi_nve_group_cfg *rfg; + struct listnode *node, *nnode; + + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, node, + nnode, rfg)) { + if ((type == RFAPI_GROUP_CFG_MAX || type == rfg->type) + && !strcmp(rfg->name, name)) + return rfg; + } + return NULL; } static struct rfapi_nve_group_cfg * -rfapi_group_new (struct bgp *bgp, - rfapi_group_cfg_type_t type, - const char *name) +rfapi_group_new(struct bgp *bgp, rfapi_group_cfg_type_t type, const char *name) { - struct rfapi_nve_group_cfg *rfg; - - rfg = XCALLOC (MTYPE_RFAPI_GROUP_CFG, sizeof (struct rfapi_nve_group_cfg)); - if (rfg) - { - rfg->type = type; - rfg->name = strdup (name); - /* add to tail of list */ - listnode_add (bgp->rfapi_cfg->nve_groups_sequential, rfg); - } - rfg->label = MPLS_LABEL_ILLEGAL; - QOBJ_REG (rfg, rfapi_nve_group_cfg); - - return rfg; + struct rfapi_nve_group_cfg *rfg; + + rfg = XCALLOC(MTYPE_RFAPI_GROUP_CFG, + sizeof(struct rfapi_nve_group_cfg)); + if (rfg) { + rfg->type = type; + rfg->name = strdup(name); + /* add to tail of list */ + listnode_add(bgp->rfapi_cfg->nve_groups_sequential, rfg); + } + rfg->label = MPLS_LABEL_ILLEGAL; + QOBJ_REG(rfg, rfapi_nve_group_cfg); + + return rfg; } -static struct rfapi_l2_group_cfg * -rfapi_l2_group_lookup_byname (struct bgp *bgp, const char *name) +static struct rfapi_l2_group_cfg *rfapi_l2_group_lookup_byname(struct bgp *bgp, + const char *name) { - struct rfapi_l2_group_cfg *rfg; - struct listnode *node, *nnode; - - if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */ - bgp->rfapi_cfg->l2_groups = list_new (); - - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) - { - if (!strcmp (rfg->name, name)) - return rfg; - } - return NULL; + struct rfapi_l2_group_cfg *rfg; + struct listnode *node, *nnode; + + if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */ + bgp->rfapi_cfg->l2_groups = list_new(); + + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) { + if (!strcmp(rfg->name, name)) + return rfg; + } + return NULL; } -static struct rfapi_l2_group_cfg * -rfapi_l2_group_new () +static struct rfapi_l2_group_cfg *rfapi_l2_group_new() { - struct rfapi_l2_group_cfg *rfg; + struct rfapi_l2_group_cfg *rfg; - rfg = XCALLOC (MTYPE_RFAPI_L2_CFG, sizeof (struct rfapi_l2_group_cfg)); - QOBJ_REG (rfg, rfapi_l2_group_cfg); + rfg = XCALLOC(MTYPE_RFAPI_L2_CFG, sizeof(struct rfapi_l2_group_cfg)); + QOBJ_REG(rfg, rfapi_l2_group_cfg); - return rfg; + return rfg; } -static void -rfapi_l2_group_del (struct rfapi_l2_group_cfg *rfg) +static void rfapi_l2_group_del(struct rfapi_l2_group_cfg *rfg) { - QOBJ_UNREG (rfg); - XFREE (MTYPE_RFAPI_L2_CFG, rfg); + QOBJ_UNREG(rfg); + XFREE(MTYPE_RFAPI_L2_CFG, rfg); } -static int -rfapi_str2route_type ( - const char *l3str, - const char *pstr, - afi_t *afi, - int *type) +static int rfapi_str2route_type(const char *l3str, const char *pstr, afi_t *afi, + int *type) { - if (!l3str || !pstr) - return EINVAL; - - if (!strcmp (l3str, "ipv4")) - { - *afi = AFI_IP; - } - else - { - if (!strcmp (l3str, "ipv6")) - *afi = AFI_IP6; - else - return ENOENT; - } - - if (!strcmp (pstr, "connected")) - *type = ZEBRA_ROUTE_CONNECT; - if (!strcmp (pstr, "kernel")) - *type = ZEBRA_ROUTE_KERNEL; - if (!strcmp (pstr, "static")) - *type = ZEBRA_ROUTE_STATIC; - if (!strcmp (pstr, "bgp")) - *type = ZEBRA_ROUTE_BGP; - if (!strcmp (pstr, "bgp-direct")) - *type = ZEBRA_ROUTE_BGP_DIRECT; - if (!strcmp (pstr, "bgp-direct-to-nve-groups")) - *type = ZEBRA_ROUTE_BGP_DIRECT_EXT; - - if (!strcmp (pstr, "rip")) - { - if (*afi == AFI_IP) - *type = ZEBRA_ROUTE_RIP; - else - *type = ZEBRA_ROUTE_RIPNG; - } - - if (!strcmp (pstr, "ripng")) - { - if (*afi == AFI_IP) - return EAFNOSUPPORT; - *type = ZEBRA_ROUTE_RIPNG; - } - - if (!strcmp (pstr, "ospf")) - { - if (*afi == AFI_IP) - *type = ZEBRA_ROUTE_OSPF; - else - *type = ZEBRA_ROUTE_OSPF6; - } - - if (!strcmp (pstr, "ospf6")) - { - if (*afi == AFI_IP) - return EAFNOSUPPORT; - *type = ZEBRA_ROUTE_OSPF6; - } - - return 0; + if (!l3str || !pstr) + return EINVAL; + + if (!strcmp(l3str, "ipv4")) { + *afi = AFI_IP; + } else { + if (!strcmp(l3str, "ipv6")) + *afi = AFI_IP6; + else + return ENOENT; + } + + if (!strcmp(pstr, "connected")) + *type = ZEBRA_ROUTE_CONNECT; + if (!strcmp(pstr, "kernel")) + *type = ZEBRA_ROUTE_KERNEL; + if (!strcmp(pstr, "static")) + *type = ZEBRA_ROUTE_STATIC; + if (!strcmp(pstr, "bgp")) + *type = ZEBRA_ROUTE_BGP; + if (!strcmp(pstr, "bgp-direct")) + *type = ZEBRA_ROUTE_BGP_DIRECT; + if (!strcmp(pstr, "bgp-direct-to-nve-groups")) + *type = ZEBRA_ROUTE_BGP_DIRECT_EXT; + + if (!strcmp(pstr, "rip")) { + if (*afi == AFI_IP) + *type = ZEBRA_ROUTE_RIP; + else + *type = ZEBRA_ROUTE_RIPNG; + } + + if (!strcmp(pstr, "ripng")) { + if (*afi == AFI_IP) + return EAFNOSUPPORT; + *type = ZEBRA_ROUTE_RIPNG; + } + + if (!strcmp(pstr, "ospf")) { + if (*afi == AFI_IP) + *type = ZEBRA_ROUTE_OSPF; + else + *type = ZEBRA_ROUTE_OSPF6; + } + + if (!strcmp(pstr, "ospf6")) { + if (*afi == AFI_IP) + return EAFNOSUPPORT; + *type = ZEBRA_ROUTE_OSPF6; + } + + return 0; } /*------------------------------------------------------------------------- * redistribute *-----------------------------------------------------------------------*/ -#define VNC_REDIST_ENABLE(bgp, afi, type) do { \ - switch (type) { \ - case ZEBRA_ROUTE_BGP_DIRECT: \ - vnc_import_bgp_redist_enable((bgp), (afi)); \ - break; \ - case ZEBRA_ROUTE_BGP_DIRECT_EXT: \ - vnc_import_bgp_exterior_redist_enable((bgp), (afi));\ - break; \ - default: \ - vnc_redistribute_set((bgp), (afi), (type)); \ - break; \ - } \ -} while (0) - -#define VNC_REDIST_DISABLE(bgp, afi, type) do { \ - switch (type) { \ - case ZEBRA_ROUTE_BGP_DIRECT: \ - vnc_import_bgp_redist_disable((bgp), (afi)); \ - break; \ - case ZEBRA_ROUTE_BGP_DIRECT_EXT: \ - vnc_import_bgp_exterior_redist_disable((bgp), (afi));\ - break; \ - default: \ - vnc_redistribute_unset((bgp), (afi), (type)); \ - break; \ - } \ -} while (0) +#define VNC_REDIST_ENABLE(bgp, afi, type) \ + do { \ + switch (type) { \ + case ZEBRA_ROUTE_BGP_DIRECT: \ + vnc_import_bgp_redist_enable((bgp), (afi)); \ + break; \ + case ZEBRA_ROUTE_BGP_DIRECT_EXT: \ + vnc_import_bgp_exterior_redist_enable((bgp), (afi)); \ + break; \ + default: \ + vnc_redistribute_set((bgp), (afi), (type)); \ + break; \ + } \ + } while (0) + +#define VNC_REDIST_DISABLE(bgp, afi, type) \ + do { \ + switch (type) { \ + case ZEBRA_ROUTE_BGP_DIRECT: \ + vnc_import_bgp_redist_disable((bgp), (afi)); \ + break; \ + case ZEBRA_ROUTE_BGP_DIRECT_EXT: \ + vnc_import_bgp_exterior_redist_disable((bgp), (afi)); \ + break; \ + default: \ + vnc_redistribute_unset((bgp), (afi), (type)); \ + break; \ + } \ + } while (0) static uint8_t redist_was_enabled[AFI_MAX][ZEBRA_ROUTE_MAX]; -static void -vnc_redistribute_prechange (struct bgp *bgp) +static void vnc_redistribute_prechange(struct bgp *bgp) { - afi_t afi; - int type; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - memset (redist_was_enabled, 0, sizeof (redist_was_enabled)); - - /* - * Look to see if we have any redistribution enabled. If so, flush - * the corresponding routes and turn off redistribution temporarily. - * We need to do it because the RD's used for the redistributed - * routes depend on the nve group. - */ - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) - { - if (bgp->rfapi_cfg->redist[afi][type]) - { - redist_was_enabled[afi][type] = 1; - VNC_REDIST_DISABLE (bgp, afi, type); - } - } - } - vnc_zlog_debug_verbose ("%s: return", __func__); + afi_t afi; + int type; + + vnc_zlog_debug_verbose("%s: entry", __func__); + memset(redist_was_enabled, 0, sizeof(redist_was_enabled)); + + /* + * Look to see if we have any redistribution enabled. If so, flush + * the corresponding routes and turn off redistribution temporarily. + * We need to do it because the RD's used for the redistributed + * routes depend on the nve group. + */ + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) { + if (bgp->rfapi_cfg->redist[afi][type]) { + redist_was_enabled[afi][type] = 1; + VNC_REDIST_DISABLE(bgp, afi, type); + } + } + } + vnc_zlog_debug_verbose("%s: return", __func__); } -static void -vnc_redistribute_postchange (struct bgp *bgp) +static void vnc_redistribute_postchange(struct bgp *bgp) { - afi_t afi; - int type; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - /* - * If we turned off redistribution above, turn it back on. Doing so - * will tell zebra to resend the routes to us - */ - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) - { - if (redist_was_enabled[afi][type]) - { - VNC_REDIST_ENABLE (bgp, afi, type); - } - } - } - vnc_zlog_debug_verbose ("%s: return", __func__); + afi_t afi; + int type; + + vnc_zlog_debug_verbose("%s: entry", __func__); + /* + * If we turned off redistribution above, turn it back on. Doing so + * will tell zebra to resend the routes to us + */ + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) { + if (redist_was_enabled[afi][type]) { + VNC_REDIST_ENABLE(bgp, afi, type); + } + } + } + vnc_zlog_debug_verbose("%s: return", __func__); } DEFUN (vnc_redistribute_rh_roo_localadmin, @@ -794,51 +732,46 @@ DEFUN (vnc_redistribute_rh_roo_localadmin, "Resolve-NVE mode\n" "Route Origin Extended Community Local Admin Field\n" "Field value\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - uint32_t localadmin; - char *endptr; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - localadmin = strtoul (argv[4]->arg, &endptr, 0); - if (!argv[4]->arg[0] || *endptr) - { - vty_out (vty, "%% Malformed value\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (localadmin > 0xffff) - { - vty_out (vty, "%% Value out of range (0-%d)\n", 0xffff); - return CMD_WARNING_CONFIG_FAILED; - } - - if (bgp->rfapi_cfg->resolve_nve_roo_local_admin == localadmin) - return CMD_SUCCESS; - - if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == - BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) - { - - vnc_export_bgp_prechange (bgp); - } - vnc_redistribute_prechange (bgp); - - bgp->rfapi_cfg->resolve_nve_roo_local_admin = localadmin; - - if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == - BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) - { - - vnc_export_bgp_postchange (bgp); - } - vnc_redistribute_postchange (bgp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + uint32_t localadmin; + char *endptr; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "RFAPI not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + localadmin = strtoul(argv[4]->arg, &endptr, 0); + if (!argv[4]->arg[0] || *endptr) { + vty_out(vty, "%% Malformed value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (localadmin > 0xffff) { + vty_out(vty, "%% Value out of range (0-%d)\n", 0xffff); + return CMD_WARNING_CONFIG_FAILED; + } + + if (bgp->rfapi_cfg->resolve_nve_roo_local_admin == localadmin) + return CMD_SUCCESS; + + if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) + == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) { + + vnc_export_bgp_prechange(bgp); + } + vnc_redistribute_prechange(bgp); + + bgp->rfapi_cfg->resolve_nve_roo_local_admin = localadmin; + + if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) + == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) { + + vnc_export_bgp_postchange(bgp); + } + vnc_redistribute_postchange(bgp); + + return CMD_SUCCESS; } @@ -851,43 +784,40 @@ DEFUN (vnc_redistribute_mode, "Based on redistribute nve-group\n" "Unmodified\n" "Resolve each nexthop to connected NVEs\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - vnc_redist_mode_t newmode; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - - switch (argv[3]->arg[0]) - { - case 'n': - newmode = VNC_REDIST_MODE_RFG; - break; - - case 'p': - newmode = VNC_REDIST_MODE_PLAIN; - break; - - case 'r': - newmode = VNC_REDIST_MODE_RESOLVE_NVE; - break; - - default: - vty_out (vty, "unknown redistribute mode\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (newmode != bgp->rfapi_cfg->redist_mode) - { - vnc_redistribute_prechange (bgp); - bgp->rfapi_cfg->redist_mode = newmode; - vnc_redistribute_postchange (bgp); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + vnc_redist_mode_t newmode; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "RFAPI not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + + switch (argv[3]->arg[0]) { + case 'n': + newmode = VNC_REDIST_MODE_RFG; + break; + + case 'p': + newmode = VNC_REDIST_MODE_PLAIN; + break; + + case 'r': + newmode = VNC_REDIST_MODE_RESOLVE_NVE; + break; + + default: + vty_out(vty, "unknown redistribute mode\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (newmode != bgp->rfapi_cfg->redist_mode) { + vnc_redistribute_prechange(bgp); + bgp->rfapi_cfg->redist_mode = newmode; + vnc_redistribute_postchange(bgp); + } + + return CMD_SUCCESS; } DEFUN (vnc_redistribute_protocol, @@ -905,36 +835,33 @@ DEFUN (vnc_redistribute_protocol, "From Open Shortest Path First (OSPF)\n" "From Routing Information Protocol (RIP)\n" "From Static routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int type = ZEBRA_ROUTE_MAX; /* init to bogus value */ - afi_t afi; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (rfapi_str2route_type (argv[2]->arg, argv[3]->arg, &afi, &type)) - { - vty_out (vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) - { - if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) - { - VNC_REDIST_DISABLE (bgp, afi, type); /* disabled view implicitly */ - free (bgp->rfapi_cfg->redist_bgp_exterior_view_name); - bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL; - } - bgp->rfapi_cfg->redist_bgp_exterior_view = bgp; - } - - VNC_REDIST_ENABLE (bgp, afi, type); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + int type = ZEBRA_ROUTE_MAX; /* init to bogus value */ + afi_t afi; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "RFAPI not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (rfapi_str2route_type(argv[2]->arg, argv[3]->arg, &afi, &type)) { + vty_out(vty, "%% Invalid route type\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) { + if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) { + VNC_REDIST_DISABLE(bgp, afi, + type); /* disabled view implicitly */ + free(bgp->rfapi_cfg->redist_bgp_exterior_view_name); + bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL; + } + bgp->rfapi_cfg->redist_bgp_exterior_view = bgp; + } + + VNC_REDIST_ENABLE(bgp, afi, type); + + return CMD_SUCCESS; } DEFUN (vnc_no_redistribute_protocol, @@ -953,35 +880,31 @@ DEFUN (vnc_no_redistribute_protocol, "From Open Shortest Path First (OSPF)\n" "From Routing Information Protocol (RIP)\n" "From Static routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int type; - afi_t afi; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (rfapi_str2route_type (argv[3]->arg, argv[4]->arg, &afi, &type)) - { - vty_out (vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - VNC_REDIST_DISABLE (bgp, afi, type); - - if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) - { - if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) - { - free (bgp->rfapi_cfg->redist_bgp_exterior_view_name); - bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL; - } - bgp->rfapi_cfg->redist_bgp_exterior_view = NULL; - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + int type; + afi_t afi; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "RFAPI not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (rfapi_str2route_type(argv[3]->arg, argv[4]->arg, &afi, &type)) { + vty_out(vty, "%% Invalid route type\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + VNC_REDIST_DISABLE(bgp, afi, type); + + if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) { + if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) { + free(bgp->rfapi_cfg->redist_bgp_exterior_view_name); + bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL; + } + bgp->rfapi_cfg->redist_bgp_exterior_view = NULL; + } + + return CMD_SUCCESS; } DEFUN (vnc_redistribute_bgp_exterior, @@ -994,31 +917,31 @@ DEFUN (vnc_redistribute_bgp_exterior, "From BGP without Zebra, only to configured NVE groups\n" "From BGP view\n" "BGP view name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int type; - afi_t afi; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (rfapi_str2route_type (argv[2]->arg, "bgp-direct-to-nve-groups", &afi, &type)) - { - vty_out (vty, "%% Invalid route type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) - free (bgp->rfapi_cfg->redist_bgp_exterior_view_name); - bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup (argv[5]->arg); - /* could be NULL if name is not defined yet */ - bgp->rfapi_cfg->redist_bgp_exterior_view = bgp_lookup_by_name (argv[5]->arg); - - VNC_REDIST_ENABLE (bgp, afi, type); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + int type; + afi_t afi; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "RFAPI not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (rfapi_str2route_type(argv[2]->arg, "bgp-direct-to-nve-groups", &afi, + &type)) { + vty_out(vty, "%% Invalid route type\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) + free(bgp->rfapi_cfg->redist_bgp_exterior_view_name); + bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup(argv[5]->arg); + /* could be NULL if name is not defined yet */ + bgp->rfapi_cfg->redist_bgp_exterior_view = + bgp_lookup_by_name(argv[5]->arg); + + VNC_REDIST_ENABLE(bgp, afi, type); + + return CMD_SUCCESS; } DEFUN (vnc_redistribute_nvegroup, @@ -1028,29 +951,28 @@ DEFUN (vnc_redistribute_nvegroup, "Assign a NVE group to routes redistributed from another routing protocol\n" "NVE group\n" "Group name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT(bgp, bgp); - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } - vnc_redistribute_prechange (bgp); + vnc_redistribute_prechange(bgp); - /* - * OK if nve group doesn't exist yet; we'll set the pointer - * when the group is defined later - */ - bgp->rfapi_cfg->rfg_redist = bgp_rfapi_cfg_match_byname (bgp, argv[3]->arg, - RFAPI_GROUP_CFG_NVE); - if (bgp->rfapi_cfg->rfg_redist_name) - free (bgp->rfapi_cfg->rfg_redist_name); - bgp->rfapi_cfg->rfg_redist_name = strdup (argv[3]->arg); + /* + * OK if nve group doesn't exist yet; we'll set the pointer + * when the group is defined later + */ + bgp->rfapi_cfg->rfg_redist = bgp_rfapi_cfg_match_byname( + bgp, argv[3]->arg, RFAPI_GROUP_CFG_NVE); + if (bgp->rfapi_cfg->rfg_redist_name) + free(bgp->rfapi_cfg->rfg_redist_name); + bgp->rfapi_cfg->rfg_redist_name = strdup(argv[3]->arg); - vnc_redistribute_postchange (bgp); + vnc_redistribute_postchange(bgp); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (vnc_redistribute_no_nvegroup, @@ -1061,24 +983,23 @@ DEFUN (vnc_redistribute_no_nvegroup, "Redistribute from other protocol\n" "Assign a NVE group to routes redistributed from another routing protocol\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT(bgp, bgp); - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } - vnc_redistribute_prechange (bgp); + vnc_redistribute_prechange(bgp); - bgp->rfapi_cfg->rfg_redist = NULL; - if (bgp->rfapi_cfg->rfg_redist_name) - free (bgp->rfapi_cfg->rfg_redist_name); - bgp->rfapi_cfg->rfg_redist_name = NULL; + bgp->rfapi_cfg->rfg_redist = NULL; + if (bgp->rfapi_cfg->rfg_redist_name) + free(bgp->rfapi_cfg->rfg_redist_name); + bgp->rfapi_cfg->rfg_redist_name = NULL; - vnc_redistribute_postchange (bgp); + vnc_redistribute_postchange(bgp); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -1091,28 +1012,25 @@ DEFUN (vnc_redistribute_lifetime, "lifetime value (32 bit)\n" "Allow lifetime to never expire\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT(bgp, bgp); - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } - vnc_redistribute_prechange (bgp); + vnc_redistribute_prechange(bgp); - if (strmatch(argv[3]->text, "infinite")) - { - bgp->rfapi_cfg->redist_lifetime = RFAPI_INFINITE_LIFETIME; - } - else - { - bgp->rfapi_cfg->redist_lifetime = strtoul(argv[3]->arg, NULL, 10); - } + if (strmatch(argv[3]->text, "infinite")) { + bgp->rfapi_cfg->redist_lifetime = RFAPI_INFINITE_LIFETIME; + } else { + bgp->rfapi_cfg->redist_lifetime = + strtoul(argv[3]->arg, NULL, 10); + } - vnc_redistribute_postchange (bgp); + vnc_redistribute_postchange(bgp); - return CMD_SUCCESS; + return CMD_SUCCESS; } /*-- redist policy, non-nvegroup start --*/ @@ -1128,45 +1046,38 @@ DEFUN (vnc_redist_bgpdirect_no_prefixlist, "IPv4 routes\n" "IPv6 routes\n" "Prefix-list for filtering redistributed routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - afi_t afi; - struct rfapi_cfg *hc; - uint8_t route_type = 0; - - if (!(hc = bgp->rfapi_cfg)) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[3]->text, "bgp-direct")) - { - route_type = ZEBRA_ROUTE_BGP_DIRECT; - } - else - { - route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; - } - - if (strmatch(argv[4]->text, "ipv4")) - { - afi = AFI_IP; - } - else - { - afi = AFI_IP6; - } - - vnc_redistribute_prechange (bgp); - - if (hc->plist_redist_name[route_type][afi]) - free (hc->plist_redist_name[route_type][afi]); - hc->plist_redist_name[route_type][afi] = NULL; - hc->plist_redist[route_type][afi] = NULL; - - vnc_redistribute_postchange (bgp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + afi_t afi; + struct rfapi_cfg *hc; + uint8_t route_type = 0; + + if (!(hc = bgp->rfapi_cfg)) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[3]->text, "bgp-direct")) { + route_type = ZEBRA_ROUTE_BGP_DIRECT; + } else { + route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; + } + + if (strmatch(argv[4]->text, "ipv4")) { + afi = AFI_IP; + } else { + afi = AFI_IP6; + } + + vnc_redistribute_prechange(bgp); + + if (hc->plist_redist_name[route_type][afi]) + free(hc->plist_redist_name[route_type][afi]); + hc->plist_redist_name[route_type][afi] = NULL; + hc->plist_redist[route_type][afi] = NULL; + + vnc_redistribute_postchange(bgp); + + return CMD_SUCCESS; } DEFUN (vnc_redist_bgpdirect_prefixlist, @@ -1181,45 +1092,39 @@ DEFUN (vnc_redist_bgpdirect_prefixlist, "Prefix-list for filtering redistributed routes\n" "prefix list name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_cfg *hc; - afi_t afi; - uint8_t route_type = 0; - - if (!(hc = bgp->rfapi_cfg)) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[2]->text, "bgp-direct")) - { - route_type = ZEBRA_ROUTE_BGP_DIRECT; - } - else - { - route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; - } - - if (strmatch(argv[3]->text, "ipv4")) - { - afi = AFI_IP; - } - else - { - afi = AFI_IP6; - } - - vnc_redistribute_prechange (bgp); - - if (hc->plist_redist_name[route_type][afi]) - free (hc->plist_redist_name[route_type][afi]); - hc->plist_redist_name[route_type][afi] = strdup (argv[5]->arg); - hc->plist_redist[route_type][afi] = prefix_list_lookup (afi, argv[5]->arg); - - vnc_redistribute_postchange (bgp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_cfg *hc; + afi_t afi; + uint8_t route_type = 0; + + if (!(hc = bgp->rfapi_cfg)) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[2]->text, "bgp-direct")) { + route_type = ZEBRA_ROUTE_BGP_DIRECT; + } else { + route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; + } + + if (strmatch(argv[3]->text, "ipv4")) { + afi = AFI_IP; + } else { + afi = AFI_IP6; + } + + vnc_redistribute_prechange(bgp); + + if (hc->plist_redist_name[route_type][afi]) + free(hc->plist_redist_name[route_type][afi]); + hc->plist_redist_name[route_type][afi] = strdup(argv[5]->arg); + hc->plist_redist[route_type][afi] = + prefix_list_lookup(afi, argv[5]->arg); + + vnc_redistribute_postchange(bgp); + + return CMD_SUCCESS; } DEFUN (vnc_redist_bgpdirect_no_routemap, @@ -1232,35 +1137,31 @@ DEFUN (vnc_redist_bgpdirect_no_routemap, "Redistribute from BGP without Zebra, only to configured NVE groups\n" "Route-map for filtering redistributed routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_cfg *hc; - uint8_t route_type = 0; - - if (!(hc = bgp->rfapi_cfg)) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[3]->text, "bgp-direct")) - { - route_type = ZEBRA_ROUTE_BGP_DIRECT; - } - else - { - route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; - } - - vnc_redistribute_prechange (bgp); - - if (hc->routemap_redist_name[route_type]) - free (hc->routemap_redist_name[route_type]); - hc->routemap_redist_name[route_type] = NULL; - hc->routemap_redist[route_type] = NULL; - - vnc_redistribute_postchange (bgp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_cfg *hc; + uint8_t route_type = 0; + + if (!(hc = bgp->rfapi_cfg)) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[3]->text, "bgp-direct")) { + route_type = ZEBRA_ROUTE_BGP_DIRECT; + } else { + route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; + } + + vnc_redistribute_prechange(bgp); + + if (hc->routemap_redist_name[route_type]) + free(hc->routemap_redist_name[route_type]); + hc->routemap_redist_name[route_type] = NULL; + hc->routemap_redist[route_type] = NULL; + + vnc_redistribute_postchange(bgp); + + return CMD_SUCCESS; } DEFUN (vnc_redist_bgpdirect_routemap, @@ -1272,35 +1173,32 @@ DEFUN (vnc_redist_bgpdirect_routemap, "Redistribute from BGP without Zebra, only to configured NVE groups\n" "Route-map for filtering exported routes\n" "route map name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_cfg *hc; - uint8_t route_type = 0; - - if (!(hc = bgp->rfapi_cfg)) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[2]->text, "bgp-direct")) - { - route_type = ZEBRA_ROUTE_BGP_DIRECT; - } - else - { - route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; - } - - vnc_redistribute_prechange (bgp); - - if (hc->routemap_redist_name[route_type]) - free (hc->routemap_redist_name[route_type]); - hc->routemap_redist_name[route_type] = strdup (argv[4]->arg); - hc->routemap_redist[route_type] = route_map_lookup_by_name (argv[4]->arg); - - vnc_redistribute_postchange (bgp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_cfg *hc; + uint8_t route_type = 0; + + if (!(hc = bgp->rfapi_cfg)) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[2]->text, "bgp-direct")) { + route_type = ZEBRA_ROUTE_BGP_DIRECT; + } else { + route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; + } + + vnc_redistribute_prechange(bgp); + + if (hc->routemap_redist_name[route_type]) + free(hc->routemap_redist_name[route_type]); + hc->routemap_redist_name[route_type] = strdup(argv[4]->arg); + hc->routemap_redist[route_type] = + route_map_lookup_by_name(argv[4]->arg); + + vnc_redistribute_postchange(bgp); + + return CMD_SUCCESS; } /*-- redist policy, non-nvegroup end --*/ @@ -1317,43 +1215,38 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist, "IPv6 routes\n" "Prefix-list for filtering redistributed routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg) - afi_t afi; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[3]->text, "ipv4")) - { - afi = AFI_IP; - } - else - { - afi = AFI_IP6; - } - - vnc_redistribute_prechange (bgp); - - if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) - free (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); - rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL; - rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL; - - vnc_redistribute_postchange (bgp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg) + afi_t afi; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[3]->text, "ipv4")) { + afi = AFI_IP; + } else { + afi = AFI_IP6; + } + + vnc_redistribute_prechange(bgp); + + if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) + free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); + rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL; + rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL; + + vnc_redistribute_postchange(bgp); + + return CMD_SUCCESS; } DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist, @@ -1366,44 +1259,40 @@ DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist, "Prefix-list for filtering redistributed routes\n" "prefix list name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - afi_t afi; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[2]->text, "ipv4")) - { - afi = AFI_IP; - } - else - { - afi = AFI_IP6; - } - - vnc_redistribute_prechange (bgp); - - if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) - free (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); - rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = strdup (argv[4]->arg); - rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = - prefix_list_lookup (afi, argv[4]->arg); - - vnc_redistribute_postchange (bgp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + afi_t afi; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[2]->text, "ipv4")) { + afi = AFI_IP; + } else { + afi = AFI_IP6; + } + + vnc_redistribute_prechange(bgp); + + if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) + free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); + rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = + strdup(argv[4]->arg); + rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = + prefix_list_lookup(afi, argv[4]->arg); + + vnc_redistribute_postchange(bgp); + + return CMD_SUCCESS; } DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap, @@ -1414,33 +1303,31 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap, "Redistribute from BGP directly\n" "Route-map for filtering redistributed routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } - vnc_redistribute_prechange (bgp); + vnc_redistribute_prechange(bgp); - if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) - free (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); - rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = NULL; - rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = NULL; + if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) + free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); + rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = NULL; + rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = NULL; - vnc_redistribute_postchange (bgp); + vnc_redistribute_postchange(bgp); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (vnc_nve_group_redist_bgpdirect_routemap, @@ -1450,34 +1337,33 @@ DEFUN (vnc_nve_group_redist_bgpdirect_routemap, "Redistribute from BGP directly\n" "Route-map for filtering exported routes\n" "route map name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - vnc_redistribute_prechange (bgp); - - if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) - free (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); - rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = strdup (argv[3]->arg); - rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = - route_map_lookup_by_name (argv[3]->arg); - - vnc_redistribute_postchange (bgp); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + vnc_redistribute_prechange(bgp); + + if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) + free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); + rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = + strdup(argv[3]->arg); + rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = + route_map_lookup_by_name(argv[3]->arg); + + vnc_redistribute_postchange(bgp); + + return CMD_SUCCESS; } /*-- redist policy, nvegroup end --*/ @@ -1498,116 +1384,106 @@ DEFUN (vnc_export_mode, "Export routes with NVE connected router next-hops\n" "Disable export\n" "Export routes with registering NVE as next-hop\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - uint32_t oldmode = 0; - uint32_t newmode = 0; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "VNC not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv[2]->arg[0] == 'b') - { - oldmode = bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS; - switch (argv[4]->arg[0]) - { - case 'g': - newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP; - break; - case 'c': - newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE; - break; - case 'n': - newmode = 0; - break; - case 'r': - newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH; - break; - default: - vty_out (vty, "Invalid mode specified\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (newmode == oldmode) - { - vty_out (vty, "Mode unchanged\n"); - return CMD_SUCCESS; - } - - vnc_export_bgp_prechange (bgp); - - bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS; - bgp->rfapi_cfg->flags |= newmode; - - vnc_export_bgp_postchange (bgp); - - - } - else - { - /* - * export to zebra with RH mode is not yet implemented - */ - vty_out (vty,"Changing modes for zebra export not implemented yet\n"); - return CMD_WARNING_CONFIG_FAILED; - - oldmode = bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS; - bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS; - switch (argv[4]->arg[0]) - { - case 'g': - if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) - { - /* TBD */ - } - bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP; - if (oldmode != BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) - { - /* TBD */ - } - break; - case 'n': - if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) - { - /* TBD */ - } - if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) - { - /* TBD */ - } - break; - case 'r': - if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) - { - /* TBD */ - } - bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH; - if (oldmode != BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) - { - /* TBD */ - } - break; - default: - vty_out (vty, "Invalid mode\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + uint32_t oldmode = 0; + uint32_t newmode = 0; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv[2]->arg[0] == 'b') { + oldmode = bgp->rfapi_cfg->flags + & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS; + switch (argv[4]->arg[0]) { + case 'g': + newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP; + break; + case 'c': + newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE; + break; + case 'n': + newmode = 0; + break; + case 'r': + newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH; + break; + default: + vty_out(vty, "Invalid mode specified\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (newmode == oldmode) { + vty_out(vty, "Mode unchanged\n"); + return CMD_SUCCESS; + } + + vnc_export_bgp_prechange(bgp); + + bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS; + bgp->rfapi_cfg->flags |= newmode; + + vnc_export_bgp_postchange(bgp); + + + } else { + /* + * export to zebra with RH mode is not yet implemented + */ + vty_out(vty, + "Changing modes for zebra export not implemented yet\n"); + return CMD_WARNING_CONFIG_FAILED; + + oldmode = bgp->rfapi_cfg->flags + & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS; + bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS; + switch (argv[4]->arg[0]) { + case 'g': + if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) { + /* TBD */ + } + bgp->rfapi_cfg->flags |= + BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP; + if (oldmode != BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) { + /* TBD */ + } + break; + case 'n': + if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) { + /* TBD */ + } + if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) { + /* TBD */ + } + break; + case 'r': + if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) { + /* TBD */ + } + bgp->rfapi_cfg->flags |= + BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH; + if (oldmode != BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) { + /* TBD */ + } + break; + default: + vty_out(vty, "Invalid mode\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + return CMD_SUCCESS; } -static struct rfapi_rfg_name * -rfgn_new () +static struct rfapi_rfg_name *rfgn_new() { - return XCALLOC (MTYPE_RFAPI_RFG_NAME, sizeof (struct rfapi_rfg_name)); + return XCALLOC(MTYPE_RFAPI_RFG_NAME, sizeof(struct rfapi_rfg_name)); } -static void -rfgn_free (struct rfapi_rfg_name *rfgn) +static void rfgn_free(struct rfapi_rfg_name *rfgn) { - XFREE (MTYPE_RFAPI_RFG_NAME, rfgn); + XFREE(MTYPE_RFAPI_RFG_NAME, rfgn); } DEFUN (vnc_export_nvegroup, @@ -1620,91 +1496,86 @@ DEFUN (vnc_export_nvegroup, "NVE group, used in 'group-nve' export mode\n" "NVE group\n" "Group name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_nve_group_cfg *rfg_new; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rfg_new = bgp_rfapi_cfg_match_byname (bgp, argv[5]->arg, RFAPI_GROUP_CFG_NVE); - - if (argv[2]->arg[0] == 'b') - { - - struct listnode *node; - struct rfapi_rfg_name *rfgn; - - /* - * Set group for export to BGP Direct - */ - - /* see if group is already included in export list */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, rfgn)) - { - - if (!strcmp (rfgn->name, argv[5]->arg)) - { - /* already in the list: we're done */ - return CMD_SUCCESS; - } - } - - rfgn = rfgn_new (); - rfgn->name = strdup (argv[5]->arg); - rfgn->rfg = rfg_new; /* OK if not set yet */ - - listnode_add (bgp->rfapi_cfg->rfg_export_direct_bgp_l, rfgn); - - vnc_zlog_debug_verbose ("%s: testing rfg_new", __func__); - if (rfg_new) - { - vnc_zlog_debug_verbose ("%s: testing bgp grp mode enabled", __func__); - if (VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) - vnc_zlog_debug_verbose ("%s: calling vnc_direct_bgp_add_group", __func__); - vnc_direct_bgp_add_group (bgp, rfg_new); - } - - } - else - { - - struct listnode *node; - struct rfapi_rfg_name *rfgn; - - /* - * Set group for export to Zebra - */ - - /* see if group is already included in export list */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, - node, rfgn)) - { - - if (!strcmp (rfgn->name, argv[5]->arg)) - { - /* already in the list: we're done */ - return CMD_SUCCESS; - } - } - - rfgn = rfgn_new (); - rfgn->name = strdup (argv[5]->arg); - rfgn->rfg = rfg_new; /* OK if not set yet */ - - listnode_add (bgp->rfapi_cfg->rfg_export_zebra_l, rfgn); - - if (rfg_new) - { - if (VNC_EXPORT_ZEBRA_GRP_ENABLED (bgp->rfapi_cfg)) - vnc_zebra_add_group (bgp, rfg_new); - } - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_nve_group_cfg *rfg_new; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg, + RFAPI_GROUP_CFG_NVE); + + if (argv[2]->arg[0] == 'b') { + + struct listnode *node; + struct rfapi_rfg_name *rfgn; + + /* + * Set group for export to BGP Direct + */ + + /* see if group is already included in export list */ + for (ALL_LIST_ELEMENTS_RO( + bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + rfgn)) { + + if (!strcmp(rfgn->name, argv[5]->arg)) { + /* already in the list: we're done */ + return CMD_SUCCESS; + } + } + + rfgn = rfgn_new(); + rfgn->name = strdup(argv[5]->arg); + rfgn->rfg = rfg_new; /* OK if not set yet */ + + listnode_add(bgp->rfapi_cfg->rfg_export_direct_bgp_l, rfgn); + + vnc_zlog_debug_verbose("%s: testing rfg_new", __func__); + if (rfg_new) { + vnc_zlog_debug_verbose( + "%s: testing bgp grp mode enabled", __func__); + if (VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) + vnc_zlog_debug_verbose( + "%s: calling vnc_direct_bgp_add_group", + __func__); + vnc_direct_bgp_add_group(bgp, rfg_new); + } + + } else { + + struct listnode *node; + struct rfapi_rfg_name *rfgn; + + /* + * Set group for export to Zebra + */ + + /* see if group is already included in export list */ + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, + node, rfgn)) { + + if (!strcmp(rfgn->name, argv[5]->arg)) { + /* already in the list: we're done */ + return CMD_SUCCESS; + } + } + + rfgn = rfgn_new(); + rfgn->name = strdup(argv[5]->arg); + rfgn->rfg = rfg_new; /* OK if not set yet */ + + listnode_add(bgp->rfapi_cfg->rfg_export_zebra_l, rfgn); + + if (rfg_new) { + if (VNC_EXPORT_ZEBRA_GRP_ENABLED(bgp->rfapi_cfg)) + vnc_zebra_add_group(bgp, rfg_new); + } + } + + return CMD_SUCCESS; } /* @@ -1721,54 +1592,52 @@ DEFUN (vnc_no_export_nvegroup, "NVE group, used in 'group-nve' export mode\n" "Disable export of VNC routes\n" "NVE group\n" "Group name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv[2]->arg[0] == 'b') - { - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, nnode, rfgn)) - { - - if (rfgn->name && !strcmp (rfgn->name, argv[6]->arg)) - { - vnc_zlog_debug_verbose ("%s: matched \"%s\"", __func__, rfgn->name); - if (rfgn->rfg) - vnc_direct_bgp_del_group (bgp, rfgn->rfg); - free (rfgn->name); - list_delete_node (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node); - rfgn_free (rfgn); - break; - } - } - } - else - { - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_zebra_l, - node, nnode, rfgn)) - { - - vnc_zlog_debug_verbose ("does rfg \"%s\" match?", rfgn->name); - if (rfgn->name && !strcmp (rfgn->name, argv[6]->arg)) - { - if (rfgn->rfg) - vnc_zebra_del_group (bgp, rfgn->rfg); - free (rfgn->name); - list_delete_node (bgp->rfapi_cfg->rfg_export_zebra_l, node); - rfgn_free (rfgn); - break; - } - } - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv[2]->arg[0] == 'b') { + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, + node, nnode, rfgn)) { + + if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) { + vnc_zlog_debug_verbose("%s: matched \"%s\"", + __func__, rfgn->name); + if (rfgn->rfg) + vnc_direct_bgp_del_group(bgp, + rfgn->rfg); + free(rfgn->name); + list_delete_node( + bgp->rfapi_cfg->rfg_export_direct_bgp_l, + node); + rfgn_free(rfgn); + break; + } + } + } else { + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node, + nnode, rfgn)) { + + vnc_zlog_debug_verbose("does rfg \"%s\" match?", + rfgn->name); + if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) { + if (rfgn->rfg) + vnc_zebra_del_group(bgp, rfgn->rfg); + free(rfgn->name); + list_delete_node( + bgp->rfapi_cfg->rfg_export_zebra_l, + node); + rfgn_free(rfgn); + break; + } + } + } + return CMD_SUCCESS; } DEFUN (vnc_nve_group_export_no_prefixlist, @@ -1782,63 +1651,53 @@ DEFUN (vnc_nve_group_export_no_prefixlist, "IPv6 routes\n" "Prefix-list for filtering exported routes\n" "prefix list name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - afi_t afi; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[3]->text, "ipv4")) - { - afi = AFI_IP; - } - else - { - afi = AFI_IP6; - } - - if (argv[2]->arg[0] == 'b') - { - if (((argc > 5) - && strmatch(argv[5]->text, rfg->plist_export_bgp_name[afi])) - || (argc <= 5)) - { - - if (rfg->plist_export_bgp_name[afi]) - free (rfg->plist_export_bgp_name[afi]); - rfg->plist_export_bgp_name[afi] = NULL; - rfg->plist_export_bgp[afi] = NULL; - - vnc_direct_bgp_reexport_group_afi (bgp, rfg, afi); - } - } - else - { - if (((argc > 5) - && strmatch(argv[5]->text, rfg->plist_export_zebra_name[afi])) - || (argc <= 5)) - { - if (rfg->plist_export_zebra_name[afi]) - free (rfg->plist_export_zebra_name[afi]); - rfg->plist_export_zebra_name[afi] = NULL; - rfg->plist_export_zebra[afi] = NULL; - - vnc_zebra_reexport_group_afi (bgp, rfg, afi); - } - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + afi_t afi; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[3]->text, "ipv4")) { + afi = AFI_IP; + } else { + afi = AFI_IP6; + } + + if (argv[2]->arg[0] == 'b') { + if (((argc > 5) && strmatch(argv[5]->text, + rfg->plist_export_bgp_name[afi])) + || (argc <= 5)) { + + if (rfg->plist_export_bgp_name[afi]) + free(rfg->plist_export_bgp_name[afi]); + rfg->plist_export_bgp_name[afi] = NULL; + rfg->plist_export_bgp[afi] = NULL; + + vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); + } + } else { + if (((argc > 5) && strmatch(argv[5]->text, + rfg->plist_export_zebra_name[afi])) + || (argc <= 5)) { + if (rfg->plist_export_zebra_name[afi]) + free(rfg->plist_export_zebra_name[afi]); + rfg->plist_export_zebra_name[afi] = NULL; + rfg->plist_export_zebra[afi] = NULL; + + vnc_zebra_reexport_group_afi(bgp, rfg, afi); + } + } + return CMD_SUCCESS; } DEFUN (vnc_nve_group_export_prefixlist, @@ -1851,53 +1710,47 @@ DEFUN (vnc_nve_group_export_prefixlist, "IPv6 routes\n" "Prefix-list for filtering exported routes\n" "prefix list name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - afi_t afi; - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[2]->text, "ipv4")) - { - afi = AFI_IP; - } - else - { - afi = AFI_IP6; - } - - if (argv[1]->arg[0] == 'b') - { - if (rfg->plist_export_bgp_name[afi]) - free (rfg->plist_export_bgp_name[afi]); - rfg->plist_export_bgp_name[afi] = strdup (argv[4]->arg); - rfg->plist_export_bgp[afi] = prefix_list_lookup (afi, argv[4]->arg); - - vnc_direct_bgp_reexport_group_afi (bgp, rfg, afi); - - } - else - { - if (rfg->plist_export_zebra_name[afi]) - free (rfg->plist_export_zebra_name[afi]); - rfg->plist_export_zebra_name[afi] = strdup (argv[4]->arg); - rfg->plist_export_zebra[afi] = prefix_list_lookup (afi, argv[4]->arg); - - vnc_zebra_reexport_group_afi (bgp, rfg, afi); - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + afi_t afi; + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[2]->text, "ipv4")) { + afi = AFI_IP; + } else { + afi = AFI_IP6; + } + + if (argv[1]->arg[0] == 'b') { + if (rfg->plist_export_bgp_name[afi]) + free(rfg->plist_export_bgp_name[afi]); + rfg->plist_export_bgp_name[afi] = strdup(argv[4]->arg); + rfg->plist_export_bgp[afi] = + prefix_list_lookup(afi, argv[4]->arg); + + vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); + + } else { + if (rfg->plist_export_zebra_name[afi]) + free(rfg->plist_export_zebra_name[afi]); + rfg->plist_export_zebra_name[afi] = strdup(argv[4]->arg); + rfg->plist_export_zebra[afi] = + prefix_list_lookup(afi, argv[4]->arg); + + vnc_zebra_reexport_group_afi(bgp, rfg, afi); + } + return CMD_SUCCESS; } DEFUN (vnc_nve_group_export_no_routemap, @@ -1909,55 +1762,48 @@ DEFUN (vnc_nve_group_export_no_routemap, "Export to Zebra (experimental)\n" "Route-map for filtering exported routes\n" "route map name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv[2]->arg[0] == 'b') - { - if (((argc > 4) - && strmatch(argv[4]->text, rfg->routemap_export_bgp_name)) - || (argc <= 4)) - { - - if (rfg->routemap_export_bgp_name) - free (rfg->routemap_export_bgp_name); - rfg->routemap_export_bgp_name = NULL; - rfg->routemap_export_bgp = NULL; - - vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP); - vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP6); - } - } - else - { - if (((argc > 4) - && strmatch(argv[4]->text, rfg->routemap_export_zebra_name)) - || (argc <= 4)) - { - if (rfg->routemap_export_zebra_name) - free (rfg->routemap_export_zebra_name); - rfg->routemap_export_zebra_name = NULL; - rfg->routemap_export_zebra = NULL; - - vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP); - vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP6); - } - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv[2]->arg[0] == 'b') { + if (((argc > 4) + && strmatch(argv[4]->text, rfg->routemap_export_bgp_name)) + || (argc <= 4)) { + + if (rfg->routemap_export_bgp_name) + free(rfg->routemap_export_bgp_name); + rfg->routemap_export_bgp_name = NULL; + rfg->routemap_export_bgp = NULL; + + vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP); + vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); + } + } else { + if (((argc > 4) && strmatch(argv[4]->text, + rfg->routemap_export_zebra_name)) + || (argc <= 4)) { + if (rfg->routemap_export_zebra_name) + free(rfg->routemap_export_zebra_name); + rfg->routemap_export_zebra_name = NULL; + rfg->routemap_export_zebra = NULL; + + vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP); + vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6); + } + } + return CMD_SUCCESS; } DEFUN (vnc_nve_group_export_routemap, @@ -1968,42 +1814,39 @@ DEFUN (vnc_nve_group_export_routemap, "Export to Zebra (experimental)\n" "Route-map for filtering exported routes\n" "route map name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - - if (!bgp->rfapi_cfg) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv[1]->arg[0] == 'b') - { - if (rfg->routemap_export_bgp_name) - free (rfg->routemap_export_bgp_name); - rfg->routemap_export_bgp_name = strdup (argv[3]->arg); - rfg->routemap_export_bgp = route_map_lookup_by_name (argv[3]->arg); - vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP); - vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP6); - } - else - { - if (rfg->routemap_export_zebra_name) - free (rfg->routemap_export_zebra_name); - rfg->routemap_export_zebra_name = strdup (argv[3]->arg); - rfg->routemap_export_zebra = route_map_lookup_by_name (argv[3]->arg); - vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP); - vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP6); - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + + if (!bgp->rfapi_cfg) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv[1]->arg[0] == 'b') { + if (rfg->routemap_export_bgp_name) + free(rfg->routemap_export_bgp_name); + rfg->routemap_export_bgp_name = strdup(argv[3]->arg); + rfg->routemap_export_bgp = + route_map_lookup_by_name(argv[3]->arg); + vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP); + vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); + } else { + if (rfg->routemap_export_zebra_name) + free(rfg->routemap_export_zebra_name); + rfg->routemap_export_zebra_name = strdup(argv[3]->arg); + rfg->routemap_export_zebra = + route_map_lookup_by_name(argv[3]->arg); + vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP); + vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6); + } + return CMD_SUCCESS; } DEFUN (vnc_nve_export_no_prefixlist, @@ -2018,54 +1861,44 @@ DEFUN (vnc_nve_export_no_prefixlist, "IPv6 prefixes\n" "Prefix-list for filtering exported routes\n" "Prefix list name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_cfg *hc; - afi_t afi; - - if (!(hc = bgp->rfapi_cfg)) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[4]->text, "ipv4")) - { - afi = AFI_IP; - } - else - { - afi = AFI_IP6; - } - - if (argv[3]->arg[0] == 'b') - { - if (((argc > 6) - && hc->plist_export_bgp_name[afi] - && strmatch(argv[6]->text, hc->plist_export_bgp_name[afi])) - || (argc <= 6)) - { - - free (hc->plist_export_bgp_name[afi]); - hc->plist_export_bgp_name[afi] = NULL; - hc->plist_export_bgp[afi] = NULL; - vnc_direct_bgp_reexport (bgp, afi); - } - } - else - { - if (((argc > 6) - && hc->plist_export_zebra_name[afi] - && strmatch(argv[6]->text, hc->plist_export_zebra_name[afi])) - || (argc <= 6)) - { - - free (hc->plist_export_zebra_name[afi]); - hc->plist_export_zebra_name[afi] = NULL; - hc->plist_export_zebra[afi] = NULL; - /* TBD vnc_zebra_rh_reexport(bgp, afi); */ - } - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_cfg *hc; + afi_t afi; + + if (!(hc = bgp->rfapi_cfg)) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[4]->text, "ipv4")) { + afi = AFI_IP; + } else { + afi = AFI_IP6; + } + + if (argv[3]->arg[0] == 'b') { + if (((argc > 6) && hc->plist_export_bgp_name[afi] + && strmatch(argv[6]->text, hc->plist_export_bgp_name[afi])) + || (argc <= 6)) { + + free(hc->plist_export_bgp_name[afi]); + hc->plist_export_bgp_name[afi] = NULL; + hc->plist_export_bgp[afi] = NULL; + vnc_direct_bgp_reexport(bgp, afi); + } + } else { + if (((argc > 6) && hc->plist_export_zebra_name[afi] + && strmatch(argv[6]->text, + hc->plist_export_zebra_name[afi])) + || (argc <= 6)) { + + free(hc->plist_export_zebra_name[afi]); + hc->plist_export_zebra_name[afi] = NULL; + hc->plist_export_zebra[afi] = NULL; + /* TBD vnc_zebra_rh_reexport(bgp, afi); */ + } + } + return CMD_SUCCESS; } DEFUN (vnc_nve_export_prefixlist, @@ -2079,42 +1912,37 @@ DEFUN (vnc_nve_export_prefixlist, "IPv6 prefixes\n" "Prefix-list for filtering exported routes\n" "Prefix list name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_cfg *hc; - afi_t afi; - - if (!(hc = bgp->rfapi_cfg)) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[3]->text, "ipv4")) - { - afi = AFI_IP; - } - else - { - afi = AFI_IP6; - } - - if (argv[2]->arg[0] == 'b') - { - if (hc->plist_export_bgp_name[afi]) - free (hc->plist_export_bgp_name[afi]); - hc->plist_export_bgp_name[afi] = strdup (argv[5]->arg); - hc->plist_export_bgp[afi] = prefix_list_lookup (afi, argv[5]->arg); - vnc_direct_bgp_reexport (bgp, afi); - } - else - { - if (hc->plist_export_zebra_name[afi]) - free (hc->plist_export_zebra_name[afi]); - hc->plist_export_zebra_name[afi] = strdup (argv[5]->arg); - hc->plist_export_zebra[afi] = prefix_list_lookup (afi, argv[5]->arg); - /* TBD vnc_zebra_rh_reexport(bgp, afi); */ - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_cfg *hc; + afi_t afi; + + if (!(hc = bgp->rfapi_cfg)) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[3]->text, "ipv4")) { + afi = AFI_IP; + } else { + afi = AFI_IP6; + } + + if (argv[2]->arg[0] == 'b') { + if (hc->plist_export_bgp_name[afi]) + free(hc->plist_export_bgp_name[afi]); + hc->plist_export_bgp_name[afi] = strdup(argv[5]->arg); + hc->plist_export_bgp[afi] = + prefix_list_lookup(afi, argv[5]->arg); + vnc_direct_bgp_reexport(bgp, afi); + } else { + if (hc->plist_export_zebra_name[afi]) + free(hc->plist_export_zebra_name[afi]); + hc->plist_export_zebra_name[afi] = strdup(argv[5]->arg); + hc->plist_export_zebra[afi] = + prefix_list_lookup(afi, argv[5]->arg); + /* TBD vnc_zebra_rh_reexport(bgp, afi); */ + } + return CMD_SUCCESS; } DEFUN (vnc_nve_export_no_routemap, @@ -2127,46 +1955,38 @@ DEFUN (vnc_nve_export_no_routemap, "Export to Zebra (experimental)\n" "Route-map for filtering exported routes\n" "Route map name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_cfg *hc; - - if (!(hc = bgp->rfapi_cfg)) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv[3]->arg[0] == 'b') - { - if (((argc > 5) - && hc->routemap_export_bgp_name - && strmatch(argv[5]->text, hc->routemap_export_bgp_name)) - || (argc <= 5)) - { - - free (hc->routemap_export_bgp_name); - hc->routemap_export_bgp_name = NULL; - hc->routemap_export_bgp = NULL; - vnc_direct_bgp_reexport (bgp, AFI_IP); - vnc_direct_bgp_reexport (bgp, AFI_IP6); - } - } - else - { - if (((argc > 5) - && hc->routemap_export_zebra_name - && strmatch(argv[5]->text, hc->routemap_export_zebra_name)) - || (argc <= 5)) - { - - free (hc->routemap_export_zebra_name); - hc->routemap_export_zebra_name = NULL; - hc->routemap_export_zebra = NULL; - /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ - /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ - } - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_cfg *hc; + + if (!(hc = bgp->rfapi_cfg)) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv[3]->arg[0] == 'b') { + if (((argc > 5) && hc->routemap_export_bgp_name + && strmatch(argv[5]->text, hc->routemap_export_bgp_name)) + || (argc <= 5)) { + + free(hc->routemap_export_bgp_name); + hc->routemap_export_bgp_name = NULL; + hc->routemap_export_bgp = NULL; + vnc_direct_bgp_reexport(bgp, AFI_IP); + vnc_direct_bgp_reexport(bgp, AFI_IP6); + } + } else { + if (((argc > 5) && hc->routemap_export_zebra_name + && strmatch(argv[5]->text, hc->routemap_export_zebra_name)) + || (argc <= 5)) { + + free(hc->routemap_export_zebra_name); + hc->routemap_export_zebra_name = NULL; + hc->routemap_export_zebra = NULL; + /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ + /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ + } + } + return CMD_SUCCESS; } DEFUN (vnc_nve_export_routemap, @@ -2178,232 +1998,210 @@ DEFUN (vnc_nve_export_routemap, "Export to Zebra (experimental)\n" "Route-map for filtering exported routes\n" "Route map name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_cfg *hc; - - if (!(hc = bgp->rfapi_cfg)) - { - vty_out (vty, "rfapi not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv[2]->arg[0] == 'b') - { - if (hc->routemap_export_bgp_name) - free (hc->routemap_export_bgp_name); - hc->routemap_export_bgp_name = strdup (argv[4]->arg); - hc->routemap_export_bgp = route_map_lookup_by_name (argv[4]->arg); - vnc_direct_bgp_reexport (bgp, AFI_IP); - vnc_direct_bgp_reexport (bgp, AFI_IP6); - } - else - { - if (hc->routemap_export_zebra_name) - free (hc->routemap_export_zebra_name); - hc->routemap_export_zebra_name = strdup (argv[4]->arg); - hc->routemap_export_zebra = route_map_lookup_by_name (argv[4]->arg); - /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ - /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_cfg *hc; + + if (!(hc = bgp->rfapi_cfg)) { + vty_out(vty, "rfapi not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv[2]->arg[0] == 'b') { + if (hc->routemap_export_bgp_name) + free(hc->routemap_export_bgp_name); + hc->routemap_export_bgp_name = strdup(argv[4]->arg); + hc->routemap_export_bgp = + route_map_lookup_by_name(argv[4]->arg); + vnc_direct_bgp_reexport(bgp, AFI_IP); + vnc_direct_bgp_reexport(bgp, AFI_IP6); + } else { + if (hc->routemap_export_zebra_name) + free(hc->routemap_export_zebra_name); + hc->routemap_export_zebra_name = strdup(argv[4]->arg); + hc->routemap_export_zebra = + route_map_lookup_by_name(argv[4]->arg); + /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ + /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ + } + return CMD_SUCCESS; } /* * respond to changes in the global prefix list configuration */ -void -vnc_prefix_list_update (struct bgp *bgp) +void vnc_prefix_list_update(struct bgp *bgp) { - afi_t afi; - struct listnode *n; - struct rfapi_nve_group_cfg *rfg; - struct rfapi_cfg *hc; - int i; - - if (!bgp) - { - vnc_zlog_debug_verbose ("%s: No BGP process is configured", __func__); - return; - } - - if (!(hc = bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: rfapi not configured", __func__); - return; - } - - for (afi = AFI_IP; afi < AFI_MAX; afi++) - { - /* - * Loop over nve groups - */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->nve_groups_sequential, - n, rfg)) - { - - if (rfg->plist_export_bgp_name[afi]) - { - rfg->plist_export_bgp[afi] = - prefix_list_lookup (afi, rfg->plist_export_bgp_name[afi]); - } - if (rfg->plist_export_zebra_name[afi]) - { - rfg->plist_export_zebra[afi] = - prefix_list_lookup (afi, rfg->plist_export_zebra_name[afi]); - } - for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) - { - if (rfg->plist_redist_name[i][afi]) - { - rfg->plist_redist[i][afi] = - prefix_list_lookup (afi, rfg->plist_redist_name[i][afi]); - } - } - - vnc_direct_bgp_reexport_group_afi (bgp, rfg, afi); - /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */ - } - - /* - * RH config, too - */ - if (hc->plist_export_bgp_name[afi]) - { - hc->plist_export_bgp[afi] = - prefix_list_lookup (afi, hc->plist_export_bgp_name[afi]); - } - if (hc->plist_export_zebra_name[afi]) - { - hc->plist_export_zebra[afi] = - prefix_list_lookup (afi, hc->plist_export_zebra_name[afi]); - } - - for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) - { - if (hc->plist_redist_name[i][afi]) - { - hc->plist_redist[i][afi] = - prefix_list_lookup (afi, hc->plist_redist_name[i][afi]); - } - } - - } - - vnc_direct_bgp_reexport (bgp, AFI_IP); - vnc_direct_bgp_reexport (bgp, AFI_IP6); - - /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ - /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ - - vnc_redistribute_prechange (bgp); - vnc_redistribute_postchange (bgp); + afi_t afi; + struct listnode *n; + struct rfapi_nve_group_cfg *rfg; + struct rfapi_cfg *hc; + int i; + + if (!bgp) { + vnc_zlog_debug_verbose("%s: No BGP process is configured", + __func__); + return; + } + + if (!(hc = bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose("%s: rfapi not configured", __func__); + return; + } + + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + /* + * Loop over nve groups + */ + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, + n, rfg)) { + + if (rfg->plist_export_bgp_name[afi]) { + rfg->plist_export_bgp[afi] = prefix_list_lookup( + afi, rfg->plist_export_bgp_name[afi]); + } + if (rfg->plist_export_zebra_name[afi]) { + rfg->plist_export_zebra + [afi] = prefix_list_lookup( + afi, rfg->plist_export_zebra_name[afi]); + } + for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) { + if (rfg->plist_redist_name[i][afi]) { + rfg->plist_redist + [i][afi] = prefix_list_lookup( + afi, + rfg->plist_redist_name[i][afi]); + } + } + + vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); + /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */ + } + + /* + * RH config, too + */ + if (hc->plist_export_bgp_name[afi]) { + hc->plist_export_bgp[afi] = prefix_list_lookup( + afi, hc->plist_export_bgp_name[afi]); + } + if (hc->plist_export_zebra_name[afi]) { + hc->plist_export_zebra[afi] = prefix_list_lookup( + afi, hc->plist_export_zebra_name[afi]); + } + + for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) { + if (hc->plist_redist_name[i][afi]) { + hc->plist_redist[i][afi] = prefix_list_lookup( + afi, hc->plist_redist_name[i][afi]); + } + } + } + + vnc_direct_bgp_reexport(bgp, AFI_IP); + vnc_direct_bgp_reexport(bgp, AFI_IP6); + + /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ + /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ + + vnc_redistribute_prechange(bgp); + vnc_redistribute_postchange(bgp); } /* * respond to changes in the global route map configuration */ -void -vnc_routemap_update (struct bgp *bgp, const char *unused) +void vnc_routemap_update(struct bgp *bgp, const char *unused) { - struct listnode *n; - struct rfapi_nve_group_cfg *rfg; - struct rfapi_cfg *hc; - int i; - - vnc_zlog_debug_verbose ("%s(arg=%s)", __func__, unused); - - if (!bgp) - { - vnc_zlog_debug_verbose ("%s: No BGP process is configured", __func__); - return; - } - - if (!(hc = bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: rfapi not configured", __func__); - return; - } - - /* - * Loop over nve groups - */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->nve_groups_sequential, n, rfg)) - { - - if (rfg->routemap_export_bgp_name) - { - rfg->routemap_export_bgp = - route_map_lookup_by_name (rfg->routemap_export_bgp_name); - } - if (rfg->routemap_export_zebra_name) - { - rfg->routemap_export_bgp = - route_map_lookup_by_name (rfg->routemap_export_zebra_name); - } - for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) - { - if (rfg->routemap_redist_name[i]) - { - rfg->routemap_redist[i] = - route_map_lookup_by_name (rfg->routemap_redist_name[i]); - } - } - - vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP); - vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP6); - /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */ - } - - /* - * RH config, too - */ - if (hc->routemap_export_bgp_name) - { - hc->routemap_export_bgp = - route_map_lookup_by_name (hc->routemap_export_bgp_name); - } - if (hc->routemap_export_zebra_name) - { - hc->routemap_export_bgp = - route_map_lookup_by_name (hc->routemap_export_zebra_name); - } - for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) - { - if (hc->routemap_redist_name[i]) - { - hc->routemap_redist[i] = - route_map_lookup_by_name (hc->routemap_redist_name[i]); - } - } - - vnc_direct_bgp_reexport (bgp, AFI_IP); - vnc_direct_bgp_reexport (bgp, AFI_IP6); - - /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ - /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ - - vnc_redistribute_prechange (bgp); - vnc_redistribute_postchange (bgp); - - vnc_zlog_debug_verbose ("%s done", __func__); + struct listnode *n; + struct rfapi_nve_group_cfg *rfg; + struct rfapi_cfg *hc; + int i; + + vnc_zlog_debug_verbose("%s(arg=%s)", __func__, unused); + + if (!bgp) { + vnc_zlog_debug_verbose("%s: No BGP process is configured", + __func__); + return; + } + + if (!(hc = bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose("%s: rfapi not configured", __func__); + return; + } + + /* + * Loop over nve groups + */ + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, n, + rfg)) { + + if (rfg->routemap_export_bgp_name) { + rfg->routemap_export_bgp = route_map_lookup_by_name( + rfg->routemap_export_bgp_name); + } + if (rfg->routemap_export_zebra_name) { + rfg->routemap_export_bgp = route_map_lookup_by_name( + rfg->routemap_export_zebra_name); + } + for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) { + if (rfg->routemap_redist_name[i]) { + rfg->routemap_redist[i] = + route_map_lookup_by_name( + rfg->routemap_redist_name[i]); + } + } + + vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP); + vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); + /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */ + } + + /* + * RH config, too + */ + if (hc->routemap_export_bgp_name) { + hc->routemap_export_bgp = + route_map_lookup_by_name(hc->routemap_export_bgp_name); + } + if (hc->routemap_export_zebra_name) { + hc->routemap_export_bgp = route_map_lookup_by_name( + hc->routemap_export_zebra_name); + } + for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) { + if (hc->routemap_redist_name[i]) { + hc->routemap_redist[i] = route_map_lookup_by_name( + hc->routemap_redist_name[i]); + } + } + + vnc_direct_bgp_reexport(bgp, AFI_IP); + vnc_direct_bgp_reexport(bgp, AFI_IP6); + + /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ + /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ + + vnc_redistribute_prechange(bgp); + vnc_redistribute_postchange(bgp); + + vnc_zlog_debug_verbose("%s done", __func__); } -static void -vnc_routemap_event (route_map_event_t type, /* ignored */ - const char *rmap_name) /* ignored */ +static void vnc_routemap_event(route_map_event_t type, /* ignored */ + const char *rmap_name) /* ignored */ { - struct listnode *mnode, *mnnode; - struct bgp *bgp; + struct listnode *mnode, *mnnode; + struct bgp *bgp; - vnc_zlog_debug_verbose ("%s(event type=%d)", __func__, type); - if (bm->bgp == NULL) /* may be called during cleanup */ - return; + vnc_zlog_debug_verbose("%s(event type=%d)", __func__, type); + if (bm->bgp == NULL) /* may be called during cleanup */ + return; - for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp)) - vnc_routemap_update (bgp, rmap_name); + for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) + vnc_routemap_update(bgp, rmap_name); - vnc_zlog_debug_verbose ("%s: done", __func__); + vnc_zlog_debug_verbose("%s: done", __func__); } /*------------------------------------------------------------------------- @@ -2416,288 +2214,267 @@ DEFUN_NOSH (vnc_nve_group, "vnc nve-group NAME", VNC_CONFIG_STR "Configure a NVE group\n" "Group name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct rfapi_nve_group_cfg *rfg; - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - - /* Search for name */ - rfg = bgp_rfapi_cfg_match_byname (bgp, argv[2]->arg, RFAPI_GROUP_CFG_NVE); - - if (!rfg) - { - rfg = rfapi_group_new (bgp, RFAPI_GROUP_CFG_NVE, argv[2]->arg); - if (!rfg) - { - /* Error out of memory */ - vty_out (vty, "Can't allocate memory for NVE group\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Copy defaults from struct rfapi_cfg */ - rfg->rd = bgp->rfapi_cfg->default_rd; - if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_L2RD) - { - rfg->l2rd = bgp->rfapi_cfg->default_l2rd; - rfg->flags |= RFAPI_RFG_L2RD; - } - rfg->rd = bgp->rfapi_cfg->default_rd; - rfg->response_lifetime = bgp->rfapi_cfg->default_response_lifetime; - - if (bgp->rfapi_cfg->default_rt_export_list) - { - rfg->rt_export_list = - ecommunity_dup (bgp->rfapi_cfg->default_rt_export_list); - } - - if (bgp->rfapi_cfg->default_rt_import_list) - { - rfg->rt_import_list = - ecommunity_dup (bgp->rfapi_cfg->default_rt_import_list); - rfg->rfapi_import_table = - rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - } - - /* - * If a redist nve group was named but the group was not defined, - * make the linkage now - */ - if (!bgp->rfapi_cfg->rfg_redist) - { - if (bgp->rfapi_cfg->rfg_redist_name && - !strcmp (bgp->rfapi_cfg->rfg_redist_name, rfg->name)) - { - - vnc_redistribute_prechange (bgp); - bgp->rfapi_cfg->rfg_redist = rfg; - vnc_redistribute_postchange (bgp); - - } - } - - /* - * Same treatment for bgp-direct export group - */ - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, nnode, rfgn)) - { - - if (!strcmp (rfgn->name, rfg->name)) - { - rfgn->rfg = rfg; - vnc_direct_bgp_add_group (bgp, rfg); - break; - } - } - - /* - * Same treatment for zebra export group - */ - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_zebra_l, - node, nnode, rfgn)) - { - - vnc_zlog_debug_verbose ("%s: ezport zebra: checking if \"%s\" == \"%s\"", - __func__, rfgn->name, rfg->name); - if (!strcmp (rfgn->name, rfg->name)) - { - rfgn->rfg = rfg; - vnc_zebra_add_group (bgp, rfg); - break; - } - } - } - - /* - * XXX subsequent calls will need to make sure this item is still - * in the linked list and has the same name - */ - VTY_PUSH_CONTEXT_SUB (BGP_VNC_NVE_GROUP_NODE, rfg); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct rfapi_nve_group_cfg *rfg; + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + + /* Search for name */ + rfg = bgp_rfapi_cfg_match_byname(bgp, argv[2]->arg, + RFAPI_GROUP_CFG_NVE); + + if (!rfg) { + rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_NVE, argv[2]->arg); + if (!rfg) { + /* Error out of memory */ + vty_out(vty, "Can't allocate memory for NVE group\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* Copy defaults from struct rfapi_cfg */ + rfg->rd = bgp->rfapi_cfg->default_rd; + if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_L2RD) { + rfg->l2rd = bgp->rfapi_cfg->default_l2rd; + rfg->flags |= RFAPI_RFG_L2RD; + } + rfg->rd = bgp->rfapi_cfg->default_rd; + rfg->response_lifetime = + bgp->rfapi_cfg->default_response_lifetime; + + if (bgp->rfapi_cfg->default_rt_export_list) { + rfg->rt_export_list = ecommunity_dup( + bgp->rfapi_cfg->default_rt_export_list); + } + + if (bgp->rfapi_cfg->default_rt_import_list) { + rfg->rt_import_list = ecommunity_dup( + bgp->rfapi_cfg->default_rt_import_list); + rfg->rfapi_import_table = rfapiImportTableRefAdd( + bgp, rfg->rt_import_list, rfg); + } + + /* + * If a redist nve group was named but the group was not + * defined, + * make the linkage now + */ + if (!bgp->rfapi_cfg->rfg_redist) { + if (bgp->rfapi_cfg->rfg_redist_name + && !strcmp(bgp->rfapi_cfg->rfg_redist_name, + rfg->name)) { + + vnc_redistribute_prechange(bgp); + bgp->rfapi_cfg->rfg_redist = rfg; + vnc_redistribute_postchange(bgp); + } + } + + /* + * Same treatment for bgp-direct export group + */ + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, + node, nnode, rfgn)) { + + if (!strcmp(rfgn->name, rfg->name)) { + rfgn->rfg = rfg; + vnc_direct_bgp_add_group(bgp, rfg); + break; + } + } + + /* + * Same treatment for zebra export group + */ + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node, + nnode, rfgn)) { + + vnc_zlog_debug_verbose( + "%s: ezport zebra: checking if \"%s\" == \"%s\"", + __func__, rfgn->name, rfg->name); + if (!strcmp(rfgn->name, rfg->name)) { + rfgn->rfg = rfg; + vnc_zebra_add_group(bgp, rfg); + break; + } + } + } + + /* + * XXX subsequent calls will need to make sure this item is still + * in the linked list and has the same name + */ + VTY_PUSH_CONTEXT_SUB(BGP_VNC_NVE_GROUP_NODE, rfg); + + return CMD_SUCCESS; } -static void -bgp_rfapi_delete_nve_group ( - struct vty *vty, /* NULL = no output */ - struct bgp *bgp, - struct rfapi_nve_group_cfg *rfg) +static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */ + struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg) { - struct list *orphaned_nves = NULL; - struct listnode *node, *nnode; - - /* - * If there are currently-open NVEs that belong to this group, - * zero out their references to this group structure. - */ - if (rfg->nves) - { - struct rfapi_descriptor *rfd; - orphaned_nves = list_new (); - while ((rfd = listnode_head (rfg->nves))) - { - rfd->rfg = NULL; - listnode_delete (rfg->nves, rfd); - listnode_add (orphaned_nves, rfd); - } - list_delete (rfg->nves); - rfg->nves = NULL; - } - - /* delete it */ - free (rfg->name); - if (rfg->rfapi_import_table) - rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); - if (rfg->rt_import_list) - ecommunity_free (&rfg->rt_import_list); - if (rfg->rt_export_list) - ecommunity_free (&rfg->rt_export_list); - - if (rfg->vn_node) - { - rfg->vn_node->info = NULL; - route_unlock_node (rfg->vn_node); /* frees */ - } - if (rfg->un_node) - { - rfg->un_node->info = NULL; - route_unlock_node (rfg->un_node); /* frees */ - } - if (rfg->rfp_cfg) - XFREE (MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); - listnode_delete (bgp->rfapi_cfg->nve_groups_sequential, rfg); - - QOBJ_UNREG (rfg); - XFREE (MTYPE_RFAPI_GROUP_CFG, rfg); - - /* - * Attempt to reassign the orphaned nves to a new group. If - * a NVE can not be reassigned, its rfd->rfg will remain NULL - * and it will become a zombie until released by rfapi_close(). - */ - if (orphaned_nves) - { - struct rfapi_descriptor *rfd; - - for (ALL_LIST_ELEMENTS (orphaned_nves, node, nnode, rfd)) - { - /* - * 1. rfapi_close() equivalent except: - * a. don't free original descriptor - * b. remember query list - * c. remember advertised route list - * 2. rfapi_open() equivalent except: - * a. reuse original descriptor - * 3. rfapi_register() on remembered advertised route list - * 4. rfapi_query on rememebred query list - */ - - int rc; - - rc = rfapi_reopen (rfd, bgp); - - if (!rc) - { - list_delete_node (orphaned_nves, node); - if (vty) - vty_out (vty, "WARNING: reassigned NVE vn="); - rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr); - if (vty) - vty_out (vty, " un="); - rfapiPrintRfapiIpAddr (vty, &rfd->un_addr); - if (vty) - vty_out (vty, " to new group \"%s\"\n",rfd->rfg->name); - - } - } - - for (ALL_LIST_ELEMENTS_RO (orphaned_nves, node, rfd)) - { - if (vty) - vty_out (vty, "WARNING: orphaned NVE vn="); - rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr); - if (vty) - vty_out (vty, " un="); - rfapiPrintRfapiIpAddr (vty, &rfd->un_addr); - if (vty) - vty_out (vty, "\n"); - } - list_delete (orphaned_nves); - } + struct list *orphaned_nves = NULL; + struct listnode *node, *nnode; + + /* + * If there are currently-open NVEs that belong to this group, + * zero out their references to this group structure. + */ + if (rfg->nves) { + struct rfapi_descriptor *rfd; + orphaned_nves = list_new(); + while ((rfd = listnode_head(rfg->nves))) { + rfd->rfg = NULL; + listnode_delete(rfg->nves, rfd); + listnode_add(orphaned_nves, rfd); + } + list_delete(rfg->nves); + rfg->nves = NULL; + } + + /* delete it */ + free(rfg->name); + if (rfg->rfapi_import_table) + rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); + if (rfg->rt_import_list) + ecommunity_free(&rfg->rt_import_list); + if (rfg->rt_export_list) + ecommunity_free(&rfg->rt_export_list); + + if (rfg->vn_node) { + rfg->vn_node->info = NULL; + route_unlock_node(rfg->vn_node); /* frees */ + } + if (rfg->un_node) { + rfg->un_node->info = NULL; + route_unlock_node(rfg->un_node); /* frees */ + } + if (rfg->rfp_cfg) + XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); + listnode_delete(bgp->rfapi_cfg->nve_groups_sequential, rfg); + + QOBJ_UNREG(rfg); + XFREE(MTYPE_RFAPI_GROUP_CFG, rfg); + + /* + * Attempt to reassign the orphaned nves to a new group. If + * a NVE can not be reassigned, its rfd->rfg will remain NULL + * and it will become a zombie until released by rfapi_close(). + */ + if (orphaned_nves) { + struct rfapi_descriptor *rfd; + + for (ALL_LIST_ELEMENTS(orphaned_nves, node, nnode, rfd)) { + /* + * 1. rfapi_close() equivalent except: + * a. don't free original descriptor + * b. remember query list + * c. remember advertised route list + * 2. rfapi_open() equivalent except: + * a. reuse original descriptor + * 3. rfapi_register() on remembered advertised route + * list + * 4. rfapi_query on rememebred query list + */ + + int rc; + + rc = rfapi_reopen(rfd, bgp); + + if (!rc) { + list_delete_node(orphaned_nves, node); + if (vty) + vty_out(vty, + "WARNING: reassigned NVE vn="); + rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr); + if (vty) + vty_out(vty, " un="); + rfapiPrintRfapiIpAddr(vty, &rfd->un_addr); + if (vty) + vty_out(vty, " to new group \"%s\"\n", + rfd->rfg->name); + } + } + + for (ALL_LIST_ELEMENTS_RO(orphaned_nves, node, rfd)) { + if (vty) + vty_out(vty, "WARNING: orphaned NVE vn="); + rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr); + if (vty) + vty_out(vty, " un="); + rfapiPrintRfapiIpAddr(vty, &rfd->un_addr); + if (vty) + vty_out(vty, "\n"); + } + list_delete(orphaned_nves); + } } static int -bgp_rfapi_delete_named_nve_group ( - struct vty *vty, /* NULL = no output */ - struct bgp *bgp, - const char *rfg_name, /* NULL = any */ - rfapi_group_cfg_type_t type) /* _MAX = any */ +bgp_rfapi_delete_named_nve_group(struct vty *vty, /* NULL = no output */ + struct bgp *bgp, + const char *rfg_name, /* NULL = any */ + rfapi_group_cfg_type_t type) /* _MAX = any */ { - struct rfapi_nve_group_cfg *rfg = NULL; - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - - /* Search for name */ - if (rfg_name) - { - rfg = bgp_rfapi_cfg_match_byname (bgp, rfg_name, type); - if (!rfg) - { - if (vty) - vty_out (vty, "No NVE group named \"%s\"\n",rfg_name); - return CMD_WARNING_CONFIG_FAILED; - } - } - - /* - * If this group is the redist nve group, unlink it - */ - if (rfg_name == NULL || bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - bgp->rfapi_cfg->rfg_redist = NULL; - vnc_redistribute_postchange (bgp); - } - - - /* - * remove reference from bgp direct export list - */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, rfgn)) - { - if (rfg_name == NULL || - (type == RFAPI_GROUP_CFG_NVE && !strcmp (rfgn->name, rfg_name))) - { - rfgn->rfg = NULL; - /* remove exported routes from this group */ - vnc_direct_bgp_del_group (bgp, rfg); - break; - } - } - - /* - * remove reference from zebra export list - */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) - { - - if (rfg_name == NULL || - (type == RFAPI_GROUP_CFG_NVE && !strcmp (rfgn->name, rfg_name))) - { - rfgn->rfg = NULL; - /* remove exported routes from this group */ - vnc_zebra_del_group (bgp, rfg); - break; - } - } - if (rfg) - bgp_rfapi_delete_nve_group (vty, bgp, rfg); - else /* must be delete all */ - for (ALL_LIST_ELEMENTS - (bgp->rfapi_cfg->nve_groups_sequential, node, nnode, rfg)) - bgp_rfapi_delete_nve_group (vty, bgp, rfg); - return CMD_SUCCESS; + struct rfapi_nve_group_cfg *rfg = NULL; + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + + /* Search for name */ + if (rfg_name) { + rfg = bgp_rfapi_cfg_match_byname(bgp, rfg_name, type); + if (!rfg) { + if (vty) + vty_out(vty, "No NVE group named \"%s\"\n", + rfg_name); + return CMD_WARNING_CONFIG_FAILED; + } + } + + /* + * If this group is the redist nve group, unlink it + */ + if (rfg_name == NULL || bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + bgp->rfapi_cfg->rfg_redist = NULL; + vnc_redistribute_postchange(bgp); + } + + + /* + * remove reference from bgp direct export list + */ + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + rfgn)) { + if (rfg_name == NULL || (type == RFAPI_GROUP_CFG_NVE + && !strcmp(rfgn->name, rfg_name))) { + rfgn->rfg = NULL; + /* remove exported routes from this group */ + vnc_direct_bgp_del_group(bgp, rfg); + break; + } + } + + /* + * remove reference from zebra export list + */ + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, + rfgn)) { + + if (rfg_name == NULL || (type == RFAPI_GROUP_CFG_NVE + && !strcmp(rfgn->name, rfg_name))) { + rfgn->rfg = NULL; + /* remove exported routes from this group */ + vnc_zebra_del_group(bgp, rfg); + break; + } + } + if (rfg) + bgp_rfapi_delete_nve_group(vty, bgp, rfg); + else /* must be delete all */ + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, + node, nnode, rfg)) + bgp_rfapi_delete_nve_group(vty, bgp, rfg); + return CMD_SUCCESS; } DEFUN (vnc_no_nve_group, @@ -2708,9 +2485,10 @@ DEFUN (vnc_no_nve_group, "Configure a NVE group\n" "Group name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT(bgp, bgp); - return bgp_rfapi_delete_named_nve_group (vty, bgp, argv[3]->arg, RFAPI_GROUP_CFG_NVE); + return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[3]->arg, + RFAPI_GROUP_CFG_NVE); } DEFUN (vnc_nve_group_prefix, @@ -2722,116 +2500,101 @@ DEFUN (vnc_nve_group_prefix, "IPv4 prefix\n" "IPv6 prefix\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - struct prefix p; - int afi; - struct route_table *rt; - struct route_node *rn; - int is_un_prefix = 0; - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!str2prefix (argv[2]->arg, &p)) - { - vty_out (vty, "Malformed prefix \"%s\"\n", argv[2]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - afi = family2afi (p.family); - if (!afi) - { - vty_out (vty, "Unsupported address family\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv[1]->arg[0] == 'u') - { - rt = &(bgp->rfapi_cfg->nve_groups_un[afi]); - is_un_prefix = 1; - } - else - { - rt = &(bgp->rfapi_cfg->nve_groups_vn[afi]); - } - - rn = route_node_get (rt, &p); /* NB locks node */ - if (rn->info) - { - /* - * There is already a group with this prefix - */ - route_unlock_node (rn); - if (rn->info != rfg) - { - /* - * different group name: fail - */ - vty_out (vty, "nve group \"%s\" already has \"%s\" prefix %s\n", - ((struct rfapi_nve_group_cfg *) (rn->info))->name, - argv[1]->arg, argv[2]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - else - { - /* - * same group name: it's already in the correct place - * in the table, so we're done. - * - * Implies rfg->(vn|un)_prefix is already correct. - */ - return CMD_SUCCESS; - } - } - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - /* New prefix, new node */ - - if (is_un_prefix) - { - - /* detach rfg from previous route table location */ - if (rfg->un_node) - { - rfg->un_node->info = NULL; - route_unlock_node (rfg->un_node); /* frees */ - } - rfg->un_node = rn; /* back ref */ - rfg->un_prefix = p; - - } - else - { - - /* detach rfg from previous route table location */ - if (rfg->vn_node) - { - rfg->vn_node->info = NULL; - route_unlock_node (rfg->vn_node); /* frees */ - } - rfg->vn_node = rn; /* back ref */ - rfg->vn_prefix = p; - } - - /* attach */ - rn->info = rfg; - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + struct prefix p; + int afi; + struct route_table *rt; + struct route_node *rn; + int is_un_prefix = 0; + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (!str2prefix(argv[2]->arg, &p)) { + vty_out(vty, "Malformed prefix \"%s\"\n", argv[2]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + afi = family2afi(p.family); + if (!afi) { + vty_out(vty, "Unsupported address family\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv[1]->arg[0] == 'u') { + rt = &(bgp->rfapi_cfg->nve_groups_un[afi]); + is_un_prefix = 1; + } else { + rt = &(bgp->rfapi_cfg->nve_groups_vn[afi]); + } + + rn = route_node_get(rt, &p); /* NB locks node */ + if (rn->info) { + /* + * There is already a group with this prefix + */ + route_unlock_node(rn); + if (rn->info != rfg) { + /* + * different group name: fail + */ + vty_out(vty, + "nve group \"%s\" already has \"%s\" prefix %s\n", + ((struct rfapi_nve_group_cfg *)(rn->info)) + ->name, + argv[1]->arg, argv[2]->arg); + return CMD_WARNING_CONFIG_FAILED; + } else { + /* + * same group name: it's already in the correct place + * in the table, so we're done. + * + * Implies rfg->(vn|un)_prefix is already correct. + */ + return CMD_SUCCESS; + } + } + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + /* New prefix, new node */ + + if (is_un_prefix) { + + /* detach rfg from previous route table location */ + if (rfg->un_node) { + rfg->un_node->info = NULL; + route_unlock_node(rfg->un_node); /* frees */ + } + rfg->un_node = rn; /* back ref */ + rfg->un_prefix = p; + + } else { + + /* detach rfg from previous route table location */ + if (rfg->vn_node) { + rfg->vn_node->info = NULL; + route_unlock_node(rfg->vn_node); /* frees */ + } + rfg->vn_node = rn; /* back ref */ + rfg->vn_prefix = p; + } + + /* attach */ + rn->info = rfg; + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + + return CMD_SUCCESS; } DEFUN (vnc_nve_group_rt_import, @@ -2841,67 +2604,64 @@ DEFUN (vnc_nve_group_rt_import, "Import filter\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - int rc; - struct listnode *node; - struct rfapi_rfg_name *rfgn; - int is_export_bgp = 0; - int is_export_zebra = 0; - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_import_list); - if (rc != CMD_SUCCESS) - return rc; - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - is_export_bgp = 1; - break; - } - } - - if (is_export_bgp) - vnc_direct_bgp_del_group (bgp, rfg); - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - is_export_zebra = 1; - break; - } - } - - if (is_export_zebra) - vnc_zebra_del_group (bgp, rfg); - - /* - * stop referencing old import table, now reference new one - */ - if (rfg->rfapi_import_table) - rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); - rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - - if (is_export_bgp) - vnc_direct_bgp_add_group (bgp, rfg); - - if (is_export_zebra) - vnc_zebra_add_group (bgp, rfg); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + int rc; + struct listnode *node; + struct rfapi_rfg_name *rfgn; + int is_export_bgp = 0; + int is_export_zebra = 0; + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list); + if (rc != CMD_SUCCESS) + return rc; + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + is_export_bgp = 1; + break; + } + } + + if (is_export_bgp) + vnc_direct_bgp_del_group(bgp, rfg); + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + is_export_zebra = 1; + break; + } + } + + if (is_export_zebra) + vnc_zebra_del_group(bgp, rfg); + + /* + * stop referencing old import table, now reference new one + */ + if (rfg->rfapi_import_table) + rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); + rfg->rfapi_import_table = + rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg); + + if (is_export_bgp) + vnc_direct_bgp_add_group(bgp, rfg); + + if (is_export_zebra) + vnc_zebra_add_group(bgp, rfg); + + return CMD_SUCCESS; } DEFUN (vnc_nve_group_rt_export, @@ -2911,31 +2671,28 @@ DEFUN (vnc_nve_group_rt_export, "Export filter\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - int rc; - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_export_list); - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - - return rc; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + int rc; + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list); + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + + return rc; } DEFUN (vnc_nve_group_rt_both, @@ -2945,83 +2702,76 @@ DEFUN (vnc_nve_group_rt_both, "Export+import filters\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - int rc; - int is_export_bgp = 0; - int is_export_zebra = 0; - struct listnode *node; - struct rfapi_rfg_name *rfgn; - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_import_list); - if (rc != CMD_SUCCESS) - return rc; - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - is_export_bgp = 1; - break; - } - } - - if (is_export_bgp) - vnc_direct_bgp_del_group (bgp, rfg); - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - is_export_zebra = 1; - break; - } - } - - if (is_export_zebra) - { - vnc_zlog_debug_verbose ("%s: is_export_zebra", __func__); - vnc_zebra_del_group (bgp, rfg); - } - - /* - * stop referencing old import table, now reference new one - */ - if (rfg->rfapi_import_table) - rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); - rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - - if (is_export_bgp) - vnc_direct_bgp_add_group (bgp, rfg); - - if (is_export_zebra) - vnc_zebra_add_group (bgp, rfg); - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_export_list); - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - - return rc; - + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + int rc; + int is_export_bgp = 0; + int is_export_zebra = 0; + struct listnode *node; + struct rfapi_rfg_name *rfgn; + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list); + if (rc != CMD_SUCCESS) + return rc; + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + is_export_bgp = 1; + break; + } + } + + if (is_export_bgp) + vnc_direct_bgp_del_group(bgp, rfg); + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + is_export_zebra = 1; + break; + } + } + + if (is_export_zebra) { + vnc_zlog_debug_verbose("%s: is_export_zebra", __func__); + vnc_zebra_del_group(bgp, rfg); + } + + /* + * stop referencing old import table, now reference new one + */ + if (rfg->rfapi_import_table) + rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); + rfg->rfapi_import_table = + rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg); + + if (is_export_bgp) + vnc_direct_bgp_add_group(bgp, rfg); + + if (is_export_zebra) + vnc_zebra_add_group(bgp, rfg); + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list); + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + + return rc; } DEFUN (vnc_nve_group_l2rd, @@ -3031,45 +2781,40 @@ DEFUN (vnc_nve_group_l2rd, "Fixed value 1-255\n" "use the low-order octet of the NVE's VN address\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[1]->text, "auto:vn")) - { - rfg->l2rd = 0; - } - else - { - char *end = NULL; - unsigned long value_l = strtoul (argv[1]->arg, &end, 10); - uint8_t value = value_l & 0xff; - - if (!argv[1]->arg[0] || *end) - { - vty_out (vty, "%% Malformed l2 nve ID \"%s\"\n",argv[1]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - if ((value_l < 1) || (value_l > 0xff)) - { - vty_out (vty, - "%% Malformed l2 nve id (must be greater than 0 and less than %u\n", - 0x100); - return CMD_WARNING_CONFIG_FAILED; - } - - rfg->l2rd = value; - } - rfg->flags |= RFAPI_RFG_L2RD; - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[1]->text, "auto:vn")) { + rfg->l2rd = 0; + } else { + char *end = NULL; + unsigned long value_l = strtoul(argv[1]->arg, &end, 10); + uint8_t value = value_l & 0xff; + + if (!argv[1]->arg[0] || *end) { + vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n", + argv[1]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if ((value_l < 1) || (value_l > 0xff)) { + vty_out(vty, + "%% Malformed l2 nve id (must be greater than 0 and less than %u\n", + 0x100); + return CMD_WARNING_CONFIG_FAILED; + } + + rfg->l2rd = value; + } + rfg->flags |= RFAPI_RFG_L2RD; + + return CMD_SUCCESS; } DEFUN (vnc_nve_group_no_l2rd, @@ -3078,21 +2823,20 @@ DEFUN (vnc_nve_group_no_l2rd, NO_STR "Specify default Local Nve ID value to use in RD for L2 routes\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } - rfg->l2rd = 0; - rfg->flags &= ~RFAPI_RFG_L2RD; + rfg->l2rd = 0; + rfg->flags &= ~RFAPI_RFG_L2RD; - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (vnc_nve_group_rd, @@ -3101,73 +2845,64 @@ DEFUN (vnc_nve_group_rd, "Specify route distinguisher\n" "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - struct prefix_rd prd; - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!strncmp (argv[1]->arg, "auto:vn:", 8)) - { - /* - * use AF_UNIX to designate automatically-assigned RD - * auto:vn:nn where nn is a 2-octet quantity - */ - char *end = NULL; - uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10); - uint16_t value = value32 & 0xffff; - - if (!argv[1]->arg[8] || *end) - { - vty_out (vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (value32 > 0xffff) - { - vty_out (vty, "%% Malformed rd (must be less than %u\n", - 0x0ffff); - return CMD_WARNING_CONFIG_FAILED; - } - - memset (&prd, 0, sizeof (prd)); - prd.family = AF_UNIX; - prd.prefixlen = 64; - prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; - prd.val[1] = RD_TYPE_IP & 0x0ff; - prd.val[6] = (value >> 8) & 0x0ff; - prd.val[7] = value & 0x0ff; - - } - else - { - - ret = str2prefix_rd (argv[1]->arg, &prd); - if (!ret) - { - vty_out (vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - rfg->rd = prd; - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + int ret; + struct prefix_rd prd; + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (!strncmp(argv[1]->arg, "auto:vn:", 8)) { + /* + * use AF_UNIX to designate automatically-assigned RD + * auto:vn:nn where nn is a 2-octet quantity + */ + char *end = NULL; + uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10); + uint16_t value = value32 & 0xffff; + + if (!argv[1]->arg[8] || *end) { + vty_out(vty, "%% Malformed rd\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (value32 > 0xffff) { + vty_out(vty, "%% Malformed rd (must be less than %u\n", + 0x0ffff); + return CMD_WARNING_CONFIG_FAILED; + } + + memset(&prd, 0, sizeof(prd)); + prd.family = AF_UNIX; + prd.prefixlen = 64; + prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; + prd.val[1] = RD_TYPE_IP & 0x0ff; + prd.val[6] = (value >> 8) & 0x0ff; + prd.val[7] = value & 0x0ff; + + } else { + + ret = str2prefix_rd(argv[1]->arg, &prd); + if (!ret) { + vty_out(vty, "%% Malformed rd\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + rfg->rd = prd; + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + return CMD_SUCCESS; } DEFUN (vnc_nve_group_responselifetime, @@ -3176,40 +2911,36 @@ DEFUN (vnc_nve_group_responselifetime, "Specify response lifetime\n" "Response lifetime in seconds\n" "Infinite response lifetime\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - unsigned int rspint; - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - struct rfapi_descriptor *rfd; - struct listnode *hdnode; - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[1]->text, "infinite")) - { - rspint = RFAPI_INFINITE_LIFETIME; - } - else - { - rspint = strtoul(argv[1]->arg, NULL, 10); - } - - rfg->response_lifetime = rspint; - rfg->flags |= RFAPI_RFG_RESPONSE_LIFETIME; - if (rfg->nves) - for (ALL_LIST_ELEMENTS_RO (rfg->nves, hdnode, rfd)) - rfd->response_lifetime = rspint; - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT(bgp, bgp); + unsigned int rspint; + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + struct rfapi_descriptor *rfd; + struct listnode *hdnode; + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[1]->text, "infinite")) { + rspint = RFAPI_INFINITE_LIFETIME; + } else { + rspint = strtoul(argv[1]->arg, NULL, 10); + } + + rfg->response_lifetime = rspint; + rfg->flags |= RFAPI_RFG_RESPONSE_LIFETIME; + if (rfg->nves) + for (ALL_LIST_ELEMENTS_RO(rfg->nves, hdnode, rfd)) + rfd->response_lifetime = rspint; + return CMD_SUCCESS; } /* * Sigh. This command, like exit-address-family, is a hack to deal - * with the lack of rigorous level control in the command handler. + * with the lack of rigorous level control in the command handler. * TBD fix command handler. */ DEFUN_NOSH (exit_vnc, @@ -3217,27 +2948,20 @@ DEFUN_NOSH (exit_vnc, "exit-vnc", "Exit VNC configuration mode\n") { - if (vty->node == BGP_VNC_DEFAULTS_NODE || - vty->node == BGP_VNC_NVE_GROUP_NODE || - vty->node == BGP_VNC_L2_GROUP_NODE) - { - - vty->node = BGP_NODE; - } - return CMD_SUCCESS; + if (vty->node == BGP_VNC_DEFAULTS_NODE + || vty->node == BGP_VNC_NVE_GROUP_NODE + || vty->node == BGP_VNC_L2_GROUP_NODE) { + + vty->node = BGP_NODE; + } + return CMD_SUCCESS; } static struct cmd_node bgp_vnc_defaults_node = { - BGP_VNC_DEFAULTS_NODE, - "%s(config-router-vnc-defaults)# ", - 1 -}; + BGP_VNC_DEFAULTS_NODE, "%s(config-router-vnc-defaults)# ", 1}; static struct cmd_node bgp_vnc_nve_group_node = { - BGP_VNC_NVE_GROUP_NODE, - "%s(config-router-vnc-nve-group)# ", - 1 -}; + BGP_VNC_NVE_GROUP_NODE, "%s(config-router-vnc-nve-group)# ", 1}; /*------------------------------------------------------------------------- * VNC nve-group @@ -3250,35 +2974,33 @@ DEFUN_NOSH (vnc_vrf_policy, "Configure a VRF policy group\n" "VRF name\n") { - struct rfapi_nve_group_cfg *rfg; - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Search for name */ - rfg = bgp_rfapi_cfg_match_byname (bgp, argv[1]->arg, RFAPI_GROUP_CFG_VRF); - - if (!rfg) - { - rfg = rfapi_group_new (bgp, RFAPI_GROUP_CFG_VRF, argv[1]->arg); - if (!rfg) - { - /* Error out of memory */ - vty_out (vty, "Can't allocate memory for NVE group\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - /* - * XXX subsequent calls will need to make sure this item is still - * in the linked list and has the same name - */ - VTY_PUSH_CONTEXT_SUB (BGP_VRF_POLICY_NODE, rfg); - - return CMD_SUCCESS; + struct rfapi_nve_group_cfg *rfg; + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* Search for name */ + rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg, + RFAPI_GROUP_CFG_VRF); + + if (!rfg) { + rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_VRF, argv[1]->arg); + if (!rfg) { + /* Error out of memory */ + vty_out(vty, "Can't allocate memory for NVE group\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + /* + * XXX subsequent calls will need to make sure this item is still + * in the linked list and has the same name + */ + VTY_PUSH_CONTEXT_SUB(BGP_VRF_POLICY_NODE, rfg); + + return CMD_SUCCESS; } DEFUN (vnc_no_vrf_policy, @@ -3288,14 +3010,14 @@ DEFUN (vnc_no_vrf_policy, "Remove a VRF policy group\n" "VRF name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return bgp_rfapi_delete_named_nve_group (vty, bgp, argv[2]->arg, RFAPI_GROUP_CFG_VRF); + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[2]->arg, + RFAPI_GROUP_CFG_VRF); } DEFUN (vnc_vrf_policy_label, @@ -3304,39 +3026,35 @@ DEFUN (vnc_vrf_policy_label, "Default label value for VRF\n" "Label Value <0-1048575>\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - - uint32_t label; - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - label = strtoul(argv[1]->arg, NULL, 10); - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - rfg->label = label; - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + + uint32_t label; + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + label = strtoul(argv[1]->arg, NULL, 10); + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + rfg->label = label; + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + return CMD_SUCCESS; } DEFUN (vnc_vrf_policy_no_label, @@ -3345,29 +3063,26 @@ DEFUN (vnc_vrf_policy_no_label, NO_STR "Remove VRF default label\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current VRF group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - rfg->label = MPLS_LABEL_ILLEGAL; - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current VRF group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + rfg->label = MPLS_LABEL_ILLEGAL; + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + return CMD_SUCCESS; } DEFUN (vnc_vrf_policy_nexthop, @@ -3378,45 +3093,40 @@ DEFUN (vnc_vrf_policy_nexthop, "IPv6 prefix\n" "Use configured router-id (default)\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - struct prefix p; - - VTY_DECLVAR_CONTEXT(bgp, bgp); - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current VRF no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - if (!str2prefix (argv[1]->arg, &p) && p.family) - { - //vty_out (vty, "Nexthop set to self\n"); - SET_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF); - memset(&rfg->vn_prefix, 0, sizeof(struct prefix)); - } - else - { - UNSET_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF); - rfg->vn_prefix = p; - rfg->un_prefix = p; - } - - /* TBD handle router-id/ nexthop changes when have advertised prefixes */ - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + struct prefix p; + + VTY_DECLVAR_CONTEXT(bgp, bgp); + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current VRF no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + if (!str2prefix(argv[1]->arg, &p) && p.family) { + // vty_out (vty, "Nexthop set to self\n"); + SET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF); + memset(&rfg->vn_prefix, 0, sizeof(struct prefix)); + } else { + UNSET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF); + rfg->vn_prefix = p; + rfg->un_prefix = p; + } + + /* TBD handle router-id/ nexthop changes when have advertised prefixes + */ + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + + return CMD_SUCCESS; } /* The RT code should be refactored/simplified with above... */ @@ -3427,73 +3137,69 @@ DEFUN (vnc_vrf_policy_rt_import, "Import filter\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - int rc; - struct listnode *node; - struct rfapi_rfg_name *rfgn; - int is_export_bgp = 0; - int is_export_zebra = 0; - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list); - if (rc != CMD_SUCCESS) - return rc; - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - is_export_bgp = 1; - break; - } - } - - if (is_export_bgp) - vnc_direct_bgp_del_group (bgp, rfg); - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - is_export_zebra = 1; - break; - } - } - - if (is_export_zebra) - vnc_zebra_del_group (bgp, rfg); - - /* - * stop referencing old import table, now reference new one - */ - if (rfg->rfapi_import_table) - rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); - rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - - if (is_export_bgp) - vnc_direct_bgp_add_group (bgp, rfg); - - if (is_export_zebra) - vnc_zebra_add_group (bgp, rfg); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + int rc; + struct listnode *node; + struct rfapi_rfg_name *rfgn; + int is_export_bgp = 0; + int is_export_zebra = 0; + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list); + if (rc != CMD_SUCCESS) + return rc; + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + is_export_bgp = 1; + break; + } + } + + if (is_export_bgp) + vnc_direct_bgp_del_group(bgp, rfg); + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + is_export_zebra = 1; + break; + } + } + + if (is_export_zebra) + vnc_zebra_del_group(bgp, rfg); + + /* + * stop referencing old import table, now reference new one + */ + if (rfg->rfapi_import_table) + rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); + rfg->rfapi_import_table = + rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg); + + if (is_export_bgp) + vnc_direct_bgp_add_group(bgp, rfg); + + if (is_export_zebra) + vnc_zebra_add_group(bgp, rfg); + + return CMD_SUCCESS; } DEFUN (vnc_vrf_policy_rt_export, @@ -3503,37 +3209,33 @@ DEFUN (vnc_vrf_policy_rt_export, "Export filter\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - int rc; - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list); - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - - return rc; + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + int rc; + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list); + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + + return rc; } DEFUN (vnc_vrf_policy_rt_both, @@ -3543,89 +3245,81 @@ DEFUN (vnc_vrf_policy_rt_both, "Export+import filters\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - int rc; - int is_export_bgp = 0; - int is_export_zebra = 0; - struct listnode *node; - struct rfapi_rfg_name *rfgn; - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list); - if (rc != CMD_SUCCESS) - return rc; - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - is_export_bgp = 1; - break; - } - } - - if (is_export_bgp) - vnc_direct_bgp_del_group (bgp, rfg); - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - is_export_zebra = 1; - break; - } - } - - if (is_export_zebra) - { - vnc_zlog_debug_verbose ("%s: is_export_zebra", __func__); - vnc_zebra_del_group (bgp, rfg); - } - - /* - * stop referencing old import table, now reference new one - */ - if (rfg->rfapi_import_table) - rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); - rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - - if (is_export_bgp) - vnc_direct_bgp_add_group (bgp, rfg); - - if (is_export_zebra) - vnc_zebra_add_group (bgp, rfg); - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list); - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - - return rc; - + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + int rc; + int is_export_bgp = 0; + int is_export_zebra = 0; + struct listnode *node; + struct rfapi_rfg_name *rfgn; + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list); + if (rc != CMD_SUCCESS) + return rc; + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + is_export_bgp = 1; + break; + } + } + + if (is_export_bgp) + vnc_direct_bgp_del_group(bgp, rfg); + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + is_export_zebra = 1; + break; + } + } + + if (is_export_zebra) { + vnc_zlog_debug_verbose("%s: is_export_zebra", __func__); + vnc_zebra_del_group(bgp, rfg); + } + + /* + * stop referencing old import table, now reference new one + */ + if (rfg->rfapi_import_table) + rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); + rfg->rfapi_import_table = + rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg); + + if (is_export_bgp) + vnc_direct_bgp_add_group(bgp, rfg); + + if (is_export_zebra) + vnc_zebra_add_group(bgp, rfg); + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list); + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + + return rc; } DEFUN (vnc_vrf_policy_rd, @@ -3634,79 +3328,69 @@ DEFUN (vnc_vrf_policy_rd, "Specify default VRF route distinguisher\n" "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:nh:<number> )\n") { - int ret; - struct prefix_rd prd; - VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!strncmp (argv[1]->arg, "auto:nh:", 8)) - { - /* - * use AF_UNIX to designate automatically-assigned RD - * auto:vn:nn where nn is a 2-octet quantity - */ - char *end = NULL; - uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10); - uint16_t value = value32 & 0xffff; - - if (!*(argv[1]->arg + 5) || *end) - { - vty_out (vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (value32 > 0xffff) - { - vty_out (vty, "%% Malformed rd (must be less than %u\n", - 0x0ffff); - return CMD_WARNING_CONFIG_FAILED; - } - - memset (&prd, 0, sizeof (prd)); - prd.family = AF_UNIX; - prd.prefixlen = 64; - prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; - prd.val[1] = RD_TYPE_IP & 0x0ff; - prd.val[6] = (value >> 8) & 0x0ff; - prd.val[7] = value & 0x0ff; - - } - else - { - - ret = str2prefix_rd (argv[1]->arg, &prd); - if (!ret) - { - vty_out (vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_prechange (bgp); - } - - rfg->rd = prd; - - if (bgp->rfapi_cfg->rfg_redist == rfg) - { - vnc_redistribute_postchange (bgp); - } - return CMD_SUCCESS; + int ret; + struct prefix_rd prd; + VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (!strncmp(argv[1]->arg, "auto:nh:", 8)) { + /* + * use AF_UNIX to designate automatically-assigned RD + * auto:vn:nn where nn is a 2-octet quantity + */ + char *end = NULL; + uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10); + uint16_t value = value32 & 0xffff; + + if (!*(argv[1]->arg + 5) || *end) { + vty_out(vty, "%% Malformed rd\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (value32 > 0xffff) { + vty_out(vty, "%% Malformed rd (must be less than %u\n", + 0x0ffff); + return CMD_WARNING_CONFIG_FAILED; + } + + memset(&prd, 0, sizeof(prd)); + prd.family = AF_UNIX; + prd.prefixlen = 64; + prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; + prd.val[1] = RD_TYPE_IP & 0x0ff; + prd.val[6] = (value >> 8) & 0x0ff; + prd.val[7] = value & 0x0ff; + + } else { + + ret = str2prefix_rd(argv[1]->arg, &prd); + if (!ret) { + vty_out(vty, "%% Malformed rd\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_prechange(bgp); + } + + rfg->rd = prd; + + if (bgp->rfapi_cfg->rfg_redist == rfg) { + vnc_redistribute_postchange(bgp); + } + return CMD_SUCCESS; } DEFUN_NOSH (exit_vrf_policy, @@ -3714,18 +3398,14 @@ DEFUN_NOSH (exit_vrf_policy, "exit-vrf-policy", "Exit VRF policy configuration mode\n") { - if (vty->node == BGP_VRF_POLICY_NODE) - { - vty->node = BGP_NODE; - } - return CMD_SUCCESS; + if (vty->node == BGP_VRF_POLICY_NODE) { + vty->node = BGP_NODE; + } + return CMD_SUCCESS; } static struct cmd_node bgp_vrf_policy_node = { - BGP_VRF_POLICY_NODE, - "%s(config-router-vrf-policy)# ", - 1 -}; + BGP_VRF_POLICY_NODE, "%s(config-router-vrf-policy)# ", 1}; /*------------------------------------------------------------------------- * vnc-l2-group @@ -3737,88 +3417,82 @@ DEFUN_NOSH (vnc_l2_group, "vnc l2-group NAME", VNC_CONFIG_STR "Configure a L2 group\n" "Group name\n") { - struct rfapi_l2_group_cfg *rfg; - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Search for name */ - rfg = rfapi_l2_group_lookup_byname (bgp, argv[1]->arg); - - if (!rfg) - { - rfg = rfapi_l2_group_new (); - if (!rfg) - { - /* Error out of memory */ - vty_out (vty, "Can't allocate memory for L2 group\n"); - return CMD_WARNING_CONFIG_FAILED; - } - rfg->name = strdup (argv[1]->arg); - /* add to tail of list */ - listnode_add (bgp->rfapi_cfg->l2_groups, rfg); - } - - /* - * XXX subsequent calls will need to make sure this item is still - * in the linked list and has the same name - */ - VTY_PUSH_CONTEXT_SUB (BGP_VNC_L2_GROUP_NODE, rfg); - return CMD_SUCCESS; + struct rfapi_l2_group_cfg *rfg; + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* Search for name */ + rfg = rfapi_l2_group_lookup_byname(bgp, argv[1]->arg); + + if (!rfg) { + rfg = rfapi_l2_group_new(); + if (!rfg) { + /* Error out of memory */ + vty_out(vty, "Can't allocate memory for L2 group\n"); + return CMD_WARNING_CONFIG_FAILED; + } + rfg->name = strdup(argv[1]->arg); + /* add to tail of list */ + listnode_add(bgp->rfapi_cfg->l2_groups, rfg); + } + + /* + * XXX subsequent calls will need to make sure this item is still + * in the linked list and has the same name + */ + VTY_PUSH_CONTEXT_SUB(BGP_VNC_L2_GROUP_NODE, rfg); + return CMD_SUCCESS; } -static void -bgp_rfapi_delete_l2_group ( - struct vty *vty, /* NULL = no output */ - struct bgp *bgp, - struct rfapi_l2_group_cfg *rfg) +static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */ + struct bgp *bgp, + struct rfapi_l2_group_cfg *rfg) { - /* delete it */ - free (rfg->name); - if (rfg->rt_import_list) - ecommunity_free (&rfg->rt_import_list); - if (rfg->rt_export_list) - ecommunity_free (&rfg->rt_export_list); - if (rfg->labels) - list_delete (rfg->labels); - if (rfg->rfp_cfg) - XFREE (MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); - listnode_delete (bgp->rfapi_cfg->l2_groups, rfg); - - rfapi_l2_group_del (rfg); + /* delete it */ + free(rfg->name); + if (rfg->rt_import_list) + ecommunity_free(&rfg->rt_import_list); + if (rfg->rt_export_list) + ecommunity_free(&rfg->rt_export_list); + if (rfg->labels) + list_delete(rfg->labels); + if (rfg->rfp_cfg) + XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); + listnode_delete(bgp->rfapi_cfg->l2_groups, rfg); + + rfapi_l2_group_del(rfg); } static int -bgp_rfapi_delete_named_l2_group ( - struct vty *vty, /* NULL = no output */ - struct bgp *bgp, - const char *rfg_name) /* NULL = any */ +bgp_rfapi_delete_named_l2_group(struct vty *vty, /* NULL = no output */ + struct bgp *bgp, + const char *rfg_name) /* NULL = any */ { - struct rfapi_l2_group_cfg *rfg = NULL; - struct listnode *node, *nnode; - - /* Search for name */ - if (rfg_name) - { - rfg = rfapi_l2_group_lookup_byname (bgp, rfg_name); - if (!rfg) - { - if (vty) - vty_out (vty, "No L2 group named \"%s\"\n",rfg_name); - return CMD_WARNING_CONFIG_FAILED; - } - } - - if (rfg) - bgp_rfapi_delete_l2_group (vty, bgp, rfg); - else /* must be delete all */ - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) - bgp_rfapi_delete_l2_group (vty, bgp, rfg); - return CMD_SUCCESS; + struct rfapi_l2_group_cfg *rfg = NULL; + struct listnode *node, *nnode; + + /* Search for name */ + if (rfg_name) { + rfg = rfapi_l2_group_lookup_byname(bgp, rfg_name); + if (!rfg) { + if (vty) + vty_out(vty, "No L2 group named \"%s\"\n", + rfg_name); + return CMD_WARNING_CONFIG_FAILED; + } + } + + if (rfg) + bgp_rfapi_delete_l2_group(vty, bgp, rfg); + else /* must be delete all */ + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode, + rfg)) + bgp_rfapi_delete_l2_group(vty, bgp, rfg); + return CMD_SUCCESS; } DEFUN (vnc_no_l2_group, @@ -3829,14 +3503,13 @@ DEFUN (vnc_no_l2_group, "Configure a L2 group\n" "Group name\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return bgp_rfapi_delete_named_l2_group (vty, bgp, argv[3]->arg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + return bgp_rfapi_delete_named_l2_group(vty, bgp, argv[3]->arg); } @@ -3846,26 +3519,24 @@ DEFUN (vnc_l2_group_lni, "Specify Logical Network ID associated with group\n" "value\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->l2_groups, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current L2 group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rfg->logical_net_id = strtoul(argv[1]->arg, NULL, 10); - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current L2 group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rfg->logical_net_id = strtoul(argv[1]->arg, NULL, 10); + + return CMD_SUCCESS; } DEFUN (vnc_l2_group_labels, @@ -3874,41 +3545,37 @@ DEFUN (vnc_l2_group_labels, "Specify label values associated with group\n" "Space separated list of label values <0-1048575>\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct list *ll; - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->l2_groups, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current L2 group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ll = rfg->labels; - if (ll == NULL) - { - ll = list_new (); - rfg->labels = ll; - } - argc--; - argv++; - for (; argc; --argc, ++argv) - { - uint32_t label; - label = strtoul(argv[0]->arg, NULL, 10); - if (!listnode_lookup (ll, (void *) (uintptr_t) label)) - listnode_add (ll, (void *) (uintptr_t) label); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct list *ll; + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current L2 group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ll = rfg->labels; + if (ll == NULL) { + ll = list_new(); + rfg->labels = ll; + } + argc--; + argv++; + for (; argc; --argc, ++argv) { + uint32_t label; + label = strtoul(argv[0]->arg, NULL, 10); + if (!listnode_lookup(ll, (void *)(uintptr_t)label)) + listnode_add(ll, (void *)(uintptr_t)label); + } + + return CMD_SUCCESS; } DEFUN (vnc_l2_group_no_labels, @@ -3918,41 +3585,37 @@ DEFUN (vnc_l2_group_no_labels, "Specify label values associated with L2 group\n" "Space separated list of label values <0-1048575>\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - struct list *ll; - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->l2_groups, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current L2 group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - ll = rfg->labels; - if (ll == NULL) - { - vty_out (vty, "Label no longer associated with group\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - argc-=2; - argv+=2; - for (; argc; --argc, ++argv) - { - uint32_t label; - label = strtoul(argv[0]->arg, NULL, 10); - listnode_delete (ll, (void *) (uintptr_t) label); - } - - return CMD_SUCCESS; + VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + struct list *ll; + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current L2 group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ll = rfg->labels; + if (ll == NULL) { + vty_out(vty, "Label no longer associated with group\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + argc -= 2; + argv += 2; + for (; argc; --argc, ++argv) { + uint32_t label; + label = strtoul(argv[0]->arg, NULL, 10); + listnode_delete(ll, (void *)(uintptr_t)label); + } + + return CMD_SUCCESS; } DEFUN (vnc_l2_group_rt, @@ -3964,1086 +3627,1075 @@ DEFUN (vnc_l2_group_rt, "Import filters\n" "A route target\n") { - VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); - VTY_DECLVAR_CONTEXT(bgp, bgp); - int rc = CMD_SUCCESS; - int do_import = 0; - int do_export = 0; - - switch (argv[1]->arg[0]) - { - case 'b': - do_export = 1; /* fall through */ - case 'i': - do_import = 1; - break; - case 'e': - do_export = 1; - break; - default: - vty_out (vty, "Unknown option, %s\n", argv[1]->arg); - return CMD_ERR_NO_MATCH; - - } - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make sure it's still in list */ - if (!listnode_lookup (bgp->rfapi_cfg->l2_groups, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current L2 group no longer exists\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (do_import) - rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list); - if (rc == CMD_SUCCESS && do_export) - rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list); - return rc; + VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); + VTY_DECLVAR_CONTEXT(bgp, bgp); + int rc = CMD_SUCCESS; + int do_import = 0; + int do_export = 0; + + switch (argv[1]->arg[0]) { + case 'b': + do_export = 1; /* fall through */ + case 'i': + do_import = 1; + break; + case 'e': + do_export = 1; + break; + default: + vty_out(vty, "Unknown option, %s\n", argv[1]->arg); + return CMD_ERR_NO_MATCH; + } + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* make sure it's still in list */ + if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current L2 group no longer exists\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (do_import) + rc = set_ecom_list(vty, argc - 2, argv + 2, + &rfg->rt_import_list); + if (rc == CMD_SUCCESS && do_export) + rc = set_ecom_list(vty, argc - 2, argv + 2, + &rfg->rt_export_list); + return rc; } static struct cmd_node bgp_vnc_l2_group_node = { - BGP_VNC_L2_GROUP_NODE, - "%s(config-router-vnc-l2-group)# ", - 1 -}; + BGP_VNC_L2_GROUP_NODE, "%s(config-router-vnc-l2-group)# ", 1}; struct rfapi_l2_group_cfg * -bgp_rfapi_get_group_by_lni_label ( - struct bgp *bgp, - uint32_t logical_net_id, - uint32_t label) +bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id, + uint32_t label) { - struct rfapi_l2_group_cfg *rfg; - struct listnode *node; - - if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */ - return NULL; - - label = label & 0xfffff; /* label is 20 bits! */ - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->l2_groups, node, rfg)) - { - if (rfg->logical_net_id == logical_net_id) - { - struct listnode *lnode; - void *data; - for (ALL_LIST_ELEMENTS_RO (rfg->labels, lnode, data)) - if (((uint32_t) ((uintptr_t) data)) == label) - { /* match! */ - return rfg; - } - } - } - return NULL; + struct rfapi_l2_group_cfg *rfg; + struct listnode *node; + + if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */ + return NULL; + + label = label & 0xfffff; /* label is 20 bits! */ + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->l2_groups, node, rfg)) { + if (rfg->logical_net_id == logical_net_id) { + struct listnode *lnode; + void *data; + for (ALL_LIST_ELEMENTS_RO(rfg->labels, lnode, data)) + if (((uint32_t)((uintptr_t)data)) + == label) { /* match! */ + return rfg; + } + } + } + return NULL; } -struct list * -bgp_rfapi_get_labellist_by_lni_label ( - struct bgp *bgp, - uint32_t logical_net_id, - uint32_t label) +struct list *bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp, + uint32_t logical_net_id, + uint32_t label) { - struct rfapi_l2_group_cfg *rfg; - rfg = bgp_rfapi_get_group_by_lni_label (bgp, logical_net_id, label); - if (rfg) - { - return rfg->labels; - } - return NULL; + struct rfapi_l2_group_cfg *rfg; + rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label); + if (rfg) { + return rfg->labels; + } + return NULL; } struct ecommunity * -bgp_rfapi_get_ecommunity_by_lni_label ( - struct bgp *bgp, - uint32_t is_import, - uint32_t logical_net_id, - uint32_t label) +bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import, + uint32_t logical_net_id, uint32_t label) { - struct rfapi_l2_group_cfg *rfg; - rfg = bgp_rfapi_get_group_by_lni_label (bgp, logical_net_id, label); - if (rfg) - { - if (is_import) - return rfg->rt_import_list; - else - return rfg->rt_export_list; - } - return NULL; + struct rfapi_l2_group_cfg *rfg; + rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label); + if (rfg) { + if (is_import) + return rfg->rt_import_list; + else + return rfg->rt_export_list; + } + return NULL; } -void -bgp_rfapi_cfg_init (void) +void bgp_rfapi_cfg_init(void) { - /* main bgpd code does not use this hook, but vnc does */ - route_map_event_hook (vnc_routemap_event); - - install_node (&bgp_vnc_defaults_node, NULL); - install_node (&bgp_vnc_nve_group_node, NULL); - install_node (&bgp_vrf_policy_node, NULL); - install_node (&bgp_vnc_l2_group_node, NULL); - install_default (BGP_VRF_POLICY_NODE); - install_default (BGP_VNC_DEFAULTS_NODE); - install_default (BGP_VNC_NVE_GROUP_NODE); - install_default (BGP_VNC_L2_GROUP_NODE); - - /* - * Add commands - */ - install_element (BGP_NODE, &vnc_defaults_cmd); - install_element (BGP_NODE, &vnc_nve_group_cmd); - install_element (BGP_NODE, &vnc_no_nve_group_cmd); - install_element (BGP_NODE, &vnc_vrf_policy_cmd); - install_element (BGP_NODE, &vnc_no_vrf_policy_cmd); - install_element (BGP_NODE, &vnc_l2_group_cmd); - install_element (BGP_NODE, &vnc_no_l2_group_cmd); - install_element (BGP_NODE, &vnc_advertise_un_method_cmd); - install_element (BGP_NODE, &vnc_export_mode_cmd); - - install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_import_cmd); - install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_export_cmd); - install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_both_cmd); - install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rd_cmd); - install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_l2rd_cmd); - install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_no_l2rd_cmd); - install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_responselifetime_cmd); - install_element (BGP_VNC_DEFAULTS_NODE, &exit_vnc_cmd); - - install_element (BGP_NODE, &vnc_redistribute_protocol_cmd); - install_element (BGP_NODE, &vnc_no_redistribute_protocol_cmd); - install_element (BGP_NODE, &vnc_redistribute_nvegroup_cmd); - install_element (BGP_NODE, &vnc_redistribute_no_nvegroup_cmd); - install_element (BGP_NODE, &vnc_redistribute_lifetime_cmd); - install_element (BGP_NODE, &vnc_redistribute_rh_roo_localadmin_cmd); - install_element (BGP_NODE, &vnc_redistribute_mode_cmd); - install_element (BGP_NODE, &vnc_redistribute_bgp_exterior_cmd); - - install_element (BGP_NODE, &vnc_redist_bgpdirect_no_prefixlist_cmd); - install_element (BGP_NODE, &vnc_redist_bgpdirect_prefixlist_cmd); - install_element (BGP_NODE, &vnc_redist_bgpdirect_no_routemap_cmd); - install_element (BGP_NODE, &vnc_redist_bgpdirect_routemap_cmd); - - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_redist_bgpdirect_prefixlist_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_redist_bgpdirect_no_routemap_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_redist_bgpdirect_routemap_cmd); - - install_element (BGP_NODE, &vnc_export_nvegroup_cmd); - install_element (BGP_NODE, &vnc_no_export_nvegroup_cmd); - install_element (BGP_NODE, &vnc_nve_export_prefixlist_cmd); - install_element (BGP_NODE, &vnc_nve_export_routemap_cmd); - install_element (BGP_NODE, &vnc_nve_export_no_prefixlist_cmd); - install_element (BGP_NODE, &vnc_nve_export_no_routemap_cmd); - - install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_l2rd_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_no_l2rd_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_prefix_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_import_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_export_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_both_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rd_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_responselifetime_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_export_prefixlist_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_export_routemap_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_export_no_prefixlist_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, - &vnc_nve_group_export_no_routemap_cmd); - install_element (BGP_VNC_NVE_GROUP_NODE, &exit_vnc_cmd); - - install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_label_cmd); - install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_no_label_cmd); - //Reenable to support VRF controller use case and testing - install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_nexthop_cmd); - install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_import_cmd); - install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_export_cmd); - install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_both_cmd); - install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rd_cmd); - install_element (BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd); - - install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_lni_cmd); - install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_labels_cmd); - install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_no_labels_cmd); - install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_rt_cmd); - install_element (BGP_VNC_L2_GROUP_NODE, &exit_vnc_cmd); + /* main bgpd code does not use this hook, but vnc does */ + route_map_event_hook(vnc_routemap_event); + + install_node(&bgp_vnc_defaults_node, NULL); + install_node(&bgp_vnc_nve_group_node, NULL); + install_node(&bgp_vrf_policy_node, NULL); + install_node(&bgp_vnc_l2_group_node, NULL); + install_default(BGP_VRF_POLICY_NODE); + install_default(BGP_VNC_DEFAULTS_NODE); + install_default(BGP_VNC_NVE_GROUP_NODE); + install_default(BGP_VNC_L2_GROUP_NODE); + + /* + * Add commands + */ + install_element(BGP_NODE, &vnc_defaults_cmd); + install_element(BGP_NODE, &vnc_nve_group_cmd); + install_element(BGP_NODE, &vnc_no_nve_group_cmd); + install_element(BGP_NODE, &vnc_vrf_policy_cmd); + install_element(BGP_NODE, &vnc_no_vrf_policy_cmd); + install_element(BGP_NODE, &vnc_l2_group_cmd); + install_element(BGP_NODE, &vnc_no_l2_group_cmd); + install_element(BGP_NODE, &vnc_advertise_un_method_cmd); + install_element(BGP_NODE, &vnc_export_mode_cmd); + + install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_import_cmd); + install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_export_cmd); + install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_both_cmd); + install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rd_cmd); + install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_l2rd_cmd); + install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_no_l2rd_cmd); + install_element(BGP_VNC_DEFAULTS_NODE, + &vnc_defaults_responselifetime_cmd); + install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_cmd); + + install_element(BGP_NODE, &vnc_redistribute_protocol_cmd); + install_element(BGP_NODE, &vnc_no_redistribute_protocol_cmd); + install_element(BGP_NODE, &vnc_redistribute_nvegroup_cmd); + install_element(BGP_NODE, &vnc_redistribute_no_nvegroup_cmd); + install_element(BGP_NODE, &vnc_redistribute_lifetime_cmd); + install_element(BGP_NODE, &vnc_redistribute_rh_roo_localadmin_cmd); + install_element(BGP_NODE, &vnc_redistribute_mode_cmd); + install_element(BGP_NODE, &vnc_redistribute_bgp_exterior_cmd); + + install_element(BGP_NODE, &vnc_redist_bgpdirect_no_prefixlist_cmd); + install_element(BGP_NODE, &vnc_redist_bgpdirect_prefixlist_cmd); + install_element(BGP_NODE, &vnc_redist_bgpdirect_no_routemap_cmd); + install_element(BGP_NODE, &vnc_redist_bgpdirect_routemap_cmd); + + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_redist_bgpdirect_prefixlist_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_redist_bgpdirect_no_routemap_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_redist_bgpdirect_routemap_cmd); + + install_element(BGP_NODE, &vnc_export_nvegroup_cmd); + install_element(BGP_NODE, &vnc_no_export_nvegroup_cmd); + install_element(BGP_NODE, &vnc_nve_export_prefixlist_cmd); + install_element(BGP_NODE, &vnc_nve_export_routemap_cmd); + install_element(BGP_NODE, &vnc_nve_export_no_prefixlist_cmd); + install_element(BGP_NODE, &vnc_nve_export_no_routemap_cmd); + + install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_l2rd_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_no_l2rd_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_prefix_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_import_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_export_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_both_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rd_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_responselifetime_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_export_prefixlist_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_export_routemap_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_export_no_prefixlist_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, + &vnc_nve_group_export_no_routemap_cmd); + install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_cmd); + + install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_label_cmd); + install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_no_label_cmd); + // Reenable to support VRF controller use case and testing + install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_nexthop_cmd); + install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_import_cmd); + install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_export_cmd); + install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_both_cmd); + install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rd_cmd); + install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd); + + install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_lni_cmd); + install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_labels_cmd); + install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_no_labels_cmd); + install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_rt_cmd); + install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_cmd); } -struct rfapi_cfg * -bgp_rfapi_cfg_new (struct rfapi_rfp_cfg *cfg) +struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg) { - struct rfapi_cfg *h; - int afi; - - h = - (struct rfapi_cfg *) XCALLOC (MTYPE_RFAPI_CFG, sizeof (struct rfapi_cfg)); - assert (h); - - h->nve_groups_sequential = list_new (); - assert (h->nve_groups_sequential); - - for (afi = AFI_IP; afi < AFI_MAX; afi++) - { - /* ugly, to deal with addition of delegates, part of 0.99.24.1 merge */ - h->nve_groups_vn[afi].delegate = route_table_get_default_delegate (); - h->nve_groups_un[afi].delegate = route_table_get_default_delegate (); - } - h->default_response_lifetime = BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT; - h->rfg_export_direct_bgp_l = list_new (); - h->rfg_export_zebra_l = list_new (); - h->resolve_nve_roo_local_admin = - BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT; - - SET_FLAG (h->flags, BGP_VNC_CONFIG_FLAGS_DEFAULT); - - if (cfg == NULL) - { - h->rfp_cfg.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL; - h->rfp_cfg.ftd_advertisement_interval = - RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL; - h->rfp_cfg.holddown_factor = RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR; - h->rfp_cfg.use_updated_response = 0; - h->rfp_cfg.use_removes = 0; - } - else - { - h->rfp_cfg.download_type = cfg->download_type; - h->rfp_cfg.ftd_advertisement_interval = cfg->ftd_advertisement_interval; - h->rfp_cfg.holddown_factor = cfg->holddown_factor; - h->rfp_cfg.use_updated_response = cfg->use_updated_response; - h->rfp_cfg.use_removes = cfg->use_removes; - if (cfg->use_updated_response) - h->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE; - else - h->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE; - if (cfg->use_removes) - h->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; - else - h->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; - } - return h; + struct rfapi_cfg *h; + int afi; + + h = (struct rfapi_cfg *)XCALLOC(MTYPE_RFAPI_CFG, + sizeof(struct rfapi_cfg)); + assert(h); + + h->nve_groups_sequential = list_new(); + assert(h->nve_groups_sequential); + + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + /* ugly, to deal with addition of delegates, part of 0.99.24.1 + * merge */ + h->nve_groups_vn[afi].delegate = + route_table_get_default_delegate(); + h->nve_groups_un[afi].delegate = + route_table_get_default_delegate(); + } + h->default_response_lifetime = + BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT; + h->rfg_export_direct_bgp_l = list_new(); + h->rfg_export_zebra_l = list_new(); + h->resolve_nve_roo_local_admin = + BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT; + + SET_FLAG(h->flags, BGP_VNC_CONFIG_FLAGS_DEFAULT); + + if (cfg == NULL) { + h->rfp_cfg.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL; + h->rfp_cfg.ftd_advertisement_interval = + RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL; + h->rfp_cfg.holddown_factor = + RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR; + h->rfp_cfg.use_updated_response = 0; + h->rfp_cfg.use_removes = 0; + } else { + h->rfp_cfg.download_type = cfg->download_type; + h->rfp_cfg.ftd_advertisement_interval = + cfg->ftd_advertisement_interval; + h->rfp_cfg.holddown_factor = cfg->holddown_factor; + h->rfp_cfg.use_updated_response = cfg->use_updated_response; + h->rfp_cfg.use_removes = cfg->use_removes; + if (cfg->use_updated_response) + h->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE; + else + h->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE; + if (cfg->use_removes) + h->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; + else + h->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; + } + return h; } -void -bgp_rfapi_cfg_destroy (struct bgp *bgp, struct rfapi_cfg *h) +void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h) { - if (h == NULL) - return; - - bgp_rfapi_delete_named_nve_group (NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX); - bgp_rfapi_delete_named_l2_group (NULL, bgp, NULL); - if (h->l2_groups != NULL) - list_delete (h->l2_groups); - list_delete (h->nve_groups_sequential); - list_delete (h->rfg_export_direct_bgp_l); - list_delete (h->rfg_export_zebra_l); - if (h->default_rt_export_list) - ecommunity_free (&h->default_rt_export_list); - if (h->default_rt_import_list) - ecommunity_free (&h->default_rt_import_list); - if (h->default_rfp_cfg) - XFREE (MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg); - XFREE (MTYPE_RFAPI_CFG, h); - + if (h == NULL) + return; + + bgp_rfapi_delete_named_nve_group(NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX); + bgp_rfapi_delete_named_l2_group(NULL, bgp, NULL); + if (h->l2_groups != NULL) + list_delete(h->l2_groups); + list_delete(h->nve_groups_sequential); + list_delete(h->rfg_export_direct_bgp_l); + list_delete(h->rfg_export_zebra_l); + if (h->default_rt_export_list) + ecommunity_free(&h->default_rt_export_list); + if (h->default_rt_import_list) + ecommunity_free(&h->default_rt_import_list); + if (h->default_rfp_cfg) + XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg); + XFREE(MTYPE_RFAPI_CFG, h); } -int -bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp) +int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) { - struct listnode *node, *nnode; - struct rfapi_nve_group_cfg *rfg; - struct rfapi_cfg *hc = bgp->rfapi_cfg; - struct rfapi_rfg_name *rfgn; - int write = 0; - afi_t afi; - int type; - if (bgp->rfapi == NULL || hc == NULL) - return write; - - vty_out (vty, "!\n"); - for (ALL_LIST_ELEMENTS (hc->nve_groups_sequential, node, nnode, rfg)) - if (rfg->type == RFAPI_GROUP_CFG_VRF) - { - ++write; - vty_out (vty, " vrf-policy %s\n", rfg->name); - if (rfg->label <= MPLS_LABEL_MAX) - { - vty_out (vty, " label %u\n", rfg->label); - - } - if (CHECK_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF)) - { - vty_out (vty, " nexthop self\n"); - - } - else - { - if (rfg->vn_prefix.family) - { - char buf[BUFSIZ]; - buf[0] = buf[BUFSIZ - 1] = 0; - inet_ntop(rfg->vn_prefix.family, &rfg->vn_prefix.u.prefix, buf, sizeof(buf)); - if (!buf[0] || buf[BUFSIZ - 1]) - { - //vty_out (vty, "nexthop self\n"); - } - else - { - vty_out (vty, " nexthop %s\n", buf); - } - } - } - - if (rfg->rd.prefixlen) - { - char buf[BUFSIZ]; - buf[0] = buf[BUFSIZ - 1] = 0; - - if (AF_UNIX == rfg->rd.family) - { - - uint16_t value = 0; - - value = ((rfg->rd.val[6] << 8) & 0x0ff00) | - (rfg->rd.val[7] & 0x0ff); - - vty_out (vty, " rd auto:nh:%d\n", value); - - } - else - { - - if (!prefix_rd2str (&rfg->rd, buf, BUFSIZ) || - !buf[0] || buf[BUFSIZ - 1]) - { - - vty_out (vty, "!Error: Can't convert rd\n"); - } - else - { - vty_out (vty, " rd %s\n", buf); - } - } - } - - if (rfg->rt_import_list && rfg->rt_export_list && - ecommunity_cmp (rfg->rt_import_list, rfg->rt_export_list)) - { - char *b = ecommunity_ecom2str (rfg->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt both %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - else - { - if (rfg->rt_import_list) - { - char *b = ecommunity_ecom2str (rfg->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt import %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - if (rfg->rt_export_list) - { - char *b = ecommunity_ecom2str (rfg->rt_export_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt export %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - } - - /* - * route filtering: prefix-lists and route-maps - */ - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6"; - - if (rfg->plist_export_bgp_name[afi]) - { - vty_out (vty, " export bgp %s prefix-list %s\n", - afistr,rfg->plist_export_bgp_name[afi]); - } - if (rfg->plist_export_zebra_name[afi]) - { - vty_out (vty, " export zebra %s prefix-list %s\n", - afistr,rfg->plist_export_zebra_name[afi]); - } - /* - * currently we only support redist plists for bgp-direct. - * If we later add plist support for redistributing other - * protocols, we'll need to loop over protocols here - */ - if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) - { - vty_out (vty, " redistribute bgp-direct %s prefix-list %s\n", - afistr, - rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); - } - if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) - { - vty_out (vty, - " redistribute bgp-direct-to-nve-groups %s prefix-list %s\n", - afistr, - rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]); - } - } - - if (rfg->routemap_export_bgp_name) - { - vty_out (vty, " export bgp route-map %s\n", - rfg->routemap_export_bgp_name); - } - if (rfg->routemap_export_zebra_name) - { - vty_out (vty, " export zebra route-map %s\n", - rfg->routemap_export_zebra_name); - } - if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) - { - vty_out (vty, " redistribute bgp-direct route-map %s\n", - rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); - } - if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vty_out (vty, - " redistribute bgp-direct-to-nve-groups route-map %s\n", - rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]); - } - vty_out (vty, " exit-vrf-policy\n"); - vty_out (vty, "!\n"); - } - if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) - { - vty_out (vty, " vnc advertise-un-method encap-safi\n"); - write++; - } - - { /* was based on listen ports */ - /* for now allow both old and new */ - if (bgp->rfapi->rfp_methods.cfg_cb) - write += (bgp->rfapi->rfp_methods.cfg_cb) (vty, bgp->rfapi->rfp); - - if (write) - vty_out (vty, "!\n"); - - if (hc->l2_groups) - { - struct rfapi_l2_group_cfg *rfg = NULL; - struct listnode *gnode; - for (ALL_LIST_ELEMENTS_RO (hc->l2_groups, gnode, rfg)) - { - struct listnode *lnode; - void *data; - ++write; - vty_out (vty, " vnc l2-group %s\n", rfg->name); - if (rfg->logical_net_id != 0) - vty_out (vty, " logical-network-id %u\n", - rfg->logical_net_id); - if (rfg->labels != NULL && listhead (rfg->labels) != NULL) - { - vty_out (vty, " labels "); - for (ALL_LIST_ELEMENTS_RO (rfg->labels, lnode, data)) - { - vty_out (vty, "%hu ", (uint16_t) ((uintptr_t) data)); - } - vty_out (vty, "\n"); - } - - if (rfg->rt_import_list && rfg->rt_export_list && - ecommunity_cmp (rfg->rt_import_list, rfg->rt_export_list)) - { - char *b = ecommunity_ecom2str (rfg->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt both %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - else - { - if (rfg->rt_import_list) - { - char *b = ecommunity_ecom2str (rfg->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt import %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - if (rfg->rt_export_list) - { - char *b = ecommunity_ecom2str (rfg->rt_export_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt export %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - } - if (bgp->rfapi->rfp_methods.cfg_group_cb) - write += - (bgp->rfapi->rfp_methods.cfg_group_cb) (vty, - bgp->rfapi->rfp, - RFAPI_RFP_CFG_GROUP_L2, - rfg->name, - rfg->rfp_cfg); - vty_out (vty, " exit-vnc\n"); - vty_out (vty, "!\n"); - } - } - - if (hc->default_rd.family || - hc->default_response_lifetime || - hc->default_rt_import_list || - hc->default_rt_export_list || hc->nve_groups_sequential->count) - { - - - ++write; - vty_out (vty, " vnc defaults\n"); - - if (hc->default_rd.prefixlen) - { - char buf[BUFSIZ]; - buf[0] = buf[BUFSIZ - 1] = 0; - - if (AF_UNIX == hc->default_rd.family) - { - uint16_t value = 0; - - value = ((hc->default_rd.val[6] << 8) & 0x0ff00) | - (hc->default_rd.val[7] & 0x0ff); - - vty_out (vty, " rd auto:vn:%d\n", value); - - } - else - { - - if (!prefix_rd2str (&hc->default_rd, buf, BUFSIZ) || - !buf[0] || buf[BUFSIZ - 1]) - { - - vty_out (vty, "!Error: Can't convert rd\n"); - } - else - { - vty_out (vty, " rd %s\n", buf); - } - } - } - if (hc->default_response_lifetime) - { - vty_out (vty, " response-lifetime "); - if (hc->default_response_lifetime != UINT32_MAX) - vty_out (vty, "%d", hc->default_response_lifetime); - else - vty_out (vty, "infinite"); - vty_out (vty, "\n"); - } - if (hc->default_rt_import_list && hc->default_rt_export_list && - ecommunity_cmp (hc->default_rt_import_list, - hc->default_rt_export_list)) - { - char *b = ecommunity_ecom2str (hc->default_rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt both %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - else - { - if (hc->default_rt_import_list) - { - char *b = ecommunity_ecom2str (hc->default_rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt import %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - if (hc->default_rt_export_list) - { - char *b = ecommunity_ecom2str (hc->default_rt_export_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt export %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - } - if (bgp->rfapi->rfp_methods.cfg_group_cb) - write += - (bgp->rfapi->rfp_methods.cfg_group_cb) (vty, - bgp->rfapi->rfp, - RFAPI_RFP_CFG_GROUP_DEFAULT, - NULL, - bgp->rfapi_cfg->default_rfp_cfg); - vty_out (vty, " exit-vnc\n"); - vty_out (vty, "!\n"); - } - - for (ALL_LIST_ELEMENTS (hc->nve_groups_sequential, node, nnode, rfg)) - if (rfg->type == RFAPI_GROUP_CFG_NVE) - { - ++write; - vty_out (vty, " vnc nve-group %s\n", rfg->name); - - if (rfg->vn_prefix.family && rfg->vn_node) - { - char buf[BUFSIZ]; - buf[0] = buf[BUFSIZ - 1] = 0; - - prefix2str (&rfg->vn_prefix, buf, BUFSIZ); - if (!buf[0] || buf[BUFSIZ - 1]) - { - vty_out (vty, "!Error: Can't convert prefix\n"); - } - else - { - vty_out (vty, " prefix %s %s\n", "vn", buf); - } - } - - if (rfg->un_prefix.family && rfg->un_node) - { - char buf[BUFSIZ]; - buf[0] = buf[BUFSIZ - 1] = 0; - prefix2str (&rfg->un_prefix, buf, BUFSIZ); - if (!buf[0] || buf[BUFSIZ - 1]) - { - vty_out (vty, "!Error: Can't convert prefix\n"); - } - else - { - vty_out (vty, " prefix %s %s\n", "un", buf); - } - } - - - if (rfg->rd.prefixlen) - { - char buf[BUFSIZ]; - buf[0] = buf[BUFSIZ - 1] = 0; - - if (AF_UNIX == rfg->rd.family) - { - - uint16_t value = 0; - - value = ((rfg->rd.val[6] << 8) & 0x0ff00) | - (rfg->rd.val[7] & 0x0ff); - - vty_out (vty, " rd auto:vn:%d\n", value); - - } - else - { - - if (!prefix_rd2str (&rfg->rd, buf, BUFSIZ) || - !buf[0] || buf[BUFSIZ - 1]) - { - - vty_out (vty, "!Error: Can't convert rd\n"); - } - else - { - vty_out (vty, " rd %s\n", buf); - } - } - } - if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) - { - vty_out (vty, " response-lifetime "); - if (rfg->response_lifetime != UINT32_MAX) - vty_out (vty, "%d", rfg->response_lifetime); - else - vty_out (vty, "infinite"); - vty_out (vty, "\n"); - } - - if (rfg->rt_import_list && rfg->rt_export_list && - ecommunity_cmp (rfg->rt_import_list, rfg->rt_export_list)) - { - char *b = ecommunity_ecom2str (rfg->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, - ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt both %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - else - { - if (rfg->rt_import_list) - { - char *b = ecommunity_ecom2str (rfg->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, - ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt import %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - if (rfg->rt_export_list) - { - char *b = ecommunity_ecom2str (rfg->rt_export_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out (vty, " rt export %s\n", b); - XFREE (MTYPE_ECOMMUNITY_STR, b); - } - } - - /* - * route filtering: prefix-lists and route-maps - */ - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6"; - - if (rfg->plist_export_bgp_name[afi]) - { - vty_out (vty, " export bgp %s prefix-list %s\n", - afistr,rfg->plist_export_bgp_name[afi]); - } - if (rfg->plist_export_zebra_name[afi]) - { - vty_out (vty, " export zebra %s prefix-list %s\n", - afistr,rfg->plist_export_zebra_name[afi]); - } - /* - * currently we only support redist plists for bgp-direct. - * If we later add plist support for redistributing other - * protocols, we'll need to loop over protocols here - */ - if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) - { - vty_out (vty, " redistribute bgp-direct %s prefix-list %s\n", - afistr, - rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); - } - if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) - { - vty_out (vty, - " redistribute bgp-direct-to-nve-groups %s prefix-list %s\n", - afistr, - rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]); - } - } - - if (rfg->routemap_export_bgp_name) - { - vty_out (vty, " export bgp route-map %s\n", - rfg->routemap_export_bgp_name); - } - if (rfg->routemap_export_zebra_name) - { - vty_out (vty, " export zebra route-map %s\n", - rfg->routemap_export_zebra_name); - } - if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) - { - vty_out (vty, " redistribute bgp-direct route-map %s\n", - rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); - } - if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vty_out (vty, - " redistribute bgp-direct-to-nve-groups route-map %s\n", - rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]); - } - if (bgp->rfapi->rfp_methods.cfg_group_cb) - write += - (bgp->rfapi->rfp_methods.cfg_group_cb) (vty, - bgp->rfapi->rfp, - RFAPI_RFP_CFG_GROUP_NVE, - rfg->name, rfg->rfp_cfg); - vty_out (vty, " exit-vnc\n"); - vty_out (vty, "!\n"); - } - } /* have listen ports */ - - /* - * route export to other protocols - */ - if (VNC_EXPORT_BGP_GRP_ENABLED (hc)) - { - vty_out (vty, " vnc export bgp mode group-nve\n"); - } - else if (VNC_EXPORT_BGP_RH_ENABLED (hc)) - { - vty_out (vty, " vnc export bgp mode registering-nve\n"); - } - else if (VNC_EXPORT_BGP_CE_ENABLED (hc)) - { - vty_out (vty, " vnc export bgp mode ce\n"); - } - - if (VNC_EXPORT_ZEBRA_GRP_ENABLED (hc)) - { - vty_out (vty, " vnc export zebra mode group-nve\n"); - } - else if (VNC_EXPORT_ZEBRA_RH_ENABLED (hc)) - { - vty_out (vty, " vnc export zebra mode registering-nve\n"); - } - - if (hc->rfg_export_direct_bgp_l) - { - for (ALL_LIST_ELEMENTS (hc->rfg_export_direct_bgp_l, node, nnode, rfgn)) - { - - vty_out (vty, " vnc export bgp group-nve group %s\n", - rfgn->name); - } - } - - if (hc->rfg_export_zebra_l) - { - for (ALL_LIST_ELEMENTS (hc->rfg_export_zebra_l, node, nnode, rfgn)) - { - - vty_out (vty, " vnc export zebra group-nve group %s\n", - rfgn->name); - } - } - - - if (hc->rfg_redist_name) - { - vty_out (vty, " vnc redistribute nve-group %s\n", - hc->rfg_redist_name); - } - if (hc->redist_lifetime) - { - vty_out (vty, " vnc redistribute lifetime %d\n", - hc->redist_lifetime); - } - if (hc->resolve_nve_roo_local_admin != - BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT) - { - - vty_out (vty, " vnc redistribute resolve-nve roo-ec-local-admin %d\n", - hc->resolve_nve_roo_local_admin); - } - - if (hc->redist_mode) /* ! default */ - { - const char *s = ""; - - switch (hc->redist_mode) - { - case VNC_REDIST_MODE_PLAIN: - s = "plain"; - break; - case VNC_REDIST_MODE_RFG: - s = "nve-group"; - break; - case VNC_REDIST_MODE_RESOLVE_NVE: - s = "resolve-nve"; - break; - } - if (s) - { - vty_out (vty, " vnc redistribute mode %s\n", s); - } - } - - /* - * route filtering: prefix-lists and route-maps - */ - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6"; - - if (hc->plist_export_bgp_name[afi]) - { - vty_out (vty, " vnc export bgp %s prefix-list %s\n", - afistr, hc->plist_export_bgp_name[afi]); - } - if (hc->plist_export_zebra_name[afi]) - { - vty_out (vty, " vnc export zebra %s prefix-list %s\n", - afistr, hc->plist_export_zebra_name[afi]); - } - if (hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) - { - vty_out (vty, " vnc redistribute bgp-direct %s prefix-list %s\n", - afistr,hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); - } - } - - if (hc->routemap_export_bgp_name) - { - vty_out (vty, " vnc export bgp route-map %s\n", - hc->routemap_export_bgp_name); - } - if (hc->routemap_export_zebra_name) - { - vty_out (vty, " vnc export zebra route-map %s\n", - hc->routemap_export_zebra_name); - } - if (hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) - { - vty_out (vty, " vnc redistribute bgp-direct route-map %s\n", - hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); - } - - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) - { - if (hc->redist[afi][type]) - { - if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT && - hc->redist_bgp_exterior_view_name) - { - vty_out (vty, " vnc redistribute %s %s view %s\n", - ((afi == AFI_IP) ? "ipv4" : "ipv6"), - zebra_route_string (type), - hc->redist_bgp_exterior_view_name); - } - else - { - vty_out (vty, " vnc redistribute %s %s\n", - ((afi == AFI_IP) ? "ipv4" : "ipv6"), - zebra_route_string(type)); - } - } - } - } - return write; + struct listnode *node, *nnode; + struct rfapi_nve_group_cfg *rfg; + struct rfapi_cfg *hc = bgp->rfapi_cfg; + struct rfapi_rfg_name *rfgn; + int write = 0; + afi_t afi; + int type; + if (bgp->rfapi == NULL || hc == NULL) + return write; + + vty_out(vty, "!\n"); + for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg)) + if (rfg->type == RFAPI_GROUP_CFG_VRF) { + ++write; + vty_out(vty, " vrf-policy %s\n", rfg->name); + if (rfg->label <= MPLS_LABEL_MAX) { + vty_out(vty, " label %u\n", rfg->label); + } + if (CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) { + vty_out(vty, " nexthop self\n"); + + } else { + if (rfg->vn_prefix.family) { + char buf[BUFSIZ]; + buf[0] = buf[BUFSIZ - 1] = 0; + inet_ntop(rfg->vn_prefix.family, + &rfg->vn_prefix.u.prefix, buf, + sizeof(buf)); + if (!buf[0] || buf[BUFSIZ - 1]) { + // vty_out (vty, "nexthop + // self\n"); + } else { + vty_out(vty, " nexthop %s\n", + buf); + } + } + } + + if (rfg->rd.prefixlen) { + char buf[BUFSIZ]; + buf[0] = buf[BUFSIZ - 1] = 0; + + if (AF_UNIX == rfg->rd.family) { + + uint16_t value = 0; + + value = ((rfg->rd.val[6] << 8) + & 0x0ff00) + | (rfg->rd.val[7] & 0x0ff); + + vty_out(vty, " rd auto:nh:%d\n", + value); + + } else { + + if (!prefix_rd2str(&rfg->rd, buf, + BUFSIZ) + || !buf[0] || buf[BUFSIZ - 1]) { + + vty_out(vty, + "!Error: Can't convert rd\n"); + } else { + vty_out(vty, " rd %s\n", buf); + } + } + } + + if (rfg->rt_import_list && rfg->rt_export_list + && ecommunity_cmp(rfg->rt_import_list, + rfg->rt_export_list)) { + char *b = ecommunity_ecom2str( + rfg->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt both %s\n", b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } else { + if (rfg->rt_import_list) { + char *b = ecommunity_ecom2str( + rfg->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt import %s\n", b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } + if (rfg->rt_export_list) { + char *b = ecommunity_ecom2str( + rfg->rt_export_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt export %s\n", b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } + } + + /* + * route filtering: prefix-lists and route-maps + */ + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + const char *afistr = + (afi == AFI_IP) ? "ipv4" : "ipv6"; + + if (rfg->plist_export_bgp_name[afi]) { + vty_out(vty, + " export bgp %s prefix-list %s\n", + afistr, + rfg->plist_export_bgp_name + [afi]); + } + if (rfg->plist_export_zebra_name[afi]) { + vty_out(vty, + " export zebra %s prefix-list %s\n", + afistr, + rfg->plist_export_zebra_name + [afi]); + } + /* + * currently we only support redist plists for + * bgp-direct. + * If we later add plist support for + * redistributing other + * protocols, we'll need to loop over protocols + * here + */ + if (rfg->plist_redist_name + [ZEBRA_ROUTE_BGP_DIRECT][afi]) { + vty_out(vty, + " redistribute bgp-direct %s prefix-list %s\n", + afistr, + rfg->plist_redist_name + [ZEBRA_ROUTE_BGP_DIRECT] + [afi]); + } + if (rfg->plist_redist_name + [ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) { + vty_out(vty, + " redistribute bgp-direct-to-nve-groups %s prefix-list %s\n", + afistr, + rfg->plist_redist_name + [ZEBRA_ROUTE_BGP_DIRECT_EXT] + [afi]); + } + } + + if (rfg->routemap_export_bgp_name) { + vty_out(vty, " export bgp route-map %s\n", + rfg->routemap_export_bgp_name); + } + if (rfg->routemap_export_zebra_name) { + vty_out(vty, " export zebra route-map %s\n", + rfg->routemap_export_zebra_name); + } + if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) { + vty_out(vty, + " redistribute bgp-direct route-map %s\n", + rfg->routemap_redist_name + [ZEBRA_ROUTE_BGP_DIRECT]); + } + if (rfg->routemap_redist_name + [ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vty_out(vty, + " redistribute bgp-direct-to-nve-groups route-map %s\n", + rfg->routemap_redist_name + [ZEBRA_ROUTE_BGP_DIRECT_EXT]); + } + vty_out(vty, " exit-vrf-policy\n"); + vty_out(vty, "!\n"); + } + if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) { + vty_out(vty, " vnc advertise-un-method encap-safi\n"); + write++; + } + + { /* was based on listen ports */ + /* for now allow both old and new */ + if (bgp->rfapi->rfp_methods.cfg_cb) + write += (bgp->rfapi->rfp_methods.cfg_cb)( + vty, bgp->rfapi->rfp); + + if (write) + vty_out(vty, "!\n"); + + if (hc->l2_groups) { + struct rfapi_l2_group_cfg *rfg = NULL; + struct listnode *gnode; + for (ALL_LIST_ELEMENTS_RO(hc->l2_groups, gnode, rfg)) { + struct listnode *lnode; + void *data; + ++write; + vty_out(vty, " vnc l2-group %s\n", rfg->name); + if (rfg->logical_net_id != 0) + vty_out(vty, + " logical-network-id %u\n", + rfg->logical_net_id); + if (rfg->labels != NULL + && listhead(rfg->labels) != NULL) { + vty_out(vty, " labels "); + for (ALL_LIST_ELEMENTS_RO(rfg->labels, + lnode, + data)) { + vty_out(vty, "%hu ", + (uint16_t)( + (uintptr_t) + data)); + } + vty_out(vty, "\n"); + } + + if (rfg->rt_import_list && rfg->rt_export_list + && ecommunity_cmp(rfg->rt_import_list, + rfg->rt_export_list)) { + char *b = ecommunity_ecom2str( + rfg->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt both %s\n", b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } else { + if (rfg->rt_import_list) { + char *b = ecommunity_ecom2str( + rfg->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt import %s\n", + b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } + if (rfg->rt_export_list) { + char *b = ecommunity_ecom2str( + rfg->rt_export_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt export %s\n", + b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } + } + if (bgp->rfapi->rfp_methods.cfg_group_cb) + write += (bgp->rfapi->rfp_methods + .cfg_group_cb)( + vty, bgp->rfapi->rfp, + RFAPI_RFP_CFG_GROUP_L2, + rfg->name, rfg->rfp_cfg); + vty_out(vty, " exit-vnc\n"); + vty_out(vty, "!\n"); + } + } + + if (hc->default_rd.family || hc->default_response_lifetime + || hc->default_rt_import_list || hc->default_rt_export_list + || hc->nve_groups_sequential->count) { + + + ++write; + vty_out(vty, " vnc defaults\n"); + + if (hc->default_rd.prefixlen) { + char buf[BUFSIZ]; + buf[0] = buf[BUFSIZ - 1] = 0; + + if (AF_UNIX == hc->default_rd.family) { + uint16_t value = 0; + + value = ((hc->default_rd.val[6] << 8) + & 0x0ff00) + | (hc->default_rd.val[7] + & 0x0ff); + + vty_out(vty, " rd auto:vn:%d\n", + value); + + } else { + + if (!prefix_rd2str(&hc->default_rd, buf, + BUFSIZ) + || !buf[0] || buf[BUFSIZ - 1]) { + + vty_out(vty, + "!Error: Can't convert rd\n"); + } else { + vty_out(vty, " rd %s\n", buf); + } + } + } + if (hc->default_response_lifetime) { + vty_out(vty, " response-lifetime "); + if (hc->default_response_lifetime != UINT32_MAX) + vty_out(vty, "%d", + hc->default_response_lifetime); + else + vty_out(vty, "infinite"); + vty_out(vty, "\n"); + } + if (hc->default_rt_import_list + && hc->default_rt_export_list + && ecommunity_cmp(hc->default_rt_import_list, + hc->default_rt_export_list)) { + char *b = ecommunity_ecom2str( + hc->default_rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt both %s\n", b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } else { + if (hc->default_rt_import_list) { + char *b = ecommunity_ecom2str( + hc->default_rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt import %s\n", b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } + if (hc->default_rt_export_list) { + char *b = ecommunity_ecom2str( + hc->default_rt_export_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt export %s\n", b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } + } + if (bgp->rfapi->rfp_methods.cfg_group_cb) + write += (bgp->rfapi->rfp_methods.cfg_group_cb)( + vty, bgp->rfapi->rfp, + RFAPI_RFP_CFG_GROUP_DEFAULT, NULL, + bgp->rfapi_cfg->default_rfp_cfg); + vty_out(vty, " exit-vnc\n"); + vty_out(vty, "!\n"); + } + + for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, + rfg)) + if (rfg->type == RFAPI_GROUP_CFG_NVE) { + ++write; + vty_out(vty, " vnc nve-group %s\n", rfg->name); + + if (rfg->vn_prefix.family && rfg->vn_node) { + char buf[BUFSIZ]; + buf[0] = buf[BUFSIZ - 1] = 0; + + prefix2str(&rfg->vn_prefix, buf, + BUFSIZ); + if (!buf[0] || buf[BUFSIZ - 1]) { + vty_out(vty, + "!Error: Can't convert prefix\n"); + } else { + vty_out(vty, " prefix %s %s\n", + "vn", buf); + } + } + + if (rfg->un_prefix.family && rfg->un_node) { + char buf[BUFSIZ]; + buf[0] = buf[BUFSIZ - 1] = 0; + prefix2str(&rfg->un_prefix, buf, + BUFSIZ); + if (!buf[0] || buf[BUFSIZ - 1]) { + vty_out(vty, + "!Error: Can't convert prefix\n"); + } else { + vty_out(vty, " prefix %s %s\n", + "un", buf); + } + } + + + if (rfg->rd.prefixlen) { + char buf[BUFSIZ]; + buf[0] = buf[BUFSIZ - 1] = 0; + + if (AF_UNIX == rfg->rd.family) { + + uint16_t value = 0; + + value = ((rfg->rd.val[6] << 8) + & 0x0ff00) + | (rfg->rd.val[7] + & 0x0ff); + + vty_out(vty, + " rd auto:vn:%d\n", + value); + + } else { + + if (!prefix_rd2str(&rfg->rd, + buf, BUFSIZ) + || !buf[0] + || buf[BUFSIZ - 1]) { + + vty_out(vty, + "!Error: Can't convert rd\n"); + } else { + vty_out(vty, + " rd %s\n", + buf); + } + } + } + if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) { + vty_out(vty, " response-lifetime "); + if (rfg->response_lifetime + != UINT32_MAX) + vty_out(vty, "%d", + rfg->response_lifetime); + else + vty_out(vty, "infinite"); + vty_out(vty, "\n"); + } + + if (rfg->rt_import_list && rfg->rt_export_list + && ecommunity_cmp(rfg->rt_import_list, + rfg->rt_export_list)) { + char *b = ecommunity_ecom2str( + rfg->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt both %s\n", b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } else { + if (rfg->rt_import_list) { + char *b = ecommunity_ecom2str( + rfg->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt import %s\n", + b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } + if (rfg->rt_export_list) { + char *b = ecommunity_ecom2str( + rfg->rt_export_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, + ECOMMUNITY_ROUTE_TARGET); + vty_out(vty, " rt export %s\n", + b); + XFREE(MTYPE_ECOMMUNITY_STR, b); + } + } + + /* + * route filtering: prefix-lists and route-maps + */ + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + const char *afistr = (afi == AFI_IP) + ? "ipv4" + : "ipv6"; + + if (rfg->plist_export_bgp_name[afi]) { + vty_out(vty, + " export bgp %s prefix-list %s\n", + afistr, + rfg->plist_export_bgp_name + [afi]); + } + if (rfg->plist_export_zebra_name[afi]) { + vty_out(vty, + " export zebra %s prefix-list %s\n", + afistr, + rfg->plist_export_zebra_name + [afi]); + } + /* + * currently we only support redist + * plists for bgp-direct. + * If we later add plist support for + * redistributing other + * protocols, we'll need to loop over + * protocols here + */ + if (rfg->plist_redist_name + [ZEBRA_ROUTE_BGP_DIRECT] + [afi]) { + vty_out(vty, + " redistribute bgp-direct %s prefix-list %s\n", + afistr, + rfg->plist_redist_name + [ZEBRA_ROUTE_BGP_DIRECT] + [afi]); + } + if (rfg->plist_redist_name + [ZEBRA_ROUTE_BGP_DIRECT_EXT] + [afi]) { + vty_out(vty, + " redistribute bgp-direct-to-nve-groups %s prefix-list %s\n", + afistr, + rfg->plist_redist_name + [ZEBRA_ROUTE_BGP_DIRECT_EXT] + [afi]); + } + } + + if (rfg->routemap_export_bgp_name) { + vty_out(vty, + " export bgp route-map %s\n", + rfg->routemap_export_bgp_name); + } + if (rfg->routemap_export_zebra_name) { + vty_out(vty, + " export zebra route-map %s\n", + rfg->routemap_export_zebra_name); + } + if (rfg->routemap_redist_name + [ZEBRA_ROUTE_BGP_DIRECT]) { + vty_out(vty, + " redistribute bgp-direct route-map %s\n", + rfg->routemap_redist_name + [ZEBRA_ROUTE_BGP_DIRECT]); + } + if (rfg->routemap_redist_name + [ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vty_out(vty, + " redistribute bgp-direct-to-nve-groups route-map %s\n", + rfg->routemap_redist_name + [ZEBRA_ROUTE_BGP_DIRECT_EXT]); + } + if (bgp->rfapi->rfp_methods.cfg_group_cb) + write += (bgp->rfapi->rfp_methods + .cfg_group_cb)( + vty, bgp->rfapi->rfp, + RFAPI_RFP_CFG_GROUP_NVE, + rfg->name, rfg->rfp_cfg); + vty_out(vty, " exit-vnc\n"); + vty_out(vty, "!\n"); + } + } /* have listen ports */ + + /* + * route export to other protocols + */ + if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) { + vty_out(vty, " vnc export bgp mode group-nve\n"); + } else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) { + vty_out(vty, " vnc export bgp mode registering-nve\n"); + } else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) { + vty_out(vty, " vnc export bgp mode ce\n"); + } + + if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) { + vty_out(vty, " vnc export zebra mode group-nve\n"); + } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) { + vty_out(vty, " vnc export zebra mode registering-nve\n"); + } + + if (hc->rfg_export_direct_bgp_l) { + for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l, node, nnode, + rfgn)) { + + vty_out(vty, " vnc export bgp group-nve group %s\n", + rfgn->name); + } + } + + if (hc->rfg_export_zebra_l) { + for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node, nnode, + rfgn)) { + + vty_out(vty, " vnc export zebra group-nve group %s\n", + rfgn->name); + } + } + + + if (hc->rfg_redist_name) { + vty_out(vty, " vnc redistribute nve-group %s\n", + hc->rfg_redist_name); + } + if (hc->redist_lifetime) { + vty_out(vty, " vnc redistribute lifetime %d\n", + hc->redist_lifetime); + } + if (hc->resolve_nve_roo_local_admin + != BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT) { + + vty_out(vty, + " vnc redistribute resolve-nve roo-ec-local-admin %d\n", + hc->resolve_nve_roo_local_admin); + } + + if (hc->redist_mode) /* ! default */ + { + const char *s = ""; + + switch (hc->redist_mode) { + case VNC_REDIST_MODE_PLAIN: + s = "plain"; + break; + case VNC_REDIST_MODE_RFG: + s = "nve-group"; + break; + case VNC_REDIST_MODE_RESOLVE_NVE: + s = "resolve-nve"; + break; + } + if (s) { + vty_out(vty, " vnc redistribute mode %s\n", s); + } + } + + /* + * route filtering: prefix-lists and route-maps + */ + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6"; + + if (hc->plist_export_bgp_name[afi]) { + vty_out(vty, " vnc export bgp %s prefix-list %s\n", + afistr, hc->plist_export_bgp_name[afi]); + } + if (hc->plist_export_zebra_name[afi]) { + vty_out(vty, " vnc export zebra %s prefix-list %s\n", + afistr, hc->plist_export_zebra_name[afi]); + } + if (hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) { + vty_out(vty, + " vnc redistribute bgp-direct %s prefix-list %s\n", + afistr, + hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT] + [afi]); + } + } + + if (hc->routemap_export_bgp_name) { + vty_out(vty, " vnc export bgp route-map %s\n", + hc->routemap_export_bgp_name); + } + if (hc->routemap_export_zebra_name) { + vty_out(vty, " vnc export zebra route-map %s\n", + hc->routemap_export_zebra_name); + } + if (hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) { + vty_out(vty, " vnc redistribute bgp-direct route-map %s\n", + hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); + } + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) { + if (hc->redist[afi][type]) { + if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT + && hc->redist_bgp_exterior_view_name) { + vty_out(vty, + " vnc redistribute %s %s view %s\n", + ((afi == AFI_IP) ? "ipv4" + : "ipv6"), + zebra_route_string(type), + hc->redist_bgp_exterior_view_name); + } else { + vty_out(vty, + " vnc redistribute %s %s\n", + ((afi == AFI_IP) ? "ipv4" + : "ipv6"), + zebra_route_string(type)); + } + } + } + } + return write; } -void -bgp_rfapi_show_summary (struct bgp *bgp, struct vty *vty) +void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty) { - struct rfapi_cfg *hc = bgp->rfapi_cfg; - int afi, type, redist = 0; - char tmp[40]; - if (hc == NULL) - return; - - vty_out (vty, "%-39s %-19s %s\n", "VNC Advertise method:", - (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP - ? "Encapsulation SAFI" : "Tunnel Encap attribute"), - ((hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) == (BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP & BGP_VNC_CONFIG_FLAGS_DEFAULT) ? "(default)" : "")); - /* export */ - vty_out (vty, "%-39s ", "Export from VNC:"); - /* - * route export to other protocols - */ - if (VNC_EXPORT_BGP_GRP_ENABLED (hc)) - { - redist++; - vty_out (vty, "ToBGP Groups={"); - if (hc->rfg_export_direct_bgp_l) - { - int cnt = 0; - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - for (ALL_LIST_ELEMENTS (hc->rfg_export_direct_bgp_l, - node, nnode, rfgn)) - { - if (cnt++ != 0) - vty_out (vty, ","); - - vty_out (vty, "%s", rfgn->name); - } - } - vty_out (vty, "}"); - } - else if (VNC_EXPORT_BGP_RH_ENABLED (hc)) - { - redist++; - vty_out (vty, "ToBGP {Registering NVE}"); - /* note filters, route-maps not shown */ - } - else if (VNC_EXPORT_BGP_CE_ENABLED (hc)) - { - redist++; - vty_out (vty, "ToBGP {NVE connected router:%d}", - hc->resolve_nve_roo_local_admin); - /* note filters, route-maps not shown */ - } - - if (VNC_EXPORT_ZEBRA_GRP_ENABLED (hc)) - { - redist++; - vty_out (vty, "%sToZebra Groups={", (redist == 1 ? "" : " ")); - if (hc->rfg_export_direct_bgp_l) - { - int cnt = 0; - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - for (ALL_LIST_ELEMENTS (hc->rfg_export_zebra_l, node, nnode, rfgn)) - { - if (cnt++ != 0) - vty_out (vty, ","); - vty_out (vty, "%s", rfgn->name); - } - } - vty_out (vty, "}"); - } - else if (VNC_EXPORT_ZEBRA_RH_ENABLED (hc)) - { - redist++; - vty_out (vty, "%sToZebra {Registering NVE}", (redist == 1 ? "" : " ")); - /* note filters, route-maps not shown */ - } - vty_out (vty, "%-19s %s\n", (redist ? "" : "Off"), - (redist ? "" : "(default)")); - - /* Redistribution */ - redist = 0; - vty_out (vty, "%-39s ", "Redistribution into VNC:"); - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) - { - if (hc->redist[afi][type]) - { - vty_out (vty, "{%s,%s} ", - ((afi == AFI_IP) ? "ipv4" : "ipv6"), - zebra_route_string (type)); - redist++; - } - } - } - vty_out (vty, "%-19s %s\n", (redist ? "" : "Off"), - (redist ? "" : "(default)")); - - vty_out (vty, "%-39s %3u%-16s %s\n", "RFP Registration Hold-Down Factor:", - hc->rfp_cfg.holddown_factor, "%", - (hc->rfp_cfg.holddown_factor == RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR ? "(default)" : "")); - vty_out (vty, "%-39s %-19s %s\n", "RFP Updated responses:", - (hc->rfp_cfg.use_updated_response == 0 ? "Off" : "On"), - (hc->rfp_cfg.use_updated_response == 0 ? "(default)" : "")); - vty_out (vty, "%-39s %-19s %s\n", "RFP Removal responses:", - (hc->rfp_cfg.use_removes == 0 ? "Off" : "On"), - (hc->rfp_cfg.use_removes == 0 ? "(default)" : "")); - vty_out (vty, "%-39s %-19s %s\n", "RFP Full table download:", - (hc->rfp_cfg.download_type == - RFAPI_RFP_DOWNLOAD_FULL ? "On" : "Off"), - (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL ? "(default)" : "")); - sprintf (tmp, "%u seconds", hc->rfp_cfg.ftd_advertisement_interval); - vty_out (vty, "%-39s %-19s %s\n", " Advertisement Interval:", tmp, - (hc->rfp_cfg.ftd_advertisement_interval == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL ? "(default)" : "")); - vty_out (vty, "%-39s %d seconds\n", "Default RFP response lifetime:", - hc->default_response_lifetime); - vty_out (vty, "\n"); - return; + struct rfapi_cfg *hc = bgp->rfapi_cfg; + int afi, type, redist = 0; + char tmp[40]; + if (hc == NULL) + return; + + vty_out(vty, "%-39s %-19s %s\n", "VNC Advertise method:", + (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP + ? "Encapsulation SAFI" + : "Tunnel Encap attribute"), + ((hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) + == (BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP + & BGP_VNC_CONFIG_FLAGS_DEFAULT) + ? "(default)" + : "")); + /* export */ + vty_out(vty, "%-39s ", "Export from VNC:"); + /* + * route export to other protocols + */ + if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) { + redist++; + vty_out(vty, "ToBGP Groups={"); + if (hc->rfg_export_direct_bgp_l) { + int cnt = 0; + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l, + node, nnode, rfgn)) { + if (cnt++ != 0) + vty_out(vty, ","); + + vty_out(vty, "%s", rfgn->name); + } + } + vty_out(vty, "}"); + } else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) { + redist++; + vty_out(vty, "ToBGP {Registering NVE}"); + /* note filters, route-maps not shown */ + } else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) { + redist++; + vty_out(vty, "ToBGP {NVE connected router:%d}", + hc->resolve_nve_roo_local_admin); + /* note filters, route-maps not shown */ + } + + if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) { + redist++; + vty_out(vty, "%sToZebra Groups={", (redist == 1 ? "" : " ")); + if (hc->rfg_export_direct_bgp_l) { + int cnt = 0; + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node, + nnode, rfgn)) { + if (cnt++ != 0) + vty_out(vty, ","); + vty_out(vty, "%s", rfgn->name); + } + } + vty_out(vty, "}"); + } else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) { + redist++; + vty_out(vty, "%sToZebra {Registering NVE}", + (redist == 1 ? "" : " ")); + /* note filters, route-maps not shown */ + } + vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"), + (redist ? "" : "(default)")); + + /* Redistribution */ + redist = 0; + vty_out(vty, "%-39s ", "Redistribution into VNC:"); + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) { + if (hc->redist[afi][type]) { + vty_out(vty, "{%s,%s} ", + ((afi == AFI_IP) ? "ipv4" : "ipv6"), + zebra_route_string(type)); + redist++; + } + } + } + vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"), + (redist ? "" : "(default)")); + + vty_out(vty, "%-39s %3u%-16s %s\n", + "RFP Registration Hold-Down Factor:", + hc->rfp_cfg.holddown_factor, "%", + (hc->rfp_cfg.holddown_factor + == RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR + ? "(default)" + : "")); + vty_out(vty, "%-39s %-19s %s\n", "RFP Updated responses:", + (hc->rfp_cfg.use_updated_response == 0 ? "Off" : "On"), + (hc->rfp_cfg.use_updated_response == 0 ? "(default)" : "")); + vty_out(vty, "%-39s %-19s %s\n", "RFP Removal responses:", + (hc->rfp_cfg.use_removes == 0 ? "Off" : "On"), + (hc->rfp_cfg.use_removes == 0 ? "(default)" : "")); + vty_out(vty, "%-39s %-19s %s\n", "RFP Full table download:", + (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL ? "On" + : "Off"), + (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL + ? "(default)" + : "")); + sprintf(tmp, "%u seconds", hc->rfp_cfg.ftd_advertisement_interval); + vty_out(vty, "%-39s %-19s %s\n", " Advertisement Interval:", tmp, + (hc->rfp_cfg.ftd_advertisement_interval + == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL + ? "(default)" + : "")); + vty_out(vty, "%-39s %d seconds\n", "Default RFP response lifetime:", + hc->default_response_lifetime); + vty_out(vty, "\n"); + return; } -struct rfapi_cfg * -bgp_rfapi_get_config (struct bgp *bgp) +struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp) { - struct rfapi_cfg *hc = NULL; - if (bgp == NULL) - bgp = bgp_get_default (); - if (bgp != NULL) - hc = bgp->rfapi_cfg; - return hc; + struct rfapi_cfg *hc = NULL; + if (bgp == NULL) + bgp = bgp_get_default(); + if (bgp != NULL) + hc = bgp->rfapi_cfg; + return hc; } #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/bgp_rfapi_cfg.h b/bgpd/rfapi/bgp_rfapi_cfg.h index 44abbe2223..d99aefa60d 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.h +++ b/bgpd/rfapi/bgp_rfapi_cfg.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -27,200 +27,195 @@ #if ENABLE_BGP_VNC #include "rfapi.h" -struct rfapi_l2_group_cfg -{ - char *name; - uint32_t logical_net_id; - struct list *labels; /* list of uint32_t */ - struct ecommunity *rt_import_list; - struct ecommunity *rt_export_list; - void *rfp_cfg; /* rfp owned group config */ +struct rfapi_l2_group_cfg { + char *name; + uint32_t logical_net_id; + struct list *labels; /* list of uint32_t */ + struct ecommunity *rt_import_list; + struct ecommunity *rt_export_list; + void *rfp_cfg; /* rfp owned group config */ - QOBJ_FIELDS + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(rfapi_l2_group_cfg) -typedef enum -{ - RFAPI_GROUP_CFG_NVE = 1, - RFAPI_GROUP_CFG_VRF, - RFAPI_GROUP_CFG_L2, - RFAPI_GROUP_CFG_MAX +typedef enum { + RFAPI_GROUP_CFG_NVE = 1, + RFAPI_GROUP_CFG_VRF, + RFAPI_GROUP_CFG_L2, + RFAPI_GROUP_CFG_MAX } rfapi_group_cfg_type_t; -struct rfapi_nve_group_cfg -{ - struct route_node *vn_node; /* backref */ - struct route_node *un_node; /* backref */ +struct rfapi_nve_group_cfg { + struct route_node *vn_node; /* backref */ + struct route_node *un_node; /* backref */ - rfapi_group_cfg_type_t type; /* NVE|VPN */ - char *name; /* unique by type! */ - struct prefix vn_prefix; - struct prefix un_prefix; + rfapi_group_cfg_type_t type; /* NVE|VPN */ + char *name; /* unique by type! */ + struct prefix vn_prefix; + struct prefix un_prefix; - struct prefix_rd rd; - uint8_t l2rd; /* 0 = VN addr LSB */ - uint32_t response_lifetime; - uint32_t flags; + struct prefix_rd rd; + uint8_t l2rd; /* 0 = VN addr LSB */ + uint32_t response_lifetime; + uint32_t flags; #define RFAPI_RFG_RESPONSE_LIFETIME 0x01 /* bits */ #define RFAPI_RFG_L2RD 0x02 #define RFAPI_RFG_VPN_NH_SELF 0x04 - struct ecommunity *rt_import_list; - struct ecommunity *rt_export_list; - struct rfapi_import_table *rfapi_import_table; - - void *rfp_cfg; /* rfp owned group config */ - /* - * List of NVE descriptors that are assigned to this NVE group - * - * Currently (Mar 2010) this list is used only by the route - * export code to generate per-NVE nexthops for each route. - * - * The nve descriptors listed here have pointers back to - * this nve group config structure to enable them to delete - * their own list entries when they are closed. Consequently, - * if an instance of this nve group config structure is deleted, - * we must first set the nve descriptor references to it to NULL. - */ - struct list *nves; - - /* - * Route filtering - * - * Prefix lists are segregated by afi (part of the base plist code) - * Route-maps are not segregated - */ - char *plist_export_bgp_name[AFI_MAX]; - struct prefix_list *plist_export_bgp[AFI_MAX]; - - char *plist_export_zebra_name[AFI_MAX]; - struct prefix_list *plist_export_zebra[AFI_MAX]; - - char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX]; - struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX]; - - char *routemap_export_bgp_name; - struct route_map *routemap_export_bgp; - - char *routemap_export_zebra_name; - struct route_map *routemap_export_zebra; - - char *routemap_redist_name[ZEBRA_ROUTE_MAX]; - struct route_map *routemap_redist[ZEBRA_ROUTE_MAX]; - - /* for VRF type groups */ - uint32_t label; - struct rfapi_descriptor *rfd; - QOBJ_FIELDS + struct ecommunity *rt_import_list; + struct ecommunity *rt_export_list; + struct rfapi_import_table *rfapi_import_table; + + void *rfp_cfg; /* rfp owned group config */ + /* + * List of NVE descriptors that are assigned to this NVE group + * + * Currently (Mar 2010) this list is used only by the route + * export code to generate per-NVE nexthops for each route. + * + * The nve descriptors listed here have pointers back to + * this nve group config structure to enable them to delete + * their own list entries when they are closed. Consequently, + * if an instance of this nve group config structure is deleted, + * we must first set the nve descriptor references to it to NULL. + */ + struct list *nves; + + /* + * Route filtering + * + * Prefix lists are segregated by afi (part of the base plist code) + * Route-maps are not segregated + */ + char *plist_export_bgp_name[AFI_MAX]; + struct prefix_list *plist_export_bgp[AFI_MAX]; + + char *plist_export_zebra_name[AFI_MAX]; + struct prefix_list *plist_export_zebra[AFI_MAX]; + + char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX]; + struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX]; + + char *routemap_export_bgp_name; + struct route_map *routemap_export_bgp; + + char *routemap_export_zebra_name; + struct route_map *routemap_export_zebra; + + char *routemap_redist_name[ZEBRA_ROUTE_MAX]; + struct route_map *routemap_redist[ZEBRA_ROUTE_MAX]; + + /* for VRF type groups */ + uint32_t label; + struct rfapi_descriptor *rfd; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(rfapi_nve_group_cfg) -struct rfapi_rfg_name -{ - struct rfapi_nve_group_cfg *rfg; - char *name; +struct rfapi_rfg_name { + struct rfapi_nve_group_cfg *rfg; + char *name; }; -typedef enum -{ - VNC_REDIST_MODE_PLAIN = 0, /* 0 = default */ - VNC_REDIST_MODE_RFG, - VNC_REDIST_MODE_RESOLVE_NVE +typedef enum { + VNC_REDIST_MODE_PLAIN = 0, /* 0 = default */ + VNC_REDIST_MODE_RFG, + VNC_REDIST_MODE_RESOLVE_NVE } vnc_redist_mode_t; -struct rfapi_cfg -{ - struct prefix_rd default_rd; - uint8_t default_l2rd; - struct ecommunity *default_rt_import_list; - struct ecommunity *default_rt_export_list; - uint32_t default_response_lifetime; +struct rfapi_cfg { + struct prefix_rd default_rd; + uint8_t default_l2rd; + struct ecommunity *default_rt_import_list; + struct ecommunity *default_rt_export_list; + uint32_t default_response_lifetime; #define BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT 3600 - void *default_rfp_cfg; /* rfp owned group config */ - - struct list *l2_groups; /* rfapi_l2_group_cfg list */ - /* three views into the same collection of rfapi_nve_group_cfg */ - struct list *nve_groups_sequential; - struct route_table nve_groups_vn[AFI_MAX]; - struct route_table nve_groups_un[AFI_MAX]; - - /* - * For Single VRF export to ordinary routing protocols. This is - * the nve-group that the ordinary protocols belong to. We use it - * to set the RD when sending unicast Zebra routes to VNC - */ - uint8_t redist[AFI_MAX][ZEBRA_ROUTE_MAX]; - uint32_t redist_lifetime; - vnc_redist_mode_t redist_mode; - - /* - * view name of BGP unicast instance that holds - * exterior routes - */ - char *redist_bgp_exterior_view_name; - struct bgp *redist_bgp_exterior_view; - - /* - * nve group for redistribution of routes from zebra to VNC - * (which is probably not useful for production networks) - */ - char *rfg_redist_name; - struct rfapi_nve_group_cfg *rfg_redist; - - /* - * List of NVE groups on whose behalf we will export VNC - * routes to zebra. ((NB: it's actually a list of <struct rfapi_rfg_name>) - * This list is used when BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS is - * BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP - */ - struct list *rfg_export_zebra_l; - - /* - * List of NVE groups on whose behalf we will export VNC - * routes directly to the bgp unicast RIB. (NB: it's actually - * a list of <struct rfapi_rfg_name>) - * This list is used when BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS is - * BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP - */ - struct list *rfg_export_direct_bgp_l; - - /* - * Exported Route filtering - * - * Prefix lists are segregated by afi (part of the base plist code) - * Route-maps are not segregated - */ - char *plist_export_bgp_name[AFI_MAX]; - struct prefix_list *plist_export_bgp[AFI_MAX]; - - char *plist_export_zebra_name[AFI_MAX]; - struct prefix_list *plist_export_zebra[AFI_MAX]; - - char *routemap_export_bgp_name; - struct route_map *routemap_export_bgp; - - char *routemap_export_zebra_name; - struct route_map *routemap_export_zebra; - - /* - * Redistributed route filtering (routes from other - * protocols into VNC) - */ - char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX]; - struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX]; - - char *routemap_redist_name[ZEBRA_ROUTE_MAX]; - struct route_map *routemap_redist[ZEBRA_ROUTE_MAX]; - - /* - * For importing bgp unicast routes to VNC, we encode the CE - * (route nexthop) in a Route Origin extended community. The - * local part (16-bit) is user-configurable. - */ - uint16_t resolve_nve_roo_local_admin; + void *default_rfp_cfg; /* rfp owned group config */ + + struct list *l2_groups; /* rfapi_l2_group_cfg list */ + /* three views into the same collection of rfapi_nve_group_cfg */ + struct list *nve_groups_sequential; + struct route_table nve_groups_vn[AFI_MAX]; + struct route_table nve_groups_un[AFI_MAX]; + + /* + * For Single VRF export to ordinary routing protocols. This is + * the nve-group that the ordinary protocols belong to. We use it + * to set the RD when sending unicast Zebra routes to VNC + */ + uint8_t redist[AFI_MAX][ZEBRA_ROUTE_MAX]; + uint32_t redist_lifetime; + vnc_redist_mode_t redist_mode; + + /* + * view name of BGP unicast instance that holds + * exterior routes + */ + char *redist_bgp_exterior_view_name; + struct bgp *redist_bgp_exterior_view; + + /* + * nve group for redistribution of routes from zebra to VNC + * (which is probably not useful for production networks) + */ + char *rfg_redist_name; + struct rfapi_nve_group_cfg *rfg_redist; + + /* + * List of NVE groups on whose behalf we will export VNC + * routes to zebra. ((NB: it's actually a list of <struct + * rfapi_rfg_name>) + * This list is used when BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS is + * BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP + */ + struct list *rfg_export_zebra_l; + + /* + * List of NVE groups on whose behalf we will export VNC + * routes directly to the bgp unicast RIB. (NB: it's actually + * a list of <struct rfapi_rfg_name>) + * This list is used when BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS is + * BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP + */ + struct list *rfg_export_direct_bgp_l; + + /* + * Exported Route filtering + * + * Prefix lists are segregated by afi (part of the base plist code) + * Route-maps are not segregated + */ + char *plist_export_bgp_name[AFI_MAX]; + struct prefix_list *plist_export_bgp[AFI_MAX]; + + char *plist_export_zebra_name[AFI_MAX]; + struct prefix_list *plist_export_zebra[AFI_MAX]; + + char *routemap_export_bgp_name; + struct route_map *routemap_export_bgp; + + char *routemap_export_zebra_name; + struct route_map *routemap_export_zebra; + + /* + * Redistributed route filtering (routes from other + * protocols into VNC) + */ + char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX]; + struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX]; + + char *routemap_redist_name[ZEBRA_ROUTE_MAX]; + struct route_map *routemap_redist[ZEBRA_ROUTE_MAX]; + + /* + * For importing bgp unicast routes to VNC, we encode the CE + * (route nexthop) in a Route Origin extended community. The + * local part (16-bit) is user-configurable. + */ + uint16_t resolve_nve_roo_local_admin; #define BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT 5226 - uint32_t flags; + uint32_t flags; #define BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP 0x00000001 #define BGP_VNC_CONFIG_CALLBACK_DISABLE 0x00000002 #define BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE 0x00000004 @@ -244,98 +239,76 @@ struct rfapi_cfg /* Filter querying NVE's registrations from responses */ /* Default to updated-responses off */ /* Default to removal-responses off */ -#define BGP_VNC_CONFIG_FLAGS_DEFAULT \ - (BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP |\ - BGP_VNC_CONFIG_CALLBACK_DISABLE |\ - BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE) +#define BGP_VNC_CONFIG_FLAGS_DEFAULT \ + (BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP | BGP_VNC_CONFIG_CALLBACK_DISABLE \ + | BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE) - struct rfapi_rfp_cfg rfp_cfg; /* rfp related configuration */ + struct rfapi_rfp_cfg rfp_cfg; /* rfp related configuration */ }; -#define VNC_EXPORT_ZEBRA_GRP_ENABLED(hc) \ - (((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) == \ - BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) +#define VNC_EXPORT_ZEBRA_GRP_ENABLED(hc) \ + (((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) \ + == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) -#define VNC_EXPORT_ZEBRA_RH_ENABLED(hc) \ - (((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) == \ - BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) +#define VNC_EXPORT_ZEBRA_RH_ENABLED(hc) \ + (((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) \ + == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) -#define VNC_EXPORT_BGP_GRP_ENABLED(hc) \ - (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \ - BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP) +#define VNC_EXPORT_BGP_GRP_ENABLED(hc) \ + (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \ + == BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP) -#define VNC_EXPORT_BGP_RH_ENABLED(hc) \ - (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \ - BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH) +#define VNC_EXPORT_BGP_RH_ENABLED(hc) \ + (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \ + == BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH) -#define VNC_EXPORT_BGP_CE_ENABLED(hc) \ - (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == \ - BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) +#define VNC_EXPORT_BGP_CE_ENABLED(hc) \ + (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) \ + == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) -void -bgp_rfapi_cfg_init (void); +void bgp_rfapi_cfg_init(void); -struct rfapi_cfg * -bgp_rfapi_cfg_new (struct rfapi_rfp_cfg *cfg); +struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg); -void -bgp_rfapi_cfg_destroy (struct bgp *bgp, struct rfapi_cfg *h); +void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h); -int -bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp); +int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp); -extern int -bgp_rfapi_is_vnc_configured (struct bgp *bgp); +extern int bgp_rfapi_is_vnc_configured(struct bgp *bgp); -extern void -nve_group_to_nve_list ( - struct rfapi_nve_group_cfg *rfg, - struct list **nves, - uint8_t family); /* AF_INET, AF_INET6 */ +extern void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg, + struct list **nves, + uint8_t family); /* AF_INET, AF_INET6 */ -struct rfapi_nve_group_cfg * -bgp_rfapi_cfg_match_group ( - struct rfapi_cfg *hc, - struct prefix *vn, - struct prefix *un); +struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc, + struct prefix *vn, + struct prefix *un); struct rfapi_nve_group_cfg * -bgp_rfapi_cfg_match_byname ( - struct bgp *bgp, - const char *name, - rfapi_group_cfg_type_t type); /* _MAX = any */ +bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name, + rfapi_group_cfg_type_t type); /* _MAX = any */ -extern void -vnc_prefix_list_update (struct bgp *bgp); +extern void vnc_prefix_list_update(struct bgp *bgp); -extern void -vnc_routemap_update (struct bgp *bgp, const char *unused); +extern void vnc_routemap_update(struct bgp *bgp, const char *unused); -extern void -bgp_rfapi_show_summary (struct bgp *bgp, struct vty *vty); +extern void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty); -extern struct rfapi_cfg * -bgp_rfapi_get_config (struct bgp *bgp); +extern struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp); extern struct rfapi_l2_group_cfg * -bgp_rfapi_get_group_by_lni_label ( - struct bgp *bgp, - uint32_t logical_net_id, - uint32_t label); +bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id, + uint32_t label); extern struct ecommunity * -bgp_rfapi_get_ecommunity_by_lni_label ( - struct bgp *bgp, - uint32_t is_import, - uint32_t logical_net_id, - uint32_t label); /* note, 20bit label! */ +bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import, + uint32_t logical_net_id, + uint32_t label); /* note, 20bit label! */ extern struct list * -bgp_rfapi_get_labellist_by_lni_label ( - struct bgp *bgp, - uint32_t logical_net_id, - uint32_t label); /* note, 20bit label! */ +bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp, uint32_t logical_net_id, + uint32_t label); /* note, 20bit label! */ #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index a959b9827c..3a2a608a7c 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -65,38 +65,36 @@ #include <execinfo.h> #endif /* HAVE_GLIBC_BACKTRACE */ -struct ethaddr rfapi_ethaddr0 = { {0} }; +struct ethaddr rfapi_ethaddr0 = {{0}}; #define DEBUG_RFAPI_STR "RF API debugging/testing command\n" -const char * -rfapi_error_str (int code) +const char *rfapi_error_str(int code) { - switch (code) - { - case 0: - return "Success"; - case ENXIO: - return "BGP or VNC not configured"; - case ENOENT: - return "No match"; - case EEXIST: - return "Handle already open"; - case ENOMSG: - return "Incomplete configuration"; - case EAFNOSUPPORT: - return "Invalid address family"; - case EDEADLK: - return "Called from within a callback procedure"; - case EBADF: - return "Invalid handle"; - case EINVAL: - return "Invalid argument"; - case ESTALE: - return "Stale descriptor"; - default: - return "Unknown error"; - } + switch (code) { + case 0: + return "Success"; + case ENXIO: + return "BGP or VNC not configured"; + case ENOENT: + return "No match"; + case EEXIST: + return "Handle already open"; + case ENOMSG: + return "Incomplete configuration"; + case EAFNOSUPPORT: + return "Invalid address family"; + case EDEADLK: + return "Called from within a callback procedure"; + case EBADF: + return "Invalid handle"; + case EINVAL: + return "Invalid argument"; + case ESTALE: + return "Stale descriptor"; + default: + return "Unknown error"; + } } /*------------------------------------------ @@ -106,20 +104,19 @@ rfapi_error_str (int code) * rfp_start_val value returned by rfp_start or * NULL (=use default instance) * - * input: + * input: * None * * output: * * return value: The bgp instance default lifetime for a response. --------------------------------------------*/ -int -rfapi_get_response_lifetime_default (void *rfp_start_val) +int rfapi_get_response_lifetime_default(void *rfp_start_val) { - struct bgp *bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - if (bgp) - return bgp->rfapi_cfg->default_response_lifetime; - return BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT; + struct bgp *bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + if (bgp) + return bgp->rfapi_cfg->default_response_lifetime; + return BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT; } /*------------------------------------------ @@ -127,7 +124,7 @@ rfapi_get_response_lifetime_default (void *rfp_start_val) * * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured * - * input: + * input: * rfp_start_val value returned by rfp_start or * NULL (=use default instance) * @@ -137,11 +134,10 @@ rfapi_get_response_lifetime_default (void *rfp_start_val) * 0 Success * ENXIO VNC not configured --------------------------------------------*/ -int -rfapi_is_vnc_configured (void *rfp_start_val) +int rfapi_is_vnc_configured(void *rfp_start_val) { - struct bgp *bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - return bgp_rfapi_is_vnc_configured (bgp); + struct bgp *bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + return bgp_rfapi_is_vnc_configured(bgp); } @@ -150,19 +146,18 @@ rfapi_is_vnc_configured (void *rfp_start_val) * * Get the virtual network address used by an NVE based on it's RFD * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic * * output: * - * return value: + * return value: * vn NVE virtual network address *------------------------------------------*/ -struct rfapi_ip_addr * -rfapi_get_vn_addr (void *rfd) +struct rfapi_ip_addr *rfapi_get_vn_addr(void *rfd) { - struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *) rfd; - return &rrfd->vn_addr; + struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *)rfd; + return &rrfd->vn_addr; } /*------------------------------------------ @@ -170,505 +165,459 @@ rfapi_get_vn_addr (void *rfd) * * Get the underlay network address used by an NVE based on it's RFD * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic * * output: * - * return value: + * return value: * un NVE underlay network address *------------------------------------------*/ -struct rfapi_ip_addr * -rfapi_get_un_addr (void *rfd) +struct rfapi_ip_addr *rfapi_get_un_addr(void *rfd) { - struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *) rfd; - return &rrfd->un_addr; + struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *)rfd; + return &rrfd->un_addr; } -int -rfapi_ip_addr_cmp (struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2) +int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2) { - if (a1->addr_family != a2->addr_family) - return a1->addr_family - a2->addr_family; + if (a1->addr_family != a2->addr_family) + return a1->addr_family - a2->addr_family; - if (a1->addr_family == AF_INET) - { - return IPV4_ADDR_CMP (&a1->addr.v4, &a2->addr.v4); - } + if (a1->addr_family == AF_INET) { + return IPV4_ADDR_CMP(&a1->addr.v4, &a2->addr.v4); + } - if (a1->addr_family == AF_INET6) - { - return IPV6_ADDR_CMP (&a1->addr.v6, &a2->addr.v6); - } + if (a1->addr_family == AF_INET6) { + return IPV6_ADDR_CMP(&a1->addr.v6, &a2->addr.v6); + } - assert (1); - /* NOTREACHED */ - return 1; + assert(1); + /* NOTREACHED */ + return 1; } -static int -rfapi_find_node ( - struct bgp *bgp, - struct rfapi_ip_addr *vn_addr, - struct rfapi_ip_addr *un_addr, - struct route_node **node) +static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, + struct rfapi_ip_addr *un_addr, + struct route_node **node) { - struct rfapi *h; - struct prefix p; - struct route_node *rn; - int rc; - int afi; + struct rfapi *h; + struct prefix p; + struct route_node *rn; + int rc; + int afi; - if (!bgp) - { - return ENXIO; - } + if (!bgp) { + return ENXIO; + } - h = bgp->rfapi; - if (!h) - { - return ENXIO; - } + h = bgp->rfapi; + if (!h) { + return ENXIO; + } - afi = family2afi (un_addr->addr_family); - if (!afi) - { - return EAFNOSUPPORT; - } + afi = family2afi(un_addr->addr_family); + if (!afi) { + return EAFNOSUPPORT; + } - if ((rc = rfapiRaddr2Qprefix (un_addr, &p))) - return rc; + if ((rc = rfapiRaddr2Qprefix(un_addr, &p))) + return rc; - rn = route_node_lookup (&h->un[afi], &p); + rn = route_node_lookup(&h->un[afi], &p); - if (!rn) - return ENOENT; + if (!rn) + return ENOENT; - route_unlock_node (rn); + route_unlock_node(rn); - *node = rn; + *node = rn; - return 0; + return 0; } -int -rfapi_find_rfd ( - struct bgp *bgp, - struct rfapi_ip_addr *vn_addr, - struct rfapi_ip_addr *un_addr, - struct rfapi_descriptor **rfd) +int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, + struct rfapi_ip_addr *un_addr, struct rfapi_descriptor **rfd) { - struct route_node *rn; - int rc; + struct route_node *rn; + int rc; - rc = rfapi_find_node (bgp, vn_addr, un_addr, &rn); + rc = rfapi_find_node(bgp, vn_addr, un_addr, &rn); - if (rc) - return rc; + if (rc) + return rc; - for (*rfd = (struct rfapi_descriptor *) (rn->info); *rfd; - *rfd = (*rfd)->next) - { - if (!rfapi_ip_addr_cmp (&(*rfd)->vn_addr, vn_addr)) - break; - } + for (*rfd = (struct rfapi_descriptor *)(rn->info); *rfd; + *rfd = (*rfd)->next) { + if (!rfapi_ip_addr_cmp(&(*rfd)->vn_addr, vn_addr)) + break; + } - if (!*rfd) - return ENOENT; + if (!*rfd) + return ENOENT; - return 0; + return 0; } /*------------------------------------------ * rfapi_find_handle * - * input: + * input: * un underlay network address * vn virtual network address * * output: * pHandle pointer to location to store handle * - * return value: + * return value: * 0 Success * ENOENT no matching handle * ENXIO BGP or VNC not configured *------------------------------------------*/ -static int -rfapi_find_handle ( - struct bgp *bgp, - struct rfapi_ip_addr *vn_addr, - struct rfapi_ip_addr *un_addr, - rfapi_handle *handle) +static int rfapi_find_handle(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, + struct rfapi_ip_addr *un_addr, + rfapi_handle *handle) { - struct rfapi_descriptor **rfd; + struct rfapi_descriptor **rfd; - rfd = (struct rfapi_descriptor **) handle; + rfd = (struct rfapi_descriptor **)handle; - return rfapi_find_rfd (bgp, vn_addr, un_addr, rfd); + return rfapi_find_rfd(bgp, vn_addr, un_addr, rfd); } -static int -rfapi_find_handle_vty ( - struct vty *vty, - struct rfapi_ip_addr *vn_addr, - struct rfapi_ip_addr *un_addr, - rfapi_handle *handle) +static int rfapi_find_handle_vty(struct vty *vty, struct rfapi_ip_addr *vn_addr, + struct rfapi_ip_addr *un_addr, + rfapi_handle *handle) { - struct bgp *bgp; - struct rfapi_descriptor **rfd; + struct bgp *bgp; + struct rfapi_descriptor **rfd; - bgp = bgp_get_default (); /* assume 1 instance for now */ + bgp = bgp_get_default(); /* assume 1 instance for now */ - rfd = (struct rfapi_descriptor **) handle; + rfd = (struct rfapi_descriptor **)handle; - return rfapi_find_rfd (bgp, vn_addr, un_addr, rfd); + return rfapi_find_rfd(bgp, vn_addr, un_addr, rfd); } -static int -is_valid_rfd (struct rfapi_descriptor *rfd) +static int is_valid_rfd(struct rfapi_descriptor *rfd) { - rfapi_handle hh; + rfapi_handle hh; - if (!rfd || rfd->bgp == NULL) - return 0; + if (!rfd || rfd->bgp == NULL) + return 0; - if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */ - return 1; + if (CHECK_FLAG( + rfd->flags, + RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */ + return 1; - if (rfapi_find_handle (rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh)) - return 0; + if (rfapi_find_handle(rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh)) + return 0; - if (rfd != hh) - return 0; + if (rfd != hh) + return 0; - return 1; + return 1; } /* * check status of descriptor */ -int -rfapi_check (void *handle) +int rfapi_check(void *handle) { - struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; - rfapi_handle hh; - int rc; + struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; + rfapi_handle hh; + int rc; - if (!rfd || rfd->bgp == NULL) - return EINVAL; + if (!rfd || rfd->bgp == NULL) + return EINVAL; - if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */ - return 0; + if (CHECK_FLAG( + rfd->flags, + RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */ + return 0; - if ((rc = rfapi_find_handle (rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh))) - return rc; + if ((rc = rfapi_find_handle(rfd->bgp, &rfd->vn_addr, &rfd->un_addr, + &hh))) + return rc; - if (rfd != hh) - return ENOENT; + if (rfd != hh) + return ENOENT; - if (!rfd->rfg) - return ESTALE; + if (!rfd->rfg) + return ESTALE; - return 0; + return 0; } - -void -del_vnc_route ( - struct rfapi_descriptor *rfd, - struct peer *peer, /* rfd->peer for RFP regs */ - struct bgp *bgp, - safi_t safi, - struct prefix *p, - struct prefix_rd *prd, - uint8_t type, - uint8_t sub_type, - struct rfapi_nexthop *lnh, - int kill) +void del_vnc_route(struct rfapi_descriptor *rfd, + struct peer *peer, /* rfd->peer for RFP regs */ + struct bgp *bgp, safi_t safi, struct prefix *p, + struct prefix_rd *prd, uint8_t type, uint8_t sub_type, + struct rfapi_nexthop *lnh, int kill) { - afi_t afi; /* of the VN address */ - struct bgp_node *bn; - struct bgp_info *bi; - char buf[BUFSIZ]; - char buf2[BUFSIZ]; - struct prefix_rd prd0; - - prefix2str (p, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ - - prefix_rd2str (prd, buf2, BUFSIZ); - buf2[BUFSIZ - 1] = 0; - - afi = family2afi (p->family); - assert (afi == AFI_IP || afi == AFI_IP6); - - if (safi == SAFI_ENCAP) - { - memset (&prd0, 0, sizeof (prd0)); - prd0.family = AF_UNSPEC; - prd0.prefixlen = 64; - prd = &prd0; - } - bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); - - vnc_zlog_debug_verbose - ("%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p", - __func__, peer, buf, buf2, afi, safi, bn, (bn ? bn->info : NULL)); - - for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) - { - - vnc_zlog_debug_verbose - ("%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u", - __func__, bi, bi->peer, bi->type, bi->sub_type, - (bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL), - ((bi->attr && CHECK_FLAG(bi->attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))? bi->attr->local_pref: 0)); - - if (bi->peer == peer && - bi->type == type && - bi->sub_type == sub_type && - bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd) - { - - vnc_zlog_debug_verbose ("%s: matched it", __func__); - - break; - } - } - - if (lnh) - { - /* - * lnh set means to JUST delete the local nexthop from this - * route. Leave the route itself in place. - * TBD add return code reporting of success/failure - */ - if (!bi || !bi->extra || !bi->extra->vnc.export.local_nexthops) - { - /* - * no local nexthops - */ - vnc_zlog_debug_verbose ("%s: lnh list already empty at prefix %s", - __func__, buf); - goto done; - } - - /* - * look for it - */ - struct listnode *node; - struct rfapi_nexthop *pLnh = NULL; - - for (ALL_LIST_ELEMENTS_RO (bi->extra->vnc.export.local_nexthops, - node, pLnh)) - { - - if (prefix_same (&pLnh->addr, &lnh->addr)) - { - break; - } - } - - if (pLnh) - { - listnode_delete (bi->extra->vnc.export.local_nexthops, pLnh); - - /* silly rabbit, listnode_delete doesn't invoke list->del on data */ - rfapi_nexthop_free (pLnh); - } - else - { - vnc_zlog_debug_verbose ("%s: desired lnh not found %s", __func__, buf); - } - goto done; - } - - /* - * loop back to import tables - * Do this before removing from BGP RIB because rfapiProcessWithdraw - * might refer to it - */ - rfapiProcessWithdraw (peer, rfd, p, prd, NULL, afi, safi, type, kill); - - if (bi) - { - char buf[BUFSIZ]; - - prefix2str (p, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ - - vnc_zlog_debug_verbose ("%s: Found route (safi=%d) to delete at prefix %s", - __func__, safi, buf); - - if (safi == SAFI_MPLS_VPN) - { - struct bgp_node *prn = NULL; - struct bgp_table *table = NULL; - - prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd); - if (prn->info) - { - table = (struct bgp_table *) (prn->info); - - vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (bgp, - prd, - table, - p, bi); - } - bgp_unlock_node (prn); - } - - /* - * Delete local_nexthops list - */ - if (bi->extra && bi->extra->vnc.export.local_nexthops) - { - list_delete (bi->extra->vnc.export.local_nexthops); - } - - bgp_aggregate_decrement (bgp, p, bi, afi, safi); - bgp_info_delete (bn, bi); - bgp_process (bgp, bn, afi, safi); - } - else - { - vnc_zlog_debug_verbose ("%s: Couldn't find route (safi=%d) at prefix %s", - __func__, safi, buf); - } + afi_t afi; /* of the VN address */ + struct bgp_node *bn; + struct bgp_info *bi; + char buf[BUFSIZ]; + char buf2[BUFSIZ]; + struct prefix_rd prd0; + + prefix2str(p, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + + prefix_rd2str(prd, buf2, BUFSIZ); + buf2[BUFSIZ - 1] = 0; + + afi = family2afi(p->family); + assert(afi == AFI_IP || afi == AFI_IP6); + + if (safi == SAFI_ENCAP) { + memset(&prd0, 0, sizeof(prd0)); + prd0.family = AF_UNSPEC; + prd0.prefixlen = 64; + prd = &prd0; + } + bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); + + vnc_zlog_debug_verbose( + "%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p", + __func__, peer, buf, buf2, afi, safi, bn, + (bn ? bn->info : NULL)); + + for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) { + + vnc_zlog_debug_verbose( + "%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u", + __func__, bi, bi->peer, bi->type, bi->sub_type, + (bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL), + ((bi->attr + && CHECK_FLAG(bi->attr->flag, + ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) + ? bi->attr->local_pref + : 0)); + + if (bi->peer == peer && bi->type == type + && bi->sub_type == sub_type && bi->extra + && bi->extra->vnc.export.rfapi_handle == (void *)rfd) { + + vnc_zlog_debug_verbose("%s: matched it", __func__); + + break; + } + } + + if (lnh) { + /* + * lnh set means to JUST delete the local nexthop from this + * route. Leave the route itself in place. + * TBD add return code reporting of success/failure + */ + if (!bi || !bi->extra + || !bi->extra->vnc.export.local_nexthops) { + /* + * no local nexthops + */ + vnc_zlog_debug_verbose( + "%s: lnh list already empty at prefix %s", + __func__, buf); + goto done; + } + + /* + * look for it + */ + struct listnode *node; + struct rfapi_nexthop *pLnh = NULL; + + for (ALL_LIST_ELEMENTS_RO(bi->extra->vnc.export.local_nexthops, + node, pLnh)) { + + if (prefix_same(&pLnh->addr, &lnh->addr)) { + break; + } + } + + if (pLnh) { + listnode_delete(bi->extra->vnc.export.local_nexthops, + pLnh); + + /* silly rabbit, listnode_delete doesn't invoke + * list->del on data */ + rfapi_nexthop_free(pLnh); + } else { + vnc_zlog_debug_verbose("%s: desired lnh not found %s", + __func__, buf); + } + goto done; + } + + /* + * loop back to import tables + * Do this before removing from BGP RIB because rfapiProcessWithdraw + * might refer to it + */ + rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill); + + if (bi) { + char buf[BUFSIZ]; + + prefix2str(p, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + + vnc_zlog_debug_verbose( + "%s: Found route (safi=%d) to delete at prefix %s", + __func__, safi, buf); + + if (safi == SAFI_MPLS_VPN) { + struct bgp_node *prn = NULL; + struct bgp_table *table = NULL; + + prn = bgp_node_get(bgp->rib[afi][safi], + (struct prefix *)prd); + if (prn->info) { + table = (struct bgp_table *)(prn->info); + + vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( + bgp, prd, table, p, bi); + } + bgp_unlock_node(prn); + } + + /* + * Delete local_nexthops list + */ + if (bi->extra && bi->extra->vnc.export.local_nexthops) { + list_delete(bi->extra->vnc.export.local_nexthops); + } + + bgp_aggregate_decrement(bgp, p, bi, afi, safi); + bgp_info_delete(bn, bi); + bgp_process(bgp, bn, afi, safi); + } else { + vnc_zlog_debug_verbose( + "%s: Couldn't find route (safi=%d) at prefix %s", + __func__, safi, buf); + } done: - bgp_unlock_node (bn); + bgp_unlock_node(bn); } -struct rfapi_nexthop * -rfapi_nexthop_new (struct rfapi_nexthop *copyme) +struct rfapi_nexthop *rfapi_nexthop_new(struct rfapi_nexthop *copyme) { - struct rfapi_nexthop *new = - XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_nexthop)); - if (copyme) - *new = *copyme; - return new; + struct rfapi_nexthop *new = + XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_nexthop)); + if (copyme) + *new = *copyme; + return new; } -void -rfapi_nexthop_free (void *p) +void rfapi_nexthop_free(void *p) { - struct rfapi_nexthop *goner = p; - XFREE (MTYPE_RFAPI_NEXTHOP, goner); + struct rfapi_nexthop *goner = p; + XFREE(MTYPE_RFAPI_NEXTHOP, goner); } -struct rfapi_vn_option * -rfapi_vn_options_dup (struct rfapi_vn_option *existing) +struct rfapi_vn_option *rfapi_vn_options_dup(struct rfapi_vn_option *existing) { - struct rfapi_vn_option *p; - struct rfapi_vn_option *head = NULL; - struct rfapi_vn_option *tail = NULL; - - for (p = existing; p; p = p->next) - { - struct rfapi_vn_option *new; - - new = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); - *new = *p; - new->next = NULL; - if (tail) - (tail)->next = new; - tail = new; - if (!head) - { - head = new; - } - } - return head; + struct rfapi_vn_option *p; + struct rfapi_vn_option *head = NULL; + struct rfapi_vn_option *tail = NULL; + + for (p = existing; p; p = p->next) { + struct rfapi_vn_option *new; + + new = XCALLOC(MTYPE_RFAPI_VN_OPTION, + sizeof(struct rfapi_vn_option)); + *new = *p; + new->next = NULL; + if (tail) + (tail)->next = new; + tail = new; + if (!head) { + head = new; + } + } + return head; } -void -rfapi_un_options_free (struct rfapi_un_option *p) +void rfapi_un_options_free(struct rfapi_un_option *p) { - struct rfapi_un_option *next; + struct rfapi_un_option *next; - while (p) - { - next = p->next; - XFREE (MTYPE_RFAPI_UN_OPTION, p); - p = next; - } + while (p) { + next = p->next; + XFREE(MTYPE_RFAPI_UN_OPTION, p); + p = next; + } } -void -rfapi_vn_options_free (struct rfapi_vn_option *p) +void rfapi_vn_options_free(struct rfapi_vn_option *p) { - struct rfapi_vn_option *next; + struct rfapi_vn_option *next; - while (p) - { - next = p->next; - XFREE (MTYPE_RFAPI_VN_OPTION, p); - p = next; - } + while (p) { + next = p->next; + XFREE(MTYPE_RFAPI_VN_OPTION, p); + p = next; + } } /* Based on bgp_redistribute_add() */ -void -add_vnc_route ( - struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ - struct bgp *bgp, - int safi, - struct prefix *p, - struct prefix_rd *prd, - struct rfapi_ip_addr *nexthop, - uint32_t *local_pref, - uint32_t *lifetime, /* NULL => dont send lifetime */ - struct bgp_tea_options *rfp_options, - struct rfapi_un_option *options_un, - struct rfapi_vn_option *options_vn, - struct ecommunity *rt_export_list,/* Copied, not consumed */ - uint32_t *med, /* NULL => don't set med */ - uint32_t *label, /* low order 3 bytes */ - uint8_t type, - uint8_t sub_type, /* RFP, NORMAL or REDIST */ - int flags) +void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ + struct bgp *bgp, int safi, struct prefix *p, + struct prefix_rd *prd, struct rfapi_ip_addr *nexthop, + uint32_t *local_pref, + uint32_t *lifetime, /* NULL => dont send lifetime */ + struct bgp_tea_options *rfp_options, + struct rfapi_un_option *options_un, + struct rfapi_vn_option *options_vn, + struct ecommunity *rt_export_list, /* Copied, not consumed */ + uint32_t *med, /* NULL => don't set med */ + uint32_t *label, /* low order 3 bytes */ + uint8_t type, uint8_t sub_type, /* RFP, NORMAL or REDIST */ + int flags) { - afi_t afi; /* of the VN address */ - struct bgp_info *new; - struct bgp_info *bi; - struct bgp_node *bn; - - struct attr attr = { 0 }; - struct attr *new_attr; - uint32_t label_val; - - struct bgp_attr_encap_subtlv *encaptlv; - char buf[BUFSIZ]; - char buf2[BUFSIZ]; -#if 0 /* unused? */ + afi_t afi; /* of the VN address */ + struct bgp_info *new; + struct bgp_info *bi; + struct bgp_node *bn; + + struct attr attr = {0}; + struct attr *new_attr; + uint32_t label_val; + + struct bgp_attr_encap_subtlv *encaptlv; + char buf[BUFSIZ]; + char buf2[BUFSIZ]; +#if 0 /* unused? */ struct prefix pfx_buf; #endif - struct rfapi_nexthop *lnh = NULL; /* local nexthop */ - struct rfapi_vn_option *vo; - struct rfapi_l2address_option *l2o = NULL; - struct rfapi_ip_addr *un_addr = &rfd->un_addr; + struct rfapi_nexthop *lnh = NULL; /* local nexthop */ + struct rfapi_vn_option *vo; + struct rfapi_l2address_option *l2o = NULL; + struct rfapi_ip_addr *un_addr = &rfd->un_addr; - bgp_encap_types TunnelType = BGP_ENCAP_TYPE_RESERVED; - struct bgp_redist *red; + bgp_encap_types TunnelType = BGP_ENCAP_TYPE_RESERVED; + struct bgp_redist *red; - if (safi == SAFI_ENCAP && - !(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)) - { + if (safi == SAFI_ENCAP + && !(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)) { - /* - * Encap mode not enabled. UN addresses will be communicated - * via VNC Tunnel subtlv instead. - */ - vnc_zlog_debug_verbose ("%s: encap mode not enabled, not adding SAFI_ENCAP route", - __func__); - return; - } + /* + * Encap mode not enabled. UN addresses will be communicated + * via VNC Tunnel subtlv instead. + */ + vnc_zlog_debug_verbose( + "%s: encap mode not enabled, not adding SAFI_ENCAP route", + __func__); + return; + } -#if 0 /* unused? */ +#if 0 /* unused? */ if ((safi == SAFI_MPLS_VPN) && (flags & RFAPI_AHR_SET_PFX_TO_NEXTHOP)) { @@ -682,579 +631,542 @@ add_vnc_route ( p = &pfx_buf; } #endif - for (vo = options_vn; vo; vo = vo->next) - { - if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) - { - l2o = &vo->v.l2addr; - if (RFAPI_0_ETHERADDR (&l2o->macaddr)) - l2o = NULL; /* not MAC resolution */ - } - if (RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP == vo->type) - { - lnh = &vo->v.local_nexthop; - } - } - - if (label) - label_val = *label; - else - label_val = MPLS_LABEL_IMPLICIT_NULL; - - prefix_rd2str (prd, buf2, BUFSIZ); - buf2[BUFSIZ - 1] = 0; - - - afi = family2afi (p->family); - assert (afi == AFI_IP || afi == AFI_IP6); - - vnc_zlog_debug_verbose ("%s: afi=%s, safi=%s", __func__, afi2str (afi), - safi2str (safi)); - - /* Make default attribute. Produces already-interned attr.aspath */ - /* Cripes, the memory management of attributes is byzantine */ - - bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE); - - /* - * At this point: - * attr: static - * extra: dynamically allocated, owned by attr - * aspath: points to interned hash from aspath hash table - */ - - - /* - * Route-specific un_options get added to the VPN SAFI - * advertisement tunnel encap attribute. (the per-NVE - * "default" un_options are put into the 1-per-NVE ENCAP - * SAFI advertisement). The VPN SAFI also gets the - * default un_options if there are no route-specific options. - */ - if (options_un) - { - struct rfapi_un_option *uo; - - for (uo = options_un; uo; uo = uo->next) - { - if (RFAPI_UN_OPTION_TYPE_TUNNELTYPE == uo->type) - { - TunnelType = rfapi_tunneltype_option_to_tlv ( - bgp, un_addr, &uo->v.tunnel, &attr, l2o != NULL); - } - } - } - else - { - /* - * Add encap attr - * These are the NVE-specific "default" un_options which are - * put into the 1-per-NVE ENCAP advertisement. - */ - if (rfd->default_tunneltype_option.type) - { - TunnelType = rfapi_tunneltype_option_to_tlv ( - bgp, un_addr, &rfd->default_tunneltype_option, &attr, - l2o != NULL); - } - else /* create default for local addse */ - if (type == ZEBRA_ROUTE_BGP && sub_type == BGP_ROUTE_RFP) - TunnelType = - rfapi_tunneltype_option_to_tlv (bgp, un_addr, NULL, - &attr, l2o != NULL); - } - - if (TunnelType == BGP_ENCAP_TYPE_MPLS) - { - if (safi == SAFI_ENCAP) - { - /* Encap SAFI not used with MPLS */ - vnc_zlog_debug_verbose ("%s: mpls tunnel type, encap safi omitted", __func__); - aspath_unintern (&attr.aspath); /* Unintern original. */ - return; - } - } - - if (local_pref) - { - attr.local_pref = *local_pref; - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); - } - - if (med) - { - attr.med = *med; - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); - } - - /* override default weight assigned by bgp_attr_default_set() */ - attr.weight = rfd->peer ? rfd->peer->weight[afi][safi] : 0; - - /* - * NB: ticket 81: do not reset attr.aspath here because it would - * cause iBGP peers to drop route - */ - - /* - * Set originator ID for routes imported from BGP directly. - * These routes could be synthetic, and therefore could - * reuse the peer pointers of the routes they are derived - * from. Setting the originator ID to "us" prevents the - * wrong originator ID from being sent when this route is - * sent from a route reflector. - */ - if (type == ZEBRA_ROUTE_BGP_DIRECT || type == ZEBRA_ROUTE_BGP_DIRECT_EXT) - { - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID); - attr.originator_id = bgp->router_id; - } - - - /* Set up vnc attribute (sub-tlv for Prefix Lifetime) */ - if (lifetime && *lifetime != RFAPI_INFINITE_LIFETIME) - { - uint32_t lt; - - encaptlv = - XCALLOC (MTYPE_ENCAP_TLV, - sizeof (struct bgp_attr_encap_subtlv) - 1 + 4); - assert (encaptlv); - encaptlv->type = BGP_VNC_SUBTLV_TYPE_LIFETIME; /* prefix lifetime */ - encaptlv->length = 4; - lt = htonl (*lifetime); - memcpy (encaptlv->value, <, 4); - attr.vnc_subtlvs = encaptlv; - vnc_zlog_debug_verbose ("%s: set Encap Attr Prefix Lifetime to %d", - __func__, *lifetime); - } - - /* add rfp options to vnc attr */ - if (rfp_options) - { - - if (flags & RFAPI_AHR_RFPOPT_IS_VNCTLV) - { - - /* - * this flag means we're passing a pointer to an - * existing encap tlv chain which we should copy. - * It's a hack to avoid adding yet another argument - * to add_vnc_route() - */ - encaptlv = - encap_tlv_dup ((struct bgp_attr_encap_subtlv *) rfp_options); - if (attr.vnc_subtlvs) - { - attr.vnc_subtlvs->next = encaptlv; - } - else - { - attr.vnc_subtlvs = encaptlv; - } - - } - else - { - struct bgp_tea_options *hop; - /* XXX max of one tlv present so far from above code */ - struct bgp_attr_encap_subtlv *tail = attr.vnc_subtlvs; - - for (hop = rfp_options; hop; hop = hop->next) - { - - /* - * Construct subtlv - */ - encaptlv = XCALLOC (MTYPE_ENCAP_TLV, - sizeof (struct bgp_attr_encap_subtlv) - 1 + - 2 + hop->length); - assert (encaptlv); - encaptlv->type = BGP_VNC_SUBTLV_TYPE_RFPOPTION; /* RFP option */ - encaptlv->length = 2 + hop->length; - *((uint8_t *) (encaptlv->value) + 0) = hop->type; - *((uint8_t *) (encaptlv->value) + 1) = hop->length; - memcpy (((uint8_t *) encaptlv->value) + 2, hop->value, - hop->length); - - /* - * add to end of subtlv chain - */ - if (tail) - { - tail->next = encaptlv; - } - else - { - attr.vnc_subtlvs = encaptlv; - } - tail = encaptlv; - } - } - } - - /* - * At this point: - * attr: static - * extra: dynamically allocated, owned by attr - * vnc_subtlvs: dynamic chain, length 1 - * aspath: points to interned hash from aspath hash table - */ - - - attr.ecommunity = ecommunity_new (); - assert (attr.ecommunity); - - if (TunnelType != BGP_ENCAP_TYPE_MPLS && - TunnelType != BGP_ENCAP_TYPE_RESERVED) - { - /* - * Add BGP Encapsulation Extended Community. Format described in - * section 4.5 of RFC 5512. - * Always include when not MPLS type, to disambiguate this case. - */ - struct ecommunity_val beec; - - memset (&beec, 0, sizeof (beec)); - beec.val[0] = ECOMMUNITY_ENCODE_OPAQUE; - beec.val[1] = ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP; - beec.val[6] = ((TunnelType) >> 8) & 0xff; - beec.val[7] = (TunnelType) & 0xff; - ecommunity_add_val (attr.ecommunity, &beec); - } - - /* - * Add extended community attributes to match rt export list - */ - if (rt_export_list) - { - attr.ecommunity = - ecommunity_merge (attr.ecommunity, rt_export_list); - } - - if (attr.ecommunity->size) - { - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES); - } - else - { - ecommunity_free (&attr.ecommunity); - attr.ecommunity = NULL; - } - vnc_zlog_debug_verbose ("%s: attr.ecommunity=%p", __func__, - attr.ecommunity); - - - /* - * At this point: - * attr: static - * extra: dynamically allocated, owned by attr - * vnc_subtlvs: dynamic chain, length 1 - * ecommunity: dynamic 2-part - * aspath: points to interned hash from aspath hash table - */ - - /* stuff nexthop in attr_extra; which field depends on IPv4 or IPv6 */ - switch (nexthop->addr_family) - { - case AF_INET: - /* - * set this field to prevent bgp_route.c code from setting - * mp_nexthop_global_in to self - */ - attr.nexthop.s_addr = nexthop->addr.v4.s_addr; - - attr.mp_nexthop_global_in = nexthop->addr.v4; - attr.mp_nexthop_len = 4; - break; - - case AF_INET6: - attr.mp_nexthop_global = nexthop->addr.v6; - attr.mp_nexthop_len = 16; - break; - - default: - assert (0); - } - - - prefix2str (p, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ - - /* - * At this point: - * - * attr: static - * extra: dynamically allocated, owned by attr - * vnc_subtlvs: dynamic chain, length 1 - * ecommunity: dynamic 2-part - * aspath: points to interned hash from aspath hash table - */ - - red = bgp_redist_lookup(bgp, afi, type, VRF_DEFAULT); - - if (red && red->redist_metric_flag) - { - attr.med = red->redist_metric; - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); - } - - bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); - - /* - * bgp_attr_intern creates a new reference to a cached - * attribute, but leaves the following bits of trash: - * - old attr - * - old attr->extra (free via bgp_attr_extra_free(attr)) - * - * Note that it frees the original attr->extra->ecommunity - * but leaves the new attribute pointing to the ORIGINAL - * vnc options (which therefore we needn't free from the - * static attr) - */ - new_attr = bgp_attr_intern (&attr); - - aspath_unintern (&attr.aspath); /* Unintern original. */ - - /* - * At this point: - * - * attr: static - * extra: dynamically allocated, owned by attr - * vnc_subtlvs: dynamic chain, length 1 - * ecommunity: POINTS TO INTERNED ecom, THIS REF NOT COUNTED - * - * new_attr: an attr that is part of the hash table, distinct - * from attr which is static. - * extra: dynamically allocated, owned by new_attr (in hash table) - * vnc_subtlvs: POINTS TO SAME dynamic chain AS attr - * ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr - * aspath: POINTS TO interned/refcounted hashed block - */ - for (bi = bn->info; bi; bi = bi->next) - { - /* probably only need to check bi->extra->vnc.export.rfapi_handle */ - if (bi->peer == rfd->peer && - bi->type == type && - bi->sub_type == sub_type && - bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd) - { - - break; - } - } - - if (bi) - { - - /* - * Adding new local_nexthop, which does not by itself change - * what is advertised via BGP - */ - if (lnh) - { - if (!bi->extra->vnc.export.local_nexthops) - { - /* TBD make arrangements to free when needed */ - bi->extra->vnc.export.local_nexthops = list_new (); - bi->extra->vnc.export.local_nexthops->del = rfapi_nexthop_free; - } - - /* - * already present? - */ - struct listnode *node; - struct rfapi_nexthop *pLnh = NULL; - - for (ALL_LIST_ELEMENTS_RO (bi->extra->vnc.export.local_nexthops, - node, pLnh)) - { - - if (prefix_same (&pLnh->addr, &lnh->addr)) - { - break; - } - } - - /* - * Not present, add new one - */ - if (!pLnh) - { - pLnh = rfapi_nexthop_new (lnh); - listnode_add (bi->extra->vnc.export.local_nexthops, pLnh); - } - } - - if (attrhash_cmp (bi->attr, new_attr) && - !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - { - bgp_attr_unintern (&new_attr); - bgp_unlock_node (bn); - - vnc_zlog_debug_any ("%s: Found route (safi=%d) at prefix %s, no change", - __func__, safi, buf); - - goto done; - } - else - { - /* The attribute is changed. */ - bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED); - - if (safi == SAFI_MPLS_VPN) - { - struct bgp_node *prn = NULL; - struct bgp_table *table = NULL; - - prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd); - if (prn->info) - { - table = (struct bgp_table *) (prn->info); - - vnc_import_bgp_del_vnc_host_route_mode_resolve_nve ( - bgp, prd, table, p, bi); - } - bgp_unlock_node (prn); - } - - /* Rewrite BGP route information. */ - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - bgp_info_restore (bn, bi); - else - bgp_aggregate_decrement (bgp, p, bi, afi, safi); - bgp_attr_unintern (&bi->attr); - bi->attr = new_attr; - bi->uptime = bgp_clock (); - - - if (safi == SAFI_MPLS_VPN) - { - struct bgp_node *prn = NULL; - struct bgp_table *table = NULL; - - prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd); - if (prn->info) - { - table = (struct bgp_table *) (prn->info); - - vnc_import_bgp_add_vnc_host_route_mode_resolve_nve ( - bgp, prd, table, p, bi); - } - bgp_unlock_node (prn); - } - - /* Process change. */ - bgp_aggregate_increment (bgp, p, bi, afi, safi); - bgp_process (bgp, bn, afi, safi); - bgp_unlock_node (bn); - - vnc_zlog_debug_any ("%s: Found route (safi=%d) at prefix %s, changed attr", - __func__, safi, buf); - - goto done; - } - } - - - new = bgp_info_new (); - new->type = type; - new->sub_type = sub_type; - new->peer = rfd->peer; - SET_FLAG (new->flags, BGP_INFO_VALID); - new->attr = new_attr; - new->uptime = bgp_clock (); - - /* save backref to rfapi handle */ - assert (bgp_info_extra_get (new)); - new->extra->vnc.export.rfapi_handle = (void *) rfd; - encode_label (label_val, &new->extra->label); - - /* debug */ - - if (VNC_DEBUG(VERBOSE)) - { - vnc_zlog_debug_verbose ("%s: printing BI", __func__); - rfapiPrintBi (NULL, new); - } - - bgp_aggregate_increment (bgp, p, new, afi, safi); - bgp_info_add (bn, new); - - if (safi == SAFI_MPLS_VPN) - { - struct bgp_node *prn = NULL; - struct bgp_table *table = NULL; - - prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd); - if (prn->info) - { - table = (struct bgp_table *) (prn->info); - - vnc_import_bgp_add_vnc_host_route_mode_resolve_nve ( - bgp, prd, table, p, new); - } - bgp_unlock_node (prn); - encode_label (label_val, &bn->local_label); - } - - bgp_unlock_node (bn); - bgp_process (bgp, bn, afi, safi); - - vnc_zlog_debug_any ("%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%s)", - __func__, safi2str (safi), buf, bn, buf2); + for (vo = options_vn; vo; vo = vo->next) { + if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) { + l2o = &vo->v.l2addr; + if (RFAPI_0_ETHERADDR(&l2o->macaddr)) + l2o = NULL; /* not MAC resolution */ + } + if (RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP == vo->type) { + lnh = &vo->v.local_nexthop; + } + } + + if (label) + label_val = *label; + else + label_val = MPLS_LABEL_IMPLICIT_NULL; + + prefix_rd2str(prd, buf2, BUFSIZ); + buf2[BUFSIZ - 1] = 0; + + + afi = family2afi(p->family); + assert(afi == AFI_IP || afi == AFI_IP6); + + vnc_zlog_debug_verbose("%s: afi=%s, safi=%s", __func__, afi2str(afi), + safi2str(safi)); + + /* Make default attribute. Produces already-interned attr.aspath */ + /* Cripes, the memory management of attributes is byzantine */ + + bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); + + /* + * At this point: + * attr: static + * extra: dynamically allocated, owned by attr + * aspath: points to interned hash from aspath hash table + */ + + + /* + * Route-specific un_options get added to the VPN SAFI + * advertisement tunnel encap attribute. (the per-NVE + * "default" un_options are put into the 1-per-NVE ENCAP + * SAFI advertisement). The VPN SAFI also gets the + * default un_options if there are no route-specific options. + */ + if (options_un) { + struct rfapi_un_option *uo; + + for (uo = options_un; uo; uo = uo->next) { + if (RFAPI_UN_OPTION_TYPE_TUNNELTYPE == uo->type) { + TunnelType = rfapi_tunneltype_option_to_tlv( + bgp, un_addr, &uo->v.tunnel, &attr, + l2o != NULL); + } + } + } else { + /* + * Add encap attr + * These are the NVE-specific "default" un_options which are + * put into the 1-per-NVE ENCAP advertisement. + */ + if (rfd->default_tunneltype_option.type) { + TunnelType = rfapi_tunneltype_option_to_tlv( + bgp, un_addr, &rfd->default_tunneltype_option, + &attr, l2o != NULL); + } else /* create default for local addse */ + if (type == ZEBRA_ROUTE_BGP + && sub_type == BGP_ROUTE_RFP) + TunnelType = rfapi_tunneltype_option_to_tlv( + bgp, un_addr, NULL, &attr, l2o != NULL); + } + + if (TunnelType == BGP_ENCAP_TYPE_MPLS) { + if (safi == SAFI_ENCAP) { + /* Encap SAFI not used with MPLS */ + vnc_zlog_debug_verbose( + "%s: mpls tunnel type, encap safi omitted", + __func__); + aspath_unintern(&attr.aspath); /* Unintern original. */ + return; + } + } + + if (local_pref) { + attr.local_pref = *local_pref; + attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); + } + + if (med) { + attr.med = *med; + attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); + } + + /* override default weight assigned by bgp_attr_default_set() */ + attr.weight = rfd->peer ? rfd->peer->weight[afi][safi] : 0; + + /* + * NB: ticket 81: do not reset attr.aspath here because it would + * cause iBGP peers to drop route + */ + + /* + * Set originator ID for routes imported from BGP directly. + * These routes could be synthetic, and therefore could + * reuse the peer pointers of the routes they are derived + * from. Setting the originator ID to "us" prevents the + * wrong originator ID from being sent when this route is + * sent from a route reflector. + */ + if (type == ZEBRA_ROUTE_BGP_DIRECT + || type == ZEBRA_ROUTE_BGP_DIRECT_EXT) { + attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID); + attr.originator_id = bgp->router_id; + } + + + /* Set up vnc attribute (sub-tlv for Prefix Lifetime) */ + if (lifetime && *lifetime != RFAPI_INFINITE_LIFETIME) { + uint32_t lt; + + encaptlv = + XCALLOC(MTYPE_ENCAP_TLV, + sizeof(struct bgp_attr_encap_subtlv) - 1 + 4); + assert(encaptlv); + encaptlv->type = + BGP_VNC_SUBTLV_TYPE_LIFETIME; /* prefix lifetime */ + encaptlv->length = 4; + lt = htonl(*lifetime); + memcpy(encaptlv->value, <, 4); + attr.vnc_subtlvs = encaptlv; + vnc_zlog_debug_verbose( + "%s: set Encap Attr Prefix Lifetime to %d", __func__, + *lifetime); + } + + /* add rfp options to vnc attr */ + if (rfp_options) { + + if (flags & RFAPI_AHR_RFPOPT_IS_VNCTLV) { + + /* + * this flag means we're passing a pointer to an + * existing encap tlv chain which we should copy. + * It's a hack to avoid adding yet another argument + * to add_vnc_route() + */ + encaptlv = encap_tlv_dup( + (struct bgp_attr_encap_subtlv *)rfp_options); + if (attr.vnc_subtlvs) { + attr.vnc_subtlvs->next = encaptlv; + } else { + attr.vnc_subtlvs = encaptlv; + } + + } else { + struct bgp_tea_options *hop; + /* XXX max of one tlv present so far from above code */ + struct bgp_attr_encap_subtlv *tail = attr.vnc_subtlvs; + + for (hop = rfp_options; hop; hop = hop->next) { + + /* + * Construct subtlv + */ + encaptlv = XCALLOC( + MTYPE_ENCAP_TLV, + sizeof(struct bgp_attr_encap_subtlv) - 1 + + 2 + hop->length); + assert(encaptlv); + encaptlv->type = + BGP_VNC_SUBTLV_TYPE_RFPOPTION; /* RFP + option + */ + encaptlv->length = 2 + hop->length; + *((uint8_t *)(encaptlv->value) + 0) = hop->type; + *((uint8_t *)(encaptlv->value) + 1) = + hop->length; + memcpy(((uint8_t *)encaptlv->value) + 2, + hop->value, hop->length); + + /* + * add to end of subtlv chain + */ + if (tail) { + tail->next = encaptlv; + } else { + attr.vnc_subtlvs = encaptlv; + } + tail = encaptlv; + } + } + } + + /* + * At this point: + * attr: static + * extra: dynamically allocated, owned by attr + * vnc_subtlvs: dynamic chain, length 1 + * aspath: points to interned hash from aspath hash table + */ + + + attr.ecommunity = ecommunity_new(); + assert(attr.ecommunity); + + if (TunnelType != BGP_ENCAP_TYPE_MPLS + && TunnelType != BGP_ENCAP_TYPE_RESERVED) { + /* + * Add BGP Encapsulation Extended Community. Format described in + * section 4.5 of RFC 5512. + * Always include when not MPLS type, to disambiguate this case. + */ + struct ecommunity_val beec; + + memset(&beec, 0, sizeof(beec)); + beec.val[0] = ECOMMUNITY_ENCODE_OPAQUE; + beec.val[1] = ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP; + beec.val[6] = ((TunnelType) >> 8) & 0xff; + beec.val[7] = (TunnelType)&0xff; + ecommunity_add_val(attr.ecommunity, &beec); + } + + /* + * Add extended community attributes to match rt export list + */ + if (rt_export_list) { + attr.ecommunity = + ecommunity_merge(attr.ecommunity, rt_export_list); + } + + if (attr.ecommunity->size) { + attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); + } else { + ecommunity_free(&attr.ecommunity); + attr.ecommunity = NULL; + } + vnc_zlog_debug_verbose("%s: attr.ecommunity=%p", __func__, + attr.ecommunity); + + + /* + * At this point: + * attr: static + * extra: dynamically allocated, owned by attr + * vnc_subtlvs: dynamic chain, length 1 + * ecommunity: dynamic 2-part + * aspath: points to interned hash from aspath hash table + */ + + /* stuff nexthop in attr_extra; which field depends on IPv4 or IPv6 */ + switch (nexthop->addr_family) { + case AF_INET: + /* + * set this field to prevent bgp_route.c code from setting + * mp_nexthop_global_in to self + */ + attr.nexthop.s_addr = nexthop->addr.v4.s_addr; + + attr.mp_nexthop_global_in = nexthop->addr.v4; + attr.mp_nexthop_len = 4; + break; + + case AF_INET6: + attr.mp_nexthop_global = nexthop->addr.v6; + attr.mp_nexthop_len = 16; + break; + + default: + assert(0); + } + + + prefix2str(p, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + + /* + * At this point: + * + * attr: static + * extra: dynamically allocated, owned by attr + * vnc_subtlvs: dynamic chain, length 1 + * ecommunity: dynamic 2-part + * aspath: points to interned hash from aspath hash table + */ + + red = bgp_redist_lookup(bgp, afi, type, VRF_DEFAULT); + + if (red && red->redist_metric_flag) { + attr.med = red->redist_metric; + attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); + } + + bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); + + /* + * bgp_attr_intern creates a new reference to a cached + * attribute, but leaves the following bits of trash: + * - old attr + * - old attr->extra (free via bgp_attr_extra_free(attr)) + * + * Note that it frees the original attr->extra->ecommunity + * but leaves the new attribute pointing to the ORIGINAL + * vnc options (which therefore we needn't free from the + * static attr) + */ + new_attr = bgp_attr_intern(&attr); + + aspath_unintern(&attr.aspath); /* Unintern original. */ + + /* + * At this point: + * + * attr: static + * extra: dynamically allocated, owned by attr + * vnc_subtlvs: dynamic chain, length 1 + * ecommunity: POINTS TO INTERNED ecom, THIS REF NOT COUNTED + * + * new_attr: an attr that is part of the hash table, distinct + * from attr which is static. + * extra: dynamically allocated, owned by new_attr (in hash table) + * vnc_subtlvs: POINTS TO SAME dynamic chain AS attr + * ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr + * aspath: POINTS TO interned/refcounted hashed block + */ + for (bi = bn->info; bi; bi = bi->next) { + /* probably only need to check + * bi->extra->vnc.export.rfapi_handle */ + if (bi->peer == rfd->peer && bi->type == type + && bi->sub_type == sub_type && bi->extra + && bi->extra->vnc.export.rfapi_handle == (void *)rfd) { + + break; + } + } + + if (bi) { + + /* + * Adding new local_nexthop, which does not by itself change + * what is advertised via BGP + */ + if (lnh) { + if (!bi->extra->vnc.export.local_nexthops) { + /* TBD make arrangements to free when needed */ + bi->extra->vnc.export.local_nexthops = + list_new(); + bi->extra->vnc.export.local_nexthops->del = + rfapi_nexthop_free; + } + + /* + * already present? + */ + struct listnode *node; + struct rfapi_nexthop *pLnh = NULL; + + for (ALL_LIST_ELEMENTS_RO( + bi->extra->vnc.export.local_nexthops, node, + pLnh)) { + + if (prefix_same(&pLnh->addr, &lnh->addr)) { + break; + } + } + + /* + * Not present, add new one + */ + if (!pLnh) { + pLnh = rfapi_nexthop_new(lnh); + listnode_add( + bi->extra->vnc.export.local_nexthops, + pLnh); + } + } + + if (attrhash_cmp(bi->attr, new_attr) + && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { + bgp_attr_unintern(&new_attr); + bgp_unlock_node(bn); + + vnc_zlog_debug_any( + "%s: Found route (safi=%d) at prefix %s, no change", + __func__, safi, buf); + + goto done; + } else { + /* The attribute is changed. */ + bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED); + + if (safi == SAFI_MPLS_VPN) { + struct bgp_node *prn = NULL; + struct bgp_table *table = NULL; + + prn = bgp_node_get(bgp->rib[afi][safi], + (struct prefix *)prd); + if (prn->info) { + table = (struct bgp_table *)(prn->info); + + vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( + bgp, prd, table, p, bi); + } + bgp_unlock_node(prn); + } + + /* Rewrite BGP route information. */ + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + bgp_info_restore(bn, bi); + else + bgp_aggregate_decrement(bgp, p, bi, afi, safi); + bgp_attr_unintern(&bi->attr); + bi->attr = new_attr; + bi->uptime = bgp_clock(); + + + if (safi == SAFI_MPLS_VPN) { + struct bgp_node *prn = NULL; + struct bgp_table *table = NULL; + + prn = bgp_node_get(bgp->rib[afi][safi], + (struct prefix *)prd); + if (prn->info) { + table = (struct bgp_table *)(prn->info); + + vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( + bgp, prd, table, p, bi); + } + bgp_unlock_node(prn); + } + + /* Process change. */ + bgp_aggregate_increment(bgp, p, bi, afi, safi); + bgp_process(bgp, bn, afi, safi); + bgp_unlock_node(bn); + + vnc_zlog_debug_any( + "%s: Found route (safi=%d) at prefix %s, changed attr", + __func__, safi, buf); + + goto done; + } + } + + + new = bgp_info_new(); + new->type = type; + new->sub_type = sub_type; + new->peer = rfd->peer; + SET_FLAG(new->flags, BGP_INFO_VALID); + new->attr = new_attr; + new->uptime = bgp_clock(); + + /* save backref to rfapi handle */ + assert(bgp_info_extra_get(new)); + new->extra->vnc.export.rfapi_handle = (void *)rfd; + encode_label(label_val, &new->extra->label); + + /* debug */ + + if (VNC_DEBUG(VERBOSE)) { + vnc_zlog_debug_verbose("%s: printing BI", __func__); + rfapiPrintBi(NULL, new); + } + + bgp_aggregate_increment(bgp, p, new, afi, safi); + bgp_info_add(bn, new); + + if (safi == SAFI_MPLS_VPN) { + struct bgp_node *prn = NULL; + struct bgp_table *table = NULL; + + prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd); + if (prn->info) { + table = (struct bgp_table *)(prn->info); + + vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( + bgp, prd, table, p, new); + } + bgp_unlock_node(prn); + encode_label(label_val, &bn->local_label); + } + + bgp_unlock_node(bn); + bgp_process(bgp, bn, afi, safi); + + vnc_zlog_debug_any( + "%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%s)", + __func__, safi2str(safi), buf, bn, buf2); done: - /* Loop back to import tables */ - rfapiProcessUpdate (rfd->peer, - rfd, - p, prd, new_attr, afi, safi, type, sub_type, &label_val); - vnc_zlog_debug_verbose ("%s: looped back import route (safi=%d)", __func__, safi); + /* Loop back to import tables */ + rfapiProcessUpdate(rfd->peer, rfd, p, prd, new_attr, afi, safi, type, + sub_type, &label_val); + vnc_zlog_debug_verbose("%s: looped back import route (safi=%d)", + __func__, safi); } -uint32_t -rfp_cost_to_localpref (uint8_t cost) +uint32_t rfp_cost_to_localpref(uint8_t cost) { - return 255 - cost; + return 255 - cost; } -static void -rfapiTunnelRouteAnnounce ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - uint32_t *pLifetime) +static void rfapiTunnelRouteAnnounce(struct bgp *bgp, + struct rfapi_descriptor *rfd, + uint32_t *pLifetime) { - struct prefix_rd prd; - struct prefix pfx_vn; - int rc; - uint32_t local_pref = rfp_cost_to_localpref (0); - - rc = rfapiRaddr2Qprefix (&(rfd->vn_addr), &pfx_vn); - assert (!rc); - - /* - * Construct route distinguisher = 0 - */ - memset (&prd, 0, sizeof (prd)); - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - add_vnc_route (rfd, /* rfapi descr, for export list & backref */ - bgp, /* which bgp instance */ - SAFI_ENCAP, /* which SAFI */ - &pfx_vn, /* prefix to advertise */ - &prd, /* route distinguisher to use */ - &rfd->un_addr, /* nexthop */ - &local_pref, - pLifetime, /* max lifetime of child VPN routes */ - NULL, /* no rfp options for ENCAP safi */ - NULL, /* rfp un options */ - NULL, /* rfp vn options */ - rfd->rt_export_list, - NULL, /* med */ - NULL, /* label: default */ - ZEBRA_ROUTE_BGP, - BGP_ROUTE_RFP, - 0); + struct prefix_rd prd; + struct prefix pfx_vn; + int rc; + uint32_t local_pref = rfp_cost_to_localpref(0); + + rc = rfapiRaddr2Qprefix(&(rfd->vn_addr), &pfx_vn); + assert(!rc); + + /* + * Construct route distinguisher = 0 + */ + memset(&prd, 0, sizeof(prd)); + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + add_vnc_route(rfd, /* rfapi descr, for export list & backref */ + bgp, /* which bgp instance */ + SAFI_ENCAP, /* which SAFI */ + &pfx_vn, /* prefix to advertise */ + &prd, /* route distinguisher to use */ + &rfd->un_addr, /* nexthop */ + &local_pref, + pLifetime, /* max lifetime of child VPN routes */ + NULL, /* no rfp options for ENCAP safi */ + NULL, /* rfp un options */ + NULL, /* rfp vn options */ + rfd->rt_export_list, NULL, /* med */ + NULL, /* label: default */ + ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); } @@ -1265,88 +1177,84 @@ rfapiTunnelRouteAnnounce ( /*------------------------------------------ * rfapi_rfp_set_configuration * - * This is used to change rfapi's processing behavior based on - * RFP requirements. + * This is used to change rfapi's processing behavior based on + * RFP requirements. * - * input: + * input: * rfp_start_val value returned by rfp_start * rfapi_rfp_cfg Pointer to configuration structure * * output: * none * - * return value: + * return value: * 0 Success * ENXIO Unabled to locate configured BGP/VNC --------------------------------------------*/ -int -rfapi_rfp_set_configuration (void *rfp_start_val, struct rfapi_rfp_cfg *new) +int rfapi_rfp_set_configuration(void *rfp_start_val, struct rfapi_rfp_cfg *new) { - struct rfapi_rfp_cfg *rcfg; - struct bgp *bgp; - - bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - - if (!new || !bgp || !bgp->rfapi_cfg) - return ENXIO; - - rcfg = &bgp->rfapi_cfg->rfp_cfg; - rcfg->download_type = new->download_type; - rcfg->ftd_advertisement_interval = new->ftd_advertisement_interval; - rcfg->holddown_factor = new->holddown_factor; - - if (rcfg->use_updated_response != new->use_updated_response) - { - rcfg->use_updated_response = new->use_updated_response; - if (rcfg->use_updated_response) - rfapiMonitorCallbacksOn (bgp); - else - rfapiMonitorCallbacksOff (bgp); - } - if (rcfg->use_removes != new->use_removes) - { - rcfg->use_removes = new->use_removes; - if (rcfg->use_removes) - rfapiMonitorResponseRemovalOn (bgp); - else - rfapiMonitorResponseRemovalOff (bgp); - } - return 0; + struct rfapi_rfp_cfg *rcfg; + struct bgp *bgp; + + bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + + if (!new || !bgp || !bgp->rfapi_cfg) + return ENXIO; + + rcfg = &bgp->rfapi_cfg->rfp_cfg; + rcfg->download_type = new->download_type; + rcfg->ftd_advertisement_interval = new->ftd_advertisement_interval; + rcfg->holddown_factor = new->holddown_factor; + + if (rcfg->use_updated_response != new->use_updated_response) { + rcfg->use_updated_response = new->use_updated_response; + if (rcfg->use_updated_response) + rfapiMonitorCallbacksOn(bgp); + else + rfapiMonitorCallbacksOff(bgp); + } + if (rcfg->use_removes != new->use_removes) { + rcfg->use_removes = new->use_removes; + if (rcfg->use_removes) + rfapiMonitorResponseRemovalOn(bgp); + else + rfapiMonitorResponseRemovalOff(bgp); + } + return 0; } /*------------------------------------------ * rfapi_rfp_set_cb_methods * - * Change registered callback functions for asynchronous notifications + * Change registered callback functions for asynchronous notifications * from RFAPI to the RFP client. * - * input: + * input: * rfp_start_val value returned by rfp_start * methods Pointer to struct rfapi_rfp_cb_methods containing * pointers to callback methods as described above * - * return value: + * return value: * 0 Success * ENXIO BGP or VNC not configured *------------------------------------------*/ -int -rfapi_rfp_set_cb_methods (void *rfp_start_val, - struct rfapi_rfp_cb_methods *methods) +int rfapi_rfp_set_cb_methods(void *rfp_start_val, + struct rfapi_rfp_cb_methods *methods) { - struct rfapi *h; - struct bgp *bgp; + struct rfapi *h; + struct bgp *bgp; - bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - if (!bgp) - return ENXIO; + bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + if (!bgp) + return ENXIO; - h = bgp->rfapi; - if (!h) - return ENXIO; + h = bgp->rfapi; + if (!h) + return ENXIO; - h->rfp_methods = *methods; + h->rfp_methods = *methods; - return 0; + return 0; } /*********************************************************************** @@ -1358,570 +1266,520 @@ rfapi_rfp_set_cb_methods (void *rfp_start_val, * The advertised_prefixes[] array elements should be NULL to * have this function set them to newly-allocated radix trees. */ -static int -rfapi_open_inner ( - struct rfapi_descriptor *rfd, - struct bgp *bgp, - struct rfapi *h, - struct rfapi_nve_group_cfg *rfg) +static int rfapi_open_inner(struct rfapi_descriptor *rfd, struct bgp *bgp, + struct rfapi *h, struct rfapi_nve_group_cfg *rfg) { - int ret; - - if (h->flags & RFAPI_INCALLBACK) - return EDEADLK; + int ret; + + if (h->flags & RFAPI_INCALLBACK) + return EDEADLK; + + /* + * Fill in configured fields + */ + + /* + * If group's RD is specified as "auto", then fill in based + * on NVE's VN address + */ + rfd->rd = rfg->rd; + + if (rfd->rd.family == AF_UNIX) { + ret = rfapi_set_autord_from_vn(&rfd->rd, &rfd->vn_addr); + if (ret != 0) + return ret; + } + rfd->rt_export_list = (rfg->rt_export_list) + ? ecommunity_dup(rfg->rt_export_list) + : NULL; + rfd->response_lifetime = rfg->response_lifetime; + rfd->rfg = rfg; + + /* + * Fill in BGP peer structure + */ + rfd->peer = peer_new(bgp); + rfd->peer->status = Established; /* keep bgp core happy */ + bgp_sync_delete(rfd->peer); /* don't need these */ + if (rfd->peer->ibuf) { + stream_free(rfd->peer->ibuf); /* don't need it */ + rfd->peer->ibuf = NULL; + } + if (rfd->peer->obuf) { + stream_fifo_free(rfd->peer->obuf); /* don't need it */ + rfd->peer->obuf = NULL; + } + if (rfd->peer->work) { + stream_free(rfd->peer->work); /* don't need it */ + rfd->peer->work = NULL; + } + { /* base code assumes have valid host pointer */ + char buf[BUFSIZ]; + buf[0] = 0; + + if (rfd->vn_addr.addr_family == AF_INET) { + inet_ntop(AF_INET, &rfd->vn_addr.addr.v4, buf, BUFSIZ); + } else if (rfd->vn_addr.addr_family == AF_INET6) { + inet_ntop(AF_INET6, &rfd->vn_addr.addr.v6, buf, BUFSIZ); + } + rfd->peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, buf); + } + /* Mark peer as belonging to HD */ + SET_FLAG(rfd->peer->flags, PEER_FLAG_IS_RFAPI_HD); + + /* + * Set min prefix lifetime to max value so it will get set + * upon first rfapi_register() + */ + rfd->min_prefix_lifetime = UINT32_MAX; - /* - * Fill in configured fields - */ - - /* - * If group's RD is specified as "auto", then fill in based - * on NVE's VN address - */ - rfd->rd = rfg->rd; - - if (rfd->rd.family == AF_UNIX) - { - ret = rfapi_set_autord_from_vn (&rfd->rd, &rfd->vn_addr); - if (ret != 0) - return ret; - } - rfd->rt_export_list = (rfg->rt_export_list) ? - ecommunity_dup (rfg->rt_export_list) : NULL; - rfd->response_lifetime = rfg->response_lifetime; - rfd->rfg = rfg; - - /* - * Fill in BGP peer structure - */ - rfd->peer = peer_new (bgp); - rfd->peer->status = Established; /* keep bgp core happy */ - bgp_sync_delete (rfd->peer); /* don't need these */ - if (rfd->peer->ibuf) - { - stream_free (rfd->peer->ibuf); /* don't need it */ - rfd->peer->ibuf = NULL; - } - if (rfd->peer->obuf) - { - stream_fifo_free (rfd->peer->obuf); /* don't need it */ - rfd->peer->obuf = NULL; - } - if (rfd->peer->work) - { - stream_free (rfd->peer->work); /* don't need it */ - rfd->peer->work = NULL; - } - { /* base code assumes have valid host pointer */ - char buf[BUFSIZ]; - buf[0] = 0; - - if (rfd->vn_addr.addr_family == AF_INET) - { - inet_ntop (AF_INET, &rfd->vn_addr.addr.v4, buf, BUFSIZ); - } - else if (rfd->vn_addr.addr_family == AF_INET6) - { - inet_ntop (AF_INET6, &rfd->vn_addr.addr.v6, buf, BUFSIZ); - } - rfd->peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf); - } - /* Mark peer as belonging to HD */ - SET_FLAG (rfd->peer->flags, PEER_FLAG_IS_RFAPI_HD); - - /* - * Set min prefix lifetime to max value so it will get set - * upon first rfapi_register() - */ - rfd->min_prefix_lifetime = UINT32_MAX; - - /* - * Allocate response tables if needed - */ -#define RFD_RTINIT_AFI(rh, ary, afi) do {\ - if (!ary[afi]) { \ - ary[afi] = route_table_init ();\ - ary[afi]->info = rh;\ - }\ -} while (0) - -#define RFD_RTINIT(rh, ary) do {\ - RFD_RTINIT_AFI(rh, ary, AFI_IP);\ - RFD_RTINIT_AFI(rh, ary, AFI_IP6);\ - RFD_RTINIT_AFI(rh, ary, AFI_L2VPN);\ -} while(0) - - RFD_RTINIT(rfd, rfd->rib); - RFD_RTINIT(rfd, rfd->rib_pending); - RFD_RTINIT(rfd, rfd->rsp_times); - - /* - * Link to Import Table - */ - rfd->import_table = rfg->rfapi_import_table; - rfd->import_table->refcount += 1; - - rfapiApInit (&rfd->advertised); - - /* - * add this NVE descriptor to the list of NVEs in the NVE group - */ - if (!rfg->nves) - { - rfg->nves = list_new (); - } - listnode_add (rfg->nves, rfd); - - vnc_direct_bgp_add_nve (bgp, rfd); - vnc_zebra_add_nve (bgp, rfd); - - return 0; +/* + * Allocate response tables if needed + */ +#define RFD_RTINIT_AFI(rh, ary, afi) \ + do { \ + if (!ary[afi]) { \ + ary[afi] = route_table_init(); \ + ary[afi]->info = rh; \ + } \ + } while (0) + +#define RFD_RTINIT(rh, ary) \ + do { \ + RFD_RTINIT_AFI(rh, ary, AFI_IP); \ + RFD_RTINIT_AFI(rh, ary, AFI_IP6); \ + RFD_RTINIT_AFI(rh, ary, AFI_L2VPN); \ + } while (0) + + RFD_RTINIT(rfd, rfd->rib); + RFD_RTINIT(rfd, rfd->rib_pending); + RFD_RTINIT(rfd, rfd->rsp_times); + + /* + * Link to Import Table + */ + rfd->import_table = rfg->rfapi_import_table; + rfd->import_table->refcount += 1; + + rfapiApInit(&rfd->advertised); + + /* + * add this NVE descriptor to the list of NVEs in the NVE group + */ + if (!rfg->nves) { + rfg->nves = list_new(); + } + listnode_add(rfg->nves, rfd); + + vnc_direct_bgp_add_nve(bgp, rfd); + vnc_zebra_add_nve(bgp, rfd); + + return 0; } /* moved from rfapi_register */ -int -rfapi_init_and_open( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct rfapi_nve_group_cfg *rfg) +int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct rfapi_nve_group_cfg *rfg) { - struct rfapi *h = bgp->rfapi; - char buf_vn[BUFSIZ]; - char buf_un[BUFSIZ]; - afi_t afi_vn, afi_un; - struct prefix pfx_un; - struct route_node *rn; - - - rfapi_time (&rfd->open_time); - - if (rfg->type == RFAPI_GROUP_CFG_VRF) - SET_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF); - - rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ); - rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ); - - vnc_zlog_debug_verbose ("%s: new RFD with VN=%s UN=%s cookie=%p", - __func__, buf_vn, buf_un, rfd->cookie); - - if (rfg->type != RFAPI_GROUP_CFG_VRF) /* unclear if needed for VRF */ - { - listnode_add (&h->descriptors, rfd); - if (h->descriptors.count > h->stat.max_descriptors) - { - h->stat.max_descriptors = h->descriptors.count; - } - - /* - * attach to UN radix tree - */ - afi_vn = family2afi (rfd->vn_addr.addr_family); - afi_un = family2afi (rfd->un_addr.addr_family); - assert (afi_vn && afi_un); - assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx_un)); - - rn = route_node_get (&(h->un[afi_un]), &pfx_un); - assert (rn); - rfd->next = rn->info; - rn->info = rfd; - rfd->un_node = rn; - } - return rfapi_open_inner (rfd, bgp, h, rfg); + struct rfapi *h = bgp->rfapi; + char buf_vn[BUFSIZ]; + char buf_un[BUFSIZ]; + afi_t afi_vn, afi_un; + struct prefix pfx_un; + struct route_node *rn; + + + rfapi_time(&rfd->open_time); + + if (rfg->type == RFAPI_GROUP_CFG_VRF) + SET_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF); + + rfapiRfapiIpAddr2Str(&rfd->vn_addr, buf_vn, BUFSIZ); + rfapiRfapiIpAddr2Str(&rfd->un_addr, buf_un, BUFSIZ); + + vnc_zlog_debug_verbose("%s: new RFD with VN=%s UN=%s cookie=%p", + __func__, buf_vn, buf_un, rfd->cookie); + + if (rfg->type != RFAPI_GROUP_CFG_VRF) /* unclear if needed for VRF */ + { + listnode_add(&h->descriptors, rfd); + if (h->descriptors.count > h->stat.max_descriptors) { + h->stat.max_descriptors = h->descriptors.count; + } + + /* + * attach to UN radix tree + */ + afi_vn = family2afi(rfd->vn_addr.addr_family); + afi_un = family2afi(rfd->un_addr.addr_family); + assert(afi_vn && afi_un); + assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un)); + + rn = route_node_get(&(h->un[afi_un]), &pfx_un); + assert(rn); + rfd->next = rn->info; + rn->info = rfd; + rfd->un_node = rn; + } + return rfapi_open_inner(rfd, bgp, h, rfg); } -struct rfapi_vn_option * -rfapiVnOptionsDup (struct rfapi_vn_option *orig) +struct rfapi_vn_option *rfapiVnOptionsDup(struct rfapi_vn_option *orig) { - struct rfapi_vn_option *head = NULL; - struct rfapi_vn_option *tail = NULL; - struct rfapi_vn_option *vo = NULL; - - for (vo = orig; vo; vo = vo->next) - { - struct rfapi_vn_option *new; - - new = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); - memcpy (new, vo, sizeof (struct rfapi_vn_option)); - new->next = NULL; - - if (tail) - { - tail->next = new; - } - else - { - head = tail = new; - } - } - return head; + struct rfapi_vn_option *head = NULL; + struct rfapi_vn_option *tail = NULL; + struct rfapi_vn_option *vo = NULL; + + for (vo = orig; vo; vo = vo->next) { + struct rfapi_vn_option *new; + + new = XCALLOC(MTYPE_RFAPI_VN_OPTION, + sizeof(struct rfapi_vn_option)); + memcpy(new, vo, sizeof(struct rfapi_vn_option)); + new->next = NULL; + + if (tail) { + tail->next = new; + } else { + head = tail = new; + } + } + return head; } -struct rfapi_un_option * -rfapiUnOptionsDup (struct rfapi_un_option *orig) +struct rfapi_un_option *rfapiUnOptionsDup(struct rfapi_un_option *orig) { - struct rfapi_un_option *head = NULL; - struct rfapi_un_option *tail = NULL; - struct rfapi_un_option *uo = NULL; - - for (uo = orig; uo; uo = uo->next) - { - struct rfapi_un_option *new; - - new = XCALLOC (MTYPE_RFAPI_UN_OPTION, sizeof (struct rfapi_un_option)); - memcpy (new, uo, sizeof (struct rfapi_un_option)); - new->next = NULL; - - if (tail) - { - tail->next = new; - } - else - { - head = tail = new; - } - } - return head; + struct rfapi_un_option *head = NULL; + struct rfapi_un_option *tail = NULL; + struct rfapi_un_option *uo = NULL; + + for (uo = orig; uo; uo = uo->next) { + struct rfapi_un_option *new; + + new = XCALLOC(MTYPE_RFAPI_UN_OPTION, + sizeof(struct rfapi_un_option)); + memcpy(new, uo, sizeof(struct rfapi_un_option)); + new->next = NULL; + + if (tail) { + tail->next = new; + } else { + head = tail = new; + } + } + return head; } -struct bgp_tea_options * -rfapiOptionsDup (struct bgp_tea_options *orig) +struct bgp_tea_options *rfapiOptionsDup(struct bgp_tea_options *orig) { - struct bgp_tea_options *head = NULL; - struct bgp_tea_options *tail = NULL; - struct bgp_tea_options *hop = NULL; - - for (hop = orig; hop; hop = hop->next) - { - struct bgp_tea_options *new; - - new = XCALLOC (MTYPE_BGP_TEA_OPTIONS, sizeof (struct bgp_tea_options)); - memcpy (new, hop, sizeof (struct bgp_tea_options)); - new->next = NULL; - if (hop->value) - { - new->value = XCALLOC (MTYPE_BGP_TEA_OPTIONS_VALUE, hop->length); - memcpy (new->value, hop->value, hop->length); - } - if (tail) - { - tail->next = new; - } - else - { - head = tail = new; - } - } - return head; + struct bgp_tea_options *head = NULL; + struct bgp_tea_options *tail = NULL; + struct bgp_tea_options *hop = NULL; + + for (hop = orig; hop; hop = hop->next) { + struct bgp_tea_options *new; + + new = XCALLOC(MTYPE_BGP_TEA_OPTIONS, + sizeof(struct bgp_tea_options)); + memcpy(new, hop, sizeof(struct bgp_tea_options)); + new->next = NULL; + if (hop->value) { + new->value = XCALLOC(MTYPE_BGP_TEA_OPTIONS_VALUE, + hop->length); + memcpy(new->value, hop->value, hop->length); + } + if (tail) { + tail->next = new; + } else { + head = tail = new; + } + } + return head; } -void -rfapiFreeBgpTeaOptionChain (struct bgp_tea_options *p) +void rfapiFreeBgpTeaOptionChain(struct bgp_tea_options *p) { - struct bgp_tea_options *next; + struct bgp_tea_options *next; - while (p) - { - next = p->next; + while (p) { + next = p->next; - if (p->value) - { - XFREE (MTYPE_BGP_TEA_OPTIONS_VALUE, p->value); - p->value = NULL; - } - XFREE (MTYPE_BGP_TEA_OPTIONS, p); + if (p->value) { + XFREE(MTYPE_BGP_TEA_OPTIONS_VALUE, p->value); + p->value = NULL; + } + XFREE(MTYPE_BGP_TEA_OPTIONS, p); - p = next; - } + p = next; + } } -void -rfapiAdbFree (struct rfapi_adb *adb) +void rfapiAdbFree(struct rfapi_adb *adb) { - XFREE (MTYPE_RFAPI_ADB, adb); + XFREE(MTYPE_RFAPI_ADB, adb); } static int -rfapi_query_inner ( - void *handle, - struct rfapi_ip_addr *target, - struct rfapi_l2address_option *l2o, /* may be NULL */ - struct rfapi_next_hop_entry **ppNextHopEntry) +rfapi_query_inner(void *handle, struct rfapi_ip_addr *target, + struct rfapi_l2address_option *l2o, /* may be NULL */ + struct rfapi_next_hop_entry **ppNextHopEntry) { - afi_t afi; - struct prefix p; - struct prefix p_original; - struct route_node *rn; - struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; - struct bgp *bgp = rfd->bgp; - struct rfapi_next_hop_entry *pNHE = NULL; - struct rfapi_ip_addr *self_vn_addr = NULL; - int eth_is_0 = 0; - int use_eth_resolution = 0; - struct rfapi_next_hop_entry *i_nhe; - - /* preemptive */ - if (!bgp) - { - vnc_zlog_debug_verbose ("%s: No BGP instance, returning ENXIO", __func__); - return ENXIO; - } - if (!bgp->rfapi) - { - vnc_zlog_debug_verbose ("%s: No RFAPI instance, returning ENXIO", __func__); - return ENXIO; - } - if (bgp->rfapi->flags & RFAPI_INCALLBACK) - { - vnc_zlog_debug_verbose ("%s: Called during calback, returning EDEADLK", __func__); - return EDEADLK; - } - - if (!is_valid_rfd (rfd)) - { - vnc_zlog_debug_verbose ("%s: invalid handle, returning EBADF", __func__); - return EBADF; - } - - rfd->rsp_counter++; /* dedup: identify this generation */ - rfd->rsp_time = rfapi_time (NULL); /* response content dedup */ - rfd->ftd_last_allowed_time = - bgp_clock() - bgp->rfapi_cfg->rfp_cfg.ftd_advertisement_interval; - - if (l2o) - { - if (!memcmp (l2o->macaddr.octet, rfapi_ethaddr0.octet, ETHER_ADDR_LEN)) - { - eth_is_0 = 1; - } - /* per t/c Paul/Lou 151022 */ - if (!eth_is_0 || l2o->logical_net_id) - { - use_eth_resolution = 1; - } - } - - if (ppNextHopEntry) - *ppNextHopEntry = NULL; - - /* - * Save original target in prefix form. In case of L2-based queries, - * p_original will be modified to reflect the L2 target - */ - assert(!rfapiRaddr2Qprefix (target, &p_original)); - - if (bgp->rfapi_cfg->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL) - { - /* convert query to 0/0 when full-table download is enabled */ - memset ((char *) &p, 0, sizeof (p)); - p.family = target->addr_family; - } - else - { - p = p_original; - } - - { - char buf[BUFSIZ]; - char *s; - - prefix2str (&p, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ - vnc_zlog_debug_verbose ("%s(rfd=%p, target=%s, ppNextHop=%p)", - __func__, rfd, buf, ppNextHopEntry); - - s = ecommunity_ecom2str(rfd->import_table->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vnc_zlog_debug_verbose("%s rfd->import_table=%p, rfd->import_table->rt_import_list: %s", - __func__, rfd->import_table, s); XFREE (MTYPE_ECOMMUNITY_STR, s); - } - - afi = family2afi (p.family); - assert (afi); - - if (CHECK_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) - { - self_vn_addr = &rfd->vn_addr; - } - - if (use_eth_resolution) - { - uint32_t logical_net_id = l2o->logical_net_id; - struct ecommunity *l2com; - - /* - * fix up p_original to contain L2 address - */ - rfapiL2o2Qprefix (l2o, &p_original); - - l2com = - bgp_rfapi_get_ecommunity_by_lni_label (bgp, 1, logical_net_id, - l2o->label); - if (l2com) - { - uint8_t *v = l2com->val; - logical_net_id = (v[5] << 16) + (v[6] << 8) + (v[7]); - } - /* - * Ethernet/L2-based lookup - * - * Always returns IT node corresponding to route - */ - - if (RFAPI_RFP_DOWNLOAD_FULL == bgp->rfapi_cfg->rfp_cfg.download_type) - { - eth_is_0 = 1; - } - - rn = rfapiMonitorEthAdd (bgp, - rfd, - (eth_is_0 ? &rfapi_ethaddr0 : &l2o->macaddr), - logical_net_id); - - if (eth_is_0) - { - struct rfapi_ip_prefix rprefix; - - memset (&rprefix, 0, sizeof (rprefix)); - rprefix.prefix.addr_family = target->addr_family; - if (target->addr_family == AF_INET) - { - rprefix.length = 32; - } - else - { - rprefix.length = 128; - } - - pNHE = rfapiEthRouteTable2NextHopList (logical_net_id, &rprefix, - rfd->response_lifetime, self_vn_addr, rfd->rib[afi], &p_original); - goto done; - } - - } - else - { - - /* - * IP-based lookup - */ - - rn = rfapiMonitorAdd (bgp, rfd, &p); - - /* - * If target address is 0, this request is special: means to - * return ALL routes in the table - * - * Monitors for All-Routes queries get put on a special list, - * not in the VPN tree - */ - if (RFAPI_0_PREFIX (&p)) - { - - vnc_zlog_debug_verbose ("%s: 0-prefix", __func__); - - /* - * Generate nexthop list for caller - */ - pNHE = rfapiRouteTable2NextHopList ( - rfd->import_table->imported_vpn[afi], rfd->response_lifetime, - self_vn_addr, rfd->rib[afi], &p_original); - goto done; - } - - if (rn) - { - route_lock_node (rn); /* so we can unlock below */ - } - else - { - /* - * returns locked node. Don't unlock yet because the unlock - * might free it before we're done with it. This situation - * could occur when rfapiMonitorGetAttachNode() returns a - * newly-created default node. - */ - rn = rfapiMonitorGetAttachNode (rfd, &p); - } - } - - assert (rn); - if (!rn->info) - { - route_unlock_node (rn); - vnc_zlog_debug_verbose ("%s: VPN route not found, returning ENOENT", __func__); - return ENOENT; - } - - if (VNC_DEBUG(RFAPI_QUERY)) - { - rfapiShowImportTable (NULL, "query", rfd->import_table->imported_vpn[afi], - 1); - } - - if (use_eth_resolution) - { - - struct rfapi_ip_prefix rprefix; - - memset (&rprefix, 0, sizeof (rprefix)); - rprefix.prefix.addr_family = target->addr_family; - if (target->addr_family == AF_INET) - { - rprefix.length = 32; - } - else - { - rprefix.length = 128; - } - - pNHE = rfapiEthRouteNode2NextHopList (rn, &rprefix, - rfd->response_lifetime, self_vn_addr, rfd->rib[afi], &p_original); - - - } - else - { - /* - * Generate answer to query - */ - pNHE = rfapiRouteNode2NextHopList(rn, rfd->response_lifetime, - self_vn_addr, rfd->rib[afi], &p_original); - } - - route_unlock_node (rn); + afi_t afi; + struct prefix p; + struct prefix p_original; + struct route_node *rn; + struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; + struct bgp *bgp = rfd->bgp; + struct rfapi_next_hop_entry *pNHE = NULL; + struct rfapi_ip_addr *self_vn_addr = NULL; + int eth_is_0 = 0; + int use_eth_resolution = 0; + struct rfapi_next_hop_entry *i_nhe; + + /* preemptive */ + if (!bgp) { + vnc_zlog_debug_verbose("%s: No BGP instance, returning ENXIO", + __func__); + return ENXIO; + } + if (!bgp->rfapi) { + vnc_zlog_debug_verbose("%s: No RFAPI instance, returning ENXIO", + __func__); + return ENXIO; + } + if (bgp->rfapi->flags & RFAPI_INCALLBACK) { + vnc_zlog_debug_verbose( + "%s: Called during calback, returning EDEADLK", + __func__); + return EDEADLK; + } + + if (!is_valid_rfd(rfd)) { + vnc_zlog_debug_verbose("%s: invalid handle, returning EBADF", + __func__); + return EBADF; + } + + rfd->rsp_counter++; /* dedup: identify this generation */ + rfd->rsp_time = rfapi_time(NULL); /* response content dedup */ + rfd->ftd_last_allowed_time = + bgp_clock() + - bgp->rfapi_cfg->rfp_cfg.ftd_advertisement_interval; + + if (l2o) { + if (!memcmp(l2o->macaddr.octet, rfapi_ethaddr0.octet, + ETHER_ADDR_LEN)) { + eth_is_0 = 1; + } + /* per t/c Paul/Lou 151022 */ + if (!eth_is_0 || l2o->logical_net_id) { + use_eth_resolution = 1; + } + } + + if (ppNextHopEntry) + *ppNextHopEntry = NULL; + + /* + * Save original target in prefix form. In case of L2-based queries, + * p_original will be modified to reflect the L2 target + */ + assert(!rfapiRaddr2Qprefix(target, &p_original)); + + if (bgp->rfapi_cfg->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL) { + /* convert query to 0/0 when full-table download is enabled */ + memset((char *)&p, 0, sizeof(p)); + p.family = target->addr_family; + } else { + p = p_original; + } + + { + char buf[BUFSIZ]; + char *s; + + prefix2str(&p, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + vnc_zlog_debug_verbose("%s(rfd=%p, target=%s, ppNextHop=%p)", + __func__, rfd, buf, ppNextHopEntry); + + s = ecommunity_ecom2str(rfd->import_table->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vnc_zlog_debug_verbose( + "%s rfd->import_table=%p, rfd->import_table->rt_import_list: %s", + __func__, rfd->import_table, s); + XFREE(MTYPE_ECOMMUNITY_STR, s); + } + + afi = family2afi(p.family); + assert(afi); + + if (CHECK_FLAG(bgp->rfapi_cfg->flags, + BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) { + self_vn_addr = &rfd->vn_addr; + } + + if (use_eth_resolution) { + uint32_t logical_net_id = l2o->logical_net_id; + struct ecommunity *l2com; + + /* + * fix up p_original to contain L2 address + */ + rfapiL2o2Qprefix(l2o, &p_original); + + l2com = bgp_rfapi_get_ecommunity_by_lni_label( + bgp, 1, logical_net_id, l2o->label); + if (l2com) { + uint8_t *v = l2com->val; + logical_net_id = (v[5] << 16) + (v[6] << 8) + (v[7]); + } + /* + * Ethernet/L2-based lookup + * + * Always returns IT node corresponding to route + */ + + if (RFAPI_RFP_DOWNLOAD_FULL + == bgp->rfapi_cfg->rfp_cfg.download_type) { + eth_is_0 = 1; + } + + rn = rfapiMonitorEthAdd( + bgp, rfd, (eth_is_0 ? &rfapi_ethaddr0 : &l2o->macaddr), + logical_net_id); + + if (eth_is_0) { + struct rfapi_ip_prefix rprefix; + + memset(&rprefix, 0, sizeof(rprefix)); + rprefix.prefix.addr_family = target->addr_family; + if (target->addr_family == AF_INET) { + rprefix.length = 32; + } else { + rprefix.length = 128; + } + + pNHE = rfapiEthRouteTable2NextHopList( + logical_net_id, &rprefix, + rfd->response_lifetime, self_vn_addr, + rfd->rib[afi], &p_original); + goto done; + } + + } else { + + /* + * IP-based lookup + */ + + rn = rfapiMonitorAdd(bgp, rfd, &p); + + /* + * If target address is 0, this request is special: means to + * return ALL routes in the table + * + * Monitors for All-Routes queries get put on a special list, + * not in the VPN tree + */ + if (RFAPI_0_PREFIX(&p)) { + + vnc_zlog_debug_verbose("%s: 0-prefix", __func__); + + /* + * Generate nexthop list for caller + */ + pNHE = rfapiRouteTable2NextHopList( + rfd->import_table->imported_vpn[afi], + rfd->response_lifetime, self_vn_addr, + rfd->rib[afi], &p_original); + goto done; + } + + if (rn) { + route_lock_node(rn); /* so we can unlock below */ + } else { + /* + * returns locked node. Don't unlock yet because the + * unlock + * might free it before we're done with it. This + * situation + * could occur when rfapiMonitorGetAttachNode() returns + * a + * newly-created default node. + */ + rn = rfapiMonitorGetAttachNode(rfd, &p); + } + } + + assert(rn); + if (!rn->info) { + route_unlock_node(rn); + vnc_zlog_debug_verbose( + "%s: VPN route not found, returning ENOENT", __func__); + return ENOENT; + } + + if (VNC_DEBUG(RFAPI_QUERY)) { + rfapiShowImportTable(NULL, "query", + rfd->import_table->imported_vpn[afi], 1); + } + + if (use_eth_resolution) { + + struct rfapi_ip_prefix rprefix; + + memset(&rprefix, 0, sizeof(rprefix)); + rprefix.prefix.addr_family = target->addr_family; + if (target->addr_family == AF_INET) { + rprefix.length = 32; + } else { + rprefix.length = 128; + } + + pNHE = rfapiEthRouteNode2NextHopList( + rn, &rprefix, rfd->response_lifetime, self_vn_addr, + rfd->rib[afi], &p_original); + + + } else { + /* + * Generate answer to query + */ + pNHE = rfapiRouteNode2NextHopList(rn, rfd->response_lifetime, + self_vn_addr, rfd->rib[afi], + &p_original); + } + + route_unlock_node(rn); done: - if (ppNextHopEntry) - { - /* only count if caller gets it */ - ++bgp->rfapi->response_immediate_count; - } - - if (!pNHE) - { - vnc_zlog_debug_verbose ("%s: NO NHEs, returning ENOENT", __func__); - return ENOENT; - } - - /* - * count nexthops for statistics - */ - for (i_nhe = pNHE; i_nhe; i_nhe = i_nhe->next) - { - ++rfd->stat_count_nh_reachable; - } - - if (ppNextHopEntry) - { - *ppNextHopEntry = pNHE; - } - else - { - rfapi_free_next_hop_list (pNHE); - } - - vnc_zlog_debug_verbose ("%s: success", __func__); - return 0; + if (ppNextHopEntry) { + /* only count if caller gets it */ + ++bgp->rfapi->response_immediate_count; + } + + if (!pNHE) { + vnc_zlog_debug_verbose("%s: NO NHEs, returning ENOENT", + __func__); + return ENOENT; + } + + /* + * count nexthops for statistics + */ + for (i_nhe = pNHE; i_nhe; i_nhe = i_nhe->next) { + ++rfd->stat_count_nh_reachable; + } + + if (ppNextHopEntry) { + *ppNextHopEntry = pNHE; + } else { + rfapi_free_next_hop_list(pNHE); + } + + vnc_zlog_debug_verbose("%s: success", __func__); + return 0; } /* @@ -1929,68 +1787,63 @@ done: * nve-group in the event that its original nve-group is * administratively deleted. */ -static int -rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp) +static int rfapi_open_rfd(struct rfapi_descriptor *rfd, struct bgp *bgp) { - struct prefix pfx_vn; - struct prefix pfx_un; - struct rfapi_nve_group_cfg *rfg; - struct rfapi *h; - struct rfapi_cfg *hc; - int rc; - - h = bgp->rfapi; - if (!h) - return ENXIO; - - hc = bgp->rfapi_cfg; - if (!hc) - return ENXIO; - - rc = rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn); - assert (!rc); - - rc = rfapiRaddr2Qprefix (&rfd->un_addr, &pfx_un); - assert (!rc); - - /* - * Find the matching nve group config block - */ - rfg = bgp_rfapi_cfg_match_group (hc, &pfx_vn, &pfx_un); - if (!rfg) - { - return ENOENT; - } - - /* - * check nve group config block for required values - */ - if (!rfg->rt_export_list || !rfg->rfapi_import_table) - { - - return ENOMSG; - } - - rc = rfapi_open_inner (rfd, bgp, h, rfg); - if (rc) - { - return rc; - } - - /* - * re-advertise registered routes, this time as part of new NVE-group - */ - rfapiApReadvertiseAll (bgp, rfd); - - /* - * re-attach callbacks to import table - */ - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) - { - rfapiMonitorAttachImportHd (rfd); - } - - return 0; + struct prefix pfx_vn; + struct prefix pfx_un; + struct rfapi_nve_group_cfg *rfg; + struct rfapi *h; + struct rfapi_cfg *hc; + int rc; + + h = bgp->rfapi; + if (!h) + return ENXIO; + + hc = bgp->rfapi_cfg; + if (!hc) + return ENXIO; + + rc = rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn); + assert(!rc); + + rc = rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un); + assert(!rc); + + /* + * Find the matching nve group config block + */ + rfg = bgp_rfapi_cfg_match_group(hc, &pfx_vn, &pfx_un); + if (!rfg) { + return ENOENT; + } + + /* + * check nve group config block for required values + */ + if (!rfg->rt_export_list || !rfg->rfapi_import_table) { + + return ENOMSG; + } + + rc = rfapi_open_inner(rfd, bgp, h, rfg); + if (rc) { + return rc; + } + + /* + * re-advertise registered routes, this time as part of new NVE-group + */ + rfapiApReadvertiseAll(bgp, rfd); + + /* + * re-attach callbacks to import table + */ + if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { + rfapiMonitorAttachImportHd(rfd); + } + + return 0; } /*------------------------------------------ @@ -1999,7 +1852,7 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp) * This function initializes a NVE record and associates it with * the specified VN and underlay network addresses * - * input: + * input: * rfp_start_val value returned by rfp_start * vn NVE virtual network address * @@ -2017,13 +1870,13 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp) * * output: * response_lifetime The length of time that responses sent to this - * NVE are valid. + * NVE are valid. * * pHandle pointer to location to store rfapi handle. The * handle must be passed on subsequent rfapi_ calls. * * - * return value: + * return value: * 0 Success * EEXIST NVE with this {vn,un} already open * ENOENT No matching nve group config @@ -2033,188 +1886,176 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp) * but underlay network address is not IPv4 * EDEADLK Called from within a callback procedure *------------------------------------------*/ -int -rfapi_open ( - void *rfp_start_val, - struct rfapi_ip_addr *vn, - struct rfapi_ip_addr *un, - struct rfapi_un_option *default_options, - uint32_t *response_lifetime, - void *userdata, /* callback cookie */ - rfapi_handle *pHandle) +int rfapi_open(void *rfp_start_val, struct rfapi_ip_addr *vn, + struct rfapi_ip_addr *un, + struct rfapi_un_option *default_options, + uint32_t *response_lifetime, + void *userdata, /* callback cookie */ + rfapi_handle *pHandle) { - struct bgp *bgp; - struct rfapi *h; - struct rfapi_descriptor *rfd; - struct rfapi_cfg *hc; - struct rfapi_nve_group_cfg *rfg; - - struct prefix pfx_vn; - struct prefix pfx_un; - - int rc; - rfapi_handle hh = NULL; - int reusing_provisional = 0; - - { - char buf[2][INET_ADDRSTRLEN]; - vnc_zlog_debug_verbose ("%s: VN=%s UN=%s", __func__, - rfapiRfapiIpAddr2Str (vn, buf[0], INET_ADDRSTRLEN), - rfapiRfapiIpAddr2Str (un, buf[1], INET_ADDRSTRLEN)); - } - - assert (pHandle); - *pHandle = NULL; - - bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - if (!bgp) - return ENXIO; - - h = bgp->rfapi; - if (!h) - return ENXIO; - - hc = bgp->rfapi_cfg; - if (!hc) - return ENXIO; - - if (h->flags & RFAPI_INCALLBACK) - return EDEADLK; - - rc = rfapiRaddr2Qprefix (vn, &pfx_vn); - assert (!rc); - - rc = rfapiRaddr2Qprefix (un, &pfx_un); - assert (!rc); - - /* - * already have a descriptor with VN and UN? - */ - if (!rfapi_find_handle (bgp, vn, un, &hh)) - { - /* - * we might have set up a handle for static routes before - * this NVE was opened. In that case, reuse the handle - */ - rfd = hh; - if (!CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_PROVISIONAL)) - { - return EEXIST; - } - - /* - * reuse provisional descriptor - * hh is not NULL - */ - reusing_provisional = 1; - } - - /* - * Find the matching nve group config block - */ - rfg = bgp_rfapi_cfg_match_group (hc, &pfx_vn, &pfx_un); - if (!rfg) - { - ++h->stat.count_unknown_nves; - { - char buf[2][INET_ADDRSTRLEN]; - zlog_notice ("%s: no matching group VN=%s UN=%s", __func__, - rfapiRfapiIpAddr2Str (vn, buf[0], INET_ADDRSTRLEN), - rfapiRfapiIpAddr2Str (un, buf[1], INET_ADDRSTRLEN)); - } - return ENOENT; - } - - /* - * check nve group config block for required values - */ - if (!rfg->rt_export_list || !rfg->rfapi_import_table) - { - - ++h->stat.count_unknown_nves; - return ENOMSG; - } - - /* - * If group config specifies auto-rd assignment, check that - * VN address is IPv4|v6 so we don't fail in rfapi_open_inner(). - * Check here so we don't need to unwind memory allocations, &c. - */ - if ((rfg->rd.family == AF_UNIX) && (vn->addr_family != AF_INET) - && (vn->addr_family != AF_INET6)) - { - return EAFNOSUPPORT; - } - - if (hh) - { - /* - * reusing provisional rfd - */ - rfd = hh; - } - else - { - rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor)); - } - assert (rfd); - - rfd->bgp = bgp; - if (default_options) - { - struct rfapi_un_option *p; - - for (p = default_options; p; p = p->next) - { - if ((RFAPI_UN_OPTION_TYPE_PROVISIONAL == p->type)) - { - rfd->flags |= RFAPI_HD_FLAG_PROVISIONAL; - } - if ((RFAPI_UN_OPTION_TYPE_TUNNELTYPE == p->type)) - { - rfd->default_tunneltype_option = p->v.tunnel; - } - } - } - - /* - * Fill in caller fields - */ - rfd->vn_addr = *vn; - rfd->un_addr = *un; - rfd->cookie = userdata; - - if (!reusing_provisional) - { - rc = rfapi_init_and_open(bgp, rfd, rfg); - /* - * This can fail only if the VN address is IPv6 and the group - * specified auto-assignment of RDs, which only works for v4, - * and the check above should catch it. - * - * Another failure possibility is that we were called - * during an rfapi callback. Also checked above. - */ - assert (!rc); - } - - if (response_lifetime) - *response_lifetime = rfd->response_lifetime; - *pHandle = rfd; - return 0; + struct bgp *bgp; + struct rfapi *h; + struct rfapi_descriptor *rfd; + struct rfapi_cfg *hc; + struct rfapi_nve_group_cfg *rfg; + + struct prefix pfx_vn; + struct prefix pfx_un; + + int rc; + rfapi_handle hh = NULL; + int reusing_provisional = 0; + + { + char buf[2][INET_ADDRSTRLEN]; + vnc_zlog_debug_verbose( + "%s: VN=%s UN=%s", __func__, + rfapiRfapiIpAddr2Str(vn, buf[0], INET_ADDRSTRLEN), + rfapiRfapiIpAddr2Str(un, buf[1], INET_ADDRSTRLEN)); + } + + assert(pHandle); + *pHandle = NULL; + + bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + if (!bgp) + return ENXIO; + + h = bgp->rfapi; + if (!h) + return ENXIO; + + hc = bgp->rfapi_cfg; + if (!hc) + return ENXIO; + + if (h->flags & RFAPI_INCALLBACK) + return EDEADLK; + + rc = rfapiRaddr2Qprefix(vn, &pfx_vn); + assert(!rc); + + rc = rfapiRaddr2Qprefix(un, &pfx_un); + assert(!rc); + + /* + * already have a descriptor with VN and UN? + */ + if (!rfapi_find_handle(bgp, vn, un, &hh)) { + /* + * we might have set up a handle for static routes before + * this NVE was opened. In that case, reuse the handle + */ + rfd = hh; + if (!CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_PROVISIONAL)) { + return EEXIST; + } + + /* + * reuse provisional descriptor + * hh is not NULL + */ + reusing_provisional = 1; + } + + /* + * Find the matching nve group config block + */ + rfg = bgp_rfapi_cfg_match_group(hc, &pfx_vn, &pfx_un); + if (!rfg) { + ++h->stat.count_unknown_nves; + { + char buf[2][INET_ADDRSTRLEN]; + zlog_notice("%s: no matching group VN=%s UN=%s", + __func__, + rfapiRfapiIpAddr2Str(vn, buf[0], + INET_ADDRSTRLEN), + rfapiRfapiIpAddr2Str(un, buf[1], + INET_ADDRSTRLEN)); + } + return ENOENT; + } + + /* + * check nve group config block for required values + */ + if (!rfg->rt_export_list || !rfg->rfapi_import_table) { + + ++h->stat.count_unknown_nves; + return ENOMSG; + } + + /* + * If group config specifies auto-rd assignment, check that + * VN address is IPv4|v6 so we don't fail in rfapi_open_inner(). + * Check here so we don't need to unwind memory allocations, &c. + */ + if ((rfg->rd.family == AF_UNIX) && (vn->addr_family != AF_INET) + && (vn->addr_family != AF_INET6)) { + return EAFNOSUPPORT; + } + + if (hh) { + /* + * reusing provisional rfd + */ + rfd = hh; + } else { + rfd = XCALLOC(MTYPE_RFAPI_DESC, + sizeof(struct rfapi_descriptor)); + } + assert(rfd); + + rfd->bgp = bgp; + if (default_options) { + struct rfapi_un_option *p; + + for (p = default_options; p; p = p->next) { + if ((RFAPI_UN_OPTION_TYPE_PROVISIONAL == p->type)) { + rfd->flags |= RFAPI_HD_FLAG_PROVISIONAL; + } + if ((RFAPI_UN_OPTION_TYPE_TUNNELTYPE == p->type)) { + rfd->default_tunneltype_option = p->v.tunnel; + } + } + } + + /* + * Fill in caller fields + */ + rfd->vn_addr = *vn; + rfd->un_addr = *un; + rfd->cookie = userdata; + + if (!reusing_provisional) { + rc = rfapi_init_and_open(bgp, rfd, rfg); + /* + * This can fail only if the VN address is IPv6 and the group + * specified auto-assignment of RDs, which only works for v4, + * and the check above should catch it. + * + * Another failure possibility is that we were called + * during an rfapi callback. Also checked above. + */ + assert(!rc); + } + + if (response_lifetime) + *response_lifetime = rfd->response_lifetime; + *pHandle = rfd; + return 0; } /* * For use with debug functions */ -static int -rfapi_set_response_cb (struct rfapi_descriptor *rfd, - rfapi_response_cb_t * response_cb) +static int rfapi_set_response_cb(struct rfapi_descriptor *rfd, + rfapi_response_cb_t *response_cb) { - if (!is_valid_rfd (rfd)) - return EBADF; - rfd->response_cb = response_cb; - return 0; + if (!is_valid_rfd(rfd)) + return EBADF; + rfd->response_cb = response_cb; + return 0; } /* @@ -2230,246 +2071,234 @@ rfapi_set_response_cb (struct rfapi_descriptor *rfd, * reassignment of an already-open nve to a new nve-group in the * event that its original nve-group is administratively deleted. */ -static int -rfapi_close_inner (struct rfapi_descriptor *rfd, struct bgp *bgp) +static int rfapi_close_inner(struct rfapi_descriptor *rfd, struct bgp *bgp) { - int rc; - struct prefix pfx_vn; - struct prefix_rd prd; /* currently always 0 for VN->UN */ - - if (!is_valid_rfd (rfd)) - return EBADF; - - rc = rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn); - assert (!rc); /* should never have bad AF in stored vn address */ - - /* - * update exported routes to reflect disappearance of this NVE as nexthop - */ - vnc_direct_bgp_del_nve (bgp, rfd); - vnc_zebra_del_nve (bgp, rfd); - - /* - * unlink this HD's monitors from import table - */ - rfapiMonitorDetachImportHd (rfd); - - /* - * Unlink from Import Table - * NB rfd->import_table will be NULL if we are closing a stale descriptor - */ - if (rfd->import_table) - rfapiImportTableRefDelByIt (bgp, rfd->import_table); - rfd->import_table = NULL; - - /* - * Construct route distinguisher - */ - memset (&prd, 0, sizeof (prd)); - prd = rfd->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - /* - * withdraw tunnel - */ - del_vnc_route ( - rfd, - rfd->peer, - bgp, - SAFI_ENCAP, - &pfx_vn, /* prefix being advertised */ - &prd, /* route distinguisher to use (0 for ENCAP) */ - ZEBRA_ROUTE_BGP, - BGP_ROUTE_RFP, - NULL, - 0); /* no kill */ - - /* - * Construct route distinguisher for VPN routes - */ - prd = rfd->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - /* - * find all VPN routes associated with this rfd and delete them, too - */ - rfapiApWithdrawAll (bgp, rfd); - - /* - * remove this nve descriptor from the list of nves - * associated with the nve group - */ - if (rfd->rfg) - { - listnode_delete (rfd->rfg->nves, rfd); - rfd->rfg = NULL; /* XXX mark as orphaned/stale */ - } - - if (rfd->rt_export_list) - ecommunity_free (&rfd->rt_export_list); - rfd->rt_export_list = NULL; - - /* - * free peer structure (possibly delayed until its - * refcount reaches zero) - */ - if (rfd->peer) - { - vnc_zlog_debug_verbose ("%s: calling peer_delete(%p), #%d", - __func__, rfd->peer, rfd->peer->lock); - peer_delete (rfd->peer); - } - rfd->peer = NULL; - - return 0; + int rc; + struct prefix pfx_vn; + struct prefix_rd prd; /* currently always 0 for VN->UN */ + + if (!is_valid_rfd(rfd)) + return EBADF; + + rc = rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn); + assert(!rc); /* should never have bad AF in stored vn address */ + + /* + * update exported routes to reflect disappearance of this NVE as + * nexthop + */ + vnc_direct_bgp_del_nve(bgp, rfd); + vnc_zebra_del_nve(bgp, rfd); + + /* + * unlink this HD's monitors from import table + */ + rfapiMonitorDetachImportHd(rfd); + + /* + * Unlink from Import Table + * NB rfd->import_table will be NULL if we are closing a stale + * descriptor + */ + if (rfd->import_table) + rfapiImportTableRefDelByIt(bgp, rfd->import_table); + rfd->import_table = NULL; + + /* + * Construct route distinguisher + */ + memset(&prd, 0, sizeof(prd)); + prd = rfd->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + /* + * withdraw tunnel + */ + del_vnc_route(rfd, rfd->peer, bgp, SAFI_ENCAP, + &pfx_vn, /* prefix being advertised */ + &prd, /* route distinguisher to use (0 for ENCAP) */ + ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); /* no kill */ + + /* + * Construct route distinguisher for VPN routes + */ + prd = rfd->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + /* + * find all VPN routes associated with this rfd and delete them, too + */ + rfapiApWithdrawAll(bgp, rfd); + + /* + * remove this nve descriptor from the list of nves + * associated with the nve group + */ + if (rfd->rfg) { + listnode_delete(rfd->rfg->nves, rfd); + rfd->rfg = NULL; /* XXX mark as orphaned/stale */ + } + + if (rfd->rt_export_list) + ecommunity_free(&rfd->rt_export_list); + rfd->rt_export_list = NULL; + + /* + * free peer structure (possibly delayed until its + * refcount reaches zero) + */ + if (rfd->peer) { + vnc_zlog_debug_verbose("%s: calling peer_delete(%p), #%d", + __func__, rfd->peer, rfd->peer->lock); + peer_delete(rfd->peer); + } + rfd->peer = NULL; + + return 0; } -int -rfapi_close (void *handle) +int rfapi_close(void *handle) { - struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; - int rc; - struct route_node *node; - struct bgp *bgp; - struct rfapi *h; + struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; + int rc; + struct route_node *node; + struct bgp *bgp; + struct rfapi *h; - vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); + vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd); #if RFAPI_WHO_IS_CALLING_ME #ifdef HAVE_GLIBC_BACKTRACE #define RFAPI_DEBUG_BACKTRACE_NENTRIES 5 - { - void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES]; - char **syms; - int i; - size_t size; - - size = backtrace (buf, RFAPI_DEBUG_BACKTRACE_NENTRIES); - syms = backtrace_symbols (buf, size); - for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i) - { - vnc_zlog_debug_verbose ("backtrace[%2d]: %s", i, syms[i]); - } - free (syms); - } + { + void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES]; + char **syms; + int i; + size_t size; + + size = backtrace(buf, RFAPI_DEBUG_BACKTRACE_NENTRIES); + syms = backtrace_symbols(buf, size); + for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; + ++i) { + vnc_zlog_debug_verbose("backtrace[%2d]: %s", i, + syms[i]); + } + free(syms); + } #endif #endif - bgp = rfd->bgp; - if (!bgp) - return ENXIO; - - h = bgp->rfapi; - if (!h) - return ENXIO; - - if (!is_valid_rfd (rfd)) - return EBADF; - - if (h->flags & RFAPI_INCALLBACK) - { - /* - * Queue these close requests for processing after callback - * is finished - */ - if (!CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) - { - work_queue_add (h->deferred_close_q, handle); - vnc_zlog_debug_verbose ("%s: added handle %p to deferred close queue", - __func__, handle); - } - return 0; - } - - if (CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) - { - - vnc_zlog_debug_verbose ("%s administrative close rfd=%p", __func__, rfd); - - if (h && h->rfp_methods.close_cb) - { - vnc_zlog_debug_verbose ("%s calling close callback rfd=%p", __func__, rfd); - - /* - * call the callback fairly early so that it can still lookup un/vn - * from handle, etc. - * - * NB RFAPI_INCALLBACK is tested above, so if we reach this point - * we are not already in the context of a callback. - */ - h->flags |= RFAPI_INCALLBACK; - (*h->rfp_methods.close_cb) (handle, EIDRM); - h->flags &= ~RFAPI_INCALLBACK; - } - } - - if (rfd->rfg) - { - /* - * Orphaned descriptors have already done this part, so do - * only for non-orphaned descriptors. - */ - if ((rc = rfapi_close_inner (rfd, bgp))) - return rc; - } - - /* - * Remove descriptor from UN index - * (remove from chain at node) - */ - rc = rfapi_find_node (bgp, &rfd->vn_addr, &rfd->un_addr, &node); - if (!rc) - { - struct rfapi_descriptor *hh; - - if (node->info == rfd) - { - node->info = rfd->next; - } - else - { - - for (hh = node->info; hh; hh = hh->next) - { - if (hh->next == rfd) - { - hh->next = rfd->next; - break; - } - } - } - route_unlock_node (node); - } - - /* - * remove from descriptor list - */ - listnode_delete (&h->descriptors, rfd); - - /* - * Delete monitor list items and free monitor structures - */ - (void) rfapiMonitorDelHd (rfd); - - /* - * release advertised prefix data - */ - rfapiApRelease (&rfd->advertised); - - /* - * Release RFP callback RIB - */ - rfapiRibFree (rfd); - - /* - * free descriptor - */ - memset (rfd, 0, sizeof (struct rfapi_descriptor)); - XFREE (MTYPE_RFAPI_DESC, rfd); - - return 0; + bgp = rfd->bgp; + if (!bgp) + return ENXIO; + + h = bgp->rfapi; + if (!h) + return ENXIO; + + if (!is_valid_rfd(rfd)) + return EBADF; + + if (h->flags & RFAPI_INCALLBACK) { + /* + * Queue these close requests for processing after callback + * is finished + */ + if (!CHECK_FLAG(rfd->flags, + RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) { + work_queue_add(h->deferred_close_q, handle); + vnc_zlog_debug_verbose( + "%s: added handle %p to deferred close queue", + __func__, handle); + } + return 0; + } + + if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) { + + vnc_zlog_debug_verbose("%s administrative close rfd=%p", + __func__, rfd); + + if (h && h->rfp_methods.close_cb) { + vnc_zlog_debug_verbose( + "%s calling close callback rfd=%p", __func__, + rfd); + + /* + * call the callback fairly early so that it can still + * lookup un/vn + * from handle, etc. + * + * NB RFAPI_INCALLBACK is tested above, so if we reach + * this point + * we are not already in the context of a callback. + */ + h->flags |= RFAPI_INCALLBACK; + (*h->rfp_methods.close_cb)(handle, EIDRM); + h->flags &= ~RFAPI_INCALLBACK; + } + } + + if (rfd->rfg) { + /* + * Orphaned descriptors have already done this part, so do + * only for non-orphaned descriptors. + */ + if ((rc = rfapi_close_inner(rfd, bgp))) + return rc; + } + + /* + * Remove descriptor from UN index + * (remove from chain at node) + */ + rc = rfapi_find_node(bgp, &rfd->vn_addr, &rfd->un_addr, &node); + if (!rc) { + struct rfapi_descriptor *hh; + + if (node->info == rfd) { + node->info = rfd->next; + } else { + + for (hh = node->info; hh; hh = hh->next) { + if (hh->next == rfd) { + hh->next = rfd->next; + break; + } + } + } + route_unlock_node(node); + } + + /* + * remove from descriptor list + */ + listnode_delete(&h->descriptors, rfd); + + /* + * Delete monitor list items and free monitor structures + */ + (void)rfapiMonitorDelHd(rfd); + + /* + * release advertised prefix data + */ + rfapiApRelease(&rfd->advertised); + + /* + * Release RFP callback RIB + */ + rfapiRibFree(rfd); + + /* + * free descriptor + */ + memset(rfd, 0, sizeof(struct rfapi_descriptor)); + XFREE(MTYPE_RFAPI_DESC, rfd); + + return 0; } /* @@ -2489,580 +2318,535 @@ rfapi_close (void *handle) * caused by deleting and then adding the NVE: advertised prefixes * and nexthop lists for exported routes can turn over. */ -int -rfapi_reopen (struct rfapi_descriptor *rfd, struct bgp *bgp) +int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp) { - struct rfapi *h; - int rc; - - if ((rc = rfapi_close_inner (rfd, bgp))) - { - return rc; - } - if ((rc = rfapi_open_rfd (rfd, bgp))) - { - - h = bgp->rfapi; - - assert (!CHECK_FLAG (h->flags, RFAPI_INCALLBACK)); - - if (CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY) && - h && h->rfp_methods.close_cb) - { - - /* - * NB RFAPI_INCALLBACK is tested above, so if we reach this point - * we are not already in the context of a callback. - */ - h->flags |= RFAPI_INCALLBACK; - (*h->rfp_methods.close_cb) ((rfapi_handle) rfd, ESTALE); - h->flags &= ~RFAPI_INCALLBACK; - } - return rc; - } - return 0; + struct rfapi *h; + int rc; + + if ((rc = rfapi_close_inner(rfd, bgp))) { + return rc; + } + if ((rc = rfapi_open_rfd(rfd, bgp))) { + + h = bgp->rfapi; + + assert(!CHECK_FLAG(h->flags, RFAPI_INCALLBACK)); + + if (CHECK_FLAG(rfd->flags, + RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY) + && h && h->rfp_methods.close_cb) { + + /* + * NB RFAPI_INCALLBACK is tested above, so if we reach + * this point + * we are not already in the context of a callback. + */ + h->flags |= RFAPI_INCALLBACK; + (*h->rfp_methods.close_cb)((rfapi_handle)rfd, ESTALE); + h->flags &= ~RFAPI_INCALLBACK; + } + return rc; + } + return 0; } /*********************************************************************** * NVE Routes ***********************************************************************/ -/* +/* * Announce reachability to this prefix via the NVE */ -int -rfapi_register ( - void *handle, - struct rfapi_ip_prefix *prefix, - uint32_t lifetime, /* host byte order */ - struct rfapi_un_option *options_un, - struct rfapi_vn_option *options_vn, - rfapi_register_action action) +int rfapi_register(void *handle, struct rfapi_ip_prefix *prefix, + uint32_t lifetime, /* host byte order */ + struct rfapi_un_option *options_un, + struct rfapi_vn_option *options_vn, + rfapi_register_action action) { - struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; - struct bgp *bgp; - struct prefix p; - struct prefix *pfx_ip = NULL; - struct prefix_rd prd; - int afi; - struct prefix pfx_mac_buf; - struct prefix *pfx_mac = NULL; - struct prefix pfx_vn_buf; - const char *action_str = NULL; - uint32_t *label = NULL; - struct rfapi_vn_option *vo; - struct rfapi_l2address_option *l2o = NULL; - struct prefix_rd *prd_override = NULL; - - switch (action) - { - case RFAPI_REGISTER_ADD: - action_str = "add"; - break; - case RFAPI_REGISTER_WITHDRAW: - action_str = "withdraw"; - break; - case RFAPI_REGISTER_KILL: - action_str = "kill"; - break; - default: - assert (0); - break; - } - - /* - * Inspect VN options - */ - for (vo = options_vn; vo; vo = vo->next) - { - if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) - { - l2o = &vo->v.l2addr; - } - if (RFAPI_VN_OPTION_TYPE_INTERNAL_RD == vo->type) - { - prd_override = &vo->v.internal_rd; - } - } - - /********************************************************************* - * advertise prefix - *********************************************************************/ - - /* - * set <p> based on <prefix> - */ - assert (!rfapiRprefix2Qprefix (prefix, &p)); - - afi = family2afi (prefix->prefix.addr_family); - assert (afi); - - - { - char buf[BUFSIZ]; - - prefix2str (&p, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ - vnc_zlog_debug_verbose - ("%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)", - __func__, rfd, buf, lifetime, options_un, options_vn, action_str); - } - - /* - * These tests come after the prefix conversion so that we can - * print the prefix in a debug message before failing - */ - - bgp = rfd->bgp; - if (!bgp) - { - vnc_zlog_debug_verbose ("%s: no BGP instance: returning ENXIO", __func__); - return ENXIO; - } - if (!bgp->rfapi) - { - vnc_zlog_debug_verbose ("%s: no RFAPI instance: returning ENXIO", __func__); - return ENXIO; - } - if (!rfd->rfg) - { - if (RFAPI_REGISTER_ADD == action) - { - ++bgp->rfapi->stat.count_registrations_failed; - } - vnc_zlog_debug_verbose ("%s: rfd=%p, no RF GRP instance: returning ESTALE", - __func__, rfd); - return ESTALE; - } - - if (bgp->rfapi->flags & RFAPI_INCALLBACK) - { - if (RFAPI_REGISTER_ADD == action) - { - ++bgp->rfapi->stat.count_registrations_failed; - } - vnc_zlog_debug_verbose ("%s: in callback: returning EDEADLK", __func__); - return EDEADLK; - } - - if (!is_valid_rfd (rfd)) - { - if (RFAPI_REGISTER_ADD == action) - { - ++bgp->rfapi->stat.count_registrations_failed; - } - vnc_zlog_debug_verbose ("%s: invalid handle: returning EBADF", __func__); - return EBADF; - } - - /* - * Is there a MAC address in this registration? - */ - if (l2o && !RFAPI_0_ETHERADDR (&l2o->macaddr)) - { - rfapiL2o2Qprefix (l2o, &pfx_mac_buf); - pfx_mac = &pfx_mac_buf; - } - - /* - * Is there an IP prefix in this registration? - */ - if (!(RFAPI_0_PREFIX (&p) && RFAPI_HOST_PREFIX (&p))) - { - pfx_ip = &p; - } - else - { - if (!pfx_mac) - { - vnc_zlog_debug_verbose ("%s: missing mac addr that is required for host 0 pfx", - __func__); - if (RFAPI_REGISTER_ADD == action) - { - ++bgp->rfapi->stat.count_registrations_failed; - } - return EINVAL; - } - if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf)) - { - vnc_zlog_debug_verbose ("%s: handle has bad vn_addr: returning EBADF", - __func__); - if (RFAPI_REGISTER_ADD == action) - { - ++bgp->rfapi->stat.count_registrations_failed; - } - return EBADF; - } - } - - if (RFAPI_REGISTER_ADD == action) - { - ++bgp->rfapi->stat.count_registrations; - } - - /* - * Figure out if this registration is missing an IP address - * - * MAC-addr based: - * - * In RFAPI, we use prefixes in family AF_LINK to store - * the MAC addresses. These prefixes are used for the - * list of advertised prefixes and in the RFAPI import - * tables. - * - * In BGP proper, we use the prefix matching the NVE's - * VN address with a host prefix-length (i.e., 32 or 128). - * - */ - if (l2o && l2o->logical_net_id && RFAPI_0_PREFIX (&p) && - RFAPI_HOST_PREFIX (&p)) - { - - rfapiL2o2Qprefix (l2o, &pfx_mac_buf); - pfx_mac = &pfx_mac_buf; - } - - /* - * Construct route distinguisher - */ - if (prd_override) - { - prd = *prd_override; - } - else - { - memset (&prd, 0, sizeof (prd)); - if (pfx_mac) - { - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - encode_rd_type(RD_TYPE_VNC_ETH, prd.val); - if (l2o->local_nve_id || !(rfd->rfg->flags & RFAPI_RFG_L2RD)) - { - /* - * If Local NVE ID is specified in message, use it. - * (if no local default configured, also use it even if 0) - */ - prd.val[1] = l2o->local_nve_id; - } - else - { - if (rfd->rfg->l2rd) - { - /* - * locally-configured literal value - */ - prd.val[1] = rfd->rfg->l2rd; - } - else - { - /* - * 0 means auto:vn, which means use LSB of VN addr - */ - if (rfd->vn_addr.addr_family == AF_INET) - { - prd.val[1] = - *(((char *) &rfd->vn_addr.addr.v4.s_addr) + 3); - } - else - { - prd.val[1] = - *(((char *) &rfd->vn_addr.addr.v6.s6_addr) + 15); - } - } - } - memcpy (prd.val + 2, pfx_mac->u.prefix_eth.octet, 6); - } - else - { - prd = rfd->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - } - } - - - if (action == RFAPI_REGISTER_WITHDRAW || action == RFAPI_REGISTER_KILL) - { - - int adv_tunnel = 0; - - /* - * withdraw previous advertisement - */ - del_vnc_route ( - rfd, - rfd->peer, - bgp, - SAFI_MPLS_VPN, - pfx_ip ? pfx_ip : &pfx_vn_buf, /* prefix being advertised */ - &prd, /* route distinguisher (0 for ENCAP) */ - ZEBRA_ROUTE_BGP, - BGP_ROUTE_RFP, - NULL, - action == RFAPI_REGISTER_KILL); - - if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &prd, &adv_tunnel)) - { - if (adv_tunnel) - rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime); - } - - } - else - { - - int adv_tunnel = 0; - uint32_t local_pref; - struct ecommunity *rtlist = NULL; - struct ecommunity_val ecom_value; - - if (!rfapiApCount (rfd)) - { - /* - * make sure we advertise tunnel route upon adding the - * first VPN route - */ - adv_tunnel = 1; - } - - if (rfapiApAdd (bgp, rfd, &p, pfx_mac, &prd, lifetime, prefix->cost, - l2o)) - { - adv_tunnel = 1; - } - - vnc_zlog_debug_verbose ("%s: adv_tunnel = %d", __func__, adv_tunnel); - if (adv_tunnel) - { - vnc_zlog_debug_verbose ("%s: announcing tunnel route", __func__); - rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime); - } - - vnc_zlog_debug_verbose ("%s: calling add_vnc_route", __func__); - - local_pref = rfp_cost_to_localpref (prefix->cost); - - if (l2o && l2o->label) - label = &l2o->label; - - if (pfx_mac) - { - struct ecommunity *l2com = NULL; - - if (label) - { - l2com = bgp_rfapi_get_ecommunity_by_lni_label (bgp, 1, - l2o->logical_net_id, - *label); - } - if (l2com) - { - rtlist = ecommunity_dup (l2com); - } - else - { - /* - * If mac address is set, add an RT based on the registered LNI - */ - memset ((char *) &ecom_value, 0, sizeof (ecom_value)); - ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET; - ecom_value.val[5] = (l2o->logical_net_id >> 16) & 0xff; - ecom_value.val[6] = (l2o->logical_net_id >> 8) & 0xff; - ecom_value.val[7] = (l2o->logical_net_id >> 0) & 0xff; - rtlist = ecommunity_new(); - ecommunity_add_val (rtlist, &ecom_value); - } - if (l2o->tag_id) - { - as_t as = bgp->as; - uint16_t val = l2o->tag_id; - memset ((char *) &ecom_value, 0, sizeof (ecom_value)); - ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET; - if (as > BGP_AS_MAX) - { - ecom_value.val[0] = ECOMMUNITY_ENCODE_AS4; - ecom_value.val[2] = (as >>24) & 0xff; - ecom_value.val[3] = (as >>16) & 0xff; - ecom_value.val[4] = (as >>8) & 0xff; - ecom_value.val[5] = as & 0xff; - } - else - { - ecom_value.val[0] = ECOMMUNITY_ENCODE_AS; - ecom_value.val[2] = (as >>8) & 0xff; - ecom_value.val[3] = as & 0xff; - } - ecom_value.val[6] = (val >> 8) & 0xff; - ecom_value.val[7] = val & 0xff; - if (rtlist == NULL) - rtlist = ecommunity_new(); - ecommunity_add_val (rtlist, &ecom_value); - } - } - - /* - * advertise prefix via tunnel endpoint - */ - add_vnc_route ( - rfd, /* rfapi descr, for export list & backref */ - bgp, /* which bgp instance */ - SAFI_MPLS_VPN, /* which SAFI */ - (pfx_ip ? pfx_ip : &pfx_vn_buf), /* prefix being advertised */ - &prd, /* route distinguisher to use (0 for ENCAP) */ - &rfd->vn_addr, /* nexthop */ - &local_pref, - &lifetime, /* prefix lifetime -> Tunnel Encap attr */ - NULL, - options_un, /* rfapi un options */ - options_vn, /* rfapi vn options */ - (rtlist ? rtlist : rfd->rt_export_list), - NULL, /* med */ - label, /* label: default */ - ZEBRA_ROUTE_BGP, - BGP_ROUTE_RFP, - 0); - - if (rtlist) - ecommunity_free (&rtlist); /* sets rtlist = NULL */ - } - - vnc_zlog_debug_verbose ("%s: success", __func__); - return 0; + struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; + struct bgp *bgp; + struct prefix p; + struct prefix *pfx_ip = NULL; + struct prefix_rd prd; + int afi; + struct prefix pfx_mac_buf; + struct prefix *pfx_mac = NULL; + struct prefix pfx_vn_buf; + const char *action_str = NULL; + uint32_t *label = NULL; + struct rfapi_vn_option *vo; + struct rfapi_l2address_option *l2o = NULL; + struct prefix_rd *prd_override = NULL; + + switch (action) { + case RFAPI_REGISTER_ADD: + action_str = "add"; + break; + case RFAPI_REGISTER_WITHDRAW: + action_str = "withdraw"; + break; + case RFAPI_REGISTER_KILL: + action_str = "kill"; + break; + default: + assert(0); + break; + } + + /* + * Inspect VN options + */ + for (vo = options_vn; vo; vo = vo->next) { + if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) { + l2o = &vo->v.l2addr; + } + if (RFAPI_VN_OPTION_TYPE_INTERNAL_RD == vo->type) { + prd_override = &vo->v.internal_rd; + } + } + + /********************************************************************* + * advertise prefix + *********************************************************************/ + + /* + * set <p> based on <prefix> + */ + assert(!rfapiRprefix2Qprefix(prefix, &p)); + + afi = family2afi(prefix->prefix.addr_family); + assert(afi); + + + { + char buf[BUFSIZ]; + + prefix2str(&p, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + vnc_zlog_debug_verbose( + "%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)", + __func__, rfd, buf, lifetime, options_un, options_vn, + action_str); + } + + /* + * These tests come after the prefix conversion so that we can + * print the prefix in a debug message before failing + */ + + bgp = rfd->bgp; + if (!bgp) { + vnc_zlog_debug_verbose("%s: no BGP instance: returning ENXIO", + __func__); + return ENXIO; + } + if (!bgp->rfapi) { + vnc_zlog_debug_verbose("%s: no RFAPI instance: returning ENXIO", + __func__); + return ENXIO; + } + if (!rfd->rfg) { + if (RFAPI_REGISTER_ADD == action) { + ++bgp->rfapi->stat.count_registrations_failed; + } + vnc_zlog_debug_verbose( + "%s: rfd=%p, no RF GRP instance: returning ESTALE", + __func__, rfd); + return ESTALE; + } + + if (bgp->rfapi->flags & RFAPI_INCALLBACK) { + if (RFAPI_REGISTER_ADD == action) { + ++bgp->rfapi->stat.count_registrations_failed; + } + vnc_zlog_debug_verbose("%s: in callback: returning EDEADLK", + __func__); + return EDEADLK; + } + + if (!is_valid_rfd(rfd)) { + if (RFAPI_REGISTER_ADD == action) { + ++bgp->rfapi->stat.count_registrations_failed; + } + vnc_zlog_debug_verbose("%s: invalid handle: returning EBADF", + __func__); + return EBADF; + } + + /* + * Is there a MAC address in this registration? + */ + if (l2o && !RFAPI_0_ETHERADDR(&l2o->macaddr)) { + rfapiL2o2Qprefix(l2o, &pfx_mac_buf); + pfx_mac = &pfx_mac_buf; + } + + /* + * Is there an IP prefix in this registration? + */ + if (!(RFAPI_0_PREFIX(&p) && RFAPI_HOST_PREFIX(&p))) { + pfx_ip = &p; + } else { + if (!pfx_mac) { + vnc_zlog_debug_verbose( + "%s: missing mac addr that is required for host 0 pfx", + __func__); + if (RFAPI_REGISTER_ADD == action) { + ++bgp->rfapi->stat.count_registrations_failed; + } + return EINVAL; + } + if (rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn_buf)) { + vnc_zlog_debug_verbose( + "%s: handle has bad vn_addr: returning EBADF", + __func__); + if (RFAPI_REGISTER_ADD == action) { + ++bgp->rfapi->stat.count_registrations_failed; + } + return EBADF; + } + } + + if (RFAPI_REGISTER_ADD == action) { + ++bgp->rfapi->stat.count_registrations; + } + + /* + * Figure out if this registration is missing an IP address + * + * MAC-addr based: + * + * In RFAPI, we use prefixes in family AF_LINK to store + * the MAC addresses. These prefixes are used for the + * list of advertised prefixes and in the RFAPI import + * tables. + * + * In BGP proper, we use the prefix matching the NVE's + * VN address with a host prefix-length (i.e., 32 or 128). + * + */ + if (l2o && l2o->logical_net_id && RFAPI_0_PREFIX(&p) + && RFAPI_HOST_PREFIX(&p)) { + + rfapiL2o2Qprefix(l2o, &pfx_mac_buf); + pfx_mac = &pfx_mac_buf; + } + + /* + * Construct route distinguisher + */ + if (prd_override) { + prd = *prd_override; + } else { + memset(&prd, 0, sizeof(prd)); + if (pfx_mac) { + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + encode_rd_type(RD_TYPE_VNC_ETH, prd.val); + if (l2o->local_nve_id + || !(rfd->rfg->flags & RFAPI_RFG_L2RD)) { + /* + * If Local NVE ID is specified in message, use + * it. + * (if no local default configured, also use it + * even if 0) + */ + prd.val[1] = l2o->local_nve_id; + } else { + if (rfd->rfg->l2rd) { + /* + * locally-configured literal value + */ + prd.val[1] = rfd->rfg->l2rd; + } else { + /* + * 0 means auto:vn, which means use LSB + * of VN addr + */ + if (rfd->vn_addr.addr_family + == AF_INET) { + prd.val[1] = + *(((char *)&rfd->vn_addr + .addr.v4 + .s_addr) + + 3); + } else { + prd.val[1] = + *(((char *)&rfd->vn_addr + .addr.v6 + .s6_addr) + + 15); + } + } + } + memcpy(prd.val + 2, pfx_mac->u.prefix_eth.octet, 6); + } else { + prd = rfd->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + } + } + + + if (action == RFAPI_REGISTER_WITHDRAW + || action == RFAPI_REGISTER_KILL) { + + int adv_tunnel = 0; + + /* + * withdraw previous advertisement + */ + del_vnc_route( + rfd, rfd->peer, bgp, SAFI_MPLS_VPN, + pfx_ip ? pfx_ip + : &pfx_vn_buf, /* prefix being advertised */ + &prd, /* route distinguisher (0 for ENCAP) */ + ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, + action == RFAPI_REGISTER_KILL); + + if (0 == rfapiApDelete(bgp, rfd, &p, pfx_mac, &prd, + &adv_tunnel)) { + if (adv_tunnel) + rfapiTunnelRouteAnnounce( + bgp, rfd, &rfd->max_prefix_lifetime); + } + + } else { + + int adv_tunnel = 0; + uint32_t local_pref; + struct ecommunity *rtlist = NULL; + struct ecommunity_val ecom_value; + + if (!rfapiApCount(rfd)) { + /* + * make sure we advertise tunnel route upon adding the + * first VPN route + */ + adv_tunnel = 1; + } + + if (rfapiApAdd(bgp, rfd, &p, pfx_mac, &prd, lifetime, + prefix->cost, l2o)) { + adv_tunnel = 1; + } + + vnc_zlog_debug_verbose("%s: adv_tunnel = %d", __func__, + adv_tunnel); + if (adv_tunnel) { + vnc_zlog_debug_verbose("%s: announcing tunnel route", + __func__); + rfapiTunnelRouteAnnounce(bgp, rfd, + &rfd->max_prefix_lifetime); + } + + vnc_zlog_debug_verbose("%s: calling add_vnc_route", __func__); + + local_pref = rfp_cost_to_localpref(prefix->cost); + + if (l2o && l2o->label) + label = &l2o->label; + + if (pfx_mac) { + struct ecommunity *l2com = NULL; + + if (label) { + l2com = bgp_rfapi_get_ecommunity_by_lni_label( + bgp, 1, l2o->logical_net_id, *label); + } + if (l2com) { + rtlist = ecommunity_dup(l2com); + } else { + /* + * If mac address is set, add an RT based on the + * registered LNI + */ + memset((char *)&ecom_value, 0, + sizeof(ecom_value)); + ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET; + ecom_value.val[5] = + (l2o->logical_net_id >> 16) & 0xff; + ecom_value.val[6] = + (l2o->logical_net_id >> 8) & 0xff; + ecom_value.val[7] = + (l2o->logical_net_id >> 0) & 0xff; + rtlist = ecommunity_new(); + ecommunity_add_val(rtlist, &ecom_value); + } + if (l2o->tag_id) { + as_t as = bgp->as; + uint16_t val = l2o->tag_id; + memset((char *)&ecom_value, 0, + sizeof(ecom_value)); + ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET; + if (as > BGP_AS_MAX) { + ecom_value.val[0] = + ECOMMUNITY_ENCODE_AS4; + ecom_value.val[2] = (as >> 24) & 0xff; + ecom_value.val[3] = (as >> 16) & 0xff; + ecom_value.val[4] = (as >> 8) & 0xff; + ecom_value.val[5] = as & 0xff; + } else { + ecom_value.val[0] = + ECOMMUNITY_ENCODE_AS; + ecom_value.val[2] = (as >> 8) & 0xff; + ecom_value.val[3] = as & 0xff; + } + ecom_value.val[6] = (val >> 8) & 0xff; + ecom_value.val[7] = val & 0xff; + if (rtlist == NULL) + rtlist = ecommunity_new(); + ecommunity_add_val(rtlist, &ecom_value); + } + } + + /* + * advertise prefix via tunnel endpoint + */ + add_vnc_route( + rfd, /* rfapi descr, for export list & backref */ + bgp, /* which bgp instance */ + SAFI_MPLS_VPN, /* which SAFI */ + (pfx_ip ? pfx_ip + : &pfx_vn_buf), /* prefix being advertised */ + &prd, /* route distinguisher to use (0 for ENCAP) */ + &rfd->vn_addr, /* nexthop */ + &local_pref, + &lifetime, /* prefix lifetime -> Tunnel Encap attr */ + NULL, options_un, /* rfapi un options */ + options_vn, /* rfapi vn options */ + (rtlist ? rtlist : rfd->rt_export_list), NULL, /* med */ + label, /* label: default */ + ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); + + if (rtlist) + ecommunity_free(&rtlist); /* sets rtlist = NULL */ + } + + vnc_zlog_debug_verbose("%s: success", __func__); + return 0; } -int -rfapi_query ( - void *handle, - struct rfapi_ip_addr *target, - struct rfapi_l2address_option *l2o, /* may be NULL */ - struct rfapi_next_hop_entry **ppNextHopEntry) +int rfapi_query(void *handle, struct rfapi_ip_addr *target, + struct rfapi_l2address_option *l2o, /* may be NULL */ + struct rfapi_next_hop_entry **ppNextHopEntry) { - struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; - struct bgp *bgp = rfd->bgp; - int rc; - - assert (ppNextHopEntry); - *ppNextHopEntry = NULL; - - if (bgp && bgp->rfapi) - { - bgp->rfapi->stat.count_queries++; - } - - if (!rfd->rfg) - { - if (bgp && bgp->rfapi) - ++bgp->rfapi->stat.count_queries_failed; - return ESTALE; - } - - if ((rc = rfapi_query_inner (handle, target, l2o, ppNextHopEntry))) - { - if (bgp && bgp->rfapi) - ++bgp->rfapi->stat.count_queries_failed; - } - return rc; + struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; + struct bgp *bgp = rfd->bgp; + int rc; + + assert(ppNextHopEntry); + *ppNextHopEntry = NULL; + + if (bgp && bgp->rfapi) { + bgp->rfapi->stat.count_queries++; + } + + if (!rfd->rfg) { + if (bgp && bgp->rfapi) + ++bgp->rfapi->stat.count_queries_failed; + return ESTALE; + } + + if ((rc = rfapi_query_inner(handle, target, l2o, ppNextHopEntry))) { + if (bgp && bgp->rfapi) + ++bgp->rfapi->stat.count_queries_failed; + } + return rc; } -int -rfapi_query_done (rfapi_handle handle, struct rfapi_ip_addr *target) +int rfapi_query_done(rfapi_handle handle, struct rfapi_ip_addr *target) { - struct prefix p; - int rc; - struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; - struct bgp *bgp = rfd->bgp; + struct prefix p; + int rc; + struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; + struct bgp *bgp = rfd->bgp; - if (!rfd->rfg) - return ESTALE; + if (!rfd->rfg) + return ESTALE; - assert (target); - rc = rfapiRaddr2Qprefix (target, &p); - assert (!rc); + assert(target); + rc = rfapiRaddr2Qprefix(target, &p); + assert(!rc); - if (!is_valid_rfd (rfd)) - return EBADF; + if (!is_valid_rfd(rfd)) + return EBADF; - /* preemptive */ - if (!bgp || !bgp->rfapi) - return ENXIO; + /* preemptive */ + if (!bgp || !bgp->rfapi) + return ENXIO; - if (bgp->rfapi->flags & RFAPI_INCALLBACK) - return EDEADLK; + if (bgp->rfapi->flags & RFAPI_INCALLBACK) + return EDEADLK; - rfapiMonitorDel (bgp, rfd, &p); + rfapiMonitorDel(bgp, rfd, &p); - return 0; + return 0; } -int -rfapi_query_done_all (rfapi_handle handle, int *count) +int rfapi_query_done_all(rfapi_handle handle, int *count) { - struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; - struct bgp *bgp = rfd->bgp;; - int num; + struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; + struct bgp *bgp = rfd->bgp; + ; + int num; - if (!rfd->rfg) - return ESTALE; + if (!rfd->rfg) + return ESTALE; - if (!is_valid_rfd (rfd)) - return EBADF; + if (!is_valid_rfd(rfd)) + return EBADF; - /* preemptive */ - if (!bgp || !bgp->rfapi) - return ENXIO; + /* preemptive */ + if (!bgp || !bgp->rfapi) + return ENXIO; - if (bgp->rfapi->flags & RFAPI_INCALLBACK) - return EDEADLK; + if (bgp->rfapi->flags & RFAPI_INCALLBACK) + return EDEADLK; - num = rfapiMonitorDelHd (rfd); + num = rfapiMonitorDelHd(rfd); - if (count) - *count = num; + if (count) + *count = num; - return 0; + return 0; } -void -rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list) +void rfapi_free_next_hop_list(struct rfapi_next_hop_entry *list) { - struct rfapi_next_hop_entry *nh; - struct rfapi_next_hop_entry *next; - - for (nh = list; nh; nh = next) - { - next = nh->next; - rfapi_un_options_free (nh->un_options); - nh->un_options = NULL; - rfapi_vn_options_free (nh->vn_options); - nh->vn_options = NULL; - XFREE (MTYPE_RFAPI_NEXTHOP, nh); - } + struct rfapi_next_hop_entry *nh; + struct rfapi_next_hop_entry *next; + + for (nh = list; nh; nh = next) { + next = nh->next; + rfapi_un_options_free(nh->un_options); + nh->un_options = NULL; + rfapi_vn_options_free(nh->vn_options); + nh->vn_options = NULL; + XFREE(MTYPE_RFAPI_NEXTHOP, nh); + } } /* * NULL handle => return total count across all nves */ -uint32_t -rfapi_monitor_count (void *handle) +uint32_t rfapi_monitor_count(void *handle) { - struct bgp *bgp = bgp_get_default (); - uint32_t count; + struct bgp *bgp = bgp_get_default(); + uint32_t count; - if (handle) - { - struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; - count = rfd->monitor_count; - } - else - { + if (handle) { + struct rfapi_descriptor *rfd = + (struct rfapi_descriptor *)handle; + count = rfd->monitor_count; + } else { - if (!bgp || !bgp->rfapi) - return 0; + if (!bgp || !bgp->rfapi) + return 0; - count = bgp->rfapi->monitor_count; - } + count = bgp->rfapi->monitor_count; + } - return count; + return count; } /*********************************************************************** @@ -3077,8 +2861,8 @@ DEFUN (debug_rfapi_show_nves, SHOW_STR "NVE Information\n") { - rfapiPrintMatchingDescriptors (vty, NULL, NULL); - return CMD_SUCCESS; + rfapiPrintMatchingDescriptors(vty, NULL, NULL); + return CMD_SUCCESS; } DEFUN ( @@ -3094,28 +2878,23 @@ DEFUN ( "IPv4 address\n" "IPv6 address\n") { - struct prefix pfx; - - if (!str2prefix (argv[5]->arg, &pfx)) - { - vty_out (vty, "Malformed address \"%s\"\n", argv[5]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - if (pfx.family != AF_INET && pfx.family != AF_INET6) - { - vty_out (vty, "Invalid address \"%s\"\n", argv[5]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - if (argv[4]->arg[0] == 'u') - { - rfapiPrintMatchingDescriptors (vty, NULL, &pfx); - } - else - { - rfapiPrintMatchingDescriptors (vty, &pfx, NULL); - } - return CMD_SUCCESS; + struct prefix pfx; + + if (!str2prefix(argv[5]->arg, &pfx)) { + vty_out(vty, "Malformed address \"%s\"\n", argv[5]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (pfx.family != AF_INET && pfx.family != AF_INET6) { + vty_out(vty, "Invalid address \"%s\"\n", argv[5]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + if (argv[4]->arg[0] == 'u') { + rfapiPrintMatchingDescriptors(vty, NULL, &pfx); + } else { + rfapiPrintMatchingDescriptors(vty, &pfx, NULL); + } + return CMD_SUCCESS; } /* @@ -3123,29 +2902,27 @@ DEFUN ( * with a stream pointing to a vty, the user will have to type something * before the callback output shows up */ -static void -test_nexthops_callback ( -// struct rfapi_ip_addr *target, - struct rfapi_next_hop_entry *next_hops, - void *userdata) +static void test_nexthops_callback( + // struct rfapi_ip_addr *target, + struct rfapi_next_hop_entry *next_hops, void *userdata) { - void *stream = userdata; + void *stream = userdata; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; - fp (out, "Nexthops Callback, Target=("); - //rfapiPrintRfapiIpAddr(stream, target); - fp (out, ")\n"); + fp(out, "Nexthops Callback, Target=("); + // rfapiPrintRfapiIpAddr(stream, target); + fp(out, ")\n"); - rfapiPrintNhl (stream, next_hops); + rfapiPrintNhl(stream, next_hops); - rfapi_free_next_hop_list (next_hops); + rfapi_free_next_hop_list(next_hops); } DEFUN (debug_rfapi_open, @@ -3161,35 +2938,35 @@ DEFUN (debug_rfapi_open, "underlay network interface IPv4 address\n" "underlay network interface IPv6 address\n") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - uint32_t lifetime; - int rc; - rfapi_handle handle; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + uint32_t lifetime; + int rc; + rfapi_handle handle; - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) - return rc; + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) + return rc; - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) - return rc; + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) + return rc; - rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp_get_default ()), - &vn, &un, /*&uo */ NULL, &lifetime, NULL, &handle); + rc = rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp_get_default()), &vn, + &un, /*&uo */ NULL, &lifetime, NULL, &handle); - vty_out (vty, "rfapi_open: status %d, handle %p, lifetime %d\n", - rc, handle, lifetime); + vty_out(vty, "rfapi_open: status %d, handle %p, lifetime %d\n", rc, + handle, lifetime); - rc = rfapi_set_response_cb (handle, test_nexthops_callback); + rc = rfapi_set_response_cb(handle, test_nexthops_callback); - vty_out (vty, "rfapi_set_response_cb: status %d\n", rc); + vty_out(vty, "rfapi_set_response_cb: status %d\n", rc); - return CMD_SUCCESS; + return CMD_SUCCESS; } @@ -3206,37 +2983,36 @@ DEFUN (debug_rfapi_close_vn_un, "underlay network interface IPv4 address\n" "underlay network interface IPv6 address\n") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - rfapi_handle handle; - int rc; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + rfapi_handle handle; + int rc; - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) - return rc; + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) + return rc; - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) - return rc; + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) + return rc; - if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) - { - vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", - argv[4]->arg, argv[6]->arg); - return CMD_WARNING_CONFIG_FAILED; - } + if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { + vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", + argv[4]->arg, argv[6]->arg); + return CMD_WARNING_CONFIG_FAILED; + } - rc = rfapi_close (handle); + rc = rfapi_close(handle); - vty_out (vty, "rfapi_close(handle=%p): status %d\n", handle,rc); + vty_out(vty, "rfapi_close(handle=%p): status %d\n", handle, rc); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_rfapi_close_rfd, @@ -3247,23 +3023,22 @@ DEFUN (debug_rfapi_close_rfd, "rfapi_close\n" "indicate handle follows\n" "rfapi handle in hexadecimal\n") { - rfapi_handle handle; - int rc; - char *endptr = NULL; + rfapi_handle handle; + int rc; + char *endptr = NULL; - handle = (rfapi_handle) (uintptr_t) (strtoull (argv[4]->arg, &endptr, 16)); + handle = (rfapi_handle)(uintptr_t)(strtoull(argv[4]->arg, &endptr, 16)); - if (*endptr != '\0' || (uintptr_t) handle == UINTPTR_MAX) - { - vty_out (vty, "Invalid value: %s\n", argv[4]->arg); - return CMD_WARNING_CONFIG_FAILED; - } + if (*endptr != '\0' || (uintptr_t)handle == UINTPTR_MAX) { + vty_out(vty, "Invalid value: %s\n", argv[4]->arg); + return CMD_WARNING_CONFIG_FAILED; + } - rc = rfapi_close (handle); + rc = rfapi_close(handle); - vty_out (vty, "rfapi_close(handle=%p): status %d\n", handle,rc); + vty_out(vty, "rfapi_close(handle=%p): status %d\n", handle, rc); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_rfapi_register_vn_un, @@ -3284,68 +3059,61 @@ DEFUN (debug_rfapi_register_vn_un, "indicate lifetime follows\n" "lifetime\n") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - rfapi_handle handle; - struct prefix pfx; - uint32_t lifetime; - struct rfapi_ip_prefix hpfx; - int rc; - - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) - return rc; - - - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) - return rc; - - - if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) - { - vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", - argv[4]->arg, argv[6]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - /* - * Get prefix to advertise - */ - if (!str2prefix (argv[8]->arg, &pfx)) - { - vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - if (pfx.family != AF_INET && pfx.family != AF_INET6) - { - vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - rfapiQprefix2Rprefix (&pfx, &hpfx); - - if (strmatch(argv[10]->text, "infinite")) - { - lifetime = RFAPI_INFINITE_LIFETIME; - } - else - { - lifetime = strtoul(argv[10]->arg, NULL, 10); - } - - - rc = rfapi_register (handle, &hpfx, lifetime, NULL, NULL, 0); - if (rc) - { - vty_out (vty, "rfapi_register failed with rc=%d (%s)\n", rc, - strerror(rc)); - } - - return CMD_SUCCESS; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + rfapi_handle handle; + struct prefix pfx; + uint32_t lifetime; + struct rfapi_ip_prefix hpfx; + int rc; + + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) + return rc; + + + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) + return rc; + + + if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { + vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", + argv[4]->arg, argv[6]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + /* + * Get prefix to advertise + */ + if (!str2prefix(argv[8]->arg, &pfx)) { + vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (pfx.family != AF_INET && pfx.family != AF_INET6) { + vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + rfapiQprefix2Rprefix(&pfx, &hpfx); + + if (strmatch(argv[10]->text, "infinite")) { + lifetime = RFAPI_INFINITE_LIFETIME; + } else { + lifetime = strtoul(argv[10]->arg, NULL, 10); + } + + + rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, 0); + if (rc) { + vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc, + strerror(rc)); + } + + return CMD_SUCCESS; } DEFUN (debug_rfapi_register_vn_un_l2o, @@ -3370,91 +3138,82 @@ DEFUN (debug_rfapi_register_vn_un_l2o, "indicate lni follows\n" "lni value range\n") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - rfapi_handle handle; - struct prefix pfx; - uint32_t lifetime; - struct rfapi_ip_prefix hpfx; - int rc; - struct rfapi_vn_option optary[10]; /* XXX must be big enough */ - struct rfapi_vn_option *opt = NULL; - int opt_next = 0; - - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) - return rc; - - - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) - return rc; - - - if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) - { - vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", - argv[4]->arg, argv[6]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - /* - * Get prefix to advertise - */ - if (!str2prefix (argv[8]->arg, &pfx)) - { - vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - if (pfx.family != AF_INET && pfx.family != AF_INET6) - { - vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - rfapiQprefix2Rprefix (&pfx, &hpfx); - - if (strmatch(argv[10]->text, "infinite")) - { - lifetime = RFAPI_INFINITE_LIFETIME; - } - else - { - lifetime = strtoul(argv[10]->arg, NULL, 10); - } - - /* L2 option parsing START */ - memset (optary, 0, sizeof (optary)); - optary[opt_next].v.l2addr.logical_net_id = strtoul(argv[14]->arg, NULL, 10); - if ((rc = rfapiStr2EthAddr (argv[12]->arg, &optary[opt_next].v.l2addr.macaddr))) - { - vty_out (vty, "Bad mac address \"%s\"\n", argv[12]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; - if (opt_next) - { - optary[opt_next - 1].next = optary + opt_next; - } - else - { - opt = optary; - } - ++opt_next; - /* L2 option parsing END */ - - /* TBD fixme */ - rc = rfapi_register (handle, &hpfx, lifetime, NULL /* &uo */ , opt, 0); - if (rc) - { - vty_out (vty, "rfapi_register failed with rc=%d (%s)\n", rc, - strerror(rc)); - } - - return CMD_SUCCESS; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + rfapi_handle handle; + struct prefix pfx; + uint32_t lifetime; + struct rfapi_ip_prefix hpfx; + int rc; + struct rfapi_vn_option optary[10]; /* XXX must be big enough */ + struct rfapi_vn_option *opt = NULL; + int opt_next = 0; + + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) + return rc; + + + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) + return rc; + + + if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { + vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", + argv[4]->arg, argv[6]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + /* + * Get prefix to advertise + */ + if (!str2prefix(argv[8]->arg, &pfx)) { + vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (pfx.family != AF_INET && pfx.family != AF_INET6) { + vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + rfapiQprefix2Rprefix(&pfx, &hpfx); + + if (strmatch(argv[10]->text, "infinite")) { + lifetime = RFAPI_INFINITE_LIFETIME; + } else { + lifetime = strtoul(argv[10]->arg, NULL, 10); + } + + /* L2 option parsing START */ + memset(optary, 0, sizeof(optary)); + optary[opt_next].v.l2addr.logical_net_id = + strtoul(argv[14]->arg, NULL, 10); + if ((rc = rfapiStr2EthAddr(argv[12]->arg, + &optary[opt_next].v.l2addr.macaddr))) { + vty_out(vty, "Bad mac address \"%s\"\n", argv[12]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; + if (opt_next) { + optary[opt_next - 1].next = optary + opt_next; + } else { + opt = optary; + } + ++opt_next; + /* L2 option parsing END */ + + /* TBD fixme */ + rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt, 0); + if (rc) { + vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc, + strerror(rc)); + } + + return CMD_SUCCESS; } @@ -3470,52 +3229,49 @@ DEFUN (debug_rfapi_unregister_vn_un, "underlay network interface address\n" "indicate prefix follows\n" "prefix") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - rfapi_handle handle; - struct prefix pfx; - struct rfapi_ip_prefix hpfx; - int rc; - - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) - return rc; - - - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) - return rc; - - - if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) - { - vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", - argv[4]->arg, argv[6]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - /* - * Get prefix to advertise - */ - if (!str2prefix (argv[8]->arg, &pfx)) - { - vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - if (pfx.family != AF_INET && pfx.family != AF_INET6) - { - vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - rfapiQprefix2Rprefix (&pfx, &hpfx); - - rfapi_register (handle, &hpfx, 0, NULL, NULL, 1); - - return CMD_SUCCESS; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + rfapi_handle handle; + struct prefix pfx; + struct rfapi_ip_prefix hpfx; + int rc; + + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) + return rc; + + + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) + return rc; + + + if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { + vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", + argv[4]->arg, argv[6]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + /* + * Get prefix to advertise + */ + if (!str2prefix(argv[8]->arg, &pfx)) { + vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (pfx.family != AF_INET && pfx.family != AF_INET6) { + vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + rfapiQprefix2Rprefix(&pfx, &hpfx); + + rfapi_register(handle, &hpfx, 0, NULL, NULL, 1); + + return CMD_SUCCESS; } DEFUN (debug_rfapi_query_vn_un, @@ -3534,60 +3290,57 @@ DEFUN (debug_rfapi_query_vn_un, "target IPv4 address\n" "target IPv6 address\n") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - struct rfapi_ip_addr target; - rfapi_handle handle; - int rc; - struct rfapi_next_hop_entry *pNextHopEntry; - - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) - return rc; - - - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) - return rc; - - - /* - * Get target addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[8]->arg, &target))) - return rc; - - - if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) - { - vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", - argv[4]->arg, argv[6]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - /* - * options parameter not used? Set to NULL for now - */ - rc = rfapi_query (handle, &target, NULL, &pNextHopEntry); - - if (rc) - { - vty_out (vty, "rfapi_query failed with rc=%d (%s)\n", rc, - strerror(rc)); - } - else - { - /* - * print nexthop list - */ - test_nexthops_callback ( /*&target, */ pNextHopEntry, vty); /* frees nh list! */ - } - - return CMD_SUCCESS; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + struct rfapi_ip_addr target; + rfapi_handle handle; + int rc; + struct rfapi_next_hop_entry *pNextHopEntry; + + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) + return rc; + + + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) + return rc; + + + /* + * Get target addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[8]->arg, &target))) + return rc; + + + if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { + vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", + argv[4]->arg, argv[6]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + /* + * options parameter not used? Set to NULL for now + */ + rc = rfapi_query(handle, &target, NULL, &pNextHopEntry); + + if (rc) { + vty_out(vty, "rfapi_query failed with rc=%d (%s)\n", rc, + strerror(rc)); + } else { + /* + * print nexthop list + */ + test_nexthops_callback(/*&target, */ pNextHopEntry, + vty); /* frees nh list! */ + } + + return CMD_SUCCESS; } @@ -3608,28 +3361,28 @@ DEFUN (debug_rfapi_query_vn_un_l2o, "indicate target MAC addr follows\n" "target MAC addr\n") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - struct rfapi_ip_addr target; - rfapi_handle handle; - int rc; - struct rfapi_next_hop_entry *pNextHopEntry; - struct rfapi_l2address_option l2o_buf; - struct bgp_tea_options hopt; - uint8_t valbuf[14]; - - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) - return rc; - - - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) - return rc; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + struct rfapi_ip_addr target; + rfapi_handle handle; + int rc; + struct rfapi_next_hop_entry *pNextHopEntry; + struct rfapi_l2address_option l2o_buf; + struct bgp_tea_options hopt; + uint8_t valbuf[14]; + + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) + return rc; + + + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) + return rc; #if 0 /* there is no IP target arg here ?????? */ @@ -3639,65 +3392,61 @@ DEFUN (debug_rfapi_query_vn_un_l2o, if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[2], &target))) return rc; #else - vty_out (vty, "%% This command is broken.\n"); - return CMD_WARNING_CONFIG_FAILED; + vty_out(vty, "%% This command is broken.\n"); + return CMD_WARNING_CONFIG_FAILED; #endif - if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) - { - vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", - argv[4]->arg, argv[6]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - /* - * Set up L2 parameters - */ - memset (&l2o_buf, 0, sizeof (l2o_buf)); - if (rfapiStr2EthAddr (argv[10]->arg, &l2o_buf.macaddr)) - { - vty_out (vty, "Bad mac address \"%s\"\n", argv[10]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - l2o_buf.logical_net_id = strtoul(argv[8]->arg, NULL, 10); - - /* construct option chain */ - - memset (valbuf, 0, sizeof (valbuf)); - memcpy (valbuf, &l2o_buf.macaddr.octet, ETHER_ADDR_LEN); - valbuf[11] = (l2o_buf.logical_net_id >> 16) & 0xff; - valbuf[12] = (l2o_buf.logical_net_id >> 8) & 0xff; - valbuf[13] = l2o_buf.logical_net_id & 0xff; - - memset (&hopt, 0, sizeof (hopt)); - hopt.options_count = 1; - hopt.options_length = sizeof (valbuf); /* is this right? */ - hopt.type = RFAPI_VN_OPTION_TYPE_L2ADDR; - hopt.length = sizeof (valbuf); - hopt.value = valbuf; - - - /* - * options parameter not used? Set to NULL for now - */ - rc = rfapi_query (handle, &target, &l2o_buf, &pNextHopEntry); - - if (rc) - { - vty_out (vty, "rfapi_query failed with rc=%d (%s)\n", rc, - strerror(rc)); - } - else - { - /* - * print nexthop list - */ - /* TBD enhance to print L2 information */ - test_nexthops_callback ( /*&target, */ pNextHopEntry, vty); /* frees nh list! */ - } - - return CMD_SUCCESS; + if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { + vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", + argv[4]->arg, argv[6]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + /* + * Set up L2 parameters + */ + memset(&l2o_buf, 0, sizeof(l2o_buf)); + if (rfapiStr2EthAddr(argv[10]->arg, &l2o_buf.macaddr)) { + vty_out(vty, "Bad mac address \"%s\"\n", argv[10]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + l2o_buf.logical_net_id = strtoul(argv[8]->arg, NULL, 10); + + /* construct option chain */ + + memset(valbuf, 0, sizeof(valbuf)); + memcpy(valbuf, &l2o_buf.macaddr.octet, ETHER_ADDR_LEN); + valbuf[11] = (l2o_buf.logical_net_id >> 16) & 0xff; + valbuf[12] = (l2o_buf.logical_net_id >> 8) & 0xff; + valbuf[13] = l2o_buf.logical_net_id & 0xff; + + memset(&hopt, 0, sizeof(hopt)); + hopt.options_count = 1; + hopt.options_length = sizeof(valbuf); /* is this right? */ + hopt.type = RFAPI_VN_OPTION_TYPE_L2ADDR; + hopt.length = sizeof(valbuf); + hopt.value = valbuf; + + + /* + * options parameter not used? Set to NULL for now + */ + rc = rfapi_query(handle, &target, &l2o_buf, &pNextHopEntry); + + if (rc) { + vty_out(vty, "rfapi_query failed with rc=%d (%s)\n", rc, + strerror(rc)); + } else { + /* + * print nexthop list + */ + /* TBD enhance to print L2 information */ + test_nexthops_callback(/*&target, */ pNextHopEntry, + vty); /* frees nh list! */ + } + + return CMD_SUCCESS; } @@ -3718,48 +3467,47 @@ DEFUN (debug_rfapi_query_done_vn_un, "Target IPv4 address\n" "Target IPv6 address\n") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - struct rfapi_ip_addr target; - rfapi_handle handle; - int rc; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + struct rfapi_ip_addr target; + rfapi_handle handle; + int rc; - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[5]->arg, &vn))) - return rc; + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[5]->arg, &vn))) + return rc; - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[7]->arg, &un))) - return rc; + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[7]->arg, &un))) + return rc; - /* - * Get target addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[9]->arg, &target))) - return rc; + /* + * Get target addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[9]->arg, &target))) + return rc; - if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) - { - vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", - argv[5]->arg, argv[7]->arg); - return CMD_WARNING_CONFIG_FAILED; - } + if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { + vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", + argv[5]->arg, argv[7]->arg); + return CMD_WARNING_CONFIG_FAILED; + } - /* - * options parameter not used? Set to NULL for now - */ - rc = rfapi_query_done (handle, &target); + /* + * options parameter not used? Set to NULL for now + */ + rc = rfapi_query_done(handle, &target); - vty_out (vty, "rfapi_query_done returned %d\n", rc); + vty_out(vty, "rfapi_query_done returned %d\n", rc); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (debug_rfapi_show_import, @@ -3770,83 +3518,82 @@ DEFUN (debug_rfapi_show_import, SHOW_STR "import\n") { - struct bgp *bgp; - struct rfapi *h; - struct rfapi_import_table *it; - char *s; - int first_l2 = 1; - - /* - * Show all import tables - */ - - bgp = bgp_get_default (); /* assume 1 instance for now */ - if (!bgp) - { - vty_out (vty, "No BGP instance\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - h = bgp->rfapi; - if (!h) - { - vty_out (vty, "No RFAPI instance\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* - * Iterate over all import tables; do a filtered import - * for the afi/safi combination - */ - - - for (it = h->imports; it; it = it->next) - { - s = ecommunity_ecom2str (it->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out (vty, "Import Table %p, RTs: %s\n", it, s); - XFREE (MTYPE_ECOMMUNITY_STR, s); - - rfapiShowImportTable (vty, "IP VPN", it->imported_vpn[AFI_IP], 1); - rfapiShowImportTable (vty, "IP ENCAP", it->imported_encap[AFI_IP], 0); - rfapiShowImportTable (vty, "IP6 VPN", it->imported_vpn[AFI_IP6], 1); - rfapiShowImportTable (vty, "IP6 ENCAP", it->imported_encap[AFI_IP6], 0); - } - - if (h->import_mac) - { - void *cursor = NULL; - uint32_t lni; - uintptr_t lni_as_ptr; - int rc; - char buf[BUFSIZ]; - - for (rc = - skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, - &cursor); !rc; - rc = - skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, - &cursor)) - { - - if (it->imported_vpn[AFI_L2VPN]) - { - lni = lni_as_ptr; - if (first_l2) - { - vty_out (vty, "\nLNI-based Ethernet Tables:\n"); - first_l2 = 0; - } - snprintf (buf, BUFSIZ, "L2VPN LNI=%u", lni); - rfapiShowImportTable (vty, buf, it->imported_vpn[AFI_L2VPN], 1); - } - } - } - - rfapiShowImportTable (vty, "CE IT - IP VPN", - h->it_ce->imported_vpn[AFI_IP], 1); - - return CMD_SUCCESS; + struct bgp *bgp; + struct rfapi *h; + struct rfapi_import_table *it; + char *s; + int first_l2 = 1; + + /* + * Show all import tables + */ + + bgp = bgp_get_default(); /* assume 1 instance for now */ + if (!bgp) { + vty_out(vty, "No BGP instance\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + h = bgp->rfapi; + if (!h) { + vty_out(vty, "No RFAPI instance\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* + * Iterate over all import tables; do a filtered import + * for the afi/safi combination + */ + + + for (it = h->imports; it; it = it->next) { + s = ecommunity_ecom2str(it->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vty_out(vty, "Import Table %p, RTs: %s\n", it, s); + XFREE(MTYPE_ECOMMUNITY_STR, s); + + rfapiShowImportTable(vty, "IP VPN", it->imported_vpn[AFI_IP], + 1); + rfapiShowImportTable(vty, "IP ENCAP", + it->imported_encap[AFI_IP], 0); + rfapiShowImportTable(vty, "IP6 VPN", it->imported_vpn[AFI_IP6], + 1); + rfapiShowImportTable(vty, "IP6 ENCAP", + it->imported_encap[AFI_IP6], 0); + } + + if (h->import_mac) { + void *cursor = NULL; + uint32_t lni; + uintptr_t lni_as_ptr; + int rc; + char buf[BUFSIZ]; + + for (rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr, + (void **)&it, &cursor); + !rc; + rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr, + (void **)&it, &cursor)) { + + if (it->imported_vpn[AFI_L2VPN]) { + lni = lni_as_ptr; + if (first_l2) { + vty_out(vty, + "\nLNI-based Ethernet Tables:\n"); + first_l2 = 0; + } + snprintf(buf, BUFSIZ, "L2VPN LNI=%u", lni); + rfapiShowImportTable( + vty, buf, it->imported_vpn[AFI_L2VPN], + 1); + } + } + } + + rfapiShowImportTable(vty, "CE IT - IP VPN", + h->it_ce->imported_vpn[AFI_IP], 1); + + return CMD_SUCCESS; } DEFUN (debug_rfapi_show_import_vn_un, @@ -3863,45 +3610,44 @@ DEFUN (debug_rfapi_show_import_vn_un, "underlay network interface IPv4 address\n" "underlay network interface IPv6 address\n") { - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - rfapi_handle handle; - int rc; - struct rfapi_descriptor *rfd; - - /* - * Get VN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[5]->arg, &vn))) - return rc; - - - /* - * Get UN addr - */ - if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[7]->arg, &un))) - return rc; - - - if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) - { - vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", - argv[5]->arg, argv[7]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - rfd = (struct rfapi_descriptor *) handle; - - rfapiShowImportTable (vty, "IP VPN", - rfd->import_table->imported_vpn[AFI_IP], 1); - rfapiShowImportTable (vty, "IP ENCAP", - rfd->import_table->imported_encap[AFI_IP], 0); - rfapiShowImportTable (vty, "IP6 VPN", - rfd->import_table->imported_vpn[AFI_IP6], 1); - rfapiShowImportTable (vty, "IP6 ENCAP", - rfd->import_table->imported_encap[AFI_IP6], 0); - - return CMD_SUCCESS; + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + rfapi_handle handle; + int rc; + struct rfapi_descriptor *rfd; + + /* + * Get VN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[5]->arg, &vn))) + return rc; + + + /* + * Get UN addr + */ + if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[7]->arg, &un))) + return rc; + + + if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { + vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", + argv[5]->arg, argv[7]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + + rfd = (struct rfapi_descriptor *)handle; + + rfapiShowImportTable(vty, "IP VPN", + rfd->import_table->imported_vpn[AFI_IP], 1); + rfapiShowImportTable(vty, "IP ENCAP", + rfd->import_table->imported_encap[AFI_IP], 0); + rfapiShowImportTable(vty, "IP6 VPN", + rfd->import_table->imported_vpn[AFI_IP6], 1); + rfapiShowImportTable(vty, "IP6 ENCAP", + rfd->import_table->imported_encap[AFI_IP6], 0); + + return CMD_SUCCESS; } DEFUN (debug_rfapi_response_omit_self, @@ -3912,25 +3658,25 @@ DEFUN (debug_rfapi_response_omit_self, "Omit self in RFP responses\n" "filter out self from responses\n" "leave self in responses\n") { - struct bgp *bgp = bgp_get_default (); - - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (!bgp->rfapi_cfg) - { - vty_out (vty, "VNC not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (strmatch(argv[3]->text, "on")) - SET_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP); - else - UNSET_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP); - - return CMD_SUCCESS; + struct bgp *bgp = bgp_get_default(); + + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (!bgp->rfapi_cfg) { + vty_out(vty, "VNC not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (strmatch(argv[3]->text, "on")) + SET_FLAG(bgp->rfapi_cfg->flags, + BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP); + else + UNSET_FLAG(bgp->rfapi_cfg->flags, + BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP); + + return CMD_SUCCESS; } @@ -3943,9 +3689,9 @@ DEFUN (skiplist_test_cli, "skiplist command\n" "test\n") { - skiplist_test (vty); + skiplist_test(vty); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (skiplist_debug_cli, @@ -3954,151 +3700,139 @@ DEFUN (skiplist_debug_cli, "skiplist command\n" "debug\n") { - skiplist_debug (vty, NULL); - return CMD_SUCCESS; + skiplist_debug(vty, NULL); + return CMD_SUCCESS; } #endif /* RFAPI_DEBUG_SKIPLIST_CLI */ -void -rfapi_init (void) +void rfapi_init(void) { - bgp_rfapi_cfg_init (); - vnc_debug_init(); + bgp_rfapi_cfg_init(); + vnc_debug_init(); - install_element (ENABLE_NODE, &debug_rfapi_show_import_cmd); - install_element (ENABLE_NODE, &debug_rfapi_show_import_vn_un_cmd); + install_element(ENABLE_NODE, &debug_rfapi_show_import_cmd); + install_element(ENABLE_NODE, &debug_rfapi_show_import_vn_un_cmd); - install_element (ENABLE_NODE, &debug_rfapi_open_cmd); - install_element (ENABLE_NODE, &debug_rfapi_close_vn_un_cmd); - install_element (ENABLE_NODE, &debug_rfapi_close_rfd_cmd); - install_element (ENABLE_NODE, &debug_rfapi_register_vn_un_cmd); - install_element (ENABLE_NODE, &debug_rfapi_unregister_vn_un_cmd); - install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_cmd); - install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_done_cmd); - install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_l2o_cmd); + install_element(ENABLE_NODE, &debug_rfapi_open_cmd); + install_element(ENABLE_NODE, &debug_rfapi_close_vn_un_cmd); + install_element(ENABLE_NODE, &debug_rfapi_close_rfd_cmd); + install_element(ENABLE_NODE, &debug_rfapi_register_vn_un_cmd); + install_element(ENABLE_NODE, &debug_rfapi_unregister_vn_un_cmd); + install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_cmd); + install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_done_cmd); + install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_l2o_cmd); - install_element (ENABLE_NODE, &debug_rfapi_response_omit_self_cmd); + install_element(ENABLE_NODE, &debug_rfapi_response_omit_self_cmd); - /* Need the following show commands for gpz test scripts */ - install_element (ENABLE_NODE, &debug_rfapi_show_nves_cmd); - install_element (ENABLE_NODE, &debug_rfapi_show_nves_vn_un_cmd); - install_element (ENABLE_NODE, &debug_rfapi_register_vn_un_l2o_cmd); + /* Need the following show commands for gpz test scripts */ + install_element(ENABLE_NODE, &debug_rfapi_show_nves_cmd); + install_element(ENABLE_NODE, &debug_rfapi_show_nves_vn_un_cmd); + install_element(ENABLE_NODE, &debug_rfapi_register_vn_un_l2o_cmd); #ifdef RFAPI_DEBUG_SKIPLIST_CLI - install_element (ENABLE_NODE, &skiplist_test_cli_cmd); - install_element (ENABLE_NODE, &skiplist_debug_cli_cmd); + install_element(ENABLE_NODE, &skiplist_test_cli_cmd); + install_element(ENABLE_NODE, &skiplist_debug_cli_cmd); #endif - rfapi_vty_init (); + rfapi_vty_init(); } #ifdef DEBUG_RFAPI -static void -rfapi_print_exported (struct bgp *bgp) +static void rfapi_print_exported(struct bgp *bgp) { - struct bgp_node *rdn; - struct bgp_node *rn; - struct bgp_info *bi; - - if (!bgp) - return; - - for (rdn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rdn; - rdn = bgp_route_next (rdn)) - { - if (!rdn->info) - continue; - fprintf (stderr, "%s: vpn rdn=%p\n", __func__, rdn); - for (rn = bgp_table_top (rdn->info); rn; rn = bgp_route_next (rn)) - { - if (!rn->info) - continue; - fprintf (stderr, "%s: rn=%p\n", __func__, rn); - for (bi = rn->info; bi; bi = bi->next) - { - rfapiPrintBi ((void *) 2, bi); /* 2 => stderr */ - } - } - } - for (rdn = bgp_table_top (bgp->rib[AFI_IP][SAFI_ENCAP]); rdn; - rdn = bgp_route_next (rdn)) - { - if (!rdn->info) - continue; - fprintf (stderr, "%s: encap rdn=%p\n", __func__, rdn); - for (rn = bgp_table_top (rdn->info); rn; rn = bgp_route_next (rn)) - { - if (!rn->info) - continue; - fprintf (stderr, "%s: rn=%p\n", __func__, rn); - for (bi = rn->info; bi; bi = bi->next) - { - rfapiPrintBi ((void *) 2, bi); /* 2 => stderr */ - } - } - } - + struct bgp_node *rdn; + struct bgp_node *rn; + struct bgp_info *bi; + + if (!bgp) + return; + + for (rdn = bgp_table_top(bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rdn; + rdn = bgp_route_next(rdn)) { + if (!rdn->info) + continue; + fprintf(stderr, "%s: vpn rdn=%p\n", __func__, rdn); + for (rn = bgp_table_top(rdn->info); rn; + rn = bgp_route_next(rn)) { + if (!rn->info) + continue; + fprintf(stderr, "%s: rn=%p\n", __func__, rn); + for (bi = rn->info; bi; bi = bi->next) { + rfapiPrintBi((void *)2, bi); /* 2 => stderr */ + } + } + } + for (rdn = bgp_table_top(bgp->rib[AFI_IP][SAFI_ENCAP]); rdn; + rdn = bgp_route_next(rdn)) { + if (!rdn->info) + continue; + fprintf(stderr, "%s: encap rdn=%p\n", __func__, rdn); + for (rn = bgp_table_top(rdn->info); rn; + rn = bgp_route_next(rn)) { + if (!rn->info) + continue; + fprintf(stderr, "%s: rn=%p\n", __func__, rn); + for (bi = rn->info; bi; bi = bi->next) { + rfapiPrintBi((void *)2, bi); /* 2 => stderr */ + } + } + } } #endif /* defined(DEBUG_RFAPI) */ /* * Free all memory to prepare for clean exit as seen by valgrind memcheck */ -void -rfapi_delete (struct bgp *bgp) +void rfapi_delete(struct bgp *bgp) { - extern void rfp_clear_vnc_nve_all (void); /* can't fix correctly yet */ - - /* - * This clears queries and registered routes, and closes nves - */ - if (bgp->rfapi) - rfp_clear_vnc_nve_all (); - bgp_rfapi_cfg_destroy (bgp, bgp->rfapi_cfg); - bgp->rfapi_cfg = NULL; - bgp_rfapi_destroy (bgp, bgp->rfapi); - bgp->rfapi = NULL; + extern void rfp_clear_vnc_nve_all(void); /* can't fix correctly yet */ + + /* + * This clears queries and registered routes, and closes nves + */ + if (bgp->rfapi) + rfp_clear_vnc_nve_all(); + bgp_rfapi_cfg_destroy(bgp, bgp->rfapi_cfg); + bgp->rfapi_cfg = NULL; + bgp_rfapi_destroy(bgp, bgp->rfapi); + bgp->rfapi = NULL; #ifdef DEBUG_RFAPI - /* - * show what's left in the BGP MPLSVPN RIB - */ - rfapi_print_exported (bgp); + /* + * show what's left in the BGP MPLSVPN RIB + */ + rfapi_print_exported(bgp); #endif - } -int -rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn) +int rfapi_set_autord_from_vn(struct prefix_rd *rd, struct rfapi_ip_addr *vn) { - vnc_zlog_debug_verbose ("%s: auto-assigning RD", __func__); - if (vn->addr_family != AF_INET - && vn->addr_family != AF_INET6) - { - vnc_zlog_debug_verbose ("%s: can't auto-assign RD, VN addr family is not IPv4" - "|v6" - , __func__); - return EAFNOSUPPORT; - } - rd->family = AF_UNSPEC; - rd->prefixlen = 64; - rd->val[1] = RD_TYPE_IP; - if (vn->addr_family == AF_INET) - { - memcpy (rd->val + 2, &vn->addr.v4.s_addr, 4); - } - else - { /* is v6 */ - memcpy (rd->val + 2, &vn->addr.v6.s6_addr32[3], 4);/* low order 4 bytes */ - } - { - char buf[BUFSIZ]; - buf[0] = 0; - prefix_rd2str (rd, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_verbose ("%s: auto-RD is set to %s", __func__, buf); - } - return 0; + vnc_zlog_debug_verbose("%s: auto-assigning RD", __func__); + if (vn->addr_family != AF_INET && vn->addr_family != AF_INET6) { + vnc_zlog_debug_verbose( + "%s: can't auto-assign RD, VN addr family is not IPv4" + "|v6", + __func__); + return EAFNOSUPPORT; + } + rd->family = AF_UNSPEC; + rd->prefixlen = 64; + rd->val[1] = RD_TYPE_IP; + if (vn->addr_family == AF_INET) { + memcpy(rd->val + 2, &vn->addr.v4.s_addr, 4); + } else { /* is v6 */ + memcpy(rd->val + 2, &vn->addr.v6.s6_addr32[3], + 4); /* low order 4 bytes */ + } + { + char buf[BUFSIZ]; + buf[0] = 0; + prefix_rd2str(rd, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_verbose("%s: auto-RD is set to %s", __func__, + buf); + } + return 0; } /*------------------------------------------ @@ -4106,7 +3840,7 @@ rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn) * * Find bgp instance pointer based on value returned by rfp_start * - * input: + * input: * rfp_start_val value returned by rfp_startor * NULL (=get default instance) * @@ -4118,19 +3852,19 @@ rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn) * NULL = not found * --------------------------------------------*/ -struct bgp * -rfapi_bgp_lookup_by_rfp (void *rfp_start_val) +struct bgp *rfapi_bgp_lookup_by_rfp(void *rfp_start_val) { - struct bgp *bgp = NULL; - struct listnode *node, *nnode; - - if (rfp_start_val == NULL) - bgp = bgp_get_default (); - else - for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp)) - if (bgp->rfapi != NULL && bgp->rfapi->rfp == rfp_start_val) - return bgp; - return bgp; + struct bgp *bgp = NULL; + struct listnode *node, *nnode; + + if (rfp_start_val == NULL) + bgp = bgp_get_default(); + else + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) + if (bgp->rfapi != NULL + && bgp->rfapi->rfp == rfp_start_val) + return bgp; + return bgp; } /*------------------------------------------ @@ -4138,7 +3872,7 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val) * * Find bgp instance pointer based on value returned by rfp_start * - * input: + * input: * bgp bgp instance pointer * * output: @@ -4149,91 +3883,81 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val) * NULL = not found * --------------------------------------------*/ -void * -rfapi_get_rfp_start_val_by_bgp (struct bgp *bgp) +void *rfapi_get_rfp_start_val_by_bgp(struct bgp *bgp) { - if (!bgp || !bgp->rfapi) - return NULL; - return bgp->rfapi->rfp; + if (!bgp || !bgp->rfapi) + return NULL; + return bgp->rfapi->rfp; } /*********************************************************************** * RFP group specific configuration ***********************************************************************/ -static void * -rfapi_rfp_get_or_init_group_config_default ( - struct rfapi_cfg *rfc, - struct vty *vty, - uint32_t size) +static void *rfapi_rfp_get_or_init_group_config_default(struct rfapi_cfg *rfc, + struct vty *vty, + uint32_t size) { - if (rfc->default_rfp_cfg == NULL && size > 0) - { - rfc->default_rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size); - vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size); - - } - return rfc->default_rfp_cfg; + if (rfc->default_rfp_cfg == NULL && size > 0) { + rfc->default_rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size); + vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__, + size); + } + return rfc->default_rfp_cfg; } -static void * -rfapi_rfp_get_or_init_group_config_nve ( - struct rfapi_cfg *rfc, - struct vty *vty, - uint32_t size) +static void *rfapi_rfp_get_or_init_group_config_nve(struct rfapi_cfg *rfc, + struct vty *vty, + uint32_t size) { - struct rfapi_nve_group_cfg *rfg = VTY_GET_CONTEXT_SUB(rfapi_nve_group_cfg); - - /* make sure group is still in list */ - if (!rfg || !listnode_lookup (rfc->nve_groups_sequential, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current NVE group no longer exists\n"); - return NULL; - } - - if (rfg->rfp_cfg == NULL && size > 0) - { - rfg->rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size); - vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size); - - } - return rfg->rfp_cfg; + struct rfapi_nve_group_cfg *rfg = + VTY_GET_CONTEXT_SUB(rfapi_nve_group_cfg); + + /* make sure group is still in list */ + if (!rfg || !listnode_lookup(rfc->nve_groups_sequential, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current NVE group no longer exists\n"); + return NULL; + } + + if (rfg->rfp_cfg == NULL && size > 0) { + rfg->rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size); + vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__, + size); + } + return rfg->rfp_cfg; } -static void * -rfapi_rfp_get_or_init_group_config_l2 ( - struct rfapi_cfg *rfc, - struct vty *vty, - uint32_t size) +static void *rfapi_rfp_get_or_init_group_config_l2(struct rfapi_cfg *rfc, + struct vty *vty, + uint32_t size) { - struct rfapi_l2_group_cfg *rfg = VTY_GET_CONTEXT_SUB(rfapi_l2_group_cfg); - - /* make sure group is still in list */ - if (!rfg || !listnode_lookup (rfc->l2_groups, rfg)) - { - /* Not in list anymore */ - vty_out (vty, "Current L2 group no longer exists\n"); - return NULL; - } - if (rfg->rfp_cfg == NULL && size > 0) - { - rfg->rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size); - vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size); - - } - return rfg->rfp_cfg; + struct rfapi_l2_group_cfg *rfg = + VTY_GET_CONTEXT_SUB(rfapi_l2_group_cfg); + + /* make sure group is still in list */ + if (!rfg || !listnode_lookup(rfc->l2_groups, rfg)) { + /* Not in list anymore */ + vty_out(vty, "Current L2 group no longer exists\n"); + return NULL; + } + if (rfg->rfp_cfg == NULL && size > 0) { + rfg->rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size); + vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__, + size); + } + return rfg->rfp_cfg; } /*------------------------------------------ * rfapi_rfp_init_group_config_ptr_vty * * This is used to init or return a previously init'ed group specific - * configuration pointer. Group is identified by vty context. + * configuration pointer. Group is identified by vty context. * NOTE: size is ignored when a previously init'ed value is returned. * RFAPI frees rfp_cfg_group when group is deleted during reconfig, * bgp restart or shutdown. * - * input: + * input: * rfp_start_val value returned by rfp_start * type group type * vty quagga vty context @@ -4242,46 +3966,43 @@ rfapi_rfp_get_or_init_group_config_l2 ( * output: * none * - * return value: + * return value: * rfp_cfg_group NULL or Pointer to configuration structure --------------------------------------------*/ -void * -rfapi_rfp_init_group_config_ptr_vty ( - void *rfp_start_val, - rfapi_rfp_cfg_group_type type, - struct vty *vty, - uint32_t size) +void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val, + rfapi_rfp_cfg_group_type type, + struct vty *vty, uint32_t size) { - struct bgp *bgp; - void *ret = NULL; - - if (rfp_start_val == NULL || vty == NULL) - return NULL; - - bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - if (!bgp || !bgp->rfapi_cfg) - return NULL; - - switch (type) - { - case RFAPI_RFP_CFG_GROUP_DEFAULT: - ret = rfapi_rfp_get_or_init_group_config_default (bgp->rfapi_cfg, - vty, size); - break; - case RFAPI_RFP_CFG_GROUP_NVE: - ret = rfapi_rfp_get_or_init_group_config_nve (bgp->rfapi_cfg, - vty, size); - break; - case RFAPI_RFP_CFG_GROUP_L2: - ret = rfapi_rfp_get_or_init_group_config_l2 (bgp->rfapi_cfg, vty, size); - break; - default: - zlog_err ("%s: Unknown group type=%d", __func__, type); - /* should never happen */ - assert ("Unknown type" == NULL); - break; - } - return ret; + struct bgp *bgp; + void *ret = NULL; + + if (rfp_start_val == NULL || vty == NULL) + return NULL; + + bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + if (!bgp || !bgp->rfapi_cfg) + return NULL; + + switch (type) { + case RFAPI_RFP_CFG_GROUP_DEFAULT: + ret = rfapi_rfp_get_or_init_group_config_default(bgp->rfapi_cfg, + vty, size); + break; + case RFAPI_RFP_CFG_GROUP_NVE: + ret = rfapi_rfp_get_or_init_group_config_nve(bgp->rfapi_cfg, + vty, size); + break; + case RFAPI_RFP_CFG_GROUP_L2: + ret = rfapi_rfp_get_or_init_group_config_l2(bgp->rfapi_cfg, vty, + size); + break; + default: + zlog_err("%s: Unknown group type=%d", __func__, type); + /* should never happen */ + assert("Unknown type" == NULL); + break; + } + return ret; } /*------------------------------------------ @@ -4290,9 +4011,9 @@ rfapi_rfp_init_group_config_ptr_vty ( * This is used to get group specific configuration pointer. * Group is identified by type and vty context. * RFAPI frees rfp_cfg_group when group is deleted during reconfig, - * bgp restart or shutdown. + * bgp restart or shutdown. * - * input: + * input: * rfp_start_val value returned by rfp_start * type group type * vty quagga vty context @@ -4301,64 +4022,56 @@ rfapi_rfp_init_group_config_ptr_vty ( * none * * return value: - * rfp_cfg_group Pointer to configuration structure + * rfp_cfg_group Pointer to configuration structure --------------------------------------------*/ -void * -rfapi_rfp_get_group_config_ptr_vty ( - void *rfp_start_val, - rfapi_rfp_cfg_group_type type, - struct vty *vty) +void *rfapi_rfp_get_group_config_ptr_vty(void *rfp_start_val, + rfapi_rfp_cfg_group_type type, + struct vty *vty) { - return rfapi_rfp_init_group_config_ptr_vty (rfp_start_val, type, vty, 0); + return rfapi_rfp_init_group_config_ptr_vty(rfp_start_val, type, vty, 0); } static void * -rfapi_rfp_get_group_config_name_nve ( - struct rfapi_cfg *rfc, - const char *name, - void *criteria, - rfp_group_config_search_cb_t *search_cb) +rfapi_rfp_get_group_config_name_nve(struct rfapi_cfg *rfc, const char *name, + void *criteria, + rfp_group_config_search_cb_t *search_cb) { - struct rfapi_nve_group_cfg *rfg; - struct listnode *node; - - for (ALL_LIST_ELEMENTS_RO (rfc->nve_groups_sequential, node, rfg)) - { - if (!strcmp (rfg->name, name) && /* name match */ - (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg))) - return rfg->rfp_cfg; - } - return NULL; + struct rfapi_nve_group_cfg *rfg; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(rfc->nve_groups_sequential, node, rfg)) { + if (!strcmp(rfg->name, name) && /* name match */ + (search_cb == NULL || !search_cb(criteria, rfg->rfp_cfg))) + return rfg->rfp_cfg; + } + return NULL; } static void * -rfapi_rfp_get_group_config_name_l2 ( - struct rfapi_cfg *rfc, - const char *name, - void *criteria, - rfp_group_config_search_cb_t *search_cb) +rfapi_rfp_get_group_config_name_l2(struct rfapi_cfg *rfc, const char *name, + void *criteria, + rfp_group_config_search_cb_t *search_cb) { - struct rfapi_l2_group_cfg *rfg; - struct listnode *node; - - for (ALL_LIST_ELEMENTS_RO (rfc->l2_groups, node, rfg)) - { - if (!strcmp (rfg->name, name) && /* name match */ - (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg))) - return rfg->rfp_cfg; - } - return NULL; + struct rfapi_l2_group_cfg *rfg; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(rfc->l2_groups, node, rfg)) { + if (!strcmp(rfg->name, name) && /* name match */ + (search_cb == NULL || !search_cb(criteria, rfg->rfp_cfg))) + return rfg->rfp_cfg; + } + return NULL; } /*------------------------------------------ * rfapi_rfp_get_group_config_ptr_name * * This is used to get group specific configuration pointer. - * Group is identified by type and name context. + * Group is identified by type and name context. * RFAPI frees rfp_cfg_group when group is deleted during reconfig, * bgp restart or shutdown. * - * input: + * input: * rfp_start_val value returned by rfp_start * type group type * name group name @@ -4369,46 +4082,41 @@ rfapi_rfp_get_group_config_name_l2 ( * none * * return value: - * rfp_cfg_group Pointer to configuration structure + * rfp_cfg_group Pointer to configuration structure --------------------------------------------*/ -void * -rfapi_rfp_get_group_config_ptr_name ( - void *rfp_start_val, - rfapi_rfp_cfg_group_type type, - const char *name, - void *criteria, - rfp_group_config_search_cb_t *search_cb) +void *rfapi_rfp_get_group_config_ptr_name( + void *rfp_start_val, rfapi_rfp_cfg_group_type type, const char *name, + void *criteria, rfp_group_config_search_cb_t *search_cb) { - struct bgp *bgp; - void *ret = NULL; - - if (rfp_start_val == NULL || name == NULL) - return NULL; - - bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - if (!bgp || !bgp->rfapi_cfg) - return NULL; - - switch (type) - { - case RFAPI_RFP_CFG_GROUP_DEFAULT: - ret = bgp->rfapi_cfg->default_rfp_cfg; - break; - case RFAPI_RFP_CFG_GROUP_NVE: - ret = rfapi_rfp_get_group_config_name_nve (bgp->rfapi_cfg, - name, criteria, search_cb); - break; - case RFAPI_RFP_CFG_GROUP_L2: - ret = rfapi_rfp_get_group_config_name_l2 (bgp->rfapi_cfg, - name, criteria, search_cb); - break; - default: - zlog_err ("%s: Unknown group type=%d", __func__, type); - /* should never happen */ - assert ("Unknown type" == NULL); - break; - } - return ret; + struct bgp *bgp; + void *ret = NULL; + + if (rfp_start_val == NULL || name == NULL) + return NULL; + + bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + if (!bgp || !bgp->rfapi_cfg) + return NULL; + + switch (type) { + case RFAPI_RFP_CFG_GROUP_DEFAULT: + ret = bgp->rfapi_cfg->default_rfp_cfg; + break; + case RFAPI_RFP_CFG_GROUP_NVE: + ret = rfapi_rfp_get_group_config_name_nve(bgp->rfapi_cfg, name, + criteria, search_cb); + break; + case RFAPI_RFP_CFG_GROUP_L2: + ret = rfapi_rfp_get_group_config_name_l2(bgp->rfapi_cfg, name, + criteria, search_cb); + break; + default: + zlog_err("%s: Unknown group type=%d", __func__, type); + /* should never happen */ + assert("Unknown type" == NULL); + break; + } + return ret; } /*------------------------------------------ @@ -4419,7 +4127,7 @@ rfapi_rfp_get_group_config_ptr_name ( * RFAPI frees rfp_cfg_group when group is deleted during reconfig, * bgp restart or shutdown. * - * input: + * input: * rfp_start_val value returned by rfp_start * type group type * logical_net_id group logical network identifier @@ -4430,35 +4138,34 @@ rfapi_rfp_get_group_config_ptr_name ( * none * * return value: - * rfp_cfg_group Pointer to configuration structure + * rfp_cfg_group Pointer to configuration structure --------------------------------------------*/ void * -rfapi_rfp_get_l2_group_config_ptr_lni ( - void *rfp_start_val, - uint32_t logical_net_id, - void *criteria, - rfp_group_config_search_cb_t *search_cb) +rfapi_rfp_get_l2_group_config_ptr_lni(void *rfp_start_val, + uint32_t logical_net_id, void *criteria, + rfp_group_config_search_cb_t *search_cb) { - struct bgp *bgp; - struct rfapi_l2_group_cfg *rfg; - struct listnode *node; - - if (rfp_start_val == NULL) - return NULL; - - bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - if (!bgp || !bgp->rfapi_cfg) - return NULL; - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->l2_groups, node, rfg)) - { - if (rfg->logical_net_id == logical_net_id && - (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg))) - { - if (rfg->rfp_cfg == NULL) - vnc_zlog_debug_verbose ("%s: returning rfp group config for lni=0", __func__); - return rfg->rfp_cfg; - } - } - return NULL; + struct bgp *bgp; + struct rfapi_l2_group_cfg *rfg; + struct listnode *node; + + if (rfp_start_val == NULL) + return NULL; + + bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + if (!bgp || !bgp->rfapi_cfg) + return NULL; + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->l2_groups, node, rfg)) { + if (rfg->logical_net_id == logical_net_id + && (search_cb == NULL + || !search_cb(criteria, rfg->rfp_cfg))) { + if (rfg->rfp_cfg == NULL) + vnc_zlog_debug_verbose( + "%s: returning rfp group config for lni=0", + __func__); + return rfg->rfp_cfg; + } + } + return NULL; } diff --git a/bgpd/rfapi/rfapi.h b/bgpd/rfapi/rfapi.h index 11d41c9d1d..8eb0d717df 100644 --- a/bgpd/rfapi/rfapi.h +++ b/bgpd/rfapi/rfapi.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -32,138 +32,127 @@ #include "bgpd/bgp_encap_types.h" /* probably ought to have a field-specific define in config.h */ -# ifndef s6_addr32 /* for solaris/bsd */ -# ifdef SOLARIS_IPV6 +#ifndef s6_addr32 /* for solaris/bsd */ +#ifdef SOLARIS_IPV6 # define s6_addr32 _S6_un._S6_u32 -# else +#else # define s6_addr32 __u6_addr.__u6_addr32 -# endif -# endif +#endif +#endif #define RFAPI_V4_ADDR 0x04 #define RFAPI_V6_ADDR 0x06 #define RFAPI_SHOW_STR "VNC information\n" -struct rfapi_ip_addr -{ - uint8_t addr_family; /* AF_INET | AF_INET6 */ - union - { - struct in_addr v4; /* in network order */ - struct in6_addr v6; /* in network order */ - } addr; +struct rfapi_ip_addr { + uint8_t addr_family; /* AF_INET | AF_INET6 */ + union { + struct in_addr v4; /* in network order */ + struct in6_addr v6; /* in network order */ + } addr; }; -struct rfapi_ip_prefix -{ - uint8_t length; - uint8_t cost; /* bgp local pref = 255 - cost */ - struct rfapi_ip_addr prefix; +struct rfapi_ip_prefix { + uint8_t length; + uint8_t cost; /* bgp local pref = 255 - cost */ + struct rfapi_ip_addr prefix; }; -struct rfapi_nexthop -{ - struct prefix addr; - uint8_t cost; +struct rfapi_nexthop { + struct prefix addr; + uint8_t cost; }; -struct rfapi_next_hop_entry -{ - struct rfapi_next_hop_entry *next; - struct rfapi_ip_prefix prefix; - uint32_t lifetime; - struct rfapi_ip_addr un_address; - struct rfapi_ip_addr vn_address; - struct rfapi_vn_option *vn_options; - struct rfapi_un_option *un_options; +struct rfapi_next_hop_entry { + struct rfapi_next_hop_entry *next; + struct rfapi_ip_prefix prefix; + uint32_t lifetime; + struct rfapi_ip_addr un_address; + struct rfapi_ip_addr vn_address; + struct rfapi_vn_option *vn_options; + struct rfapi_un_option *un_options; }; #define RFAPI_REMOVE_RESPONSE_LIFETIME 0 #define RFAPI_INFINITE_LIFETIME 0xFFFFFFFF -struct rfapi_l2address_option -{ - struct ethaddr macaddr; /* use 0 to assign label to IP prefix */ - uint32_t label; /* 20bit label in low bits, no TC, S, or TTL */ - uint32_t logical_net_id; /* ~= EVPN Ethernet Segment Id, - must not be zero for mac regis. */ - uint8_t local_nve_id; - uint16_t tag_id; /* EVPN Ethernet Tag ID, 0 = none */ +struct rfapi_l2address_option { + struct ethaddr macaddr; /* use 0 to assign label to IP prefix */ + uint32_t label; /* 20bit label in low bits, no TC, S, or TTL */ + uint32_t logical_net_id; /* ~= EVPN Ethernet Segment Id, + must not be zero for mac regis. */ + uint8_t local_nve_id; + uint16_t tag_id; /* EVPN Ethernet Tag ID, 0 = none */ }; -typedef enum -{ - RFAPI_UN_OPTION_TYPE_PROVISIONAL, /* internal use only */ - RFAPI_UN_OPTION_TYPE_TUNNELTYPE, +typedef enum { + RFAPI_UN_OPTION_TYPE_PROVISIONAL, /* internal use only */ + RFAPI_UN_OPTION_TYPE_TUNNELTYPE, } rfapi_un_option_type; -struct rfapi_tunneltype_option -{ - bgp_encap_types type; - union - { - struct bgp_encap_type_reserved reserved; - struct bgp_encap_type_l2tpv3_over_ip l2tpv3_ip; - struct bgp_encap_type_gre gre; - struct bgp_encap_type_transmit_tunnel_endpoint transmit_tunnel_endpoint; - struct bgp_encap_type_ipsec_in_tunnel_mode ipsec_tunnel; - struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode ip_ipsec; - struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode mpls_ipsec; - struct bgp_encap_type_ip_in_ip ip_ip; - struct bgp_encap_type_vxlan vxlan; - struct bgp_encap_type_nvgre nvgre; - struct bgp_encap_type_mpls mpls; - struct bgp_encap_type_mpls_in_gre mpls_gre; - struct bgp_encap_type_vxlan_gpe vxlan_gpe; - struct bgp_encap_type_mpls_in_udp mpls_udp; - struct bgp_encap_type_pbb pbb; - } bgpinfo; +struct rfapi_tunneltype_option { + bgp_encap_types type; + union { + struct bgp_encap_type_reserved reserved; + struct bgp_encap_type_l2tpv3_over_ip l2tpv3_ip; + struct bgp_encap_type_gre gre; + struct bgp_encap_type_transmit_tunnel_endpoint + transmit_tunnel_endpoint; + struct bgp_encap_type_ipsec_in_tunnel_mode ipsec_tunnel; + struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode + ip_ipsec; + struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode + mpls_ipsec; + struct bgp_encap_type_ip_in_ip ip_ip; + struct bgp_encap_type_vxlan vxlan; + struct bgp_encap_type_nvgre nvgre; + struct bgp_encap_type_mpls mpls; + struct bgp_encap_type_mpls_in_gre mpls_gre; + struct bgp_encap_type_vxlan_gpe vxlan_gpe; + struct bgp_encap_type_mpls_in_udp mpls_udp; + struct bgp_encap_type_pbb pbb; + } bgpinfo; }; -struct rfapi_un_option -{ - struct rfapi_un_option *next; - rfapi_un_option_type type; - union - { - struct rfapi_tunneltype_option tunnel; - } v; +struct rfapi_un_option { + struct rfapi_un_option *next; + rfapi_un_option_type type; + union { + struct rfapi_tunneltype_option tunnel; + } v; }; -typedef enum -{ - RFAPI_VN_OPTION_TYPE_L2ADDR = 3, /* Layer 2 address, 3 for legacy compatibility */ - RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP, /* for static routes */ - RFAPI_VN_OPTION_TYPE_INTERNAL_RD, /* internal use only */ +typedef enum { + RFAPI_VN_OPTION_TYPE_L2ADDR = + 3, /* Layer 2 address, 3 for legacy compatibility */ + RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP, /* for static routes */ + RFAPI_VN_OPTION_TYPE_INTERNAL_RD, /* internal use only */ } rfapi_vn_option_type; -struct rfapi_vn_option -{ - struct rfapi_vn_option *next; +struct rfapi_vn_option { + struct rfapi_vn_option *next; - rfapi_vn_option_type type; + rfapi_vn_option_type type; - union - { - struct rfapi_l2address_option l2addr; + union { + struct rfapi_l2address_option l2addr; - /* - * If this option is present, the next hop is local to the - * client NVE (i.e., not via a tunnel). - */ - struct rfapi_nexthop local_nexthop; + /* + * If this option is present, the next hop is local to the + * client NVE (i.e., not via a tunnel). + */ + struct rfapi_nexthop local_nexthop; - /* - * For rfapi internal use only - */ - struct prefix_rd internal_rd; - } v; + /* + * For rfapi internal use only + */ + struct prefix_rd internal_rd; + } v; }; -struct rfapi_l2address_option_match -{ - struct rfapi_l2address_option o; - uint32_t flags; +struct rfapi_l2address_option_match { + struct rfapi_l2address_option o; + uint32_t flags; #define RFAPI_L2O_MACADDR 0x00000001 #define RFAPI_L2O_LABEL 0x00000002 @@ -181,7 +170,7 @@ typedef void *rfapi_handle; /*------------------------------------------ * rfapi_response_cb_t (callback typedef) * - * Callbacks of this type are used to provide asynchronous + * Callbacks of this type are used to provide asynchronous * route updates from RFAPI to the RFP client. * * response_cb @@ -200,7 +189,7 @@ typedef void *rfapi_handle; * has been added or deleted. Deleted routes are indicated * with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME. * - * input: + * input: * next_hops a list of possible next hops. * This is a linked list allocated within the * rfapi. The response_cb callback function is responsible @@ -211,16 +200,16 @@ typedef void *rfapi_handle; * rfapi_open() * *------------------------------------------*/ -typedef void (rfapi_response_cb_t) (struct rfapi_next_hop_entry * next_hops, - void *userdata); +typedef void(rfapi_response_cb_t)(struct rfapi_next_hop_entry *next_hops, + void *userdata); /*------------------------------------------ * rfapi_nve_close_cb_t (callback typedef) * - * Callbacks of this type are used to provide asynchronous + * Callbacks of this type are used to provide asynchronous * notification that an rfapi_handle was invalidated * - * input: + * input: * pHandle Firmerly valid rfapi_handle returned to * client via rfapi_open(). * @@ -228,72 +217,67 @@ typedef void (rfapi_response_cb_t) (struct rfapi_next_hop_entry * next_hops, * ESTALE handle invalidated by configuration change * *------------------------------------------*/ -typedef void (rfapi_nve_close_cb_t) (rfapi_handle pHandle, int reason); +typedef void(rfapi_nve_close_cb_t)(rfapi_handle pHandle, int reason); /*------------------------------------------ * rfp_cfg_write_cb_t (callback typedef) * * This callback is used to generate output for any config parameters - * that may supported by RFP via RFP defined vty commands at the bgp + * that may supported by RFP via RFP defined vty commands at the bgp * level. See loglevel as an example. * - * input: + * input: * vty -- quagga vty context * rfp_start_val -- value returned by rfp_start * * output: * to vty, rfp related configuration * - * return value: + * return value: * lines written --------------------------------------------*/ -typedef int (rfp_cfg_write_cb_t) (struct vty * vty, void *rfp_start_val); +typedef int(rfp_cfg_write_cb_t)(struct vty *vty, void *rfp_start_val); /*------------------------------------------ * rfp_cfg_group_write_cb_t (callback typedef) * * This callback is used to generate output for any config parameters - * that may supported by RFP via RFP defined vty commands at the + * that may supported by RFP via RFP defined vty commands at the * L2 or NVE level. See loglevel as an example. * - * input: + * input: * vty quagga vty context * rfp_start_val value returned by rfp_start * type group type * name group name - * rfp_cfg_group Pointer to configuration structure + * rfp_cfg_group Pointer to configuration structure * * output: * to vty, rfp related configuration * - * return value: + * return value: * lines written --------------------------------------------*/ -typedef enum -{ - RFAPI_RFP_CFG_GROUP_DEFAULT, - RFAPI_RFP_CFG_GROUP_NVE, - RFAPI_RFP_CFG_GROUP_L2 +typedef enum { + RFAPI_RFP_CFG_GROUP_DEFAULT, + RFAPI_RFP_CFG_GROUP_NVE, + RFAPI_RFP_CFG_GROUP_L2 } rfapi_rfp_cfg_group_type; -typedef int (rfp_cfg_group_write_cb_t) (struct vty * vty, - void *rfp_start_val, - rfapi_rfp_cfg_group_type type, - const char *name, - void *rfp_cfg_group); +typedef int(rfp_cfg_group_write_cb_t)(struct vty *vty, void *rfp_start_val, + rfapi_rfp_cfg_group_type type, + const char *name, void *rfp_cfg_group); /*********************************************************************** * Configuration related defines and structures ***********************************************************************/ -struct rfapi_rfp_cb_methods -{ - rfp_cfg_write_cb_t *cfg_cb; /* show top level config */ - rfp_cfg_group_write_cb_t *cfg_group_cb; /* show group level config */ - rfapi_response_cb_t *response_cb; /* unsolicited responses */ - rfapi_response_cb_t *local_cb; /* local route add/delete */ - rfapi_nve_close_cb_t *close_cb; /* handle closed */ - +struct rfapi_rfp_cb_methods { + rfp_cfg_write_cb_t *cfg_cb; /* show top level config */ + rfp_cfg_group_write_cb_t *cfg_group_cb; /* show group level config */ + rfapi_response_cb_t *response_cb; /* unsolicited responses */ + rfapi_response_cb_t *local_cb; /* local route add/delete */ + rfapi_nve_close_cb_t *close_cb; /* handle closed */ }; /* @@ -303,7 +287,7 @@ struct rfapi_rfp_cb_methods */ #define RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY (60*120) -/* +/* * the factor that should be applied to a prefix's <lifetime> value * before using it to expire a withdrawn prefix, expressed as a percent. * Thus, a value of 100 means to use the exact value of <lifetime>, @@ -312,46 +296,44 @@ struct rfapi_rfp_cb_methods #define RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR 150 /* - * This is used by rfapi to determine if RFP is using/supports + * This is used by rfapi to determine if RFP is using/supports * a partial (i.e., cache) or full table download approach for * mapping information. When full table download approach is * used all information is passed to RFP after an initial - * rfapi_query. When partial table download is used, only - * information matching a query is passed. + * rfapi_query. When partial table download is used, only + * information matching a query is passed. */ -typedef enum -{ - RFAPI_RFP_DOWNLOAD_PARTIAL = 0, - RFAPI_RFP_DOWNLOAD_FULL +typedef enum { + RFAPI_RFP_DOWNLOAD_PARTIAL = 0, + RFAPI_RFP_DOWNLOAD_FULL } rfapi_rfp_download_type; #define RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL 1 -struct rfapi_rfp_cfg -{ - /* partial or full table download */ - rfapi_rfp_download_type download_type; /* default=partial */ - /* - * When full-table-download is enabled, this is the minimum - * number of seconds between times a non-queried prefix will - * be updated to a particular NVE. - * default: RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL - */ - uint32_t ftd_advertisement_interval; - /* - * percentage of registration lifetime to continue to use information - * post soft-state refresh timeout - default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR - */ - uint32_t holddown_factor; - /* Control generation of updated RFP responses */ - uint8_t use_updated_response; /* default=0/no */ - /* when use_updated_response, also generate remove responses */ - uint8_t use_removes; /* default=0/no */ +struct rfapi_rfp_cfg { + /* partial or full table download */ + rfapi_rfp_download_type download_type; /* default=partial */ + /* + * When full-table-download is enabled, this is the minimum + * number of seconds between times a non-queried prefix will + * be updated to a particular NVE. + * default: RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL + */ + uint32_t ftd_advertisement_interval; + /* + * percentage of registration lifetime to continue to use information + * post soft-state refresh timeout + default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR + */ + uint32_t holddown_factor; + /* Control generation of updated RFP responses */ + uint8_t use_updated_response; /* default=0/no */ + /* when use_updated_response, also generate remove responses */ + uint8_t use_removes; /* default=0/no */ }; /*********************************************************************** - * Process related functions -- MUST be provided by the RFAPI user <<=== + * Process related functions -- MUST be provided by the RFAPI user <<=== ***********************************************************************/ /*------------------------------------------ @@ -359,38 +341,35 @@ struct rfapi_rfp_cfg * * This function will start the RFP code * - * input: + * input: * master quagga thread_master to tie into bgpd threads - * + * * output: - * cfgp Pointer to rfapi_rfp_cfg (null = use defaults), + * cfgp Pointer to rfapi_rfp_cfg (null = use defaults), * copied by caller, updated via rfp_set_configuration * cbmp Pointer to rfapi_rfp_cb_methods, may be null * copied by caller, updated via rfapi_rfp_set_cb_methods - * return value: + * return value: * rfp_start_val rfp returned value passed on rfp_stop and other rfapi calls --------------------------------------------*/ -extern void * -rfp_start ( - struct thread_master *master, - struct rfapi_rfp_cfg **cfgp, - struct rfapi_rfp_cb_methods **cbmp); +extern void *rfp_start(struct thread_master *master, + struct rfapi_rfp_cfg **cfgp, + struct rfapi_rfp_cb_methods **cbmp); /*------------------------------------------ * rfp_stop * * This function is called on shutdown to trigger RFP cleanup * - * input: + * input: * rfp_start_val * * output: * none * - * return value: + * return value: --------------------------------------------*/ -extern void -rfp_stop (void *rfp_start_val); +extern void rfp_stop(void *rfp_start_val); /*********************************************************************** * RFP processing behavior configuration @@ -399,44 +378,40 @@ rfp_stop (void *rfp_start_val); /*------------------------------------------ * rfapi_rfp_set_configuration * - * This is used to change rfapi's processing behavior based on - * RFP requirements. + * This is used to change rfapi's processing behavior based on + * RFP requirements. * - * input: + * input: * rfp_start_val value returned by rfp_start * rfapi_rfp_cfg Pointer to configuration structure * * output: * none * - * return value: + * return value: * 0 Success * ENXIO Unabled to locate configured BGP/VNC --------------------------------------------*/ -extern int -rfapi_rfp_set_configuration ( - void *rfp_start_val, - struct rfapi_rfp_cfg *rfp_cfg); +extern int rfapi_rfp_set_configuration(void *rfp_start_val, + struct rfapi_rfp_cfg *rfp_cfg); /*------------------------------------------ * rfapi_rfp_set_cb_methods * - * Change registered callback functions for asynchronous notifications + * Change registered callback functions for asynchronous notifications * from RFAPI to the RFP client. * - * input: + * input: * rfp_start_val value by rfp_start * methods Pointer to struct rfapi_rfp_cb_methods containing * pointers to callback methods as described above * - * return value: + * return value: * 0 Success * ENXIO BGP or VNC not configured *------------------------------------------*/ -extern int -rfapi_rfp_set_cb_methods ( - void *rfp_start_val, - struct rfapi_rfp_cb_methods *methods); +extern int rfapi_rfp_set_cb_methods(void *rfp_start_val, + struct rfapi_rfp_cb_methods *methods); /*********************************************************************** * RFP group specific configuration @@ -446,12 +421,12 @@ rfapi_rfp_set_cb_methods ( * rfapi_rfp_init_group_config_ptr_vty * * This is used to init or return a previously init'ed group specific - * configuration pointer. Group is identified by vty context. + * configuration pointer. Group is identified by vty context. * NOTE: size is ignored when a previously init'ed value is returned. * RFAPI frees rfp_cfg_group when group is deleted during reconfig, * bgp restart or shutdown. * - * input: + * input: * rfp_start_val value returned by rfp_start * type group type * vty quagga vty context @@ -460,25 +435,23 @@ rfapi_rfp_set_cb_methods ( * output: * none * - * return value: + * return value: * rfp_cfg_group NULL or Pointer to configuration structure --------------------------------------------*/ -extern void * -rfapi_rfp_init_group_config_ptr_vty ( - void *rfp_start_val, - rfapi_rfp_cfg_group_type type, - struct vty *vty, - uint32_t size); +extern void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val, + rfapi_rfp_cfg_group_type type, + struct vty *vty, + uint32_t size); /*------------------------------------------ * rfapi_rfp_get_group_config_ptr_vty * * This is used to get group specific configuration pointer. - * Group is identified by type and vty context. + * Group is identified by type and vty context. * RFAPI frees rfp_cfg_group when group is deleted during reconfig, * bgp restart or shutdown. * - * input: + * input: * rfp_start_val value returned by rfp_start * type group type * vty quagga vty context @@ -487,43 +460,40 @@ rfapi_rfp_init_group_config_ptr_vty ( * none * * return value: - * rfp_cfg_group Pointer to configuration structure + * rfp_cfg_group Pointer to configuration structure --------------------------------------------*/ -extern void * -rfapi_rfp_get_group_config_ptr_vty ( - void *rfp_start_val, - rfapi_rfp_cfg_group_type type, - struct vty *vty); +extern void *rfapi_rfp_get_group_config_ptr_vty(void *rfp_start_val, + rfapi_rfp_cfg_group_type type, + struct vty *vty); /*------------------------------------------ * rfp_group_config_search_cb_t (callback typedef) * - * This callback is used to called from within a + * This callback is used to called from within a * rfapi_rfp_get_group_config_ptr to check if the rfp_cfg_group * matches the search criteria * - * input: + * input: * criteria RFAPI caller provided serach criteria * rfp_cfg_group Pointer to configuration structure | NULL * * output: * - * return value: + * return value: * 0 Match/Success * ENOENT No matching --------------------------------------------*/ -typedef int (rfp_group_config_search_cb_t) (void *criteria, - void *rfp_cfg_group); +typedef int(rfp_group_config_search_cb_t)(void *criteria, void *rfp_cfg_group); /*------------------------------------------ * rfapi_rfp_get_group_config_ptr_name * * This is used to get group specific configuration pointer. - * Group is identified by type and name context. + * Group is identified by type and name context. * RFAPI frees rfp_cfg_group when group is deleted during reconfig, * bgp restart or shutdown. * - * input: + * input: * rfp_start_val value returned by rfp_start * type group type * name group name @@ -534,15 +504,11 @@ typedef int (rfp_group_config_search_cb_t) (void *criteria, * none * * return value: - * rfp_cfg_group Pointer to configuration structure + * rfp_cfg_group Pointer to configuration structure --------------------------------------------*/ -extern void * -rfapi_rfp_get_group_config_ptr_name ( - void *rfp_start_val, - rfapi_rfp_cfg_group_type type, - const char *name, - void *criteria, - rfp_group_config_search_cb_t *search_cb); +extern void *rfapi_rfp_get_group_config_ptr_name( + void *rfp_start_val, rfapi_rfp_cfg_group_type type, const char *name, + void *criteria, rfp_group_config_search_cb_t *search_cb); /*------------------------------------------ * rfapi_rfp_get_l2_group_config_ptr_lni @@ -550,9 +516,9 @@ rfapi_rfp_get_group_config_ptr_name ( * This is used to get group specific configuration pointer. * Group is identified by type and logical network identifier. * RFAPI frees rfp_cfg_group when group is deleted during reconfig, - * bgp restart or shutdown. + * bgp restart or shutdown. * - * input: + * input: * rfp_start_val value returned by rfp_start * logical_net_id group logical network identifier * criteria RFAPI caller provided serach criteria @@ -562,14 +528,12 @@ rfapi_rfp_get_group_config_ptr_name ( * none * * return value: - * rfp_cfg_group Pointer to configuration structure + * rfp_cfg_group Pointer to configuration structure --------------------------------------------*/ extern void * -rfapi_rfp_get_l2_group_config_ptr_lni ( - void *rfp_start_val, - uint32_t logical_net_id, - void *criteria, - rfp_group_config_search_cb_t *search_cb); +rfapi_rfp_get_l2_group_config_ptr_lni(void *rfp_start_val, + uint32_t logical_net_id, void *criteria, + rfp_group_config_search_cb_t *search_cb); /*********************************************************************** * NVE Sessions @@ -581,7 +545,7 @@ rfapi_rfp_get_l2_group_config_ptr_lni ( * This function initializes a NVE record and associates it with * the specified VN and underlay network addresses * - * input: + * input: * rfp_start_val value returned by rfp_start * vn NVE virtual network address * @@ -599,13 +563,13 @@ rfapi_rfp_get_l2_group_config_ptr_lni ( * * output: * response_lifetime The length of time that responses sent to this - * NVE are valid. + * NVE are valid. * * pHandle pointer to location to store rfapi handle. The * handle must be passed on subsequent rfapi_ calls. * * - * return value: + * return value: * 0 Success * EEXIST NVE with this {vn,un} already open * ENOENT No matching nve group config @@ -615,15 +579,11 @@ rfapi_rfp_get_l2_group_config_ptr_lni ( * but underlay network address is not IPv4 * EDEADLK Called from within a callback procedure *------------------------------------------*/ -extern int -rfapi_open ( - void *rfp_start_val, - struct rfapi_ip_addr *vn, - struct rfapi_ip_addr *un, - struct rfapi_un_option *default_options, - uint32_t *response_lifetime, - void *userdata, - rfapi_handle *pHandle); +extern int rfapi_open(void *rfp_start_val, struct rfapi_ip_addr *vn, + struct rfapi_ip_addr *un, + struct rfapi_un_option *default_options, + uint32_t *response_lifetime, void *userdata, + rfapi_handle *pHandle); /*------------------------------------------ @@ -633,7 +593,7 @@ rfapi_open ( * from within a rfapi callback procedure is permitted (the close * will be completed asynchronously after the callback finishes). * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open * * output: @@ -643,15 +603,14 @@ rfapi_open ( * EBADF invalid handle * ENXIO BGP or VNC not configured *------------------------------------------*/ -extern int -rfapi_close (rfapi_handle rfd); +extern int rfapi_close(rfapi_handle rfd); /*------------------------------------------ * rfapi_check * * Test rfapi descriptor * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open * * output: @@ -664,8 +623,7 @@ rfapi_close (rfapi_handle rfd); * ENXIO BGP or VNC not configured * EAFNOSUPPORT Internal addressing error *------------------------------------------*/ -extern int -rfapi_check (rfapi_handle rfd); +extern int rfapi_check(rfapi_handle rfd); /*********************************************************************** * NVE Routes @@ -674,14 +632,14 @@ rfapi_check (rfapi_handle rfd); /*------------------------------------------ * rfapi_query * - * This function queries the RIB for a - * particular route. Note that this call may result in subsequent + * This function queries the RIB for a + * particular route. Note that this call may result in subsequent * callbacks to response_cb. Response callbacks can be cancelled * by calling rfapi_query_done. A duplicate query using the same target * will result in only one callback per change in next_hops. (i.e., * cancel/replace the prior query results.) * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open * target: the destination address * l2o ptr to L2 Options struct, NULL if not present in query @@ -701,20 +659,17 @@ rfapi_check (rfapi_handle rfd); * ESTALE descriptor is no longer usable; should be closed * EDEADLK Called from within a callback procedure --------------------------------------------*/ -extern int -rfapi_query ( - rfapi_handle rfd, - struct rfapi_ip_addr *target, - struct rfapi_l2address_option *l2o, - struct rfapi_next_hop_entry **ppNextHopEntry); +extern int rfapi_query(rfapi_handle rfd, struct rfapi_ip_addr *target, + struct rfapi_l2address_option *l2o, + struct rfapi_next_hop_entry **ppNextHopEntry); /*------------------------------------------ * rfapi_query_done * - * Notifies the rfapi that the user is no longer interested - * in the specified target. + * Notifies the rfapi that the user is no longer interested + * in the specified target. * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open * target: the destination address * @@ -728,16 +683,15 @@ rfapi_query ( * ESTALE descriptor is no longer usable; should be closed * EDEADLK Called from within a callback procedure --------------------------------------------*/ -extern int -rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target); +extern int rfapi_query_done(rfapi_handle rfd, struct rfapi_ip_addr *target); /*------------------------------------------ * rfapi_query_done_all * - * Notifies the rfapi that the user is no longer interested - * in any target. + * Notifies the rfapi that the user is no longer interested + * in any target. * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open * * output: @@ -750,8 +704,7 @@ rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target); * ESTALE descriptor is no longer usable; should be closed * EDEADLK Called from within a callback procedure --------------------------------------------*/ -extern int -rfapi_query_done_all (rfapi_handle rfd, int *count); +extern int rfapi_query_done_all(rfapi_handle rfd, int *count); /*------------------------------------------ * rfapi_register @@ -759,11 +712,11 @@ rfapi_query_done_all (rfapi_handle rfd, int *count); * Requests that reachability to the indicated prefix via this NVE * be advertised by BGP. If <unregister> is non-zero, then the previously- * advertised prefix should be withdrawn. - * - * (This function should NOT be called if the rfapi_open() function + * + * (This function should NOT be called if the rfapi_open() function * returns NULL) * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open * prefix: A prefix to be registered or deregistered * lifetime Prefix lifetime in seconds, host byte order @@ -785,21 +738,16 @@ rfapi_query_done_all (rfapi_handle rfd, int *count); * EDEADLK Called from within a callback procedure --------------------------------------------*/ -typedef enum -{ - RFAPI_REGISTER_ADD, - RFAPI_REGISTER_WITHDRAW, - RFAPI_REGISTER_KILL +typedef enum { + RFAPI_REGISTER_ADD, + RFAPI_REGISTER_WITHDRAW, + RFAPI_REGISTER_KILL } rfapi_register_action; -extern int -rfapi_register ( - rfapi_handle rfd, - struct rfapi_ip_prefix *prefix, - uint32_t lifetime, - struct rfapi_un_option *options_un, - struct rfapi_vn_option *options_vn, - rfapi_register_action action); +extern int rfapi_register(rfapi_handle rfd, struct rfapi_ip_prefix *prefix, + uint32_t lifetime, struct rfapi_un_option *options_un, + struct rfapi_vn_option *options_vn, + rfapi_register_action action); /*********************************************************************** * Helper / Utility functions @@ -810,32 +758,30 @@ rfapi_register ( * * Get the virtual network address used by an NVE based on it's RFD * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic * * output: * - * return value: + * return value: * vn NVE virtual network address *------------------------------------------*/ -extern struct rfapi_ip_addr * -rfapi_get_vn_addr (void *); +extern struct rfapi_ip_addr *rfapi_get_vn_addr(void *); /*------------------------------------------ * rfapi_get_un_addr * * Get the underlay network address used by an NVE based on it's RFD * - * input: + * input: * rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic * * output: * - * return value: + * return value: * un NVE underlay network address *------------------------------------------*/ -extern struct rfapi_ip_addr * -rfapi_get_un_addr (void *); +extern struct rfapi_ip_addr *rfapi_get_un_addr(void *); /*------------------------------------------ * rfapi_error_str @@ -850,8 +796,7 @@ rfapi_get_un_addr (void *); * * const char * String *------------------------------------------*/ -extern const char * -rfapi_error_str (int code); +extern const char *rfapi_error_str(int code); /*------------------------------------------ * rfapi_get_rfp_start_val @@ -862,17 +807,16 @@ rfapi_error_str (int code); * void * bgp structure * * returns: - * void * + * void * *------------------------------------------*/ -extern void * -rfapi_get_rfp_start_val (void *bgpv); +extern void *rfapi_get_rfp_start_val(void *bgpv); /*------------------------------------------ * rfapi_compare_rfds * * Compare two generic rfapi descriptors. * - * input: + * input: * rfd1: rfapi descriptor returned by rfapi_open or rfapi_create_generic * rfd2: rfapi descriptor returned by rfapi_open or rfapi_create_generic * @@ -882,24 +826,22 @@ rfapi_get_rfp_start_val (void *bgpv); * 0 Mismatch * 1 Match *------------------------------------------*/ -extern int -rfapi_compare_rfds (void *rfd1, void *rfd2); +extern int rfapi_compare_rfds(void *rfd1, void *rfd2); /*------------------------------------------ * rfapi_free_next_hop_list * * Frees a next_hop_list returned by a rfapi_query invocation * - * input: - * list: a pointer to a response list (as a + * input: + * list: a pointer to a response list (as a * struct rfapi_next_hop_entry) to free. * * output: * * return value: None --------------------------------------------*/ -extern void -rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list); +extern void rfapi_free_next_hop_list(struct rfapi_next_hop_entry *list); /*------------------------------------------ * rfapi_get_response_lifetime_default @@ -908,22 +850,21 @@ rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list); * rfp_start_val value returned by rfp_start or * NULL (=use default instance) * - * input: + * input: * None * * output: * * return value: The bgp instance default lifetime for a response. --------------------------------------------*/ -extern int -rfapi_get_response_lifetime_default (void *rfp_start_val); +extern int rfapi_get_response_lifetime_default(void *rfp_start_val); /*------------------------------------------ * rfapi_is_vnc_configured * * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured * - * input: + * input: * rfp_start_val value returned by rfp_start or * NULL (=use default instance) * @@ -933,15 +874,14 @@ rfapi_get_response_lifetime_default (void *rfp_start_val); * 0 Success * ENXIO VNC not configured --------------------------------------------*/ -extern int -rfapi_is_vnc_configured (void *rfp_start_val); +extern int rfapi_is_vnc_configured(void *rfp_start_val); /*------------------------------------------ * rfapi_bgp_lookup_by_rfp * * Find bgp instance pointer based on value returned by rfp_start * - * input: + * input: * rfp_start_val value returned by rfp_startor * NULL (=get default instance) * @@ -953,15 +893,14 @@ rfapi_is_vnc_configured (void *rfp_start_val); * NULL = not found * --------------------------------------------*/ -extern struct bgp * -rfapi_bgp_lookup_by_rfp (void *rfp_start_val); +extern struct bgp *rfapi_bgp_lookup_by_rfp(void *rfp_start_val); /*------------------------------------------ * rfapi_get_rfp_start_val_by_bgp * * Find bgp instance pointer based on value returned by rfp_start * - * input: + * input: * bgp bgp instance pointer * * output: @@ -972,8 +911,7 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val); * NULL = not found * --------------------------------------------*/ -extern void * -rfapi_get_rfp_start_val_by_bgp (struct bgp *bgp); +extern void *rfapi_get_rfp_start_val_by_bgp(struct bgp *bgp); #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c index fac28cd74c..3112505d4b 100644 --- a/bgpd/rfapi/rfapi_ap.c +++ b/bgpd/rfapi/rfapi_ap.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -83,541 +83,476 @@ * is used to spread out the sort for adbs with the same lifetime * and thereby make the skip list operations more efficient. */ -static int -sl_adb_lifetime_cmp (void *adb1, void *adb2) +static int sl_adb_lifetime_cmp(void *adb1, void *adb2) { - struct rfapi_adb *a1 = adb1; - struct rfapi_adb *a2 = adb2; + struct rfapi_adb *a1 = adb1; + struct rfapi_adb *a2 = adb2; - if (a1->lifetime < a2->lifetime) - return -1; - if (a1->lifetime > a2->lifetime) - return 1; + if (a1->lifetime < a2->lifetime) + return -1; + if (a1->lifetime > a2->lifetime) + return 1; - if (a1 < a2) - return -1; - if (a1 > a2) - return 1; + if (a1 < a2) + return -1; + if (a1 > a2) + return 1; - return 0; + return 0; } -void -rfapiApInit (struct rfapi_advertised_prefixes *ap) +void rfapiApInit(struct rfapi_advertised_prefixes *ap) { - ap->ipN_by_prefix = skiplist_new (0, rfapi_rib_key_cmp, NULL); - ap->ip0_by_ether = skiplist_new (0, rfapi_rib_key_cmp, NULL); - ap->by_lifetime = skiplist_new (0, sl_adb_lifetime_cmp, NULL); + ap->ipN_by_prefix = skiplist_new(0, rfapi_rib_key_cmp, NULL); + ap->ip0_by_ether = skiplist_new(0, rfapi_rib_key_cmp, NULL); + ap->by_lifetime = skiplist_new(0, sl_adb_lifetime_cmp, NULL); } -void -rfapiApRelease (struct rfapi_advertised_prefixes *ap) +void rfapiApRelease(struct rfapi_advertised_prefixes *ap) { - struct rfapi_adb *adb; - - /* Free ADBs and lifetime items */ - while (0 == skiplist_first (ap->by_lifetime, NULL, (void **) &adb)) - { - rfapiAdbFree (adb); - skiplist_delete_first (ap->by_lifetime); - } - - while (0 == skiplist_delete_first (ap->ipN_by_prefix)); - while (0 == skiplist_delete_first (ap->ip0_by_ether)); - - /* Free lists */ - skiplist_free (ap->ipN_by_prefix); - skiplist_free (ap->ip0_by_ether); - skiplist_free (ap->by_lifetime); - - ap->ipN_by_prefix = NULL; - ap->ip0_by_ether = NULL; - ap->by_lifetime = NULL; + struct rfapi_adb *adb; + + /* Free ADBs and lifetime items */ + while (0 == skiplist_first(ap->by_lifetime, NULL, (void **)&adb)) { + rfapiAdbFree(adb); + skiplist_delete_first(ap->by_lifetime); + } + + while (0 == skiplist_delete_first(ap->ipN_by_prefix)) + ; + while (0 == skiplist_delete_first(ap->ip0_by_ether)) + ; + + /* Free lists */ + skiplist_free(ap->ipN_by_prefix); + skiplist_free(ap->ip0_by_ether); + skiplist_free(ap->by_lifetime); + + ap->ipN_by_prefix = NULL; + ap->ip0_by_ether = NULL; + ap->by_lifetime = NULL; } -int -rfapiApCount (struct rfapi_descriptor *rfd) +int rfapiApCount(struct rfapi_descriptor *rfd) { - if (!rfd->advertised.by_lifetime) - return 0; + if (!rfd->advertised.by_lifetime) + return 0; - return skiplist_count (rfd->advertised.by_lifetime); + return skiplist_count(rfd->advertised.by_lifetime); } -int -rfapiApCountAll (struct bgp *bgp) +int rfapiApCountAll(struct bgp *bgp) { - struct rfapi *h; - struct listnode *node; - struct rfapi_descriptor *rfd; - int total = 0; - - h = bgp->rfapi; - if (h) - { - for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) - { - total += rfapiApCount (rfd); - } - } - return total; + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; + int total = 0; + + h = bgp->rfapi; + if (h) { + for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { + total += rfapiApCount(rfd); + } + } + return total; } -void -rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd) +void rfapiApReadvertiseAll(struct bgp *bgp, struct rfapi_descriptor *rfd) { - struct rfapi_adb *adb; - void *cursor = NULL; - int rc; - - for (rc = - skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, - &cursor); rc == 0; - rc = - skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, - &cursor)) - { - - struct prefix_rd prd; - uint32_t local_pref = rfp_cost_to_localpref (adb->cost); - - prd = rfd->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - /* - * TBD this is not quite right. When pfx_ip is 0/32 or 0/128, - * we need to substitute the VN address as the prefix - */ - add_vnc_route (rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, &prd, /* RD to use (0 for ENCAP) */ - &rfd->vn_addr, /* nexthop */ - &local_pref, &adb->lifetime, NULL, NULL, /* struct rfapi_un_option */ - NULL, /* struct rfapi_vn_option */ - rfd->rt_export_list, NULL, /* med */ - NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); - } + struct rfapi_adb *adb; + void *cursor = NULL; + int rc; + + for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL, + (void **)&adb, &cursor); + rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL, + (void **)&adb, &cursor)) { + + struct prefix_rd prd; + uint32_t local_pref = rfp_cost_to_localpref(adb->cost); + + prd = rfd->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + /* + * TBD this is not quite right. When pfx_ip is 0/32 or 0/128, + * we need to substitute the VN address as the prefix + */ + add_vnc_route(rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, + &prd, /* RD to use (0 for ENCAP) */ + &rfd->vn_addr, /* nexthop */ + &local_pref, &adb->lifetime, NULL, + NULL, /* struct rfapi_un_option */ + NULL, /* struct rfapi_vn_option */ + rfd->rt_export_list, NULL, /* med */ + NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); + } } -void -rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd) +void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd) { - struct rfapi_adb *adb; - void *cursor; - int rc; - - - cursor = NULL; - for (rc = - skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, - &cursor); rc == 0; - rc = - skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, - &cursor)) - { - - struct prefix pfx_vn_buf; - struct prefix *pfx_ip; - - if (!(RFAPI_0_PREFIX (&adb->u.s.prefix_ip) && - RFAPI_HOST_PREFIX (&adb->u.s.prefix_ip))) - { - - pfx_ip = &adb->u.s.prefix_ip; - - } - else - { - - pfx_ip = NULL; - - /* - * 0/32 or 0/128 => mac advertisement - */ - if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf)) - { - /* - * Bad: it means we can't delete the route - */ - vnc_zlog_debug_verbose ("%s: BAD: handle has bad vn_addr: skipping", - __func__); - continue; - } - } - - del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->u.s.prd, /* RD to use (0 for ENCAP) */ - ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); - } + struct rfapi_adb *adb; + void *cursor; + int rc; + + + cursor = NULL; + for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL, + (void **)&adb, &cursor); + rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL, + (void **)&adb, &cursor)) { + + struct prefix pfx_vn_buf; + struct prefix *pfx_ip; + + if (!(RFAPI_0_PREFIX(&adb->u.s.prefix_ip) + && RFAPI_HOST_PREFIX(&adb->u.s.prefix_ip))) { + + pfx_ip = &adb->u.s.prefix_ip; + + } else { + + pfx_ip = NULL; + + /* + * 0/32 or 0/128 => mac advertisement + */ + if (rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn_buf)) { + /* + * Bad: it means we can't delete the route + */ + vnc_zlog_debug_verbose( + "%s: BAD: handle has bad vn_addr: skipping", + __func__); + continue; + } + } + + del_vnc_route(rfd, rfd->peer, bgp, SAFI_MPLS_VPN, + pfx_ip ? pfx_ip : &pfx_vn_buf, + &adb->u.s.prd, /* RD to use (0 for ENCAP) */ + ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); + } } /* * returns nonzero if tunnel readvertisement is needed, 0 otherwise */ -static int -rfapiApAdjustLifetimeStats ( - struct rfapi_descriptor *rfd, - uint32_t *old_lifetime, /* set if removing/replacing */ - uint32_t *new_lifetime) /* set if replacing/adding */ +static int rfapiApAdjustLifetimeStats( + struct rfapi_descriptor *rfd, + uint32_t *old_lifetime, /* set if removing/replacing */ + uint32_t *new_lifetime) /* set if replacing/adding */ { - int advertise = 0; - int find_max = 0; - int find_min = 0; - - vnc_zlog_debug_verbose ("%s: rfd=%p, pOldLife=%p, pNewLife=%p", - __func__, rfd, old_lifetime, new_lifetime); - if (old_lifetime) - vnc_zlog_debug_verbose ("%s: OldLife=%d", __func__, *old_lifetime); - if (new_lifetime) - vnc_zlog_debug_verbose ("%s: NewLife=%d", __func__, *new_lifetime); - - if (new_lifetime) - { - /* - * Adding new lifetime - */ - if (old_lifetime) - { - /* - * replacing existing lifetime - */ - - - /* old and new are same */ - if (*old_lifetime == *new_lifetime) - return 0; - - if (*old_lifetime == rfd->min_prefix_lifetime) - { - find_min = 1; - } - if (*old_lifetime == rfd->max_prefix_lifetime) - { - find_max = 1; - } - - /* no need to search if new value is at or equals min|max */ - if (*new_lifetime <= rfd->min_prefix_lifetime) - { - rfd->min_prefix_lifetime = *new_lifetime; - find_min = 0; - } - if (*new_lifetime >= rfd->max_prefix_lifetime) - { - rfd->max_prefix_lifetime = *new_lifetime; - advertise = 1; - find_max = 0; - } - - } - else - { - /* - * Just adding new lifetime - */ - if (*new_lifetime < rfd->min_prefix_lifetime) - { - rfd->min_prefix_lifetime = *new_lifetime; - } - if (*new_lifetime > rfd->max_prefix_lifetime) - { - advertise = 1; - rfd->max_prefix_lifetime = *new_lifetime; - } - - } - } - else - { - /* - * Deleting - */ - - /* - * See if the max prefix lifetime for this NVE has decreased. - * The easy optimization: track min & max; walk the table only - * if they are different. - * The general optimization: index the advertised_prefixes - * table by lifetime. - * - * Note: for a given nve_descriptor, only one of the - * advertised_prefixes[] tables will be used: viz., the - * address family that matches the VN address. - * - */ - if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime) - { - - /* - * Common case: all lifetimes are the same. Only - * thing we need to do here is check if there are - * no exported routes left. In that case, reinitialize - * the max and min values. - */ - if (!rfapiApCount (rfd)) - { - rfd->max_prefix_lifetime = 0; - rfd->min_prefix_lifetime = UINT32_MAX; - } - - - } - else - { - if (old_lifetime) - { - if (*old_lifetime == rfd->min_prefix_lifetime) - { - find_min = 1; - } - if (*old_lifetime == rfd->max_prefix_lifetime) - { - find_max = 1; - } - } - } - } - - if (find_min || find_max) - { - uint32_t min = UINT32_MAX; - uint32_t max = 0; - - struct rfapi_adb *adb_min; - struct rfapi_adb *adb_max; - - if (!skiplist_first - (rfd->advertised.by_lifetime, (void **) &adb_min, NULL) - && !skiplist_last (rfd->advertised.by_lifetime, (void **) &adb_max, - NULL)) - { - - /* - * This should always work - */ - min = adb_min->lifetime; - max = adb_max->lifetime; - - } - else - { - - void *cursor; - struct rfapi_rib_key rk; - struct rfapi_adb *adb; - int rc; - - vnc_zlog_debug_verbose ("%s: walking to find new min/max", __func__); - - cursor = NULL; - for (rc = skiplist_next (rfd->advertised.ipN_by_prefix, - (void **) &rk, (void **) &adb, - &cursor); !rc; - rc = - skiplist_next (rfd->advertised.ipN_by_prefix, - (void **) &rk, (void **) &adb, &cursor)) - { - - uint32_t lt = adb->lifetime; - - if (lt > max) - max = lt; - if (lt < min) - min = lt; - } - cursor = NULL; - for (rc = skiplist_next (rfd->advertised.ip0_by_ether, - (void **) &rk, (void **) &adb, - &cursor); !rc; - rc = - skiplist_next (rfd->advertised.ip0_by_ether, (void **) &rk, - (void **) &adb, &cursor)) - { - - uint32_t lt = adb->lifetime; - - if (lt > max) - max = lt; - if (lt < min) - min = lt; - } - } - - /* - * trigger tunnel route update - * but only if we found a VPN route and it had - * a lifetime greater than 0 - */ - if (max && rfd->max_prefix_lifetime != max) - advertise = 1; - rfd->max_prefix_lifetime = max; - rfd->min_prefix_lifetime = min; - } - - vnc_zlog_debug_verbose ("%s: returning advertise=%d, min=%d, max=%d", - __func__, advertise, rfd->min_prefix_lifetime, - rfd->max_prefix_lifetime); - - return (advertise != 0); + int advertise = 0; + int find_max = 0; + int find_min = 0; + + vnc_zlog_debug_verbose("%s: rfd=%p, pOldLife=%p, pNewLife=%p", __func__, + rfd, old_lifetime, new_lifetime); + if (old_lifetime) + vnc_zlog_debug_verbose("%s: OldLife=%d", __func__, + *old_lifetime); + if (new_lifetime) + vnc_zlog_debug_verbose("%s: NewLife=%d", __func__, + *new_lifetime); + + if (new_lifetime) { + /* + * Adding new lifetime + */ + if (old_lifetime) { + /* + * replacing existing lifetime + */ + + + /* old and new are same */ + if (*old_lifetime == *new_lifetime) + return 0; + + if (*old_lifetime == rfd->min_prefix_lifetime) { + find_min = 1; + } + if (*old_lifetime == rfd->max_prefix_lifetime) { + find_max = 1; + } + + /* no need to search if new value is at or equals + * min|max */ + if (*new_lifetime <= rfd->min_prefix_lifetime) { + rfd->min_prefix_lifetime = *new_lifetime; + find_min = 0; + } + if (*new_lifetime >= rfd->max_prefix_lifetime) { + rfd->max_prefix_lifetime = *new_lifetime; + advertise = 1; + find_max = 0; + } + + } else { + /* + * Just adding new lifetime + */ + if (*new_lifetime < rfd->min_prefix_lifetime) { + rfd->min_prefix_lifetime = *new_lifetime; + } + if (*new_lifetime > rfd->max_prefix_lifetime) { + advertise = 1; + rfd->max_prefix_lifetime = *new_lifetime; + } + } + } else { + /* + * Deleting + */ + + /* + * See if the max prefix lifetime for this NVE has decreased. + * The easy optimization: track min & max; walk the table only + * if they are different. + * The general optimization: index the advertised_prefixes + * table by lifetime. + * + * Note: for a given nve_descriptor, only one of the + * advertised_prefixes[] tables will be used: viz., the + * address family that matches the VN address. + * + */ + if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime) { + + /* + * Common case: all lifetimes are the same. Only + * thing we need to do here is check if there are + * no exported routes left. In that case, reinitialize + * the max and min values. + */ + if (!rfapiApCount(rfd)) { + rfd->max_prefix_lifetime = 0; + rfd->min_prefix_lifetime = UINT32_MAX; + } + + + } else { + if (old_lifetime) { + if (*old_lifetime == rfd->min_prefix_lifetime) { + find_min = 1; + } + if (*old_lifetime == rfd->max_prefix_lifetime) { + find_max = 1; + } + } + } + } + + if (find_min || find_max) { + uint32_t min = UINT32_MAX; + uint32_t max = 0; + + struct rfapi_adb *adb_min; + struct rfapi_adb *adb_max; + + if (!skiplist_first(rfd->advertised.by_lifetime, + (void **)&adb_min, NULL) + && !skiplist_last(rfd->advertised.by_lifetime, + (void **)&adb_max, NULL)) { + + /* + * This should always work + */ + min = adb_min->lifetime; + max = adb_max->lifetime; + + } else { + + void *cursor; + struct rfapi_rib_key rk; + struct rfapi_adb *adb; + int rc; + + vnc_zlog_debug_verbose( + "%s: walking to find new min/max", __func__); + + cursor = NULL; + for (rc = skiplist_next(rfd->advertised.ipN_by_prefix, + (void **)&rk, (void **)&adb, + &cursor); + !rc; + rc = skiplist_next(rfd->advertised.ipN_by_prefix, + (void **)&rk, (void **)&adb, + &cursor)) { + + uint32_t lt = adb->lifetime; + + if (lt > max) + max = lt; + if (lt < min) + min = lt; + } + cursor = NULL; + for (rc = skiplist_next(rfd->advertised.ip0_by_ether, + (void **)&rk, (void **)&adb, + &cursor); + !rc; + rc = skiplist_next(rfd->advertised.ip0_by_ether, + (void **)&rk, (void **)&adb, + &cursor)) { + + uint32_t lt = adb->lifetime; + + if (lt > max) + max = lt; + if (lt < min) + min = lt; + } + } + + /* + * trigger tunnel route update + * but only if we found a VPN route and it had + * a lifetime greater than 0 + */ + if (max && rfd->max_prefix_lifetime != max) + advertise = 1; + rfd->max_prefix_lifetime = max; + rfd->min_prefix_lifetime = min; + } + + vnc_zlog_debug_verbose("%s: returning advertise=%d, min=%d, max=%d", + __func__, advertise, rfd->min_prefix_lifetime, + rfd->max_prefix_lifetime); + + return (advertise != 0); } -/* +/* * Return Value * * 0 No need to advertise tunnel route * non-0 advertise tunnel route */ -int -rfapiApAdd ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *pfx_ip, - struct prefix *pfx_eth, - struct prefix_rd *prd, - uint32_t lifetime, - uint8_t cost, - struct rfapi_l2address_option *l2o) /* other options TBD */ +int rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct prefix *pfx_ip, struct prefix *pfx_eth, + struct prefix_rd *prd, uint32_t lifetime, uint8_t cost, + struct rfapi_l2address_option *l2o) /* other options TBD */ { - int rc; - struct rfapi_adb *adb; - uint32_t old_lifetime = 0; - int use_ip0 = 0; - struct rfapi_rib_key rk; - - rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); - if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip)) - { - use_ip0 = 1; - assert (pfx_eth); - rc = - skiplist_search (rfd->advertised.ip0_by_ether, &rk, - (void **) &adb); - - } - else - { - - /* find prefix in advertised prefixes list */ - rc = - skiplist_search (rfd->advertised.ipN_by_prefix, &rk, - (void **) &adb); - } - - - if (rc) - { - /* Not found */ - adb = XCALLOC (MTYPE_RFAPI_ADB, sizeof (struct rfapi_adb)); - assert (adb); - adb->lifetime = lifetime; - adb->u.key = rk; - - if (use_ip0) - { - assert (pfx_eth); - skiplist_insert (rfd->advertised.ip0_by_ether, &adb->u.key, - adb); - } - else - { - skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->u.key, - adb); - } - - skiplist_insert (rfd->advertised.by_lifetime, adb, adb); - } - else - { - old_lifetime = adb->lifetime; - if (old_lifetime != lifetime) - { - assert (!skiplist_delete (rfd->advertised.by_lifetime, adb, NULL)); - adb->lifetime = lifetime; - assert (!skiplist_insert (rfd->advertised.by_lifetime, adb, adb)); - } - } - adb->cost = cost; - if (l2o) - adb->l2o = *l2o; - else - memset (&adb->l2o, 0, sizeof (struct rfapi_l2address_option)); - - if (rfapiApAdjustLifetimeStats - (rfd, (rc ? NULL : &old_lifetime), &lifetime)) - return 1; - - return 0; + int rc; + struct rfapi_adb *adb; + uint32_t old_lifetime = 0; + int use_ip0 = 0; + struct rfapi_rib_key rk; + + rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); + if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) { + use_ip0 = 1; + assert(pfx_eth); + rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk, + (void **)&adb); + + } else { + + /* find prefix in advertised prefixes list */ + rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk, + (void **)&adb); + } + + + if (rc) { + /* Not found */ + adb = XCALLOC(MTYPE_RFAPI_ADB, sizeof(struct rfapi_adb)); + assert(adb); + adb->lifetime = lifetime; + adb->u.key = rk; + + if (use_ip0) { + assert(pfx_eth); + skiplist_insert(rfd->advertised.ip0_by_ether, + &adb->u.key, adb); + } else { + skiplist_insert(rfd->advertised.ipN_by_prefix, + &adb->u.key, adb); + } + + skiplist_insert(rfd->advertised.by_lifetime, adb, adb); + } else { + old_lifetime = adb->lifetime; + if (old_lifetime != lifetime) { + assert(!skiplist_delete(rfd->advertised.by_lifetime, + adb, NULL)); + adb->lifetime = lifetime; + assert(!skiplist_insert(rfd->advertised.by_lifetime, + adb, adb)); + } + } + adb->cost = cost; + if (l2o) + adb->l2o = *l2o; + else + memset(&adb->l2o, 0, sizeof(struct rfapi_l2address_option)); + + if (rfapiApAdjustLifetimeStats(rfd, (rc ? NULL : &old_lifetime), + &lifetime)) + return 1; + + return 0; } /* * After this function returns successfully, caller should call * rfapiAdjustLifetimeStats() and possibly rfapiTunnelRouteAnnounce() */ -int -rfapiApDelete ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *pfx_ip, - struct prefix *pfx_eth, - struct prefix_rd *prd, - int *advertise_tunnel) /* out */ +int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct prefix *pfx_ip, struct prefix *pfx_eth, + struct prefix_rd *prd, int *advertise_tunnel) /* out */ { - int rc; - struct rfapi_adb *adb; - uint32_t old_lifetime; - int use_ip0 = 0; - struct rfapi_rib_key rk; - - if (advertise_tunnel) - *advertise_tunnel = 0; - - rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); - /* find prefix in advertised prefixes list */ - if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip)) - { - use_ip0 = 1; - assert (pfx_eth); - - rc = - skiplist_search (rfd->advertised.ip0_by_ether, &rk, - (void **) &adb); - - } - else - { - - /* find prefix in advertised prefixes list */ - rc = - skiplist_search (rfd->advertised.ipN_by_prefix, &rk, - (void **) &adb); - } - - if (rc) - { - return ENOENT; - } - - old_lifetime = adb->lifetime; - - if (use_ip0) - { - rc = skiplist_delete (rfd->advertised.ip0_by_ether, &rk, NULL); - } - else - { - rc = skiplist_delete (rfd->advertised.ipN_by_prefix, &rk, NULL); - } - assert (!rc); - - rc = skiplist_delete (rfd->advertised.by_lifetime, adb, NULL); - assert (!rc); - - rfapiAdbFree (adb); - - if (rfapiApAdjustLifetimeStats (rfd, &old_lifetime, NULL)) - { - if (advertise_tunnel) - *advertise_tunnel = 1; - } - - return 0; + int rc; + struct rfapi_adb *adb; + uint32_t old_lifetime; + int use_ip0 = 0; + struct rfapi_rib_key rk; + + if (advertise_tunnel) + *advertise_tunnel = 0; + + rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); + /* find prefix in advertised prefixes list */ + if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) { + use_ip0 = 1; + assert(pfx_eth); + + rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk, + (void **)&adb); + + } else { + + /* find prefix in advertised prefixes list */ + rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk, + (void **)&adb); + } + + if (rc) { + return ENOENT; + } + + old_lifetime = adb->lifetime; + + if (use_ip0) { + rc = skiplist_delete(rfd->advertised.ip0_by_ether, &rk, NULL); + } else { + rc = skiplist_delete(rfd->advertised.ipN_by_prefix, &rk, NULL); + } + assert(!rc); + + rc = skiplist_delete(rfd->advertised.by_lifetime, adb, NULL); + assert(!rc); + + rfapiAdbFree(adb); + + if (rfapiApAdjustLifetimeStats(rfd, &old_lifetime, NULL)) { + if (advertise_tunnel) + *advertise_tunnel = 1; + } + + return 0; } diff --git a/bgpd/rfapi/rfapi_ap.h b/bgpd/rfapi/rfapi_ap.h index c875a52e50..56977bd246 100644 --- a/bgpd/rfapi/rfapi_ap.h +++ b/bgpd/rfapi/rfapi_ap.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -56,44 +56,30 @@ #include "rfapi_rib.h" -extern void -rfapiApInit (struct rfapi_advertised_prefixes *ap); +extern void rfapiApInit(struct rfapi_advertised_prefixes *ap); -extern void -rfapiApRelease (struct rfapi_advertised_prefixes *ap); - -extern int -rfapiApCount (struct rfapi_descriptor *rfd); +extern void rfapiApRelease(struct rfapi_advertised_prefixes *ap); +extern int rfapiApCount(struct rfapi_descriptor *rfd); -extern int -rfapiApCountAll (struct bgp *bgp); -extern void -rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd); +extern int rfapiApCountAll(struct bgp *bgp); -extern void -rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd); +extern void rfapiApReadvertiseAll(struct bgp *bgp, + struct rfapi_descriptor *rfd); -extern int -rfapiApAdd ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *pfx_ip, - struct prefix *pfx_eth, - struct prefix_rd *prd, - uint32_t lifetime, - uint8_t cost, - struct rfapi_l2address_option *l2o); /* other options TBD */ +extern void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd); extern int -rfapiApDelete ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *pfx_ip, - struct prefix *pfx_eth, - struct prefix_rd *prd, - int *advertise_tunnel); /* out */ +rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *pfx_ip, + struct prefix *pfx_eth, struct prefix_rd *prd, uint32_t lifetime, + uint8_t cost, + struct rfapi_l2address_option *l2o); /* other options TBD */ + +extern int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct prefix *pfx_ip, struct prefix *pfx_eth, + struct prefix_rd *prd, + int *advertise_tunnel); /* out */ #endif /* _QUAGGA_BGP_RFAPI_AP_H */ diff --git a/bgpd/rfapi/rfapi_backend.h b/bgpd/rfapi/rfapi_backend.h index a2537bd918..4455d66a26 100644 --- a/bgpd/rfapi/rfapi_backend.h +++ b/bgpd/rfapi/rfapi_backend.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -26,56 +26,44 @@ #include "bgpd/bgp_route.h" #include "bgpd/bgp_nexthop.h" -extern void rfapi_init (void); -extern void vnc_zebra_init (struct thread_master *master); -extern void vnc_zebra_destroy (void); +extern void rfapi_init(void); +extern void vnc_zebra_init(struct thread_master *master); +extern void vnc_zebra_destroy(void); -extern void rfapi_delete (struct bgp *); +extern void rfapi_delete(struct bgp *); -struct rfapi *bgp_rfapi_new (struct bgp *bgp); -void bgp_rfapi_destroy (struct bgp *bgp, struct rfapi *h); +struct rfapi *bgp_rfapi_new(struct bgp *bgp); +void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h); -extern void -rfapiProcessUpdate (struct peer *peer, - void *rfd, - struct prefix *p, - struct prefix_rd *prd, - struct attr *attr, - afi_t afi, - safi_t safi, - u_char type, u_char sub_type, uint32_t * label); +extern void rfapiProcessUpdate(struct peer *peer, void *rfd, struct prefix *p, + struct prefix_rd *prd, struct attr *attr, + afi_t afi, safi_t safi, u_char type, + u_char sub_type, uint32_t *label); -extern void -rfapiProcessWithdraw (struct peer *peer, - void *rfd, - struct prefix *p, - struct prefix_rd *prd, - struct attr *attr, - afi_t afi, safi_t safi, u_char type, int kill); +extern void rfapiProcessWithdraw(struct peer *peer, void *rfd, struct prefix *p, + struct prefix_rd *prd, struct attr *attr, + afi_t afi, safi_t safi, u_char type, int kill); -extern void rfapiProcessPeerDown (struct peer *peer); +extern void rfapiProcessPeerDown(struct peer *peer); -extern void -vnc_zebra_announce (struct prefix *p, - struct bgp_info *new_select, struct bgp *bgp); +extern void vnc_zebra_announce(struct prefix *p, struct bgp_info *new_select, + struct bgp *bgp); -extern void -vnc_zebra_withdraw (struct prefix *p, struct bgp_info *old_select); +extern void vnc_zebra_withdraw(struct prefix *p, struct bgp_info *old_select); -extern void -rfapi_vty_out_vncinfo (struct vty *vty, - struct prefix *p, struct bgp_info *bi, safi_t safi); +extern void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p, + struct bgp_info *bi, safi_t safi); -extern void vnc_direct_bgp_vpn_enable (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi); -extern void vnc_direct_bgp_vpn_disable (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi); -extern void vnc_direct_bgp_rh_vpn_enable (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi); -extern void vnc_direct_bgp_rh_vpn_disable (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi); #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c index d05b271288..3217d34e77 100644 --- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c +++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -36,15 +36,14 @@ #include "bgpd/rfapi/vnc_debug.h" -void * -rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un) +void *rfapi_create_generic(struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un) { - struct rfapi_descriptor *rfd; - rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor)); - vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); - rfd->vn_addr = *vn; - rfd->un_addr = *un; - return (void *) rfd; + struct rfapi_descriptor *rfd; + rfd = XCALLOC(MTYPE_RFAPI_DESC, sizeof(struct rfapi_descriptor)); + vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd); + rfd->vn_addr = *vn; + rfd->un_addr = *un; + return (void *)rfd; } /*------------------------------------------ @@ -52,20 +51,19 @@ rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un) * * Compare two generic rfapi descriptors. * - * input: + * input: * grfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic * * output: * - * return value: + * return value: * *------------------------------------------*/ -void -rfapi_free_generic (void *grfd) +void rfapi_free_generic(void *grfd) { - struct rfapi_descriptor *rfd; - rfd = (struct rfapi_descriptor *) grfd; - XFREE (MTYPE_RFAPI_DESC, rfd); + struct rfapi_descriptor *rfd; + rfd = (struct rfapi_descriptor *)grfd; + XFREE(MTYPE_RFAPI_DESC, rfd); } @@ -74,7 +72,7 @@ rfapi_free_generic (void *grfd) * * Compare two generic rfapi descriptors. * - * input: + * input: * rfd1: rfapi descriptor returned by rfapi_open or rfapi_create_generic * rfd2: rfapi descriptor returned by rfapi_open or rfapi_create_generic * @@ -84,48 +82,45 @@ rfapi_free_generic (void *grfd) * 0 Mismatch * 1 Match *------------------------------------------*/ -int -rfapi_compare_rfds (void *rfd1, void *rfd2) +int rfapi_compare_rfds(void *rfd1, void *rfd2) { - struct rfapi_descriptor *rrfd1, *rrfd2; - int match = 0; + struct rfapi_descriptor *rrfd1, *rrfd2; + int match = 0; - rrfd1 = (struct rfapi_descriptor *) rfd1; - rrfd2 = (struct rfapi_descriptor *) rfd2; + rrfd1 = (struct rfapi_descriptor *)rfd1; + rrfd2 = (struct rfapi_descriptor *)rfd2; - if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family) - { - if (rrfd1->vn_addr.addr_family == AF_INET) - match = IPV4_ADDR_SAME (&(rrfd1->vn_addr.addr.v4), - &(rrfd2->vn_addr.addr.v4)); - else - match = IPV6_ADDR_SAME (&(rrfd1->vn_addr.addr.v6), - &(rrfd2->vn_addr.addr.v6)); - } + if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family) { + if (rrfd1->vn_addr.addr_family == AF_INET) + match = IPV4_ADDR_SAME(&(rrfd1->vn_addr.addr.v4), + &(rrfd2->vn_addr.addr.v4)); + else + match = IPV6_ADDR_SAME(&(rrfd1->vn_addr.addr.v6), + &(rrfd2->vn_addr.addr.v6)); + } - /* - * If the VN addresses don't match in all forms, - * give up. - */ - if (!match) - return 0; + /* + * If the VN addresses don't match in all forms, + * give up. + */ + if (!match) + return 0; - /* - * do the process again for the UN addresses. - */ - match = 0; - if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family) - { - /* VN addresses match - * UN address families match - * now check the actual UN addresses - */ - if (rrfd1->un_addr.addr_family == AF_INET) - match = IPV4_ADDR_SAME (&(rrfd1->un_addr.addr.v4), - &(rrfd2->un_addr.addr.v4)); - else - match = IPV6_ADDR_SAME (&(rrfd1->un_addr.addr.v6), - &(rrfd2->un_addr.addr.v6)); - } - return match; + /* + * do the process again for the UN addresses. + */ + match = 0; + if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family) { + /* VN addresses match + * UN address families match + * now check the actual UN addresses + */ + if (rrfd1->un_addr.addr_family == AF_INET) + match = IPV4_ADDR_SAME(&(rrfd1->un_addr.addr.v4), + &(rrfd2->un_addr.addr.v4)); + else + match = IPV6_ADDR_SAME(&(rrfd1->un_addr.addr.v6), + &(rrfd2->un_addr.addr.v6)); + } + return match; } diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.h b/bgpd/rfapi/rfapi_descriptor_rfp_utils.h index 04fbfbcec8..dcc197961c 100644 --- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.h +++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -19,20 +19,20 @@ */ -extern void *rfapi_create_generic (struct rfapi_ip_addr *vn, - struct rfapi_ip_addr *un); +extern void *rfapi_create_generic(struct rfapi_ip_addr *vn, + struct rfapi_ip_addr *un); /*------------------------------------------ * rfapi_free_generic * * Compare two generic rfapi descriptors. * - * input: + * input: * grfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic * * output: * - * return value: + * return value: * *------------------------------------------*/ -extern void rfapi_free_generic (void *grfd); +extern void rfapi_free_generic(void *grfd); diff --git a/bgpd/rfapi/rfapi_encap_tlv.c b/bgpd/rfapi/rfapi_encap_tlv.c index 24bfb41bfa..f31342e192 100644 --- a/bgpd/rfapi/rfapi_encap_tlv.c +++ b/bgpd/rfapi/rfapi_encap_tlv.c @@ -1,4 +1,4 @@ -/* +/* * Copyright 2015-2016, LabN Consulting, L.L.C. * * This program is free software; you can redistribute it and/or @@ -37,374 +37,350 @@ #include "bgpd/rfapi/bgp_rfapi_cfg.h" #include "bgpd/rfapi/vnc_debug.h" -static void -rfapi_add_endpoint_address_to_subtlv ( - struct bgp *bgp, - struct rfapi_ip_addr *ea, - struct bgp_tea_subtlv_remote_endpoint *subtlv) +static void rfapi_add_endpoint_address_to_subtlv( + struct bgp *bgp, struct rfapi_ip_addr *ea, + struct bgp_tea_subtlv_remote_endpoint *subtlv) { - subtlv->family = ea->addr_family; - if (subtlv->family == AF_INET) - subtlv->ip_address.v4 = ea->addr.v4; - else - subtlv->ip_address.v6 = ea->addr.v6; - subtlv->as4 = htonl (bgp->as); + subtlv->family = ea->addr_family; + if (subtlv->family == AF_INET) + subtlv->ip_address.v4 = ea->addr.v4; + else + subtlv->ip_address.v6 = ea->addr.v6; + subtlv->as4 = htonl(bgp->as); } bgp_encap_types -rfapi_tunneltype_option_to_tlv ( - struct bgp *bgp, - struct rfapi_ip_addr *ea, - struct rfapi_tunneltype_option *tto, - struct attr *attr, - int always_add) +rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea, + struct rfapi_tunneltype_option *tto, + struct attr *attr, int always_add) { -#define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype) \ - if ((always_add || (bgp->rfapi_cfg && \ - !CHECK_FLAG(bgp->rfapi_cfg->flags, \ - BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) && \ - ea && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype, \ - BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) { \ - rfapi_add_endpoint_address_to_subtlv(bgp, ea, \ - &tto->bgpinfo.ttype.st_endpoint); \ - SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \ - } - - struct rfapi_tunneltype_option dto; - if (tto == NULL) - { /* create default type */ - tto = &dto; - memset (tto, 0, sizeof (dto)); - tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT; - } - switch (tto->type) - { - case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (l2tpv3_ip); - bgp_encap_type_l2tpv3overip_to_tlv (&tto->bgpinfo.l2tpv3_ip, attr); - break; - - case BGP_ENCAP_TYPE_GRE: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (gre); - bgp_encap_type_gre_to_tlv (&tto->bgpinfo.gre, attr); - break; - - case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (transmit_tunnel_endpoint); - bgp_encap_type_transmit_tunnel_endpoint (&tto->bgpinfo.transmit_tunnel_endpoint, - attr); - break; - - case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ipsec_tunnel); - bgp_encap_type_ipsec_in_tunnel_mode_to_tlv (&tto->bgpinfo.ipsec_tunnel, - attr); - break; - - case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ip_ipsec); - bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv - (&tto->bgpinfo.ip_ipsec, attr); - break; - - case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_ipsec); - bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv - (&tto->bgpinfo.mpls_ipsec, attr); - break; - - case BGP_ENCAP_TYPE_IP_IN_IP: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ip_ip); - bgp_encap_type_ip_in_ip_to_tlv (&tto->bgpinfo.ip_ip, attr); - break; - - case BGP_ENCAP_TYPE_VXLAN: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (vxlan); - bgp_encap_type_vxlan_to_tlv (&tto->bgpinfo.vxlan, attr); - break; - - case BGP_ENCAP_TYPE_NVGRE: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (nvgre); - bgp_encap_type_nvgre_to_tlv (&tto->bgpinfo.nvgre, attr); - break; - - case BGP_ENCAP_TYPE_MPLS: - /* nothing to do for MPLS */ - break; - - case BGP_ENCAP_TYPE_MPLS_IN_GRE: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_gre); - bgp_encap_type_mpls_in_gre_to_tlv (&tto->bgpinfo.mpls_gre, attr); - break; - - case BGP_ENCAP_TYPE_VXLAN_GPE: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (vxlan_gpe); - bgp_encap_type_vxlan_gpe_to_tlv (&tto->bgpinfo.vxlan_gpe, attr); - break; - - case BGP_ENCAP_TYPE_MPLS_IN_UDP: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_udp); - bgp_encap_type_mpls_in_udp_to_tlv (&tto->bgpinfo.mpls_udp, attr); - break; - - case BGP_ENCAP_TYPE_PBB: - _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (pbb); - bgp_encap_type_pbb_to_tlv (&tto->bgpinfo.pbb, attr); - break; - - default: - assert (0); - } - return tto->type; +#define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype) \ + if ((always_add \ + || (bgp->rfapi_cfg \ + && !CHECK_FLAG(bgp->rfapi_cfg->flags, \ + BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) \ + && ea \ + && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype, \ + BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) { \ + rfapi_add_endpoint_address_to_subtlv( \ + bgp, ea, &tto->bgpinfo.ttype.st_endpoint); \ + SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, \ + BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \ + } + + struct rfapi_tunneltype_option dto; + if (tto == NULL) { /* create default type */ + tto = &dto; + memset(tto, 0, sizeof(dto)); + tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT; + } + switch (tto->type) { + case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(l2tpv3_ip); + bgp_encap_type_l2tpv3overip_to_tlv(&tto->bgpinfo.l2tpv3_ip, + attr); + break; + + case BGP_ENCAP_TYPE_GRE: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(gre); + bgp_encap_type_gre_to_tlv(&tto->bgpinfo.gre, attr); + break; + + case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(transmit_tunnel_endpoint); + bgp_encap_type_transmit_tunnel_endpoint( + &tto->bgpinfo.transmit_tunnel_endpoint, attr); + break; + + case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ipsec_tunnel); + bgp_encap_type_ipsec_in_tunnel_mode_to_tlv( + &tto->bgpinfo.ipsec_tunnel, attr); + break; + + case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ipsec); + bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv( + &tto->bgpinfo.ip_ipsec, attr); + break; + + case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_ipsec); + bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv( + &tto->bgpinfo.mpls_ipsec, attr); + break; + + case BGP_ENCAP_TYPE_IP_IN_IP: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ip); + bgp_encap_type_ip_in_ip_to_tlv(&tto->bgpinfo.ip_ip, attr); + break; + + case BGP_ENCAP_TYPE_VXLAN: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan); + bgp_encap_type_vxlan_to_tlv(&tto->bgpinfo.vxlan, attr); + break; + + case BGP_ENCAP_TYPE_NVGRE: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(nvgre); + bgp_encap_type_nvgre_to_tlv(&tto->bgpinfo.nvgre, attr); + break; + + case BGP_ENCAP_TYPE_MPLS: + /* nothing to do for MPLS */ + break; + + case BGP_ENCAP_TYPE_MPLS_IN_GRE: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_gre); + bgp_encap_type_mpls_in_gre_to_tlv(&tto->bgpinfo.mpls_gre, attr); + break; + + case BGP_ENCAP_TYPE_VXLAN_GPE: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan_gpe); + bgp_encap_type_vxlan_gpe_to_tlv(&tto->bgpinfo.vxlan_gpe, attr); + break; + + case BGP_ENCAP_TYPE_MPLS_IN_UDP: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_udp); + bgp_encap_type_mpls_in_udp_to_tlv(&tto->bgpinfo.mpls_udp, attr); + break; + + case BGP_ENCAP_TYPE_PBB: + _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(pbb); + bgp_encap_type_pbb_to_tlv(&tto->bgpinfo.pbb, attr); + break; + + default: + assert(0); + } + return tto->type; } -struct rfapi_un_option * -rfapi_encap_tlv_to_un_option (struct attr *attr) +struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr) { - struct rfapi_un_option *uo = NULL; - struct rfapi_tunneltype_option *tto; - int rc; - struct bgp_attr_encap_subtlv *stlv; - - /* no tunnel encap attr stored */ - if (!attr->encap_tunneltype) - return NULL; - - stlv = attr->encap_subtlvs; - - uo = XCALLOC (MTYPE_RFAPI_UN_OPTION, sizeof (struct rfapi_un_option)); - assert (uo); - uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; - uo->v.tunnel.type = attr->encap_tunneltype; - tto = &uo->v.tunnel; - - switch (attr->encap_tunneltype) - { - case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: - rc = tlv_to_bgp_encap_type_l2tpv3overip (stlv, &tto->bgpinfo.l2tpv3_ip); - break; - - case BGP_ENCAP_TYPE_GRE: - rc = tlv_to_bgp_encap_type_gre (stlv, &tto->bgpinfo.gre); - break; - - case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: - rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint (stlv, - &tto->bgpinfo.transmit_tunnel_endpoint); - break; - - case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: - rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode (stlv, - &tto->bgpinfo.ipsec_tunnel); - break; - - case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: - rc = - tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stlv, - &tto->bgpinfo.ip_ipsec); - break; - - case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: - rc = - tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode - (stlv, &tto->bgpinfo.mpls_ipsec); - break; - - case BGP_ENCAP_TYPE_IP_IN_IP: - rc = tlv_to_bgp_encap_type_ip_in_ip (stlv, &tto->bgpinfo.ip_ip); - break; - - case BGP_ENCAP_TYPE_VXLAN: - rc = tlv_to_bgp_encap_type_vxlan (stlv, &tto->bgpinfo.vxlan); - break; - - case BGP_ENCAP_TYPE_NVGRE: - rc = tlv_to_bgp_encap_type_nvgre (stlv, &tto->bgpinfo.nvgre); - break; - - case BGP_ENCAP_TYPE_MPLS: - rc = tlv_to_bgp_encap_type_mpls (stlv, &tto->bgpinfo.mpls); - break; - - case BGP_ENCAP_TYPE_MPLS_IN_GRE: - rc = tlv_to_bgp_encap_type_mpls_in_gre (stlv, &tto->bgpinfo.mpls_gre); - break; - - case BGP_ENCAP_TYPE_VXLAN_GPE: - rc = tlv_to_bgp_encap_type_vxlan_gpe (stlv, &tto->bgpinfo.vxlan_gpe); - break; - - case BGP_ENCAP_TYPE_MPLS_IN_UDP: - rc = tlv_to_bgp_encap_type_mpls_in_udp (stlv, &tto->bgpinfo.mpls_udp); - break; - - case BGP_ENCAP_TYPE_PBB: - rc = tlv_to_bgp_encap_type_pbb (stlv, &tto->bgpinfo.pbb); - break; - - default: - vnc_zlog_debug_verbose ("%s: unknown tunnel type %d", - __func__, attr->encap_tunneltype); - rc = -1; - break; - } - if (rc) - { - XFREE (MTYPE_RFAPI_UN_OPTION, uo); - uo = NULL; - } - return uo; + struct rfapi_un_option *uo = NULL; + struct rfapi_tunneltype_option *tto; + int rc; + struct bgp_attr_encap_subtlv *stlv; + + /* no tunnel encap attr stored */ + if (!attr->encap_tunneltype) + return NULL; + + stlv = attr->encap_subtlvs; + + uo = XCALLOC(MTYPE_RFAPI_UN_OPTION, sizeof(struct rfapi_un_option)); + assert(uo); + uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; + uo->v.tunnel.type = attr->encap_tunneltype; + tto = &uo->v.tunnel; + + switch (attr->encap_tunneltype) { + case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: + rc = tlv_to_bgp_encap_type_l2tpv3overip( + stlv, &tto->bgpinfo.l2tpv3_ip); + break; + + case BGP_ENCAP_TYPE_GRE: + rc = tlv_to_bgp_encap_type_gre(stlv, &tto->bgpinfo.gre); + break; + + case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: + rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint( + stlv, &tto->bgpinfo.transmit_tunnel_endpoint); + break; + + case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: + rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode( + stlv, &tto->bgpinfo.ipsec_tunnel); + break; + + case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: + rc = tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( + stlv, &tto->bgpinfo.ip_ipsec); + break; + + case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: + rc = tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( + stlv, &tto->bgpinfo.mpls_ipsec); + break; + + case BGP_ENCAP_TYPE_IP_IN_IP: + rc = tlv_to_bgp_encap_type_ip_in_ip(stlv, &tto->bgpinfo.ip_ip); + break; + + case BGP_ENCAP_TYPE_VXLAN: + rc = tlv_to_bgp_encap_type_vxlan(stlv, &tto->bgpinfo.vxlan); + break; + + case BGP_ENCAP_TYPE_NVGRE: + rc = tlv_to_bgp_encap_type_nvgre(stlv, &tto->bgpinfo.nvgre); + break; + + case BGP_ENCAP_TYPE_MPLS: + rc = tlv_to_bgp_encap_type_mpls(stlv, &tto->bgpinfo.mpls); + break; + + case BGP_ENCAP_TYPE_MPLS_IN_GRE: + rc = tlv_to_bgp_encap_type_mpls_in_gre(stlv, + &tto->bgpinfo.mpls_gre); + break; + + case BGP_ENCAP_TYPE_VXLAN_GPE: + rc = tlv_to_bgp_encap_type_vxlan_gpe(stlv, + &tto->bgpinfo.vxlan_gpe); + break; + + case BGP_ENCAP_TYPE_MPLS_IN_UDP: + rc = tlv_to_bgp_encap_type_mpls_in_udp(stlv, + &tto->bgpinfo.mpls_udp); + break; + + case BGP_ENCAP_TYPE_PBB: + rc = tlv_to_bgp_encap_type_pbb(stlv, &tto->bgpinfo.pbb); + break; + + default: + vnc_zlog_debug_verbose("%s: unknown tunnel type %d", __func__, + attr->encap_tunneltype); + rc = -1; + break; + } + if (rc) { + XFREE(MTYPE_RFAPI_UN_OPTION, uo); + uo = NULL; + } + return uo; } /*********************************************************************** * SUBTLV PRINT ***********************************************************************/ -static void -subtlv_print_encap_l2tpv3_over_ip ( - void *stream, - int column_offset, - struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st) +static void subtlv_print_encap_l2tpv3_over_ip( + void *stream, int column_offset, + struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!st) - return; - - fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)", - vty_newline); - fp (out, "%*s SessionID: %d%s", column_offset, "", st->sessionid, - vty_newline); - fp (out, "%*s Cookie: (length %d)%s", column_offset, "", st->cookie_length, - vty_newline); + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!st) + return; + + fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)", + vty_newline); + fp(out, "%*s SessionID: %d%s", column_offset, "", st->sessionid, + vty_newline); + fp(out, "%*s Cookie: (length %d)%s", column_offset, "", + st->cookie_length, vty_newline); } -static void -subtlv_print_encap_gre ( - void *stream, - int column_offset, - struct bgp_tea_subtlv_encap_gre_key *st) +static void subtlv_print_encap_gre(void *stream, int column_offset, + struct bgp_tea_subtlv_encap_gre_key *st) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!st) - return; - - fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)", vty_newline); - fp (out, "%*s GRE key: %d (0x%x)%s", column_offset, "", st->gre_key, - st->gre_key, vty_newline); + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!st) + return; + + fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)", + vty_newline); + fp(out, "%*s GRE key: %d (0x%x)%s", column_offset, "", st->gre_key, + st->gre_key, vty_newline); } -static void -subtlv_print_encap_pbb ( - void *stream, - int column_offset, - struct bgp_tea_subtlv_encap_pbb *st) +static void subtlv_print_encap_pbb(void *stream, int column_offset, + struct bgp_tea_subtlv_encap_pbb *st) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!st) - return; - - fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)", vty_newline); - if (st->flag_isid) - { - fp (out, "%*s ISID: %d (0x%x)%s", column_offset, "", st->isid, - st->isid, vty_newline); - } - if (st->flag_vid) - { - fp (out, "%*s VID: %d (0x%x)%s", column_offset, "", st->vid, st->vid, - vty_newline); - } - fp (out, "%*s MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s", - column_offset, "", - st->macaddr[0], - st->macaddr[1], - st->macaddr[2], - st->macaddr[3], st->macaddr[4], st->macaddr[5], vty_newline); + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!st) + return; + + fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)", + vty_newline); + if (st->flag_isid) { + fp(out, "%*s ISID: %d (0x%x)%s", column_offset, "", st->isid, + st->isid, vty_newline); + } + if (st->flag_vid) { + fp(out, "%*s VID: %d (0x%x)%s", column_offset, "", st->vid, + st->vid, vty_newline); + } + fp(out, "%*s MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s", column_offset, + "", st->macaddr[0], st->macaddr[1], st->macaddr[2], st->macaddr[3], + st->macaddr[4], st->macaddr[5], vty_newline); } -static void -subtlv_print_proto_type ( - void *stream, - int column_offset, - struct bgp_tea_subtlv_proto_type *st) +static void subtlv_print_proto_type(void *stream, int column_offset, + struct bgp_tea_subtlv_proto_type *st) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!st) - return; - - fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)", - vty_newline); - fp (out, "%*s Proto %d (0x%x)%s", column_offset, "", st->proto, st->proto, - vty_newline); + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!st) + return; + + fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)", + vty_newline); + fp(out, "%*s Proto %d (0x%x)%s", column_offset, "", st->proto, + st->proto, vty_newline); } -static void -subtlv_print_color ( - void *stream, - int column_offset, - struct bgp_tea_subtlv_color *st) +static void subtlv_print_color(void *stream, int column_offset, + struct bgp_tea_subtlv_color *st) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!st) - return; - - fp (out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline); - fp (out, "%*s Color: %d (0x%x)", column_offset, "", st->color, st->color, - vty_newline); + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!st) + return; + + fp(out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline); + fp(out, "%*s Color: %d (0x%x)", column_offset, "", st->color, + st->color, vty_newline); } -static void -subtlv_print_ipsec_ta ( - void *stream, - int column_offset, - struct bgp_tea_subtlv_ipsec_ta *st) +static void subtlv_print_ipsec_ta(void *stream, int column_offset, + struct bgp_tea_subtlv_ipsec_ta *st) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!st) - return; - - fp (out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline); - fp (out, "%*s Authenticator Type: %d (0x%x)", column_offset, "", - st->authenticator_type, st->authenticator_type, vty_newline); - fp (out, "%*s Authenticator: (length %d)", column_offset, "", - st->authenticator_length, vty_newline); + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!st) + return; + + fp(out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline); + fp(out, "%*s Authenticator Type: %d (0x%x)", column_offset, "", + st->authenticator_type, st->authenticator_type, vty_newline); + fp(out, "%*s Authenticator: (length %d)", column_offset, "", + st->authenticator_length, vty_newline); } /*********************************************************************** @@ -412,396 +388,358 @@ subtlv_print_ipsec_ta ( ***********************************************************************/ static void -print_encap_type_l2tpv3overip ( - void *stream, - int column_offset, - struct bgp_encap_type_l2tpv3_over_ip *bet) +print_encap_type_l2tpv3overip(void *stream, int column_offset, + struct bgp_encap_type_l2tpv3_over_ip *bet) { - const char *type = "L2TPv3 over IP"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; - - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - - subtlv_print_encap_l2tpv3_over_ip (stream, column_offset + 2, - &bet->st_encap); - subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto); - subtlv_print_color (stream, column_offset + 2, &bet->st_color); + const char *type = "L2TPv3 over IP"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; + + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + + subtlv_print_encap_l2tpv3_over_ip(stream, column_offset + 2, + &bet->st_encap); + subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); + subtlv_print_color(stream, column_offset + 2, &bet->st_color); } -static void -print_encap_type_gre ( - void *stream, - int column_offset, - struct bgp_encap_type_gre *bet) +static void print_encap_type_gre(void *stream, int column_offset, + struct bgp_encap_type_gre *bet) { - const char *type = "GRE"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; - - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - - subtlv_print_encap_gre (stream, column_offset + 2, &bet->st_encap); - subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto); - subtlv_print_color (stream, column_offset + 2, &bet->st_color); + const char *type = "GRE"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; + + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + + subtlv_print_encap_gre(stream, column_offset + 2, &bet->st_encap); + subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); + subtlv_print_color(stream, column_offset + 2, &bet->st_color); } -static void -print_encap_type_ip_in_ip ( - void *stream, - int column_offset, - struct bgp_encap_type_ip_in_ip *bet) +static void print_encap_type_ip_in_ip(void *stream, int column_offset, + struct bgp_encap_type_ip_in_ip *bet) { - const char *type = "IP in IP"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "IP in IP"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto); - subtlv_print_color (stream, column_offset + 2, &bet->st_color); + subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); + subtlv_print_color(stream, column_offset + 2, &bet->st_color); } -static void -print_encap_type_transmit_tunnel_endpoint ( - void *stream, - int column_offset, - struct bgp_encap_type_transmit_tunnel_endpoint *bet) +static void print_encap_type_transmit_tunnel_endpoint( + void *stream, int column_offset, + struct bgp_encap_type_transmit_tunnel_endpoint *bet) { - const char *type = "Transmit Tunnel Endpoint"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "Transmit Tunnel Endpoint"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - /* no subtlvs for this type */ + /* no subtlvs for this type */ } -static void -print_encap_type_ipsec_in_tunnel_mode ( - void *stream, - int column_offset, - struct bgp_encap_type_ipsec_in_tunnel_mode *bet) +static void print_encap_type_ipsec_in_tunnel_mode( + void *stream, int column_offset, + struct bgp_encap_type_ipsec_in_tunnel_mode *bet) { - const char *type = "IPSEC in Tunnel mode"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; - - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta); + const char *type = "IPSEC in Tunnel mode"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; + + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta); } -static void -print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode ( - void *stream, - int column_offset, - struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet) +static void print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( + void *stream, int column_offset, + struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet) { - const char *type = "IP in IP Tunnel with IPSEC transport mode"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "IP in IP Tunnel with IPSEC transport mode"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta); + subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta); } -static void -print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode ( - void *stream, - int column_offset, - struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet) +static void print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( + void *stream, int column_offset, + struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet) { - const char *type = "MPLS in IP Tunnel with IPSEC transport mode"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "MPLS in IP Tunnel with IPSEC transport mode"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta); + subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta); } -static void -print_encap_type_pbb ( - void *stream, - int column_offset, - struct bgp_encap_type_pbb *bet) +static void print_encap_type_pbb(void *stream, int column_offset, + struct bgp_encap_type_pbb *bet) { - const char *type = "PBB"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "PBB"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - subtlv_print_encap_pbb (stream, column_offset + 2, &bet->st_encap); + subtlv_print_encap_pbb(stream, column_offset + 2, &bet->st_encap); } -static void -print_encap_type_vxlan ( - void *stream, - int column_offset, - struct bgp_encap_type_vxlan *bet) +static void print_encap_type_vxlan(void *stream, int column_offset, + struct bgp_encap_type_vxlan *bet) { - const char *type = "VXLAN"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "VXLAN"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - /* no subtlvs for this type */ + /* no subtlvs for this type */ } -static void -print_encap_type_nvgre ( - void *stream, - int column_offset, - struct bgp_encap_type_nvgre *bet) +static void print_encap_type_nvgre(void *stream, int column_offset, + struct bgp_encap_type_nvgre *bet) { - const char *type = "NVGRE"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "NVGRE"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - /* no subtlvs for this type */ + /* no subtlvs for this type */ } -static void -print_encap_type_mpls ( - void *stream, - int column_offset, - struct bgp_encap_type_mpls *bet) +static void print_encap_type_mpls(void *stream, int column_offset, + struct bgp_encap_type_mpls *bet) { - const char *type = "MPLS"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "MPLS"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - /* no subtlvs for this type */ + /* no subtlvs for this type */ } -static void -print_encap_type_mpls_in_gre ( - void *stream, - int column_offset, - struct bgp_encap_type_mpls_in_gre *bet) +static void print_encap_type_mpls_in_gre(void *stream, int column_offset, + struct bgp_encap_type_mpls_in_gre *bet) { - const char *type = "MPLS in GRE"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "MPLS in GRE"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - /* no subtlvs for this type */ + /* no subtlvs for this type */ } -static void -print_encap_type_vxlan_gpe ( - void *stream, - int column_offset, - struct bgp_encap_type_vxlan_gpe *bet) +static void print_encap_type_vxlan_gpe(void *stream, int column_offset, + struct bgp_encap_type_vxlan_gpe *bet) { - const char *type = "VXLAN GPE"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "VXLAN GPE"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - /* no subtlvs for this type */ + /* no subtlvs for this type */ } -static void -print_encap_type_mpls_in_udp ( - void *stream, - int column_offset, - struct bgp_encap_type_mpls_in_udp *bet) +static void print_encap_type_mpls_in_udp(void *stream, int column_offset, + struct bgp_encap_type_mpls_in_udp *bet) { - const char *type = "MPLS in UDP"; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + const char *type = "MPLS in UDP"; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - if (!bet) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + if (!bet) + return; - fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - /* no subtlvs for this type */ + /* no subtlvs for this type */ } -void -rfapi_print_tunneltype_option ( - void *stream, - int column_offset, - struct rfapi_tunneltype_option *tto) +void rfapi_print_tunneltype_option(void *stream, int column_offset, + struct rfapi_tunneltype_option *tto) { - switch (tto->type) - { - case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: - print_encap_type_l2tpv3overip (stream, column_offset, - &tto->bgpinfo.l2tpv3_ip); - break; - - case BGP_ENCAP_TYPE_GRE: - print_encap_type_gre (stream, column_offset, &tto->bgpinfo.gre); - break; - - case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: - print_encap_type_transmit_tunnel_endpoint (stream, column_offset, - &tto->bgpinfo.transmit_tunnel_endpoint); - break; - - case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: - print_encap_type_ipsec_in_tunnel_mode (stream, column_offset, - &tto->bgpinfo.ipsec_tunnel); - break; - - case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: - print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stream, - column_offset, - &tto->bgpinfo.ip_ipsec); - break; - - case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: - print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (stream, - column_offset, - &tto->bgpinfo.mpls_ipsec); - break; - - case BGP_ENCAP_TYPE_IP_IN_IP: - print_encap_type_ip_in_ip (stream, column_offset, &tto->bgpinfo.ip_ip); - break; - - case BGP_ENCAP_TYPE_VXLAN: - print_encap_type_vxlan (stream, column_offset, &tto->bgpinfo.vxlan); - break; - - case BGP_ENCAP_TYPE_NVGRE: - print_encap_type_nvgre (stream, column_offset, &tto->bgpinfo.nvgre); - break; - - case BGP_ENCAP_TYPE_MPLS: - print_encap_type_mpls (stream, column_offset, &tto->bgpinfo.mpls); - break; - - case BGP_ENCAP_TYPE_MPLS_IN_GRE: - print_encap_type_mpls_in_gre (stream, column_offset, - &tto->bgpinfo.mpls_gre); - break; - - case BGP_ENCAP_TYPE_VXLAN_GPE: - print_encap_type_vxlan_gpe (stream, column_offset, - &tto->bgpinfo.vxlan_gpe); - break; - - case BGP_ENCAP_TYPE_MPLS_IN_UDP: - print_encap_type_mpls_in_udp (stream, column_offset, - &tto->bgpinfo.mpls_udp); - break; - - case BGP_ENCAP_TYPE_PBB: - print_encap_type_pbb (stream, column_offset, &tto->bgpinfo.pbb); - break; - - default: - assert (0); - } + switch (tto->type) { + case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: + print_encap_type_l2tpv3overip(stream, column_offset, + &tto->bgpinfo.l2tpv3_ip); + break; + + case BGP_ENCAP_TYPE_GRE: + print_encap_type_gre(stream, column_offset, &tto->bgpinfo.gre); + break; + + case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: + print_encap_type_transmit_tunnel_endpoint( + stream, column_offset, + &tto->bgpinfo.transmit_tunnel_endpoint); + break; + + case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: + print_encap_type_ipsec_in_tunnel_mode( + stream, column_offset, &tto->bgpinfo.ipsec_tunnel); + break; + + case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: + print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( + stream, column_offset, &tto->bgpinfo.ip_ipsec); + break; + + case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: + print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( + stream, column_offset, &tto->bgpinfo.mpls_ipsec); + break; + + case BGP_ENCAP_TYPE_IP_IN_IP: + print_encap_type_ip_in_ip(stream, column_offset, + &tto->bgpinfo.ip_ip); + break; + + case BGP_ENCAP_TYPE_VXLAN: + print_encap_type_vxlan(stream, column_offset, + &tto->bgpinfo.vxlan); + break; + + case BGP_ENCAP_TYPE_NVGRE: + print_encap_type_nvgre(stream, column_offset, + &tto->bgpinfo.nvgre); + break; + + case BGP_ENCAP_TYPE_MPLS: + print_encap_type_mpls(stream, column_offset, + &tto->bgpinfo.mpls); + break; + + case BGP_ENCAP_TYPE_MPLS_IN_GRE: + print_encap_type_mpls_in_gre(stream, column_offset, + &tto->bgpinfo.mpls_gre); + break; + + case BGP_ENCAP_TYPE_VXLAN_GPE: + print_encap_type_vxlan_gpe(stream, column_offset, + &tto->bgpinfo.vxlan_gpe); + break; + + case BGP_ENCAP_TYPE_MPLS_IN_UDP: + print_encap_type_mpls_in_udp(stream, column_offset, + &tto->bgpinfo.mpls_udp); + break; + + case BGP_ENCAP_TYPE_PBB: + print_encap_type_pbb(stream, column_offset, &tto->bgpinfo.pbb); + break; + + default: + assert(0); + } } diff --git a/bgpd/rfapi/rfapi_encap_tlv.h b/bgpd/rfapi/rfapi_encap_tlv.h index 19e16a41a5..57e1b5ef04 100644 --- a/bgpd/rfapi/rfapi_encap_tlv.h +++ b/bgpd/rfapi/rfapi_encap_tlv.h @@ -1,4 +1,4 @@ -/* +/* * Copyright 2015-2016, LabN Consulting, L.L.C. * * This program is free software; you can redistribute it and/or @@ -22,21 +22,14 @@ #define RFAPI_BGP_ENCAP_TYPE_DEFAULT BGP_ENCAP_TYPE_IP_IN_IP extern bgp_encap_types -rfapi_tunneltype_option_to_tlv ( - struct bgp *bgp, - struct rfapi_ip_addr *ea, - struct rfapi_tunneltype_option *tto, - struct attr *attr, - int always_add); +rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea, + struct rfapi_tunneltype_option *tto, + struct attr *attr, int always_add); -extern struct rfapi_un_option * -rfapi_encap_tlv_to_un_option (struct attr *attr); +extern struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr); -extern void -rfapi_print_tunneltype_option ( - void *stream, - int column_offset, - struct rfapi_tunneltype_option *tto); +extern void rfapi_print_tunneltype_option(void *stream, int column_offset, + struct rfapi_tunneltype_option *tto); #endif /* _QUAGGA_BGP_RFAPI_ENCAP_TLV_H */ diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index dc8dc1ed2e..d0379e1ef8 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -1,22 +1,22 @@ - /* - * - * Copyright 2009-2016, LabN Consulting, L.L.C. - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ +/* +* +* Copyright 2009-2016, LabN Consulting, L.L.C. +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; see the file COPYING; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ /* * File: rfapi_import.c @@ -38,7 +38,7 @@ #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_route.h" -#include "bgpd/bgp_mplsvpn.h" /* prefix_rd2str() */ +#include "bgpd/bgp_mplsvpn.h" /* prefix_rd2str() */ #include "bgpd/bgp_vnc_types.h" #include "bgpd/rfapi/rfapi.h" @@ -75,47 +75,44 @@ * Allocated for each withdraw timer instance; freed when the timer * expires or is canceled */ -struct rfapi_withdraw -{ - struct rfapi_import_table *import_table; - struct route_node *node; - struct bgp_info *info; - safi_t safi; /* used only for bulk operations */ - /* - * For import table node reference count checking (i.e., debugging). - * Normally when a timer expires, lockoffset should be 0. However, if - * the timer expiration function is called directly (e.g., - * rfapiExpireVpnNow), the node could be locked by a preceding - * route_top() or route_next() in a loop, so we need to pass this - * value in. - */ - int lockoffset; +struct rfapi_withdraw { + struct rfapi_import_table *import_table; + struct route_node *node; + struct bgp_info *info; + safi_t safi; /* used only for bulk operations */ + /* + * For import table node reference count checking (i.e., debugging). + * Normally when a timer expires, lockoffset should be 0. However, if + * the timer expiration function is called directly (e.g., + * rfapiExpireVpnNow), the node could be locked by a preceding + * route_top() or route_next() in a loop, so we need to pass this + * value in. + */ + int lockoffset; }; -/* +/* * DEBUG FUNCTION * It's evil and fiendish. It's compiler-dependent. * ? Might need LDFLAGS -rdynamic to produce all function names */ -void -rfapiDebugBacktrace (void) +void rfapiDebugBacktrace(void) { #ifdef HAVE_GLIBC_BACKTRACE #define RFAPI_DEBUG_BACKTRACE_NENTRIES 200 - void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES]; - char **syms; - size_t i; - size_t size; + void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES]; + char **syms; + size_t i; + size_t size; - size = backtrace (buf, RFAPI_DEBUG_BACKTRACE_NENTRIES); - syms = backtrace_symbols (buf, size); + size = backtrace(buf, RFAPI_DEBUG_BACKTRACE_NENTRIES); + syms = backtrace_symbols(buf, size); - for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i) - { - vnc_zlog_debug_verbose ("backtrace[%2zu]: %s", i, syms[i]); - } + for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i) { + vnc_zlog_debug_verbose("backtrace[%2zu]: %s", i, syms[i]); + } - free (syms); + free(syms); #else #endif } @@ -125,89 +122,80 @@ rfapiDebugBacktrace (void) * Count remote routes and compare with actively-maintained values. * Abort if they disagree. */ -void -rfapiCheckRouteCount () +void rfapiCheckRouteCount() { - struct bgp *bgp = bgp_get_default (); - struct rfapi *h; - struct rfapi_import_table *it; - afi_t afi; - - assert (bgp); - - h = bgp->rfapi; - assert (h); - - for (it = h->imports; it; it = it->next) - { - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - struct route_table *rt; - struct route_node *rn; - - int holddown_count = 0; - int local_count = 0; - int imported_count = 0; - int remote_count = 0; - - rt = it->imported_vpn[afi]; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - struct bgp_info *bi; - struct bgp_info *next; - - for (bi = rn->info; bi; bi = next) - { - next = bi->next; - - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - { - ++holddown_count; - - } - else - { - if (RFAPI_LOCAL_BI (bi)) - { - ++local_count; - } - else - { - if (RFAPI_DIRECT_IMPORT_BI (bi)) - { - ++imported_count; - } - else - { - ++remote_count; - } - } - } - } - } - - if (it->holddown_count[afi] != holddown_count) - { - vnc_zlog_debug_verbose ("%s: it->holddown_count %d != holddown_count %d", - __func__, it->holddown_count[afi], holddown_count); - assert (0); - } - if (it->remote_count[afi] != remote_count) - { - vnc_zlog_debug_verbose ("%s: it->remote_count %d != remote_count %d", - __func__, it->remote_count[afi], remote_count); - assert (0); - } - if (it->imported_count[afi] != imported_count) - { - vnc_zlog_debug_verbose ("%s: it->imported_count %d != imported_count %d", - __func__, it->imported_count[afi], imported_count); - assert (0); - } - } - } + struct bgp *bgp = bgp_get_default(); + struct rfapi *h; + struct rfapi_import_table *it; + afi_t afi; + + assert(bgp); + + h = bgp->rfapi; + assert(h); + + for (it = h->imports; it; it = it->next) { + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + struct route_table *rt; + struct route_node *rn; + + int holddown_count = 0; + int local_count = 0; + int imported_count = 0; + int remote_count = 0; + + rt = it->imported_vpn[afi]; + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + struct bgp_info *bi; + struct bgp_info *next; + + for (bi = rn->info; bi; bi = next) { + next = bi->next; + + if (CHECK_FLAG(bi->flags, + BGP_INFO_REMOVED)) { + ++holddown_count; + + } else { + if (RFAPI_LOCAL_BI(bi)) { + ++local_count; + } else { + if (RFAPI_DIRECT_IMPORT_BI( + bi)) { + ++imported_count; + } else { + ++remote_count; + } + } + } + } + } + + if (it->holddown_count[afi] != holddown_count) { + vnc_zlog_debug_verbose( + "%s: it->holddown_count %d != holddown_count %d", + __func__, it->holddown_count[afi], + holddown_count); + assert(0); + } + if (it->remote_count[afi] != remote_count) { + vnc_zlog_debug_verbose( + "%s: it->remote_count %d != remote_count %d", + __func__, it->remote_count[afi], + remote_count); + assert(0); + } + if (it->imported_count[afi] != imported_count) { + vnc_zlog_debug_verbose( + "%s: it->imported_count %d != imported_count %d", + __func__, it->imported_count[afi], + imported_count); + assert(0); + } + } + } } #if DEBUG_ROUTE_COUNTERS @@ -224,825 +212,777 @@ rfapiCheckRouteCount () * node->lock == 1, and we have to validate the refcount before * the node is deleted. In this case, we specify lockoffset 1. */ -void -rfapiCheckRefcount (struct route_node *rn, safi_t safi, int lockoffset) +void rfapiCheckRefcount(struct route_node *rn, safi_t safi, int lockoffset) { - unsigned int count_bi = 0; - unsigned int count_monitor = 0; - struct bgp_info *bi; - struct rfapi_monitor_encap *hme; - struct rfapi_monitor_vpn *hmv; - - for (bi = rn->info; bi; bi = bi->next) - ++count_bi; - - - if (rn->aggregate) - { - ++count_monitor; /* rfapi_it_extra */ - - switch (safi) - { - void *cursor; - int rc; - - case SAFI_ENCAP: - for (hme = RFAPI_MONITOR_ENCAP (rn); hme; hme = hme->next) - ++count_monitor; - break; - - case SAFI_MPLS_VPN: - - for (hmv = RFAPI_MONITOR_VPN (rn); hmv; hmv = hmv->next) - ++count_monitor; - - if (RFAPI_MONITOR_EXTERIOR (rn)->source) - { - ++count_monitor; /* sl */ - cursor = NULL; - for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn)->source, - NULL, NULL, &cursor); - !rc; - rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn)->source, - NULL, NULL, &cursor)) - { - - ++count_monitor; /* sl entry */ - } - } - break; - - default: - assert (0); - } - } - - if (count_bi + count_monitor + lockoffset != rn->lock) - { - vnc_zlog_debug_verbose - ("%s: count_bi=%d, count_monitor=%d, lockoffset=%d, rn->lock=%d", - __func__, count_bi, count_monitor, lockoffset, rn->lock); - assert (0); - } + unsigned int count_bi = 0; + unsigned int count_monitor = 0; + struct bgp_info *bi; + struct rfapi_monitor_encap *hme; + struct rfapi_monitor_vpn *hmv; + + for (bi = rn->info; bi; bi = bi->next) + ++count_bi; + + + if (rn->aggregate) { + ++count_monitor; /* rfapi_it_extra */ + + switch (safi) { + void *cursor; + int rc; + + case SAFI_ENCAP: + for (hme = RFAPI_MONITOR_ENCAP(rn); hme; + hme = hme->next) + ++count_monitor; + break; + + case SAFI_MPLS_VPN: + + for (hmv = RFAPI_MONITOR_VPN(rn); hmv; hmv = hmv->next) + ++count_monitor; + + if (RFAPI_MONITOR_EXTERIOR(rn)->source) { + ++count_monitor; /* sl */ + cursor = NULL; + for (rc = skiplist_next( + RFAPI_MONITOR_EXTERIOR(rn)->source, + NULL, NULL, &cursor); + !rc; + rc = skiplist_next( + RFAPI_MONITOR_EXTERIOR(rn)->source, + NULL, NULL, &cursor)) { + + ++count_monitor; /* sl entry */ + } + } + break; + + default: + assert(0); + } + } + + if (count_bi + count_monitor + lockoffset != rn->lock) { + vnc_zlog_debug_verbose( + "%s: count_bi=%d, count_monitor=%d, lockoffset=%d, rn->lock=%d", + __func__, count_bi, count_monitor, lockoffset, + rn->lock); + assert(0); + } } /* * Perform deferred rfapi_close operations that were queued * during callbacks. */ -static wq_item_status -rfapi_deferred_close_workfunc (struct work_queue *q, void *data) +static wq_item_status rfapi_deferred_close_workfunc(struct work_queue *q, + void *data) { - struct rfapi_descriptor *rfd = data; - struct rfapi *h = q->spec.data; - - assert (!(h->flags & RFAPI_INCALLBACK)); - rfapi_close (rfd); - vnc_zlog_debug_verbose ("%s: completed deferred close on handle %p", __func__, rfd); - return WQ_SUCCESS; + struct rfapi_descriptor *rfd = data; + struct rfapi *h = q->spec.data; + + assert(!(h->flags & RFAPI_INCALLBACK)); + rfapi_close(rfd); + vnc_zlog_debug_verbose("%s: completed deferred close on handle %p", + __func__, rfd); + return WQ_SUCCESS; } /* * Extract layer 2 option from Encap TLVS in BGP attrs */ -int -rfapiGetL2o (struct attr *attr, struct rfapi_l2address_option *l2o) +int rfapiGetL2o(struct attr *attr, struct rfapi_l2address_option *l2o) { - if (attr) - { - - struct bgp_attr_encap_subtlv *pEncap; - - for (pEncap = attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) - { - - if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) - { - if (pEncap->value[0] == RFAPI_VN_OPTION_TYPE_L2ADDR) - { - - if (pEncap->value[1] == 14) - { - memcpy (l2o->macaddr.octet, pEncap->value + 2, - ETHER_ADDR_LEN); - l2o->label = - ((pEncap->value[10] >> 4) & 0x0f) + - ((pEncap->value[9] << 4) & 0xff0) + - ((pEncap->value[8] << 12) & 0xff000); - - l2o->local_nve_id = pEncap->value[12]; - - l2o->logical_net_id = - (pEncap->value[15] & 0xff) + - ((pEncap->value[14] << 8) & 0xff00) + - ((pEncap->value[13] << 16) & 0xff0000); - } - - return 0; - } - } - } - } - - return ENOENT; + if (attr) { + + struct bgp_attr_encap_subtlv *pEncap; + + for (pEncap = attr->vnc_subtlvs; pEncap; + pEncap = pEncap->next) { + + if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) { + if (pEncap->value[0] + == RFAPI_VN_OPTION_TYPE_L2ADDR) { + + if (pEncap->value[1] == 14) { + memcpy(l2o->macaddr.octet, + pEncap->value + 2, + ETHER_ADDR_LEN); + l2o->label = + ((pEncap->value[10] + >> 4) + & 0x0f) + + ((pEncap->value[9] + << 4) + & 0xff0) + + ((pEncap->value[8] + << 12) + & 0xff000); + + l2o->local_nve_id = + pEncap->value[12]; + + l2o->logical_net_id = + (pEncap->value[15] + & 0xff) + + ((pEncap->value[14] + << 8) + & 0xff00) + + ((pEncap->value[13] + << 16) + & 0xff0000); + } + + return 0; + } + } + } + } + + return ENOENT; } /* * Extract the lifetime from the Tunnel Encap attribute of a route in * an import table */ -int -rfapiGetVncLifetime (struct attr *attr, uint32_t * lifetime) +int rfapiGetVncLifetime(struct attr *attr, uint32_t *lifetime) { - struct bgp_attr_encap_subtlv *pEncap; + struct bgp_attr_encap_subtlv *pEncap; - *lifetime = RFAPI_INFINITE_LIFETIME; /* default to infinite */ + *lifetime = RFAPI_INFINITE_LIFETIME; /* default to infinite */ - if (attr) - { + if (attr) { - for (pEncap = attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) - { + for (pEncap = attr->vnc_subtlvs; pEncap; + pEncap = pEncap->next) { - if (pEncap->type == BGP_VNC_SUBTLV_TYPE_LIFETIME) - { /* lifetime */ - if (pEncap->length == 4) - { - memcpy (lifetime, pEncap->value, 4); - *lifetime = ntohl (*lifetime); - return 0; - } - } - } - } + if (pEncap->type + == BGP_VNC_SUBTLV_TYPE_LIFETIME) { /* lifetime */ + if (pEncap->length == 4) { + memcpy(lifetime, pEncap->value, 4); + *lifetime = ntohl(*lifetime); + return 0; + } + } + } + } - return ENOENT; + return ENOENT; } /* * Extract the tunnel type from the extended community */ -int -rfapiGetTunnelType (struct attr *attr, - bgp_encap_types *type) +int rfapiGetTunnelType(struct attr *attr, bgp_encap_types *type) { - *type = BGP_ENCAP_TYPE_MPLS; /* default to MPLS */ - if (attr && attr->ecommunity) - { - struct ecommunity *ecom = attr->ecommunity; - int i; - - for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += ECOMMUNITY_SIZE) - { - uint8_t *ep; - - ep = ecom->val + i; - if (ep[0] == ECOMMUNITY_ENCODE_OPAQUE && - ep[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP) - { - *type = (ep[6]<<8) + ep[7]; - return 0; - } - } - } - - return ENOENT; + *type = BGP_ENCAP_TYPE_MPLS; /* default to MPLS */ + if (attr && attr->ecommunity) { + struct ecommunity *ecom = attr->ecommunity; + int i; + + for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); + i += ECOMMUNITY_SIZE) { + uint8_t *ep; + + ep = ecom->val + i; + if (ep[0] == ECOMMUNITY_ENCODE_OPAQUE + && ep[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP) { + *type = (ep[6] << 8) + ep[7]; + return 0; + } + } + } + + return ENOENT; } /* * Look for UN address in Encap attribute */ -int -rfapiGetVncTunnelUnAddr (struct attr *attr, struct prefix *p) +int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p) { - struct bgp_attr_encap_subtlv *pEncap; - bgp_encap_types tun_type; - - rfapiGetTunnelType (attr, &tun_type); - if (tun_type == BGP_ENCAP_TYPE_MPLS) - { - if (!p) - return 0; - /* MPLS carries UN address in next hop */ - rfapiNexthop2Prefix (attr, p); - if (p->family != 0) - return 0; - - return ENOENT; - } - if (attr) - { - for (pEncap = attr->encap_subtlvs; pEncap; pEncap = pEncap->next) - { - - if (pEncap->type == BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT) - { /* un addr */ - switch (pEncap->length) - { - case 8: - if (p) - { - p->family = AF_INET; - p->prefixlen = 32; - memcpy (p->u.val, pEncap->value, 4); - } - return 0; - - case 20: - if (p) - { - p->family = AF_INET6; - p->prefixlen = 128; - memcpy (p->u.val, pEncap->value, 16); - } - return 0; - } - } - } - } - - return ENOENT; + struct bgp_attr_encap_subtlv *pEncap; + bgp_encap_types tun_type; + + rfapiGetTunnelType(attr, &tun_type); + if (tun_type == BGP_ENCAP_TYPE_MPLS) { + if (!p) + return 0; + /* MPLS carries UN address in next hop */ + rfapiNexthop2Prefix(attr, p); + if (p->family != 0) + return 0; + + return ENOENT; + } + if (attr) { + for (pEncap = attr->encap_subtlvs; pEncap; + pEncap = pEncap->next) { + + if (pEncap->type + == BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT) { /* un + addr + */ + switch (pEncap->length) { + case 8: + if (p) { + p->family = AF_INET; + p->prefixlen = 32; + memcpy(p->u.val, pEncap->value, + 4); + } + return 0; + + case 20: + if (p) { + p->family = AF_INET6; + p->prefixlen = 128; + memcpy(p->u.val, pEncap->value, + 16); + } + return 0; + } + } + } + } + + return ENOENT; } /* * Get UN address wherever it might be */ -int -rfapiGetUnAddrOfVpnBi (struct bgp_info *bi, struct prefix *p) +int rfapiGetUnAddrOfVpnBi(struct bgp_info *bi, struct prefix *p) { - /* If it's in this route's VNC attribute, we're done */ - if (!rfapiGetVncTunnelUnAddr (bi->attr, p)) - return 0; - /* - * Otherwise, see if it's cached from a corresponding ENCAP SAFI - * advertisement - */ - if (bi->extra) - { - switch (bi->extra->vnc.import.un_family) - { - case AF_INET: - if (p) - { - p->family = bi->extra->vnc.import.un_family; - p->u.prefix4 = bi->extra->vnc.import.un.addr4; - p->prefixlen = 32; - } - return 0; - case AF_INET6: - if (p) - { - p->family = bi->extra->vnc.import.un_family; - p->u.prefix6 = bi->extra->vnc.import.un.addr6; - p->prefixlen = 128; - } - return 0; - default: - if (p) - p->family = 0; + /* If it's in this route's VNC attribute, we're done */ + if (!rfapiGetVncTunnelUnAddr(bi->attr, p)) + return 0; + /* + * Otherwise, see if it's cached from a corresponding ENCAP SAFI + * advertisement + */ + if (bi->extra) { + switch (bi->extra->vnc.import.un_family) { + case AF_INET: + if (p) { + p->family = bi->extra->vnc.import.un_family; + p->u.prefix4 = bi->extra->vnc.import.un.addr4; + p->prefixlen = 32; + } + return 0; + case AF_INET6: + if (p) { + p->family = bi->extra->vnc.import.un_family; + p->u.prefix6 = bi->extra->vnc.import.un.addr6; + p->prefixlen = 128; + } + return 0; + default: + if (p) + p->family = 0; #if DEBUG_ENCAP_MONITOR - vnc_zlog_debug_verbose ("%s: bi->extra->vnc.import.un_family is 0, no UN addr", - __func__); + vnc_zlog_debug_verbose( + "%s: bi->extra->vnc.import.un_family is 0, no UN addr", + __func__); #endif - break; - } - } + break; + } + } - return ENOENT; + return ENOENT; } /* * Make a new bgp_info from gathered parameters */ -static struct bgp_info * -rfapiBgpInfoCreate ( - struct attr *attr, - struct peer *peer, - void *rfd, - struct prefix_rd *prd, - u_char type, - u_char sub_type, - uint32_t *label) +static struct bgp_info *rfapiBgpInfoCreate(struct attr *attr, struct peer *peer, + void *rfd, struct prefix_rd *prd, + u_char type, u_char sub_type, + uint32_t *label) { - struct bgp_info *new; - - new = bgp_info_new (); - assert (new); - - if (attr) - { - if (!new->attr) - new->attr = bgp_attr_intern (attr); - } - bgp_info_extra_get (new); - if (prd) - { - new->extra->vnc.import.rd = *prd; - rfapi_time (&new->extra->vnc.import.create_time); - } - if (label) - encode_label (*label, &new->extra->label); - new->type = type; - new->sub_type = sub_type; - new->peer = peer; - peer_lock (peer); - - return new; + struct bgp_info *new; + + new = bgp_info_new(); + assert(new); + + if (attr) { + if (!new->attr) + new->attr = bgp_attr_intern(attr); + } + bgp_info_extra_get(new); + if (prd) { + new->extra->vnc.import.rd = *prd; + rfapi_time(&new->extra->vnc.import.create_time); + } + if (label) + encode_label(*label, &new->extra->label); + new->type = type; + new->sub_type = sub_type; + new->peer = peer; + peer_lock(peer); + + return new; } /* * Frees bgp_info as used in import tables (parts are not * allocated exactly the way they are in the main RIBs) */ -static void -rfapiBgpInfoFree (struct bgp_info *goner) +static void rfapiBgpInfoFree(struct bgp_info *goner) { - if (!goner) - return; - - if (goner->peer) - { - vnc_zlog_debug_verbose ("%s: calling peer_unlock(%p), #%d", - __func__, goner->peer, goner->peer->lock); - peer_unlock (goner->peer); - } - - if (goner->attr) - { - bgp_attr_unintern (&goner->attr); - } - if (goner->extra) - { - assert (!goner->extra->damp_info); /* Not used in import tbls */ - XFREE (MTYPE_BGP_ROUTE_EXTRA, goner->extra); - goner->extra = NULL; - } - XFREE (MTYPE_BGP_ROUTE, goner); + if (!goner) + return; + + if (goner->peer) { + vnc_zlog_debug_verbose("%s: calling peer_unlock(%p), #%d", + __func__, goner->peer, + goner->peer->lock); + peer_unlock(goner->peer); + } + + if (goner->attr) { + bgp_attr_unintern(&goner->attr); + } + if (goner->extra) { + assert(!goner->extra->damp_info); /* Not used in import tbls */ + XFREE(MTYPE_BGP_ROUTE_EXTRA, goner->extra); + goner->extra = NULL; + } + XFREE(MTYPE_BGP_ROUTE, goner); } -struct rfapi_import_table * -rfapiMacImportTableGetNoAlloc (struct bgp *bgp, uint32_t lni) +struct rfapi_import_table *rfapiMacImportTableGetNoAlloc(struct bgp *bgp, + uint32_t lni) { - struct rfapi *h; - struct rfapi_import_table *it = NULL; - uintptr_t lni_as_ptr = lni; + struct rfapi *h; + struct rfapi_import_table *it = NULL; + uintptr_t lni_as_ptr = lni; - h = bgp->rfapi; - if (!h) - return NULL; + h = bgp->rfapi; + if (!h) + return NULL; - if (!h->import_mac) - return NULL; + if (!h->import_mac) + return NULL; - if (skiplist_search (h->import_mac, (void *) lni_as_ptr, (void **) &it)) - return NULL; + if (skiplist_search(h->import_mac, (void *)lni_as_ptr, (void **)&it)) + return NULL; - return it; + return it; } -struct rfapi_import_table * -rfapiMacImportTableGet (struct bgp *bgp, uint32_t lni) +struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp, uint32_t lni) { - struct rfapi *h; - struct rfapi_import_table *it = NULL; - uintptr_t lni_as_ptr = lni; - - h = bgp->rfapi; - assert (h); - - if (!h->import_mac) - { - /* default cmp is good enough for LNI */ - h->import_mac = skiplist_new (0, NULL, NULL); - } - - if (skiplist_search (h->import_mac, (void *) lni_as_ptr, (void **) &it)) - { - - struct ecommunity *enew; - struct ecommunity_val eval; - afi_t afi; - - it = - XCALLOC (MTYPE_RFAPI_IMPORTTABLE, sizeof (struct rfapi_import_table)); - /* set RT list of new import table based on LNI */ - memset ((char *) &eval, 0, sizeof (eval)); - eval.val[0] = 0; /* VNC L2VPN */ - eval.val[1] = 2; /* VNC L2VPN */ - eval.val[5] = (lni >> 16) & 0xff; - eval.val[6] = (lni >> 8) & 0xff; - eval.val[7] = (lni >> 0) & 0xff; - - enew = ecommunity_new (); - ecommunity_add_val (enew, &eval); - it->rt_import_list = enew; - - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - it->imported_vpn[afi] = route_table_init (); - it->imported_encap[afi] = route_table_init (); - } - - it->l2_logical_net_id = lni; - - skiplist_insert (h->import_mac, (void *) lni_as_ptr, it); - } - - assert (it); - return it; + struct rfapi *h; + struct rfapi_import_table *it = NULL; + uintptr_t lni_as_ptr = lni; + + h = bgp->rfapi; + assert(h); + + if (!h->import_mac) { + /* default cmp is good enough for LNI */ + h->import_mac = skiplist_new(0, NULL, NULL); + } + + if (skiplist_search(h->import_mac, (void *)lni_as_ptr, (void **)&it)) { + + struct ecommunity *enew; + struct ecommunity_val eval; + afi_t afi; + + it = XCALLOC(MTYPE_RFAPI_IMPORTTABLE, + sizeof(struct rfapi_import_table)); + /* set RT list of new import table based on LNI */ + memset((char *)&eval, 0, sizeof(eval)); + eval.val[0] = 0; /* VNC L2VPN */ + eval.val[1] = 2; /* VNC L2VPN */ + eval.val[5] = (lni >> 16) & 0xff; + eval.val[6] = (lni >> 8) & 0xff; + eval.val[7] = (lni >> 0) & 0xff; + + enew = ecommunity_new(); + ecommunity_add_val(enew, &eval); + it->rt_import_list = enew; + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + it->imported_vpn[afi] = route_table_init(); + it->imported_encap[afi] = route_table_init(); + } + + it->l2_logical_net_id = lni; + + skiplist_insert(h->import_mac, (void *)lni_as_ptr, it); + } + + assert(it); + return it; } /* * Implement MONITOR_MOVE_SHORTER(original_node) from * RFAPI-Import-Event-Handling.txt - * + * * Returns pointer to the list of moved monitors */ static struct rfapi_monitor_vpn * -rfapiMonitorMoveShorter (struct route_node *original_vpn_node, int lockoffset) +rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset) { - struct bgp_info *bi; - struct route_node *par; - struct rfapi_monitor_vpn *m; - struct rfapi_monitor_vpn *mlast; - struct rfapi_monitor_vpn *moved; - int movecount = 0; - int parent_already_refcounted = 0; + struct bgp_info *bi; + struct route_node *par; + struct rfapi_monitor_vpn *m; + struct rfapi_monitor_vpn *mlast; + struct rfapi_monitor_vpn *moved; + int movecount = 0; + int parent_already_refcounted = 0; - RFAPI_CHECK_REFCOUNT (original_vpn_node, SAFI_MPLS_VPN, lockoffset); + RFAPI_CHECK_REFCOUNT(original_vpn_node, SAFI_MPLS_VPN, lockoffset); #if DEBUG_MONITOR_MOVE_SHORTER - { - char buf[BUFSIZ]; + { + char buf[BUFSIZ]; - prefix2str (&original_vpn_node->p, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_verbose ("%s: called with node pfx=%s", __func__, buf); - } + prefix2str(&original_vpn_node->p, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_verbose("%s: called with node pfx=%s", __func__, + buf); + } #endif - /* - * 1. If there is at least one bi (either regular route or - * route marked as withdrawn, with a pending timer) at - * original_node with a valid UN address, we're done. Return. - */ - for (bi = original_vpn_node->info; bi; bi = bi->next) - { - struct prefix pfx; - - if (!rfapiGetUnAddrOfVpnBi (bi, &pfx)) - { + /* + * 1. If there is at least one bi (either regular route or + * route marked as withdrawn, with a pending timer) at + * original_node with a valid UN address, we're done. Return. + */ + for (bi = original_vpn_node->info; bi; bi = bi->next) { + struct prefix pfx; + + if (!rfapiGetUnAddrOfVpnBi(bi, &pfx)) { #if DEBUG_MONITOR_MOVE_SHORTER - vnc_zlog_debug_verbose ("%s: have valid UN at original node, no change", - __func__); + vnc_zlog_debug_verbose( + "%s: have valid UN at original node, no change", + __func__); #endif - return NULL; - } - } - - /* - * 2. Travel up the tree (toward less-specific prefixes) from - * original_node to find the first node that has at least - * one route (even if it is only a withdrawn route) with a - * valid UN address. Call this node "Node P." - */ - for (par = original_vpn_node->parent; par; par = par->parent) - { - for (bi = par->info; bi; bi = bi->next) - { - struct prefix pfx; - if (!rfapiGetUnAddrOfVpnBi (bi, &pfx)) - { - break; - } - } - if (bi) - break; - } - - if (par) - { - RFAPI_CHECK_REFCOUNT (par, SAFI_MPLS_VPN, 0); - } - - /* - * If no less-specific routes, try to use the 0/0 node - */ - if (!par) - { - /* this isn't necessarily 0/0 */ - par = route_top (original_vpn_node->table); - - /* - * If we got the top node but it wasn't 0/0, - * ignore it - */ - if (par && par->p.prefixlen) - { - route_unlock_node (par); /* maybe free */ - par = NULL; - } - - if (par) - { - ++parent_already_refcounted; - } - } - - /* - * Create 0/0 node if it isn't there - */ - if (!par) - { - struct prefix pfx_default; - - memset (&pfx_default, 0, sizeof (pfx_default)); - pfx_default.family = original_vpn_node->p.family; - - /* creates default node if none exists */ - par = route_node_get (original_vpn_node->table, &pfx_default); - ++parent_already_refcounted; - } - - /* - * 3. Move each of the monitors found at original_node to Node P. - * These are "Moved Monitors." - * - */ - - /* - * Attach at end so that the list pointer we return points - * only to the moved routes - */ - for (m = RFAPI_MONITOR_VPN (par), mlast = NULL; m; mlast = m, m = m->next); - - if (mlast) - { - moved = mlast->next = RFAPI_MONITOR_VPN (original_vpn_node); - } - else - { - moved = RFAPI_MONITOR_VPN_W_ALLOC (par) = - RFAPI_MONITOR_VPN (original_vpn_node); - } - if (RFAPI_MONITOR_VPN (original_vpn_node)) /* check agg, so not allocated */ - RFAPI_MONITOR_VPN_W_ALLOC (original_vpn_node) = NULL; - - /* - * update the node pointers on the monitors - */ - for (m = moved; m; m = m->next) - { - ++movecount; - m->node = par; - } - - RFAPI_CHECK_REFCOUNT (par, SAFI_MPLS_VPN, - parent_already_refcounted - movecount); - while (movecount > parent_already_refcounted) - { - route_lock_node (par); - ++parent_already_refcounted; - } - while (movecount < parent_already_refcounted) - { - /* unlikely, but code defensively */ - route_unlock_node (par); - --parent_already_refcounted; - } - RFAPI_CHECK_REFCOUNT (original_vpn_node, SAFI_MPLS_VPN, - movecount + lockoffset); - while (movecount--) - { - route_unlock_node (original_vpn_node); - } + return NULL; + } + } + + /* + * 2. Travel up the tree (toward less-specific prefixes) from + * original_node to find the first node that has at least + * one route (even if it is only a withdrawn route) with a + * valid UN address. Call this node "Node P." + */ + for (par = original_vpn_node->parent; par; par = par->parent) { + for (bi = par->info; bi; bi = bi->next) { + struct prefix pfx; + if (!rfapiGetUnAddrOfVpnBi(bi, &pfx)) { + break; + } + } + if (bi) + break; + } + + if (par) { + RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, 0); + } + + /* + * If no less-specific routes, try to use the 0/0 node + */ + if (!par) { + /* this isn't necessarily 0/0 */ + par = route_top(original_vpn_node->table); + + /* + * If we got the top node but it wasn't 0/0, + * ignore it + */ + if (par && par->p.prefixlen) { + route_unlock_node(par); /* maybe free */ + par = NULL; + } + + if (par) { + ++parent_already_refcounted; + } + } + + /* + * Create 0/0 node if it isn't there + */ + if (!par) { + struct prefix pfx_default; + + memset(&pfx_default, 0, sizeof(pfx_default)); + pfx_default.family = original_vpn_node->p.family; + + /* creates default node if none exists */ + par = route_node_get(original_vpn_node->table, &pfx_default); + ++parent_already_refcounted; + } + + /* + * 3. Move each of the monitors found at original_node to Node P. + * These are "Moved Monitors." + * + */ + + /* + * Attach at end so that the list pointer we return points + * only to the moved routes + */ + for (m = RFAPI_MONITOR_VPN(par), mlast = NULL; m; + mlast = m, m = m->next) + ; + + if (mlast) { + moved = mlast->next = RFAPI_MONITOR_VPN(original_vpn_node); + } else { + moved = RFAPI_MONITOR_VPN_W_ALLOC(par) = + RFAPI_MONITOR_VPN(original_vpn_node); + } + if (RFAPI_MONITOR_VPN( + original_vpn_node)) /* check agg, so not allocated */ + RFAPI_MONITOR_VPN_W_ALLOC(original_vpn_node) = NULL; + + /* + * update the node pointers on the monitors + */ + for (m = moved; m; m = m->next) { + ++movecount; + m->node = par; + } + + RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, + parent_already_refcounted - movecount); + while (movecount > parent_already_refcounted) { + route_lock_node(par); + ++parent_already_refcounted; + } + while (movecount < parent_already_refcounted) { + /* unlikely, but code defensively */ + route_unlock_node(par); + --parent_already_refcounted; + } + RFAPI_CHECK_REFCOUNT(original_vpn_node, SAFI_MPLS_VPN, + movecount + lockoffset); + while (movecount--) { + route_unlock_node(original_vpn_node); + } #if DEBUG_MONITOR_MOVE_SHORTER - { - char buf[BUFSIZ]; + { + char buf[BUFSIZ]; - prefix2str (&par->p, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_verbose ("%s: moved to node pfx=%s", __func__, buf); - } + prefix2str(&par->p, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_verbose("%s: moved to node pfx=%s", __func__, + buf); + } #endif - return moved; + return moved; } /* * Implement MONITOR_MOVE_LONGER(new_node) from * RFAPI-Import-Event-Handling.txt */ -static void -rfapiMonitorMoveLonger (struct route_node *new_vpn_node) +static void rfapiMonitorMoveLonger(struct route_node *new_vpn_node) { - struct rfapi_monitor_vpn *monitor; - struct rfapi_monitor_vpn *mlast; - struct bgp_info *bi; - struct route_node *par; - - RFAPI_CHECK_REFCOUNT (new_vpn_node, SAFI_MPLS_VPN, 0); - - /* - * Make sure we have at least one valid route at the new node - */ - for (bi = new_vpn_node->info; bi; bi = bi->next) - { - struct prefix pfx; - if (!rfapiGetUnAddrOfVpnBi (bi, &pfx)) - break; - } - - if (!bi) - { - vnc_zlog_debug_verbose ("%s: no valid routes at node %p, so not attempting moves", - __func__, new_vpn_node); - return; - } - - /* - * Find first parent node that has monitors - */ - for (par = new_vpn_node->parent; par; par = par->parent) - { - if (RFAPI_MONITOR_VPN (par)) - break; - } - - if (!par) - { - vnc_zlog_debug_verbose ("%s: no parent nodes with monitors, done", __func__); - return; - } - - /* - * Check each of these monitors to see of their longest-match - * is now the updated node. Move any such monitors to the more- - * specific updated node - */ - for (mlast = NULL, monitor = RFAPI_MONITOR_VPN (par); monitor;) - { - - /* - * If new longest match for monitor prefix is the new - * route's prefix, move monitor to new route's prefix - */ - if (prefix_match (&new_vpn_node->p, &monitor->p)) - { - /* detach */ - if (mlast) - { - mlast->next = monitor->next; - } - else - { - RFAPI_MONITOR_VPN_W_ALLOC (par) = monitor->next; - } - - - /* attach */ - monitor->next = RFAPI_MONITOR_VPN (new_vpn_node); - RFAPI_MONITOR_VPN_W_ALLOC (new_vpn_node) = monitor; - monitor->node = new_vpn_node; - - route_lock_node (new_vpn_node); /* incr refcount */ - - monitor = mlast ? mlast->next : RFAPI_MONITOR_VPN (par); - - RFAPI_CHECK_REFCOUNT (par, SAFI_MPLS_VPN, 1); - /* decr refcount after we're done with par as this might free it */ - route_unlock_node (par); - - continue; - } - mlast = monitor; - monitor = monitor->next; - } - - RFAPI_CHECK_REFCOUNT (new_vpn_node, SAFI_MPLS_VPN, 0); + struct rfapi_monitor_vpn *monitor; + struct rfapi_monitor_vpn *mlast; + struct bgp_info *bi; + struct route_node *par; + + RFAPI_CHECK_REFCOUNT(new_vpn_node, SAFI_MPLS_VPN, 0); + + /* + * Make sure we have at least one valid route at the new node + */ + for (bi = new_vpn_node->info; bi; bi = bi->next) { + struct prefix pfx; + if (!rfapiGetUnAddrOfVpnBi(bi, &pfx)) + break; + } + + if (!bi) { + vnc_zlog_debug_verbose( + "%s: no valid routes at node %p, so not attempting moves", + __func__, new_vpn_node); + return; + } + + /* + * Find first parent node that has monitors + */ + for (par = new_vpn_node->parent; par; par = par->parent) { + if (RFAPI_MONITOR_VPN(par)) + break; + } + + if (!par) { + vnc_zlog_debug_verbose( + "%s: no parent nodes with monitors, done", __func__); + return; + } + + /* + * Check each of these monitors to see of their longest-match + * is now the updated node. Move any such monitors to the more- + * specific updated node + */ + for (mlast = NULL, monitor = RFAPI_MONITOR_VPN(par); monitor;) { + + /* + * If new longest match for monitor prefix is the new + * route's prefix, move monitor to new route's prefix + */ + if (prefix_match(&new_vpn_node->p, &monitor->p)) { + /* detach */ + if (mlast) { + mlast->next = monitor->next; + } else { + RFAPI_MONITOR_VPN_W_ALLOC(par) = monitor->next; + } + + + /* attach */ + monitor->next = RFAPI_MONITOR_VPN(new_vpn_node); + RFAPI_MONITOR_VPN_W_ALLOC(new_vpn_node) = monitor; + monitor->node = new_vpn_node; + + route_lock_node(new_vpn_node); /* incr refcount */ + + monitor = mlast ? mlast->next : RFAPI_MONITOR_VPN(par); + + RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, 1); + /* decr refcount after we're done with par as this might + * free it */ + route_unlock_node(par); + + continue; + } + mlast = monitor; + monitor = monitor->next; + } + + RFAPI_CHECK_REFCOUNT(new_vpn_node, SAFI_MPLS_VPN, 0); } -static void -rfapiBgpInfoChainFree (struct bgp_info *bi) +static void rfapiBgpInfoChainFree(struct bgp_info *bi) { - struct bgp_info *next; - - while (bi) - { - - /* - * If there is a timer waiting to delete this bi, cancel - * the timer and delete immediately - */ - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && - bi->extra->vnc.import.timer) - { - - struct thread *t = (struct thread *) bi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; - - XFREE (MTYPE_RFAPI_WITHDRAW, wcb); - thread_cancel (t); - } - - next = bi->next; - bi->next = NULL; - rfapiBgpInfoFree (bi); - bi = next; - } + struct bgp_info *next; + + while (bi) { + + /* + * If there is a timer waiting to delete this bi, cancel + * the timer and delete immediately + */ + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) + && bi->extra->vnc.import.timer) { + + struct thread *t = + (struct thread *)bi->extra->vnc.import.timer; + struct rfapi_withdraw *wcb = t->arg; + + XFREE(MTYPE_RFAPI_WITHDRAW, wcb); + thread_cancel(t); + } + + next = bi->next; + bi->next = NULL; + rfapiBgpInfoFree(bi); + bi = next; + } } -static void -rfapiImportTableFlush (struct rfapi_import_table *it) +static void rfapiImportTableFlush(struct rfapi_import_table *it) { - afi_t afi; - - /* - * Free ecommunity - */ - ecommunity_free (&it->rt_import_list); - it->rt_import_list = NULL; - - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - struct route_node *rn; - - for (rn = route_top (it->imported_vpn[afi]); rn; rn = route_next (rn)) - { - /* - * Each route_node has: - * aggregate: points to rfapi_it_extra with monitor chain(s) - * info: points to chain of bgp_info - */ - /* free bgp_info and its children */ - rfapiBgpInfoChainFree (rn->info); - rn->info = NULL; - - rfapiMonitorExtraFlush (SAFI_MPLS_VPN, rn); - } - - for (rn = route_top (it->imported_encap[afi]); rn; rn = route_next (rn)) - { - /* free bgp_info and its children */ - rfapiBgpInfoChainFree (rn->info); - rn->info = NULL; - - rfapiMonitorExtraFlush (SAFI_ENCAP, rn); - } - - route_table_finish (it->imported_vpn[afi]); - route_table_finish (it->imported_encap[afi]); - } - if (it->monitor_exterior_orphans) - { - skiplist_free (it->monitor_exterior_orphans); - } + afi_t afi; + + /* + * Free ecommunity + */ + ecommunity_free(&it->rt_import_list); + it->rt_import_list = NULL; + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + struct route_node *rn; + + for (rn = route_top(it->imported_vpn[afi]); rn; + rn = route_next(rn)) { + /* + * Each route_node has: + * aggregate: points to rfapi_it_extra with monitor + * chain(s) + * info: points to chain of bgp_info + */ + /* free bgp_info and its children */ + rfapiBgpInfoChainFree(rn->info); + rn->info = NULL; + + rfapiMonitorExtraFlush(SAFI_MPLS_VPN, rn); + } + + for (rn = route_top(it->imported_encap[afi]); rn; + rn = route_next(rn)) { + /* free bgp_info and its children */ + rfapiBgpInfoChainFree(rn->info); + rn->info = NULL; + + rfapiMonitorExtraFlush(SAFI_ENCAP, rn); + } + + route_table_finish(it->imported_vpn[afi]); + route_table_finish(it->imported_encap[afi]); + } + if (it->monitor_exterior_orphans) { + skiplist_free(it->monitor_exterior_orphans); + } } -void -rfapiImportTableRefDelByIt ( - struct bgp *bgp, - struct rfapi_import_table *it_target) +void rfapiImportTableRefDelByIt(struct bgp *bgp, + struct rfapi_import_table *it_target) { - struct rfapi *h; - struct rfapi_import_table *it; - struct rfapi_import_table *prev = NULL; - - assert (it_target); - - h = bgp->rfapi; - assert (h); - - for (it = h->imports; it; prev = it, it = it->next) - { - if (it == it_target) - break; - } - - assert (it); - assert (it->refcount); - - it->refcount -= 1; - - if (!it->refcount) - { - if (prev) - { - prev->next = it->next; - } - else - { - h->imports = it->next; - } - rfapiImportTableFlush (it); - XFREE (MTYPE_RFAPI_IMPORTTABLE, it); - } + struct rfapi *h; + struct rfapi_import_table *it; + struct rfapi_import_table *prev = NULL; + + assert(it_target); + + h = bgp->rfapi; + assert(h); + + for (it = h->imports; it; prev = it, it = it->next) { + if (it == it_target) + break; + } + + assert(it); + assert(it->refcount); + + it->refcount -= 1; + + if (!it->refcount) { + if (prev) { + prev->next = it->next; + } else { + h->imports = it->next; + } + rfapiImportTableFlush(it); + XFREE(MTYPE_RFAPI_IMPORTTABLE, it); + } } #if RFAPI_REQUIRE_ENCAP_BEEC @@ -1050,298 +990,272 @@ rfapiImportTableRefDelByIt ( * Look for magic BGP Encapsulation Extended Community value * Format in RFC 5512 Sect. 4.5 */ -static int -rfapiEcommunitiesMatchBeec (struct ecommunity *ecom, - bgp_encap_types type) +static int rfapiEcommunitiesMatchBeec(struct ecommunity *ecom, + bgp_encap_types type) { - int i; - - if (!ecom) - return 0; + int i; - for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += ECOMMUNITY_SIZE) - { + if (!ecom) + return 0; - uint8_t *ep; + for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += ECOMMUNITY_SIZE) { - ep = ecom->val + i; + uint8_t *ep; - if (ep[0] == ECOMMUNITY_ENCODE_OPAQUE && - ep[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP && - ep[6] == ((type && 0xff00)>>8) && - ep[7] == (type&0xff)) - { + ep = ecom->val + i; - return 1; - } - } - return 0; + if (ep[0] == ECOMMUNITY_ENCODE_OPAQUE + && ep[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP + && ep[6] == ((type && 0xff00) >> 8) + && ep[7] == (type & 0xff)) { + return 1; + } + } + return 0; } #endif -int -rfapiEcommunitiesIntersect (struct ecommunity *e1, struct ecommunity *e2) +int rfapiEcommunitiesIntersect(struct ecommunity *e1, struct ecommunity *e2) { - int i, j; - - if (!e1 || !e2) - return 0; - - { - char *s1, *s2; - s1 = ecommunity_ecom2str (e1, ECOMMUNITY_FORMAT_DISPLAY, 0); - s2 = ecommunity_ecom2str (e2, ECOMMUNITY_FORMAT_DISPLAY, 0); - vnc_zlog_debug_verbose ("%s: e1[%s], e2[%s]", __func__, s1, s2); - XFREE (MTYPE_ECOMMUNITY_STR, s1); - XFREE (MTYPE_ECOMMUNITY_STR, s2); - } - - for (i = 0; i < e1->size; ++i) - { - for (j = 0; j < e2->size; ++j) - { - if (!memcmp (e1->val + (i * ECOMMUNITY_SIZE), - e2->val + (j * ECOMMUNITY_SIZE), ECOMMUNITY_SIZE)) - { - - return 1; - } - } - } - return 0; + int i, j; + + if (!e1 || !e2) + return 0; + + { + char *s1, *s2; + s1 = ecommunity_ecom2str(e1, ECOMMUNITY_FORMAT_DISPLAY, 0); + s2 = ecommunity_ecom2str(e2, ECOMMUNITY_FORMAT_DISPLAY, 0); + vnc_zlog_debug_verbose("%s: e1[%s], e2[%s]", __func__, s1, s2); + XFREE(MTYPE_ECOMMUNITY_STR, s1); + XFREE(MTYPE_ECOMMUNITY_STR, s2); + } + + for (i = 0; i < e1->size; ++i) { + for (j = 0; j < e2->size; ++j) { + if (!memcmp(e1->val + (i * ECOMMUNITY_SIZE), + e2->val + (j * ECOMMUNITY_SIZE), + ECOMMUNITY_SIZE)) { + + return 1; + } + } + } + return 0; } -int -rfapiEcommunityGetLNI (struct ecommunity *ecom, uint32_t * lni) +int rfapiEcommunityGetLNI(struct ecommunity *ecom, uint32_t *lni) { - if (ecom) - { - int i; - for (i = 0; i < ecom->size; ++i) - { - uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); - - if ((*(p + 0) == 0x00) && (*(p + 1) == 0x02)) - { - - *lni = (*(p + 5) << 16) | (*(p + 6) << 8) | (*(p + 7)); - return 0; - } - } - } - return ENOENT; + if (ecom) { + int i; + for (i = 0; i < ecom->size; ++i) { + uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); + + if ((*(p + 0) == 0x00) && (*(p + 1) == 0x02)) { + + *lni = (*(p + 5) << 16) | (*(p + 6) << 8) + | (*(p + 7)); + return 0; + } + } + } + return ENOENT; } -int -rfapiEcommunityGetEthernetTag (struct ecommunity *ecom, uint16_t * tag_id) +int rfapiEcommunityGetEthernetTag(struct ecommunity *ecom, uint16_t *tag_id) { - struct bgp *bgp = bgp_get_default (); - *tag_id = 0; /* default to untagged */ - if (ecom) - { - int i; - for (i = 0; i < ecom->size; ++i) - { - as_t as = 0; - int encode = 0; - uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); - - /* High-order octet of type. */ - encode = *p++; - - if (*p++ == ECOMMUNITY_ROUTE_TARGET) { - if (encode == ECOMMUNITY_ENCODE_AS4) - { - as = (*p++ << 24); - as |= (*p++ << 16); - as |= (*p++ << 8); - as |= (*p++); - } - else if (encode == ECOMMUNITY_ENCODE_AS) - { - as = (*p++ << 8); - as |= (*p++); - p += 2; /* skip next two, tag/vid always in lowest bytes */ - } - if (as == bgp->as) - { - *tag_id = *p++ << 8; - *tag_id |= (*p++); - return 0; - } - } - } - } - return ENOENT; + struct bgp *bgp = bgp_get_default(); + *tag_id = 0; /* default to untagged */ + if (ecom) { + int i; + for (i = 0; i < ecom->size; ++i) { + as_t as = 0; + int encode = 0; + uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); + + /* High-order octet of type. */ + encode = *p++; + + if (*p++ == ECOMMUNITY_ROUTE_TARGET) { + if (encode == ECOMMUNITY_ENCODE_AS4) { + as = (*p++ << 24); + as |= (*p++ << 16); + as |= (*p++ << 8); + as |= (*p++); + } else if (encode == ECOMMUNITY_ENCODE_AS) { + as = (*p++ << 8); + as |= (*p++); + p += + 2; /* skip next two, tag/vid + always in lowest bytes */ + } + if (as == bgp->as) { + *tag_id = *p++ << 8; + *tag_id |= (*p++); + return 0; + } + } + } + } + return ENOENT; } -static int -rfapiVpnBiNhEqualsPt (struct bgp_info *bi, struct rfapi_ip_addr *hpt) +static int rfapiVpnBiNhEqualsPt(struct bgp_info *bi, struct rfapi_ip_addr *hpt) { - uint8_t family; + uint8_t family; - if (!hpt || !bi) - return 0; + if (!hpt || !bi) + return 0; - family = BGP_MP_NEXTHOP_FAMILY (bi->attr->mp_nexthop_len); + family = BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len); - if (hpt->addr_family != family) - return 0; + if (hpt->addr_family != family) + return 0; - switch (family) - { - case AF_INET: - if (bi->attr->mp_nexthop_global_in.s_addr != hpt->addr.v4.s_addr) - return 0; - break; + switch (family) { + case AF_INET: + if (bi->attr->mp_nexthop_global_in.s_addr + != hpt->addr.v4.s_addr) + return 0; + break; - case AF_INET6: - if (IPV6_ADDR_CMP (&bi->attr->mp_nexthop_global, &hpt->addr.v6)) - return 0; - break; + case AF_INET6: + if (IPV6_ADDR_CMP(&bi->attr->mp_nexthop_global, &hpt->addr.v6)) + return 0; + break; - default: - return 0; - break; - } + default: + return 0; + break; + } - return 1; + return 1; } /* * Compare 2 VPN BIs. Return true if they have the same VN and UN addresses */ -static int -rfapiVpnBiSamePtUn (struct bgp_info *bi1, struct bgp_info *bi2) +static int rfapiVpnBiSamePtUn(struct bgp_info *bi1, struct bgp_info *bi2) { - struct prefix pfx_un1; - struct prefix pfx_un2; - - if (!bi1 || !bi2) - return 0; - - if (!bi1->attr || !bi2->attr) - return 0; - - /* - * VN address comparisons - */ - - if (BGP_MP_NEXTHOP_FAMILY (bi1->attr->mp_nexthop_len) != - BGP_MP_NEXTHOP_FAMILY (bi2->attr->mp_nexthop_len)) - { - return 0; - } - - switch (BGP_MP_NEXTHOP_FAMILY (bi1->attr->mp_nexthop_len)) - { - case AF_INET: - if (bi1->attr->mp_nexthop_global_in.s_addr != - bi2->attr->mp_nexthop_global_in.s_addr) - return 0; - break; - - case AF_INET6: - if (IPV6_ADDR_CMP (&bi1->attr->mp_nexthop_global, - &bi2->attr->mp_nexthop_global)) - return 0; - break; - - default: - return 0; - break; - } - - /* - * UN address comparisons - */ - if (rfapiGetVncTunnelUnAddr (bi1->attr, &pfx_un1)) - { - if (bi1->extra) - { - pfx_un1.family = bi1->extra->vnc.import.un_family; - switch (bi1->extra->vnc.import.un_family) - { - case AF_INET: - pfx_un1.u.prefix4 = bi1->extra->vnc.import.un.addr4; - break; - case AF_INET6: - pfx_un1.u.prefix6 = bi1->extra->vnc.import.un.addr6; - break; - default: - pfx_un1.family = 0; - break; - } - } - } - - if (rfapiGetVncTunnelUnAddr (bi2->attr, &pfx_un2)) - { - if (bi2->extra) - { - pfx_un2.family = bi2->extra->vnc.import.un_family; - switch (bi2->extra->vnc.import.un_family) - { - case AF_INET: - pfx_un2.u.prefix4 = bi2->extra->vnc.import.un.addr4; - break; - case AF_INET6: - pfx_un2.u.prefix6 = bi2->extra->vnc.import.un.addr6; - break; - default: - pfx_un2.family = 0; - break; - } - } - } - - if (!pfx_un1.family || !pfx_un2.family) - return 0; - - if (pfx_un1.family != pfx_un2.family) - return 0; - - switch (pfx_un1.family) - { - case AF_INET: - if (!IPV4_ADDR_SAME - (&pfx_un1.u.prefix4.s_addr, &pfx_un2.u.prefix4.s_addr)) - return 0; - break; - case AF_INET6: - if (!IPV6_ADDR_SAME (&pfx_un1.u.prefix6, &pfx_un2.u.prefix6)) - return 0; - break; - } - - - - return 1; + struct prefix pfx_un1; + struct prefix pfx_un2; + + if (!bi1 || !bi2) + return 0; + + if (!bi1->attr || !bi2->attr) + return 0; + + /* + * VN address comparisons + */ + + if (BGP_MP_NEXTHOP_FAMILY(bi1->attr->mp_nexthop_len) + != BGP_MP_NEXTHOP_FAMILY(bi2->attr->mp_nexthop_len)) { + return 0; + } + + switch (BGP_MP_NEXTHOP_FAMILY(bi1->attr->mp_nexthop_len)) { + case AF_INET: + if (bi1->attr->mp_nexthop_global_in.s_addr + != bi2->attr->mp_nexthop_global_in.s_addr) + return 0; + break; + + case AF_INET6: + if (IPV6_ADDR_CMP(&bi1->attr->mp_nexthop_global, + &bi2->attr->mp_nexthop_global)) + return 0; + break; + + default: + return 0; + break; + } + + /* + * UN address comparisons + */ + if (rfapiGetVncTunnelUnAddr(bi1->attr, &pfx_un1)) { + if (bi1->extra) { + pfx_un1.family = bi1->extra->vnc.import.un_family; + switch (bi1->extra->vnc.import.un_family) { + case AF_INET: + pfx_un1.u.prefix4 = + bi1->extra->vnc.import.un.addr4; + break; + case AF_INET6: + pfx_un1.u.prefix6 = + bi1->extra->vnc.import.un.addr6; + break; + default: + pfx_un1.family = 0; + break; + } + } + } + + if (rfapiGetVncTunnelUnAddr(bi2->attr, &pfx_un2)) { + if (bi2->extra) { + pfx_un2.family = bi2->extra->vnc.import.un_family; + switch (bi2->extra->vnc.import.un_family) { + case AF_INET: + pfx_un2.u.prefix4 = + bi2->extra->vnc.import.un.addr4; + break; + case AF_INET6: + pfx_un2.u.prefix6 = + bi2->extra->vnc.import.un.addr6; + break; + default: + pfx_un2.family = 0; + break; + } + } + } + + if (!pfx_un1.family || !pfx_un2.family) + return 0; + + if (pfx_un1.family != pfx_un2.family) + return 0; + + switch (pfx_un1.family) { + case AF_INET: + if (!IPV4_ADDR_SAME(&pfx_un1.u.prefix4.s_addr, + &pfx_un2.u.prefix4.s_addr)) + return 0; + break; + case AF_INET6: + if (!IPV6_ADDR_SAME(&pfx_un1.u.prefix6, &pfx_un2.u.prefix6)) + return 0; + break; + } + + + return 1; } -uint8_t -rfapiRfpCost (struct attr * attr) +uint8_t rfapiRfpCost(struct attr *attr) { - if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) - { - if (attr->local_pref > 255) - { - return 0; - } - return 255 - attr->local_pref; - } - - return 255; + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { + if (attr->local_pref > 255) { + return 0; + } + return 255 - attr->local_pref; + } + + return 255; } /*------------------------------------------ * rfapi_extract_l2o * - * Find Layer 2 options in an option chain + * Find Layer 2 options in an option chain * - * input: + * input: * pHop option chain * * output: @@ -1352,404 +1266,384 @@ rfapiRfpCost (struct attr * attr) * 1 no options found * --------------------------------------------*/ -int -rfapi_extract_l2o (struct bgp_tea_options *pHop, /* chain of options */ - struct rfapi_l2address_option *l2o) /* return extracted value */ +int rfapi_extract_l2o( + struct bgp_tea_options *pHop, /* chain of options */ + struct rfapi_l2address_option *l2o) /* return extracted value */ { - struct bgp_tea_options *p; + struct bgp_tea_options *p; - for (p = pHop; p; p = p->next) - { - if ((p->type == RFAPI_VN_OPTION_TYPE_L2ADDR) && (p->length >= 8)) - { + for (p = pHop; p; p = p->next) { + if ((p->type == RFAPI_VN_OPTION_TYPE_L2ADDR) + && (p->length >= 8)) { - char *v = p->value; + char *v = p->value; - memcpy (&l2o->macaddr, v, 6); + memcpy(&l2o->macaddr, v, 6); - l2o->label = - ((v[6] << 12) & 0xff000) + - ((v[7] << 4) & 0xff0) + ((v[8] >> 4) & 0xf); + l2o->label = ((v[6] << 12) & 0xff000) + + ((v[7] << 4) & 0xff0) + + ((v[8] >> 4) & 0xf); - l2o->local_nve_id = (uint8_t) v[10]; + l2o->local_nve_id = (uint8_t)v[10]; - l2o->logical_net_id = (v[11] << 16) + (v[12] << 8) + (v[13] << 0); + l2o->logical_net_id = + (v[11] << 16) + (v[12] << 8) + (v[13] << 0); - return 0; - } - } - return 1; + return 0; + } + } + return 1; } static struct rfapi_next_hop_entry * -rfapiRouteInfo2NextHopEntry ( - struct rfapi_ip_prefix *rprefix, - struct bgp_info *bi, /* route to encode */ - uint32_t lifetime, /* use this in nhe */ - struct route_node *rn) /* req for L2 eth addr */ +rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, + struct bgp_info *bi, /* route to encode */ + uint32_t lifetime, /* use this in nhe */ + struct route_node *rn) /* req for L2 eth addr */ { - struct rfapi_next_hop_entry *new; - int have_vnc_tunnel_un = 0; + struct rfapi_next_hop_entry *new; + int have_vnc_tunnel_un = 0; #if DEBUG_ENCAP_MONITOR - vnc_zlog_debug_verbose ("%s: entry, bi %p, rn %p", __func__, bi, rn); + vnc_zlog_debug_verbose("%s: entry, bi %p, rn %p", __func__, bi, rn); #endif - new = XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_next_hop_entry)); - assert (new); - - new->prefix = *rprefix; - - if (bi->extra && - decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH) - { - /* ethernet */ - - struct rfapi_vn_option *vo; - - vo = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); - assert (vo); - - vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; - - memcpy (&vo->v.l2addr.macaddr, &rn->p.u.prefix_eth.octet, - ETHER_ADDR_LEN); - /* only low 3 bytes of this are significant */ - if (bi->attr) - { - (void) rfapiEcommunityGetLNI (bi->attr->ecommunity, - &vo->v.l2addr.logical_net_id); - (void) rfapiEcommunityGetEthernetTag (bi->attr->ecommunity, - &vo->v.l2addr.tag_id); - } - - /* local_nve_id comes from lower byte of RD type */ - vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; - - /* label comes from MP_REACH_NLRI label */ - vo->v.l2addr.label = decode_label (&bi->extra->label); - - new->vn_options = vo; - - /* - * If there is an auxiliary prefix (i.e., host IP address), - * use it as the nexthop prefix instead of the query prefix - */ - if (bi->extra->vnc.import.aux_prefix.family) - { - rfapiQprefix2Rprefix (&bi->extra->vnc.import.aux_prefix, - &new->prefix); - } - } - - if (bi->attr) - { - bgp_encap_types tun_type; - new->prefix.cost = rfapiRfpCost (bi->attr); - - struct bgp_attr_encap_subtlv *pEncap; - - switch (BGP_MP_NEXTHOP_FAMILY (bi->attr->mp_nexthop_len)) - { - case AF_INET: - new->vn_address.addr_family = AF_INET; - new->vn_address.addr.v4 = bi->attr->mp_nexthop_global_in; - break; - - case AF_INET6: - new->vn_address.addr_family = AF_INET6; - new->vn_address.addr.v6 = bi->attr->mp_nexthop_global; - break; - - default: - zlog_warn ("%s: invalid vpn nexthop length: %d", - __func__, bi->attr->mp_nexthop_len); - rfapi_free_next_hop_list (new); - return NULL; - } - - for (pEncap = bi->attr->vnc_subtlvs; pEncap; - pEncap = pEncap->next) - { - switch (pEncap->type) - { - case BGP_VNC_SUBTLV_TYPE_LIFETIME: - /* use configured lifetime, not attr lifetime */ - break; - - default: - zlog_warn ("%s: unknown VNC option type %d", - __func__, pEncap->type); - - - break; - } - } - - rfapiGetTunnelType (bi->attr, &tun_type); - if (tun_type == BGP_ENCAP_TYPE_MPLS) - { - struct prefix p; - /* MPLS carries UN address in next hop */ - rfapiNexthop2Prefix (bi->attr, &p); - if (p.family != 0) - { - rfapiQprefix2Raddr(&p, &new->un_address); - have_vnc_tunnel_un = 1; - } - } - - for (pEncap = bi->attr->encap_subtlvs; pEncap; - pEncap = pEncap->next) - { - switch (pEncap->type) - { - case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT: - /* - * Overrides ENCAP UN address, if any - */ - switch (pEncap->length) - { - - case 8: - new->un_address.addr_family = AF_INET; - memcpy (&new->un_address.addr.v4, pEncap->value, 4); - have_vnc_tunnel_un = 1; - break; - - case 20: - new->un_address.addr_family = AF_INET6; - memcpy (&new->un_address.addr.v6, pEncap->value, 16); - have_vnc_tunnel_un = 1; - break; - - default: - zlog_warn - ("%s: invalid tunnel subtlv UN addr length (%d) for bi %p", - __func__, pEncap->length, bi); - } - break; - - default: - zlog_warn ("%s: unknown Encap Attribute option type %d", - __func__, pEncap->type); - - - break; - } - } - - new->un_options = rfapi_encap_tlv_to_un_option (bi->attr); + new = XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_next_hop_entry)); + assert(new); + + new->prefix = *rprefix; + + if (bi->extra + && decode_rd_type(bi->extra->vnc.import.rd.val) + == RD_TYPE_VNC_ETH) { + /* ethernet */ + + struct rfapi_vn_option *vo; + + vo = XCALLOC(MTYPE_RFAPI_VN_OPTION, + sizeof(struct rfapi_vn_option)); + assert(vo); + + vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; + + memcpy(&vo->v.l2addr.macaddr, &rn->p.u.prefix_eth.octet, + ETHER_ADDR_LEN); + /* only low 3 bytes of this are significant */ + if (bi->attr) { + (void)rfapiEcommunityGetLNI( + bi->attr->ecommunity, + &vo->v.l2addr.logical_net_id); + (void)rfapiEcommunityGetEthernetTag( + bi->attr->ecommunity, &vo->v.l2addr.tag_id); + } + + /* local_nve_id comes from lower byte of RD type */ + vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; + + /* label comes from MP_REACH_NLRI label */ + vo->v.l2addr.label = decode_label(&bi->extra->label); + + new->vn_options = vo; + + /* + * If there is an auxiliary prefix (i.e., host IP address), + * use it as the nexthop prefix instead of the query prefix + */ + if (bi->extra->vnc.import.aux_prefix.family) { + rfapiQprefix2Rprefix(&bi->extra->vnc.import.aux_prefix, + &new->prefix); + } + } + + if (bi->attr) { + bgp_encap_types tun_type; + new->prefix.cost = rfapiRfpCost(bi->attr); + + struct bgp_attr_encap_subtlv *pEncap; + + switch (BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len)) { + case AF_INET: + new->vn_address.addr_family = AF_INET; + new->vn_address.addr.v4 = + bi->attr->mp_nexthop_global_in; + break; + + case AF_INET6: + new->vn_address.addr_family = AF_INET6; + new->vn_address.addr.v6 = bi->attr->mp_nexthop_global; + break; + + default: + zlog_warn("%s: invalid vpn nexthop length: %d", + __func__, bi->attr->mp_nexthop_len); + rfapi_free_next_hop_list(new); + return NULL; + } + + for (pEncap = bi->attr->vnc_subtlvs; pEncap; + pEncap = pEncap->next) { + switch (pEncap->type) { + case BGP_VNC_SUBTLV_TYPE_LIFETIME: + /* use configured lifetime, not attr lifetime */ + break; + + default: + zlog_warn("%s: unknown VNC option type %d", + __func__, pEncap->type); + + + break; + } + } + + rfapiGetTunnelType(bi->attr, &tun_type); + if (tun_type == BGP_ENCAP_TYPE_MPLS) { + struct prefix p; + /* MPLS carries UN address in next hop */ + rfapiNexthop2Prefix(bi->attr, &p); + if (p.family != 0) { + rfapiQprefix2Raddr(&p, &new->un_address); + have_vnc_tunnel_un = 1; + } + } + + for (pEncap = bi->attr->encap_subtlvs; pEncap; + pEncap = pEncap->next) { + switch (pEncap->type) { + case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT: + /* + * Overrides ENCAP UN address, if any + */ + switch (pEncap->length) { + + case 8: + new->un_address.addr_family = AF_INET; + memcpy(&new->un_address.addr.v4, + pEncap->value, 4); + have_vnc_tunnel_un = 1; + break; + + case 20: + new->un_address.addr_family = AF_INET6; + memcpy(&new->un_address.addr.v6, + pEncap->value, 16); + have_vnc_tunnel_un = 1; + break; + + default: + zlog_warn( + "%s: invalid tunnel subtlv UN addr length (%d) for bi %p", + __func__, pEncap->length, bi); + } + break; + + default: + zlog_warn( + "%s: unknown Encap Attribute option type %d", + __func__, pEncap->type); + + + break; + } + } + + new->un_options = rfapi_encap_tlv_to_un_option(bi->attr); #if DEBUG_ENCAP_MONITOR - vnc_zlog_debug_verbose ("%s: line %d: have_vnc_tunnel_un=%d", - __func__, __LINE__, have_vnc_tunnel_un); + vnc_zlog_debug_verbose("%s: line %d: have_vnc_tunnel_un=%d", + __func__, __LINE__, have_vnc_tunnel_un); #endif - if (!have_vnc_tunnel_un && bi && bi->extra) - { - /* - * use cached UN address from ENCAP route - */ - new->un_address.addr_family = bi->extra->vnc.import.un_family; - switch (new->un_address.addr_family) - { - case AF_INET: - new->un_address.addr.v4 = bi->extra->vnc.import.un.addr4; - break; - case AF_INET6: - new->un_address.addr.v6 = bi->extra->vnc.import.un.addr6; - break; - default: - zlog_warn ("%s: invalid UN addr family (%d) for bi %p", - __func__, new->un_address.addr_family, bi); - rfapi_free_next_hop_list (new); - return NULL; - break; - } - } - } - - new->lifetime = lifetime; - return new; + if (!have_vnc_tunnel_un && bi && bi->extra) { + /* + * use cached UN address from ENCAP route + */ + new->un_address.addr_family = + bi->extra->vnc.import.un_family; + switch (new->un_address.addr_family) { + case AF_INET: + new->un_address.addr.v4 = + bi->extra->vnc.import.un.addr4; + break; + case AF_INET6: + new->un_address.addr.v6 = + bi->extra->vnc.import.un.addr6; + break; + default: + zlog_warn( + "%s: invalid UN addr family (%d) for bi %p", + __func__, new->un_address.addr_family, + bi); + rfapi_free_next_hop_list(new); + return NULL; + break; + } + } + } + + new->lifetime = lifetime; + return new; } -int -rfapiHasNonRemovedRoutes (struct route_node *rn) +int rfapiHasNonRemovedRoutes(struct route_node *rn) { - struct bgp_info *bi; + struct bgp_info *bi; - for (bi = rn->info; bi; bi = bi->next) - { - struct prefix pfx; + for (bi = rn->info; bi; bi = bi->next) { + struct prefix pfx; - if (!CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && - (bi->extra && !rfapiGetUnAddrOfVpnBi (bi, &pfx))) - { + if (!CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) + && (bi->extra && !rfapiGetUnAddrOfVpnBi(bi, &pfx))) { - return 1; - } - } - return 0; + return 1; + } + } + return 0; } #if DEBUG_IT_NODES -/* +/* * DEBUG FUNCTION */ -void -rfapiDumpNode (struct route_node *rn) +void rfapiDumpNode(struct route_node *rn) { - struct bgp_info *bi; - - vnc_zlog_debug_verbose ("%s: rn=%p", __func__, rn); - for (bi = rn->info; bi; bi = bi->next) - { - struct prefix pfx; - int ctrc = rfapiGetUnAddrOfVpnBi (bi, &pfx); - int nr; - - if (!CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && (bi->extra && !ctrc)) - { - - nr = 1; - } - else - { - nr = 0; - } - - vnc_zlog_debug_verbose (" bi=%p, nr=%d, flags=0x%x, extra=%p, ctrc=%d", - bi, nr, bi->flags, bi->extra, ctrc); - } + struct bgp_info *bi; + + vnc_zlog_debug_verbose("%s: rn=%p", __func__, rn); + for (bi = rn->info; bi; bi = bi->next) { + struct prefix pfx; + int ctrc = rfapiGetUnAddrOfVpnBi(bi, &pfx); + int nr; + + if (!CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) + && (bi->extra && !ctrc)) { + + nr = 1; + } else { + nr = 0; + } + + vnc_zlog_debug_verbose( + " bi=%p, nr=%d, flags=0x%x, extra=%p, ctrc=%d", bi, nr, + bi->flags, bi->extra, ctrc); + } } #endif -static int -rfapiNhlAddNodeRoutes ( - struct route_node *rn, /* in */ - struct rfapi_ip_prefix *rprefix, /* in */ - uint32_t lifetime, /* in */ - int removed, /* in */ - struct rfapi_next_hop_entry **head, /* in/out */ - struct rfapi_next_hop_entry **tail, /* in/out */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_node *rfd_rib_node,/* preload this NVE rib node */ - struct prefix *pfx_target_original) /* query target */ +static int rfapiNhlAddNodeRoutes( + struct route_node *rn, /* in */ + struct rfapi_ip_prefix *rprefix, /* in */ + uint32_t lifetime, /* in */ + int removed, /* in */ + struct rfapi_next_hop_entry **head, /* in/out */ + struct rfapi_next_hop_entry **tail, /* in/out */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_node *rfd_rib_node, /* preload this NVE rib node */ + struct prefix *pfx_target_original) /* query target */ { - struct bgp_info *bi; - struct rfapi_next_hop_entry *new; - struct prefix pfx_un; - struct skiplist *seen_nexthops; - int count = 0; - int is_l2 = (rn->p.family == AF_ETHERNET); - - if (rfapiRibFTDFilterRecentPrefix( - (struct rfapi_descriptor *)(rfd_rib_node->table->info), rn, - pfx_target_original)) - { - return 0; - } - - seen_nexthops = - skiplist_new (0, vnc_prefix_cmp, (void (*)(void *)) prefix_free); - - for (bi = rn->info; bi; bi = bi->next) - { - - struct prefix pfx_vn; - struct prefix *newpfx; - - if (removed && !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - { + struct bgp_info *bi; + struct rfapi_next_hop_entry *new; + struct prefix pfx_un; + struct skiplist *seen_nexthops; + int count = 0; + int is_l2 = (rn->p.family == AF_ETHERNET); + + if (rfapiRibFTDFilterRecentPrefix( + (struct rfapi_descriptor *)(rfd_rib_node->table->info), rn, + pfx_target_original)) { + return 0; + } + + seen_nexthops = + skiplist_new(0, vnc_prefix_cmp, (void (*)(void *))prefix_free); + + for (bi = rn->info; bi; bi = bi->next) { + + struct prefix pfx_vn; + struct prefix *newpfx; + + if (removed && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { #if DEBUG_RETURNED_NHL - vnc_zlog_debug_verbose ("%s: want holddown, this route not holddown, skip", - __func__); + vnc_zlog_debug_verbose( + "%s: want holddown, this route not holddown, skip", + __func__); #endif - continue; - } - if (!removed && CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - { - continue; - } - - if (!bi->extra) - { - continue; - } - - /* - * Check for excluded VN address - */ - if (rfapiVpnBiNhEqualsPt (bi, exclude_vnaddr)) - continue; - - /* - * Check for VN address (nexthop) copied already - */ - if (is_l2) - { - /* L2 routes: semantic nexthop in aux_prefix; VN addr ain't it */ - pfx_vn = bi->extra->vnc.import.aux_prefix; - } - else - { - rfapiNexthop2Prefix (bi->attr, &pfx_vn); - } - if (!skiplist_search (seen_nexthops, &pfx_vn, NULL)) - { + continue; + } + if (!removed && CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { + continue; + } + + if (!bi->extra) { + continue; + } + + /* + * Check for excluded VN address + */ + if (rfapiVpnBiNhEqualsPt(bi, exclude_vnaddr)) + continue; + + /* + * Check for VN address (nexthop) copied already + */ + if (is_l2) { + /* L2 routes: semantic nexthop in aux_prefix; VN addr + * ain't it */ + pfx_vn = bi->extra->vnc.import.aux_prefix; + } else { + rfapiNexthop2Prefix(bi->attr, &pfx_vn); + } + if (!skiplist_search(seen_nexthops, &pfx_vn, NULL)) { #if DEBUG_RETURNED_NHL - char buf[BUFSIZ]; + char buf[BUFSIZ]; - prefix2str (&pfx_vn, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ - vnc_zlog_debug_verbose ("%s: already put VN/nexthop %s, skip", __func__, buf); + prefix2str(&pfx_vn, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + vnc_zlog_debug_verbose( + "%s: already put VN/nexthop %s, skip", __func__, + buf); #endif - continue; - } + continue; + } - if (rfapiGetUnAddrOfVpnBi (bi, &pfx_un)) - { + if (rfapiGetUnAddrOfVpnBi(bi, &pfx_un)) { #if DEBUG_ENCAP_MONITOR - vnc_zlog_debug_verbose ("%s: failed to get UN address of this VPN bi", - __func__); + vnc_zlog_debug_verbose( + "%s: failed to get UN address of this VPN bi", + __func__); #endif - continue; - } - - newpfx = prefix_new (); - *newpfx = pfx_vn; - skiplist_insert (seen_nexthops, newpfx, newpfx); - - new = rfapiRouteInfo2NextHopEntry(rprefix, bi, lifetime, rn); - if (new) - { - if (rfapiRibPreloadBi(rfd_rib_node, &pfx_vn, &pfx_un, lifetime, bi)) - { - /* duplicate filtered by RIB */ - rfapi_free_next_hop_list (new); - new = NULL; - } - } - - if (new) - { - if (*tail) - { - (*tail)->next = new; - } - else - { - *head = new; - } - *tail = new; - ++count; - } - } - - skiplist_free (seen_nexthops); - - return count; + continue; + } + + newpfx = prefix_new(); + *newpfx = pfx_vn; + skiplist_insert(seen_nexthops, newpfx, newpfx); + + new = rfapiRouteInfo2NextHopEntry(rprefix, bi, lifetime, rn); + if (new) { + if (rfapiRibPreloadBi(rfd_rib_node, &pfx_vn, &pfx_un, + lifetime, bi)) { + /* duplicate filtered by RIB */ + rfapi_free_next_hop_list(new); + new = NULL; + } + } + + if (new) { + if (*tail) { + (*tail)->next = new; + } else { + *head = new; + } + *tail = new; + ++count; + } + } + + skiplist_free(seen_nexthops); + + return count; } @@ -1762,85 +1656,84 @@ rfapiNhlAddNodeRoutes ( * its routes in the list, so we skip it if the right or left node * matches (of course, we still travel down its child subtrees). */ -static int -rfapiNhlAddSubtree ( - struct route_node *rn, /* in */ - uint32_t lifetime, /* in */ - struct rfapi_next_hop_entry **head, /* in/out */ - struct rfapi_next_hop_entry **tail, /* in/out */ - struct route_node *omit_node, /* in */ - struct rfapi_ip_addr *exclude_vnaddr,/* omit routes to same NVE */ - struct route_table *rfd_rib_table,/* preload here */ - struct prefix *pfx_target_original) /* query target */ +static int rfapiNhlAddSubtree( + struct route_node *rn, /* in */ + uint32_t lifetime, /* in */ + struct rfapi_next_hop_entry **head, /* in/out */ + struct rfapi_next_hop_entry **tail, /* in/out */ + struct route_node *omit_node, /* in */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rfd_rib_table, /* preload here */ + struct prefix *pfx_target_original) /* query target */ { - struct rfapi_ip_prefix rprefix; - int rcount = 0; - - /* FIXME: need to find a better way here to work without sticking our - * hands in node->link */ - if (rn->l_left && rn->l_left != omit_node) - { - if (rn->l_left->info) - { - int count = 0; - struct route_node *rib_rn = NULL; - - rfapiQprefix2Rprefix (&rn->l_left->p, &rprefix); - if (rfd_rib_table) - { - rib_rn = route_node_get(rfd_rib_table, &rn->l_left->p); - } - - count = rfapiNhlAddNodeRoutes (rn->l_left, &rprefix, lifetime, 0, - head, tail, exclude_vnaddr, rib_rn, pfx_target_original); - if (!count) - { - count = rfapiNhlAddNodeRoutes (rn->l_left, &rprefix, lifetime, 1, - head, tail, exclude_vnaddr, rib_rn, pfx_target_original); - } - rcount += count; - if (rib_rn) - route_unlock_node(rib_rn); - } - } - - if (rn->l_right && rn->l_right != omit_node) - { - if (rn->l_right->info) - { - int count = 0; - struct route_node *rib_rn = NULL; - - rfapiQprefix2Rprefix (&rn->l_right->p, &rprefix); - if (rfd_rib_table) - { - rib_rn = route_node_get(rfd_rib_table, &rn->l_right->p); - } - count = rfapiNhlAddNodeRoutes (rn->l_right, &rprefix, lifetime, 0, - head, tail, exclude_vnaddr, rib_rn, pfx_target_original); - if (!count) - { - count = rfapiNhlAddNodeRoutes (rn->l_right, &rprefix, lifetime, 1, - head, tail, exclude_vnaddr, rib_rn, pfx_target_original); - } - rcount += count; - if (rib_rn) - route_unlock_node(rib_rn); - } - } - - if (rn->l_left) - { - rcount += rfapiNhlAddSubtree (rn->l_left, lifetime, head, tail, omit_node, - exclude_vnaddr, rfd_rib_table, pfx_target_original); - } - if (rn->l_right) - { - rcount += rfapiNhlAddSubtree (rn->l_right, lifetime, head, tail, - omit_node, exclude_vnaddr, rfd_rib_table, pfx_target_original); - } - - return rcount; + struct rfapi_ip_prefix rprefix; + int rcount = 0; + + /* FIXME: need to find a better way here to work without sticking our + * hands in node->link */ + if (rn->l_left && rn->l_left != omit_node) { + if (rn->l_left->info) { + int count = 0; + struct route_node *rib_rn = NULL; + + rfapiQprefix2Rprefix(&rn->l_left->p, &rprefix); + if (rfd_rib_table) { + rib_rn = route_node_get(rfd_rib_table, + &rn->l_left->p); + } + + count = rfapiNhlAddNodeRoutes( + rn->l_left, &rprefix, lifetime, 0, head, tail, + exclude_vnaddr, rib_rn, pfx_target_original); + if (!count) { + count = rfapiNhlAddNodeRoutes( + rn->l_left, &rprefix, lifetime, 1, head, + tail, exclude_vnaddr, rib_rn, + pfx_target_original); + } + rcount += count; + if (rib_rn) + route_unlock_node(rib_rn); + } + } + + if (rn->l_right && rn->l_right != omit_node) { + if (rn->l_right->info) { + int count = 0; + struct route_node *rib_rn = NULL; + + rfapiQprefix2Rprefix(&rn->l_right->p, &rprefix); + if (rfd_rib_table) { + rib_rn = route_node_get(rfd_rib_table, + &rn->l_right->p); + } + count = rfapiNhlAddNodeRoutes( + rn->l_right, &rprefix, lifetime, 0, head, tail, + exclude_vnaddr, rib_rn, pfx_target_original); + if (!count) { + count = rfapiNhlAddNodeRoutes( + rn->l_right, &rprefix, lifetime, 1, + head, tail, exclude_vnaddr, rib_rn, + pfx_target_original); + } + rcount += count; + if (rib_rn) + route_unlock_node(rib_rn); + } + } + + if (rn->l_left) { + rcount += rfapiNhlAddSubtree( + rn->l_left, lifetime, head, tail, omit_node, + exclude_vnaddr, rfd_rib_table, pfx_target_original); + } + if (rn->l_right) { + rcount += rfapiNhlAddSubtree( + rn->l_right, lifetime, head, tail, omit_node, + exclude_vnaddr, rfd_rib_table, pfx_target_original); + } + + return rcount; } /* @@ -1854,343 +1747,326 @@ rfapiNhlAddSubtree ( * then return those, and also include all the non-removed routes from the * next less-specific node (i.e., this node's parent) at the end. */ -struct rfapi_next_hop_entry * -rfapiRouteNode2NextHopList ( - struct route_node *rn, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr,/* omit routes to same NVE */ - struct route_table *rfd_rib_table,/* preload here */ - struct prefix *pfx_target_original) /* query target */ +struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( + struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rfd_rib_table, /* preload here */ + struct prefix *pfx_target_original) /* query target */ { - struct rfapi_ip_prefix rprefix; - struct rfapi_next_hop_entry *answer = NULL; - struct rfapi_next_hop_entry *last = NULL; - struct route_node *parent; - int count = 0; - struct route_node *rib_rn; + struct rfapi_ip_prefix rprefix; + struct rfapi_next_hop_entry *answer = NULL; + struct rfapi_next_hop_entry *last = NULL; + struct route_node *parent; + int count = 0; + struct route_node *rib_rn; #if DEBUG_RETURNED_NHL - { - char buf[BUFSIZ]; - - prefix2str (&rn->p, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_verbose ("%s: called with node pfx=%s", __func__, buf); - } - rfapiDebugBacktrace (); + { + char buf[BUFSIZ]; + + prefix2str(&rn->p, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_verbose("%s: called with node pfx=%s", __func__, + buf); + } + rfapiDebugBacktrace(); #endif - rfapiQprefix2Rprefix (&rn->p, &rprefix); - - rib_rn = rfd_rib_table? route_node_get(rfd_rib_table, &rn->p): NULL; - - /* - * Add non-withdrawn routes at this node - */ - count = rfapiNhlAddNodeRoutes (rn, &rprefix, lifetime, 0, &answer, &last, - exclude_vnaddr, rib_rn, pfx_target_original); - - /* - * If the list has at least one entry, it's finished - */ - if (count) - { - count += rfapiNhlAddSubtree (rn, lifetime, &answer, &last, NULL, - exclude_vnaddr, rfd_rib_table, pfx_target_original); - vnc_zlog_debug_verbose ("%s: %d nexthops, answer=%p", __func__, count, answer); + rfapiQprefix2Rprefix(&rn->p, &rprefix); + + rib_rn = rfd_rib_table ? route_node_get(rfd_rib_table, &rn->p) : NULL; + + /* + * Add non-withdrawn routes at this node + */ + count = rfapiNhlAddNodeRoutes(rn, &rprefix, lifetime, 0, &answer, &last, + exclude_vnaddr, rib_rn, + pfx_target_original); + + /* + * If the list has at least one entry, it's finished + */ + if (count) { + count += rfapiNhlAddSubtree(rn, lifetime, &answer, &last, NULL, + exclude_vnaddr, rfd_rib_table, + pfx_target_original); + vnc_zlog_debug_verbose("%s: %d nexthops, answer=%p", __func__, + count, answer); #if DEBUG_RETURNED_NHL - rfapiPrintNhl (NULL, answer); + rfapiPrintNhl(NULL, answer); #endif - if (rib_rn) - route_unlock_node(rib_rn); - return answer; - } - - /* - * Add withdrawn routes at this node - */ - count = rfapiNhlAddNodeRoutes (rn, &rprefix, lifetime, 1, &answer, &last, - exclude_vnaddr, rib_rn, pfx_target_original); - if (rib_rn) - route_unlock_node(rib_rn); - - // rfapiPrintNhl(NULL, answer); - - /* - * walk up the tree until we find a node with non-deleted - * routes, then add them - */ - for (parent = rn->parent; parent; parent = parent->parent) - { - if (rfapiHasNonRemovedRoutes (parent)) - { - break; - } - } - - /* - * Add non-withdrawn routes from less-specific prefix - */ - if (parent) - { - rib_rn = rfd_rib_table? route_node_get(rfd_rib_table, &parent->p): NULL; - rfapiQprefix2Rprefix (&parent->p, &rprefix); - count += rfapiNhlAddNodeRoutes (parent, &rprefix, lifetime, 0, - &answer, &last, exclude_vnaddr, rib_rn, pfx_target_original); - count += rfapiNhlAddSubtree (parent, lifetime, &answer, &last, rn, - exclude_vnaddr, rfd_rib_table, pfx_target_original); - if (rib_rn) - route_unlock_node(rib_rn); - } - else - { - /* - * There is no parent with non-removed routes. Still need to - * add subtree of original node if it contributed routes to the - * answer. - */ - if (count) - count += rfapiNhlAddSubtree (rn, lifetime, &answer, &last, rn, - exclude_vnaddr, rfd_rib_table, pfx_target_original); - } - - vnc_zlog_debug_verbose ("%s: %d nexthops, answer=%p", __func__, count, answer); + if (rib_rn) + route_unlock_node(rib_rn); + return answer; + } + + /* + * Add withdrawn routes at this node + */ + count = rfapiNhlAddNodeRoutes(rn, &rprefix, lifetime, 1, &answer, &last, + exclude_vnaddr, rib_rn, + pfx_target_original); + if (rib_rn) + route_unlock_node(rib_rn); + + // rfapiPrintNhl(NULL, answer); + + /* + * walk up the tree until we find a node with non-deleted + * routes, then add them + */ + for (parent = rn->parent; parent; parent = parent->parent) { + if (rfapiHasNonRemovedRoutes(parent)) { + break; + } + } + + /* + * Add non-withdrawn routes from less-specific prefix + */ + if (parent) { + rib_rn = rfd_rib_table + ? route_node_get(rfd_rib_table, &parent->p) + : NULL; + rfapiQprefix2Rprefix(&parent->p, &rprefix); + count += rfapiNhlAddNodeRoutes(parent, &rprefix, lifetime, 0, + &answer, &last, exclude_vnaddr, + rib_rn, pfx_target_original); + count += rfapiNhlAddSubtree(parent, lifetime, &answer, &last, + rn, exclude_vnaddr, rfd_rib_table, + pfx_target_original); + if (rib_rn) + route_unlock_node(rib_rn); + } else { + /* + * There is no parent with non-removed routes. Still need to + * add subtree of original node if it contributed routes to the + * answer. + */ + if (count) + count += rfapiNhlAddSubtree(rn, lifetime, &answer, + &last, rn, exclude_vnaddr, + rfd_rib_table, + pfx_target_original); + } + + vnc_zlog_debug_verbose("%s: %d nexthops, answer=%p", __func__, count, + answer); #if DEBUG_RETURNED_NHL - rfapiPrintNhl (NULL, answer); + rfapiPrintNhl(NULL, answer); #endif - return answer; + return answer; } /* * Construct nexthop list of all routes in table */ -struct rfapi_next_hop_entry * -rfapiRouteTable2NextHopList ( - struct route_table *rt, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr,/* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload this NVE rib table */ - struct prefix *pfx_target_original) /* query target */ +struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList( + struct route_table *rt, + uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rfd_rib_table, /* preload this NVE rib table */ + struct prefix *pfx_target_original) /* query target */ { - struct route_node *rn; - struct rfapi_next_hop_entry *biglist = NULL; - struct rfapi_next_hop_entry *nhl; - struct rfapi_next_hop_entry *tail = NULL; - int count = 0; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - - nhl = rfapiRouteNode2NextHopList (rn, lifetime, exclude_vnaddr, - rfd_rib_table, pfx_target_original); - if (!tail) - { - tail = biglist = nhl; - if (tail) - count = 1; - } - else - { - tail->next = nhl; - } - if (tail) - { - while (tail->next) - { - ++count; - tail = tail->next; - } - } - } - - vnc_zlog_debug_verbose ("%s: returning %d routes", __func__, count); - return biglist; + struct route_node *rn; + struct rfapi_next_hop_entry *biglist = NULL; + struct rfapi_next_hop_entry *nhl; + struct rfapi_next_hop_entry *tail = NULL; + int count = 0; + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + + nhl = rfapiRouteNode2NextHopList(rn, lifetime, exclude_vnaddr, + rfd_rib_table, + pfx_target_original); + if (!tail) { + tail = biglist = nhl; + if (tail) + count = 1; + } else { + tail->next = nhl; + } + if (tail) { + while (tail->next) { + ++count; + tail = tail->next; + } + } + } + + vnc_zlog_debug_verbose("%s: returning %d routes", __func__, count); + return biglist; } -struct rfapi_next_hop_entry * -rfapiEthRouteNode2NextHopList ( - struct route_node *rn, - struct rfapi_ip_prefix *rprefix, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr,/* omit routes to same NVE */ - struct route_table *rfd_rib_table,/* preload NVE rib table */ - struct prefix *pfx_target_original) /* query target */ +struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList( + struct route_node *rn, struct rfapi_ip_prefix *rprefix, + uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rfd_rib_table, /* preload NVE rib table */ + struct prefix *pfx_target_original) /* query target */ { - int count = 0; - struct rfapi_next_hop_entry *answer = NULL; - struct rfapi_next_hop_entry *last = NULL; - struct route_node *rib_rn; + int count = 0; + struct rfapi_next_hop_entry *answer = NULL; + struct rfapi_next_hop_entry *last = NULL; + struct route_node *rib_rn; - rib_rn = rfd_rib_table? route_node_get(rfd_rib_table, &rn->p): NULL; + rib_rn = rfd_rib_table ? route_node_get(rfd_rib_table, &rn->p) : NULL; - count = rfapiNhlAddNodeRoutes (rn, rprefix, lifetime, 0, &answer, &last, - NULL, rib_rn, pfx_target_original); + count = rfapiNhlAddNodeRoutes(rn, rprefix, lifetime, 0, &answer, &last, + NULL, rib_rn, pfx_target_original); #if DEBUG_ENCAP_MONITOR - vnc_zlog_debug_verbose ("%s: node %p: %d non-holddown routes", __func__, rn, count); + vnc_zlog_debug_verbose("%s: node %p: %d non-holddown routes", __func__, + rn, count); #endif - if (!count) - { - count = rfapiNhlAddNodeRoutes (rn, rprefix, lifetime, 1, &answer, &last, - exclude_vnaddr, rib_rn, pfx_target_original); - vnc_zlog_debug_verbose ("%s: node %p: %d holddown routes", __func__, rn, count); - } + if (!count) { + count = rfapiNhlAddNodeRoutes(rn, rprefix, lifetime, 1, &answer, + &last, exclude_vnaddr, rib_rn, + pfx_target_original); + vnc_zlog_debug_verbose("%s: node %p: %d holddown routes", + __func__, rn, count); + } - if (rib_rn) - route_unlock_node(rib_rn); + if (rib_rn) + route_unlock_node(rib_rn); #if DEBUG_RETURNED_NHL - rfapiPrintNhl (NULL, answer); + rfapiPrintNhl(NULL, answer); #endif - return answer; + return answer; } /* * Construct nexthop list of all routes in table */ -struct rfapi_next_hop_entry * -rfapiEthRouteTable2NextHopList ( - uint32_t logical_net_id, - struct rfapi_ip_prefix *rprefix, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr,/* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload NVE rib node */ - struct prefix *pfx_target_original) /* query target */ +struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList( + uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix, + uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rfd_rib_table, /* preload NVE rib node */ + struct prefix *pfx_target_original) /* query target */ { - struct rfapi_import_table *it; - struct bgp *bgp = bgp_get_default (); - struct route_table *rt; - struct route_node *rn; - struct rfapi_next_hop_entry *biglist = NULL; - struct rfapi_next_hop_entry *nhl; - struct rfapi_next_hop_entry *tail = NULL; - int count = 0; - - - it = rfapiMacImportTableGet (bgp, logical_net_id); - rt = it->imported_vpn[AFI_L2VPN]; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - - nhl = rfapiEthRouteNode2NextHopList(rn, rprefix, lifetime, - exclude_vnaddr, rfd_rib_table, pfx_target_original); - if (!tail) - { - tail = biglist = nhl; - if (tail) - count = 1; - } - else - { - tail->next = nhl; - } - if (tail) - { - while (tail->next) - { - ++count; - tail = tail->next; - } - } - } - - vnc_zlog_debug_verbose ("%s: returning %d routes", __func__, count); - return biglist; + struct rfapi_import_table *it; + struct bgp *bgp = bgp_get_default(); + struct route_table *rt; + struct route_node *rn; + struct rfapi_next_hop_entry *biglist = NULL; + struct rfapi_next_hop_entry *nhl; + struct rfapi_next_hop_entry *tail = NULL; + int count = 0; + + + it = rfapiMacImportTableGet(bgp, logical_net_id); + rt = it->imported_vpn[AFI_L2VPN]; + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + + nhl = rfapiEthRouteNode2NextHopList( + rn, rprefix, lifetime, exclude_vnaddr, rfd_rib_table, + pfx_target_original); + if (!tail) { + tail = biglist = nhl; + if (tail) + count = 1; + } else { + tail->next = nhl; + } + if (tail) { + while (tail->next) { + ++count; + tail = tail->next; + } + } + } + + vnc_zlog_debug_verbose("%s: returning %d routes", __func__, count); + return biglist; } /* * Insert a new bi to the imported route table node, * keeping the list of BIs sorted best route first */ -static void -rfapiBgpInfoAttachSorted ( - struct route_node *rn, - struct bgp_info *info_new, - afi_t afi, - safi_t safi) +static void rfapiBgpInfoAttachSorted(struct route_node *rn, + struct bgp_info *info_new, afi_t afi, + safi_t safi) { - struct bgp *bgp; - struct bgp_info *prev; - struct bgp_info *next; - char pfx_buf[PREFIX2STR_BUFFER]; - - - bgp = bgp_get_default (); /* assume 1 instance for now */ - - if (VNC_DEBUG(IMPORT_BI_ATTACH)) - { - vnc_zlog_debug_verbose ("%s: info_new->peer=%p", __func__, info_new->peer); - vnc_zlog_debug_verbose ("%s: info_new->peer->su_remote=%p", __func__, - info_new->peer->su_remote); - } - - for (prev = NULL, next = rn->info; next; prev = next, next = next->next) - { - if (!bgp || - (!CHECK_FLAG (info_new->flags, BGP_INFO_REMOVED) && - CHECK_FLAG (next->flags, BGP_INFO_REMOVED)) || - bgp_info_cmp_compatible (bgp, info_new, next, pfx_buf, afi, safi) == -1) - { /* -1 if 1st is better */ - break; - } - } - vnc_zlog_debug_verbose ("%s: prev=%p, next=%p", __func__, prev, next); - if (prev) - { - prev->next = info_new; - } - else - { - rn->info = info_new; - } - info_new->prev = prev; - info_new->next = next; - if (next) - next->prev = info_new; - bgp_attr_intern (info_new->attr); + struct bgp *bgp; + struct bgp_info *prev; + struct bgp_info *next; + char pfx_buf[PREFIX2STR_BUFFER]; + + + bgp = bgp_get_default(); /* assume 1 instance for now */ + + if (VNC_DEBUG(IMPORT_BI_ATTACH)) { + vnc_zlog_debug_verbose("%s: info_new->peer=%p", __func__, + info_new->peer); + vnc_zlog_debug_verbose("%s: info_new->peer->su_remote=%p", + __func__, info_new->peer->su_remote); + } + + for (prev = NULL, next = rn->info; next; + prev = next, next = next->next) { + if (!bgp || (!CHECK_FLAG(info_new->flags, BGP_INFO_REMOVED) + && CHECK_FLAG(next->flags, BGP_INFO_REMOVED)) + || bgp_info_cmp_compatible(bgp, info_new, next, pfx_buf, + afi, safi) + == -1) { /* -1 if 1st is better */ + break; + } + } + vnc_zlog_debug_verbose("%s: prev=%p, next=%p", __func__, prev, next); + if (prev) { + prev->next = info_new; + } else { + rn->info = info_new; + } + info_new->prev = prev; + info_new->next = next; + if (next) + next->prev = info_new; + bgp_attr_intern(info_new->attr); } -static void -rfapiBgpInfoDetach (struct route_node *rn, struct bgp_info *bi) +static void rfapiBgpInfoDetach(struct route_node *rn, struct bgp_info *bi) { - /* - * Remove the route (doubly-linked) - */ - // bgp_attr_unintern (&bi->attr); - if (bi->next) - bi->next->prev = bi->prev; - if (bi->prev) - bi->prev->next = bi->next; - else - rn->info = bi->next; + /* + * Remove the route (doubly-linked) + */ + // bgp_attr_unintern (&bi->attr); + if (bi->next) + bi->next->prev = bi->prev; + if (bi->prev) + bi->prev->next = bi->next; + else + rn->info = bi->next; } /* * For L3-indexed import tables */ -static int -rfapi_bi_peer_rd_cmp (void *b1, void *b2) +static int rfapi_bi_peer_rd_cmp(void *b1, void *b2) { - struct bgp_info *bi1 = b1; - struct bgp_info *bi2 = b2; - - /* - * Compare peers - */ - if (bi1->peer < bi2->peer) - return -1; - if (bi1->peer > bi2->peer) - return 1; - - /* - * compare RDs - */ - return vnc_prefix_cmp ((struct prefix *) &bi1->extra->vnc.import.rd, - (struct prefix *) &bi2->extra->vnc.import.rd); + struct bgp_info *bi1 = b1; + struct bgp_info *bi2 = b2; + + /* + * Compare peers + */ + if (bi1->peer < bi2->peer) + return -1; + if (bi1->peer > bi2->peer) + return 1; + + /* + * compare RDs + */ + return vnc_prefix_cmp((struct prefix *)&bi1->extra->vnc.import.rd, + (struct prefix *)&bi2->extra->vnc.import.rd); } /* @@ -2198,765 +2074,717 @@ rfapi_bi_peer_rd_cmp (void *b1, void *b2) * The BIs in these tables should ALWAYS have an aux_prefix set because * they arrive via IPv4 or IPv6 advertisements. */ -static int -rfapi_bi_peer_rd_aux_cmp (void *b1, void *b2) +static int rfapi_bi_peer_rd_aux_cmp(void *b1, void *b2) { - struct bgp_info *bi1 = b1; - struct bgp_info *bi2 = b2; - int rc; - - /* - * Compare peers - */ - if (bi1->peer < bi2->peer) - return -1; - if (bi1->peer > bi2->peer) - return 1; - - /* - * compare RDs - */ - rc = vnc_prefix_cmp ((struct prefix *) &bi1->extra->vnc.import.rd, - (struct prefix *) &bi2->extra->vnc.import.rd); - if (rc) - { - return rc; - } - - /* - * L2 import tables can have multiple entries with the - * same MAC address, same RD, but different L3 addresses. - * - * Use presence of aux_prefix with AF=ethernet and prefixlen=1 - * as magic value to signify explicit wildcarding of the aux_prefix. - * This magic value will not appear in bona fide bi entries in - * the import table, but is allowed in the "fake" bi used to - * probe the table when searching. (We have to test both b1 and b2 - * because there is no guarantee of the order the test key and - * the real key will be passed) - */ - if ((bi1->extra->vnc.import.aux_prefix.family == AF_ETHERNET && - (bi1->extra->vnc.import.aux_prefix.prefixlen == 1)) || - (bi2->extra->vnc.import.aux_prefix.family == AF_ETHERNET && - (bi2->extra->vnc.import.aux_prefix.prefixlen == 1))) - { - - /* - * wildcard aux address specified - */ - return 0; - } - - return vnc_prefix_cmp (&bi1->extra->vnc.import.aux_prefix, - &bi2->extra->vnc.import.aux_prefix); + struct bgp_info *bi1 = b1; + struct bgp_info *bi2 = b2; + int rc; + + /* + * Compare peers + */ + if (bi1->peer < bi2->peer) + return -1; + if (bi1->peer > bi2->peer) + return 1; + + /* + * compare RDs + */ + rc = vnc_prefix_cmp((struct prefix *)&bi1->extra->vnc.import.rd, + (struct prefix *)&bi2->extra->vnc.import.rd); + if (rc) { + return rc; + } + + /* + * L2 import tables can have multiple entries with the + * same MAC address, same RD, but different L3 addresses. + * + * Use presence of aux_prefix with AF=ethernet and prefixlen=1 + * as magic value to signify explicit wildcarding of the aux_prefix. + * This magic value will not appear in bona fide bi entries in + * the import table, but is allowed in the "fake" bi used to + * probe the table when searching. (We have to test both b1 and b2 + * because there is no guarantee of the order the test key and + * the real key will be passed) + */ + if ((bi1->extra->vnc.import.aux_prefix.family == AF_ETHERNET + && (bi1->extra->vnc.import.aux_prefix.prefixlen == 1)) + || (bi2->extra->vnc.import.aux_prefix.family == AF_ETHERNET + && (bi2->extra->vnc.import.aux_prefix.prefixlen == 1))) { + + /* + * wildcard aux address specified + */ + return 0; + } + + return vnc_prefix_cmp(&bi1->extra->vnc.import.aux_prefix, + &bi2->extra->vnc.import.aux_prefix); } /* * Index on RD and Peer */ -static void -rfapiItBiIndexAdd ( - struct route_node *rn, /* Import table VPN node */ - struct bgp_info *bi) /* new BI */ +static void rfapiItBiIndexAdd(struct route_node *rn, /* Import table VPN node */ + struct bgp_info *bi) /* new BI */ { - struct skiplist *sl; - - assert (rn); - assert (bi); - assert (bi->extra); - - { - char buf[BUFSIZ]; - prefix_rd2str (&bi->extra->vnc.import.rd, buf, BUFSIZ); - vnc_zlog_debug_verbose ("%s: bi %p, peer %p, rd %s", __func__, bi, bi->peer, buf); - } - - sl = RFAPI_RDINDEX_W_ALLOC (rn); - if (!sl) - { - if (AF_ETHERNET == rn->p.family) - { - sl = skiplist_new (0, rfapi_bi_peer_rd_aux_cmp, NULL); - } - else - { - sl = skiplist_new (0, rfapi_bi_peer_rd_cmp, NULL); - } - RFAPI_IT_EXTRA_GET (rn)->u.vpn.idx_rd = sl; - route_lock_node (rn); /* for skiplist */ - } - assert (!skiplist_insert (sl, (void *) bi, (void *) bi)); - route_lock_node (rn); /* for skiplist entry */ - - /* NB: BIs in import tables are not refcounted */ + struct skiplist *sl; + + assert(rn); + assert(bi); + assert(bi->extra); + + { + char buf[BUFSIZ]; + prefix_rd2str(&bi->extra->vnc.import.rd, buf, BUFSIZ); + vnc_zlog_debug_verbose("%s: bi %p, peer %p, rd %s", __func__, + bi, bi->peer, buf); + } + + sl = RFAPI_RDINDEX_W_ALLOC(rn); + if (!sl) { + if (AF_ETHERNET == rn->p.family) { + sl = skiplist_new(0, rfapi_bi_peer_rd_aux_cmp, NULL); + } else { + sl = skiplist_new(0, rfapi_bi_peer_rd_cmp, NULL); + } + RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd = sl; + route_lock_node(rn); /* for skiplist */ + } + assert(!skiplist_insert(sl, (void *)bi, (void *)bi)); + route_lock_node(rn); /* for skiplist entry */ + + /* NB: BIs in import tables are not refcounted */ } -static void -rfapiItBiIndexDump (struct route_node *rn) +static void rfapiItBiIndexDump(struct route_node *rn) { - struct skiplist *sl; - void *cursor = NULL; - struct bgp_info *k; - struct bgp_info *v; - int rc; - - sl = RFAPI_RDINDEX (rn); - if (!sl) - return; - - for (rc = skiplist_next (sl, (void **) &k, (void **) &v, &cursor); - !rc; rc = skiplist_next (sl, (void **) &k, (void **) &v, &cursor)) - { - - char buf[BUFSIZ]; - char buf_aux_pfx[BUFSIZ]; - - prefix_rd2str (&k->extra->vnc.import.rd, buf, BUFSIZ); - buf_aux_pfx[0] = 0; - if (k->extra->vnc.import.aux_prefix.family) - { - prefix2str (&k->extra->vnc.import.aux_prefix, buf_aux_pfx, BUFSIZ); - } - else - { - strncpy (buf_aux_pfx, "(none)", BUFSIZ); - buf_aux_pfx[BUFSIZ - 1] = 0; - } - - vnc_zlog_debug_verbose ("bi %p, peer %p, rd %s, aux_prefix %s", k, k->peer, buf, - buf_aux_pfx); - } + struct skiplist *sl; + void *cursor = NULL; + struct bgp_info *k; + struct bgp_info *v; + int rc; + + sl = RFAPI_RDINDEX(rn); + if (!sl) + return; + + for (rc = skiplist_next(sl, (void **)&k, (void **)&v, &cursor); !rc; + rc = skiplist_next(sl, (void **)&k, (void **)&v, &cursor)) { + + char buf[BUFSIZ]; + char buf_aux_pfx[BUFSIZ]; + + prefix_rd2str(&k->extra->vnc.import.rd, buf, BUFSIZ); + buf_aux_pfx[0] = 0; + if (k->extra->vnc.import.aux_prefix.family) { + prefix2str(&k->extra->vnc.import.aux_prefix, + buf_aux_pfx, BUFSIZ); + } else { + strncpy(buf_aux_pfx, "(none)", BUFSIZ); + buf_aux_pfx[BUFSIZ - 1] = 0; + } + + vnc_zlog_debug_verbose("bi %p, peer %p, rd %s, aux_prefix %s", + k, k->peer, buf, buf_aux_pfx); + } } -static struct bgp_info * -rfapiItBiIndexSearch ( - struct route_node *rn, /* Import table VPN node */ - struct prefix_rd *prd, - struct peer *peer, - struct prefix *aux_prefix) /* optional L3 addr for L2 ITs */ +static struct bgp_info *rfapiItBiIndexSearch( + struct route_node *rn, /* Import table VPN node */ + struct prefix_rd *prd, struct peer *peer, + struct prefix *aux_prefix) /* optional L3 addr for L2 ITs */ { - struct skiplist *sl; - int rc; - struct bgp_info bi_fake; - struct bgp_info_extra bi_extra; - struct bgp_info *bi_result; + struct skiplist *sl; + int rc; + struct bgp_info bi_fake; + struct bgp_info_extra bi_extra; + struct bgp_info *bi_result; - sl = RFAPI_RDINDEX (rn); - if (!sl) - return NULL; + sl = RFAPI_RDINDEX(rn); + if (!sl) + return NULL; #if DEBUG_BI_SEARCH - { - char buf[BUFSIZ]; - char buf_aux_pfx[BUFSIZ]; - - prefix_rd2str (prd, buf, BUFSIZ); - if (aux_prefix) - { - prefix2str (aux_prefix, buf_aux_pfx, BUFSIZ); - } - else - { - strncpy (buf_aux_pfx, "(nil)", BUFSIZ - 1); - buf_aux_pfx[BUFSIZ - 1] = 0; - } - - vnc_zlog_debug_verbose ("%s want prd=%s, peer=%p, aux_prefix=%s", - __func__, buf, peer, buf_aux_pfx); - rfapiItBiIndexDump (rn); - } + { + char buf[BUFSIZ]; + char buf_aux_pfx[BUFSIZ]; + + prefix_rd2str(prd, buf, BUFSIZ); + if (aux_prefix) { + prefix2str(aux_prefix, buf_aux_pfx, BUFSIZ); + } else { + strncpy(buf_aux_pfx, "(nil)", BUFSIZ - 1); + buf_aux_pfx[BUFSIZ - 1] = 0; + } + + vnc_zlog_debug_verbose("%s want prd=%s, peer=%p, aux_prefix=%s", + __func__, buf, peer, buf_aux_pfx); + rfapiItBiIndexDump(rn); + } #endif - /* threshold is a WAG */ - if (sl->count < 3) - { + /* threshold is a WAG */ + if (sl->count < 3) { #if DEBUG_BI_SEARCH - vnc_zlog_debug_verbose ("%s: short list algorithm", __func__); + vnc_zlog_debug_verbose("%s: short list algorithm", __func__); #endif - /* if short list, linear search might be faster */ - for (bi_result = rn->info; bi_result; bi_result = bi_result->next) - { + /* if short list, linear search might be faster */ + for (bi_result = rn->info; bi_result; + bi_result = bi_result->next) { #if DEBUG_BI_SEARCH - { - char buf[BUFSIZ]; - prefix_rd2str (&bi_result->extra->vnc.import.rd, buf, BUFSIZ); - vnc_zlog_debug_verbose ("%s: bi has prd=%s, peer=%p", __func__, - buf, bi_result->peer); - } + { + char buf[BUFSIZ]; + prefix_rd2str(&bi_result->extra->vnc.import.rd, + buf, BUFSIZ); + vnc_zlog_debug_verbose( + "%s: bi has prd=%s, peer=%p", __func__, + buf, bi_result->peer); + } #endif - if (peer == bi_result->peer && - !prefix_cmp ((struct prefix *) &bi_result->extra->vnc.import.rd, - (struct prefix *) prd)) - { + if (peer == bi_result->peer + && !prefix_cmp((struct prefix *)&bi_result->extra + ->vnc.import.rd, + (struct prefix *)prd)) { #if DEBUG_BI_SEARCH - vnc_zlog_debug_verbose ("%s: peer and RD same, doing aux_prefix check", - __func__); + vnc_zlog_debug_verbose( + "%s: peer and RD same, doing aux_prefix check", + __func__); #endif - if (!aux_prefix || - !prefix_cmp (aux_prefix, - &bi_result->extra->vnc.import.aux_prefix)) - { + if (!aux_prefix + || !prefix_cmp(aux_prefix, + &bi_result->extra->vnc.import + .aux_prefix)) { #if DEBUG_BI_SEARCH - vnc_zlog_debug_verbose ("%s: match", __func__); + vnc_zlog_debug_verbose("%s: match", + __func__); #endif - break; - } - - } - } - return bi_result; - } - - bi_fake.peer = peer; - bi_fake.extra = &bi_extra; - bi_fake.extra->vnc.import.rd = *(struct prefix_rd *) prd; - if (aux_prefix) - { - bi_fake.extra->vnc.import.aux_prefix = *aux_prefix; - } - else - { - /* wildcard */ - bi_fake.extra->vnc.import.aux_prefix.family = AF_ETHERNET; - bi_fake.extra->vnc.import.aux_prefix.prefixlen = 1; - } - - rc = skiplist_search (sl, (void *) &bi_fake, (void *) &bi_result); - - if (rc) - { + break; + } + } + } + return bi_result; + } + + bi_fake.peer = peer; + bi_fake.extra = &bi_extra; + bi_fake.extra->vnc.import.rd = *(struct prefix_rd *)prd; + if (aux_prefix) { + bi_fake.extra->vnc.import.aux_prefix = *aux_prefix; + } else { + /* wildcard */ + bi_fake.extra->vnc.import.aux_prefix.family = AF_ETHERNET; + bi_fake.extra->vnc.import.aux_prefix.prefixlen = 1; + } + + rc = skiplist_search(sl, (void *)&bi_fake, (void *)&bi_result); + + if (rc) { #if DEBUG_BI_SEARCH - vnc_zlog_debug_verbose ("%s: no match", __func__); + vnc_zlog_debug_verbose("%s: no match", __func__); #endif - return NULL; - } + return NULL; + } #if DEBUG_BI_SEARCH - vnc_zlog_debug_verbose ("%s: matched bi=%p", __func__, bi_result); + vnc_zlog_debug_verbose("%s: matched bi=%p", __func__, bi_result); #endif - return bi_result; + return bi_result; } -static void -rfapiItBiIndexDel ( - struct route_node *rn, /* Import table VPN node */ - struct bgp_info *bi) /* old BI */ +static void rfapiItBiIndexDel(struct route_node *rn, /* Import table VPN node */ + struct bgp_info *bi) /* old BI */ { - struct skiplist *sl; - int rc; + struct skiplist *sl; + int rc; - { - char buf[BUFSIZ]; - prefix_rd2str (&bi->extra->vnc.import.rd, buf, BUFSIZ); - vnc_zlog_debug_verbose ("%s: bi %p, peer %p, rd %s", __func__, bi, bi->peer, buf); - } + { + char buf[BUFSIZ]; + prefix_rd2str(&bi->extra->vnc.import.rd, buf, BUFSIZ); + vnc_zlog_debug_verbose("%s: bi %p, peer %p, rd %s", __func__, + bi, bi->peer, buf); + } - sl = RFAPI_RDINDEX (rn); - assert (sl); + sl = RFAPI_RDINDEX(rn); + assert(sl); - rc = skiplist_delete (sl, (void *) (bi), (void *) bi); - if (rc) - { - rfapiItBiIndexDump (rn); - } - assert (!rc); + rc = skiplist_delete(sl, (void *)(bi), (void *)bi); + if (rc) { + rfapiItBiIndexDump(rn); + } + assert(!rc); - route_unlock_node (rn); /* for skiplist entry */ + route_unlock_node(rn); /* for skiplist entry */ - /* NB: BIs in import tables are not refcounted */ + /* NB: BIs in import tables are not refcounted */ } /* * Add a backreference at the ENCAP node to the VPN route that * refers to it */ -static void -rfapiMonitorEncapAdd ( - struct rfapi_import_table *import_table, - struct prefix *p, /* VN address */ - struct route_node *vpn_rn, /* VPN node */ - struct bgp_info *vpn_bi) /* VPN bi/route */ +static void rfapiMonitorEncapAdd(struct rfapi_import_table *import_table, + struct prefix *p, /* VN address */ + struct route_node *vpn_rn, /* VPN node */ + struct bgp_info *vpn_bi) /* VPN bi/route */ { - afi_t afi = family2afi (p->family); - struct route_node *rn; - struct rfapi_monitor_encap *m; - - assert (afi); - rn = route_node_get (import_table->imported_encap[afi], p); /* locks rn */ - assert (rn); - - m = - XCALLOC (MTYPE_RFAPI_MONITOR_ENCAP, sizeof (struct rfapi_monitor_encap)); - assert (m); - - m->node = vpn_rn; - m->bi = vpn_bi; - m->rn = rn; - - /* insert to encap node's list */ - m->next = RFAPI_MONITOR_ENCAP (rn); - if (m->next) - m->next->prev = m; - RFAPI_MONITOR_ENCAP_W_ALLOC (rn) = m; - - /* for easy lookup when deleting vpn route */ - vpn_bi->extra->vnc.import.hme = m; - - vnc_zlog_debug_verbose - ("%s: it=%p, vpn_bi=%p, afi=%d, encap rn=%p, setting vpn_bi->extra->vnc.import.hme=%p", - __func__, import_table, vpn_bi, afi, rn, m); - - RFAPI_CHECK_REFCOUNT (rn, SAFI_ENCAP, 0); - bgp_attr_intern (vpn_bi->attr); + afi_t afi = family2afi(p->family); + struct route_node *rn; + struct rfapi_monitor_encap *m; + + assert(afi); + rn = route_node_get(import_table->imported_encap[afi], + p); /* locks rn */ + assert(rn); + + m = XCALLOC(MTYPE_RFAPI_MONITOR_ENCAP, + sizeof(struct rfapi_monitor_encap)); + assert(m); + + m->node = vpn_rn; + m->bi = vpn_bi; + m->rn = rn; + + /* insert to encap node's list */ + m->next = RFAPI_MONITOR_ENCAP(rn); + if (m->next) + m->next->prev = m; + RFAPI_MONITOR_ENCAP_W_ALLOC(rn) = m; + + /* for easy lookup when deleting vpn route */ + vpn_bi->extra->vnc.import.hme = m; + + vnc_zlog_debug_verbose( + "%s: it=%p, vpn_bi=%p, afi=%d, encap rn=%p, setting vpn_bi->extra->vnc.import.hme=%p", + __func__, import_table, vpn_bi, afi, rn, m); + + RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 0); + bgp_attr_intern(vpn_bi->attr); } -static void -rfapiMonitorEncapDelete (struct bgp_info *vpn_bi) +static void rfapiMonitorEncapDelete(struct bgp_info *vpn_bi) { - /* - * Remove encap monitor - */ - vnc_zlog_debug_verbose ("%s: vpn_bi=%p", __func__, vpn_bi); - if (vpn_bi->extra) - { - struct rfapi_monitor_encap *hme = vpn_bi->extra->vnc.import.hme; - - if (hme) - { - - vnc_zlog_debug_verbose ("%s: hme=%p", __func__, hme); - - /* Refcount checking takes too long here */ - //RFAPI_CHECK_REFCOUNT(hme->rn, SAFI_ENCAP, 0); - if (hme->next) - hme->next->prev = hme->prev; - if (hme->prev) - hme->prev->next = hme->next; - else - RFAPI_MONITOR_ENCAP_W_ALLOC (hme->rn) = hme->next; - /* Refcount checking takes too long here */ - //RFAPI_CHECK_REFCOUNT(hme->rn, SAFI_ENCAP, 1); - - /* see if the struct rfapi_it_extra is empty and can be freed */ - rfapiMonitorExtraPrune (SAFI_ENCAP, hme->rn); - - route_unlock_node (hme->rn); /* decr ref count */ - XFREE (MTYPE_RFAPI_MONITOR_ENCAP, hme); - vpn_bi->extra->vnc.import.hme = NULL; - } - } + /* + * Remove encap monitor + */ + vnc_zlog_debug_verbose("%s: vpn_bi=%p", __func__, vpn_bi); + if (vpn_bi->extra) { + struct rfapi_monitor_encap *hme = vpn_bi->extra->vnc.import.hme; + + if (hme) { + + vnc_zlog_debug_verbose("%s: hme=%p", __func__, hme); + + /* Refcount checking takes too long here */ + // RFAPI_CHECK_REFCOUNT(hme->rn, SAFI_ENCAP, 0); + if (hme->next) + hme->next->prev = hme->prev; + if (hme->prev) + hme->prev->next = hme->next; + else + RFAPI_MONITOR_ENCAP_W_ALLOC(hme->rn) = + hme->next; + /* Refcount checking takes too long here */ + // RFAPI_CHECK_REFCOUNT(hme->rn, SAFI_ENCAP, 1); + + /* see if the struct rfapi_it_extra is empty and can be + * freed */ + rfapiMonitorExtraPrune(SAFI_ENCAP, hme->rn); + + route_unlock_node(hme->rn); /* decr ref count */ + XFREE(MTYPE_RFAPI_MONITOR_ENCAP, hme); + vpn_bi->extra->vnc.import.hme = NULL; + } + } } /* * quagga lib/thread.h says this must return int even though * it doesn't do anything with the return value */ -static int -rfapiWithdrawTimerVPN (struct thread *t) +static int rfapiWithdrawTimerVPN(struct thread *t) { - struct rfapi_withdraw *wcb = t->arg; - struct bgp_info *bi = wcb->info; - struct bgp *bgp = bgp_get_default (); - - struct rfapi_monitor_vpn *moved; - afi_t afi; - - assert (wcb->node); - assert (bi); - assert (wcb->import_table); - assert (bi->extra); - - RFAPI_CHECK_REFCOUNT (wcb->node, SAFI_MPLS_VPN, wcb->lockoffset); - - { - char buf[BUFSIZ]; - - vnc_zlog_debug_verbose ("%s: removing bi %p at prefix %s/%d", - __func__, - bi, - rfapi_ntop (wcb->node->p.family, &wcb->node->p.u.prefix, buf, - BUFSIZ), wcb->node->p.prefixlen); - } - - /* - * Remove the route (doubly-linked) - */ - if (CHECK_FLAG (bi->flags, BGP_INFO_VALID) - && VALID_INTERIOR_TYPE (bi->type)) - RFAPI_MONITOR_EXTERIOR (wcb->node)->valid_interior_count--; - - afi = family2afi (wcb->node->p.family); - wcb->import_table->holddown_count[afi] -= 1; /* keep count consistent */ - rfapiItBiIndexDel (wcb->node, bi); - rfapiBgpInfoDetach (wcb->node, bi); /* with removed bi */ - - vnc_import_bgp_exterior_del_route_interior (bgp, wcb->import_table, - wcb->node, bi); - - - /* - * If VNC is configured to send response remove messages, AND - * if the removed route had a UN address, do response removal - * processing. - */ - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) - { - - int has_valid_duplicate = 0; - struct bgp_info *bii; - - /* - * First check if there are any OTHER routes at this node - * that have the same nexthop and a valid UN address. If - * there are (e.g., from other peers), then the route isn't - * really gone, so skip sending a response removal message. - */ - for (bii = wcb->node->info; bii; bii = bii->next) - { - if (rfapiVpnBiSamePtUn (bi, bii)) - { - has_valid_duplicate = 1; - break; - } - } - - vnc_zlog_debug_verbose ("%s: has_valid_duplicate=%d", __func__, - has_valid_duplicate); - - if (!has_valid_duplicate) - { - rfapiRibPendingDeleteRoute (bgp, wcb->import_table, afi, wcb->node); - } - } - - rfapiMonitorEncapDelete (bi); - - /* - * If there are no VPN monitors at this VPN Node A, - * we are done - */ - if (!RFAPI_MONITOR_VPN (wcb->node)) - { - vnc_zlog_debug_verbose ("%s: no VPN monitors at this node", __func__); - goto done; - } - - /* - * rfapiMonitorMoveShorter only moves monitors if there are - * no remaining valid routes at the current node - */ - moved = rfapiMonitorMoveShorter (wcb->node, 1); - - if (moved) - { - rfapiMonitorMovedUp (wcb->import_table, wcb->node, moved->node, moved); - } + struct rfapi_withdraw *wcb = t->arg; + struct bgp_info *bi = wcb->info; + struct bgp *bgp = bgp_get_default(); + + struct rfapi_monitor_vpn *moved; + afi_t afi; + + assert(wcb->node); + assert(bi); + assert(wcb->import_table); + assert(bi->extra); + + RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_MPLS_VPN, wcb->lockoffset); + + { + char buf[BUFSIZ]; + + vnc_zlog_debug_verbose( + "%s: removing bi %p at prefix %s/%d", __func__, bi, + rfapi_ntop(wcb->node->p.family, &wcb->node->p.u.prefix, + buf, BUFSIZ), + wcb->node->p.prefixlen); + } + + /* + * Remove the route (doubly-linked) + */ + if (CHECK_FLAG(bi->flags, BGP_INFO_VALID) + && VALID_INTERIOR_TYPE(bi->type)) + RFAPI_MONITOR_EXTERIOR(wcb->node)->valid_interior_count--; + + afi = family2afi(wcb->node->p.family); + wcb->import_table->holddown_count[afi] -= 1; /* keep count consistent */ + rfapiItBiIndexDel(wcb->node, bi); + rfapiBgpInfoDetach(wcb->node, bi); /* with removed bi */ + + vnc_import_bgp_exterior_del_route_interior(bgp, wcb->import_table, + wcb->node, bi); + + + /* + * If VNC is configured to send response remove messages, AND + * if the removed route had a UN address, do response removal + * processing. + */ + if (!(bgp->rfapi_cfg->flags + & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) { + + int has_valid_duplicate = 0; + struct bgp_info *bii; + + /* + * First check if there are any OTHER routes at this node + * that have the same nexthop and a valid UN address. If + * there are (e.g., from other peers), then the route isn't + * really gone, so skip sending a response removal message. + */ + for (bii = wcb->node->info; bii; bii = bii->next) { + if (rfapiVpnBiSamePtUn(bi, bii)) { + has_valid_duplicate = 1; + break; + } + } + + vnc_zlog_debug_verbose("%s: has_valid_duplicate=%d", __func__, + has_valid_duplicate); + + if (!has_valid_duplicate) { + rfapiRibPendingDeleteRoute(bgp, wcb->import_table, afi, + wcb->node); + } + } + + rfapiMonitorEncapDelete(bi); + + /* + * If there are no VPN monitors at this VPN Node A, + * we are done + */ + if (!RFAPI_MONITOR_VPN(wcb->node)) { + vnc_zlog_debug_verbose("%s: no VPN monitors at this node", + __func__); + goto done; + } + + /* + * rfapiMonitorMoveShorter only moves monitors if there are + * no remaining valid routes at the current node + */ + moved = rfapiMonitorMoveShorter(wcb->node, 1); + + if (moved) { + rfapiMonitorMovedUp(wcb->import_table, wcb->node, moved->node, + moved); + } done: - /* - * Free VPN bi - */ - rfapiBgpInfoFree (bi); - wcb->info = NULL; - - /* - * If route count at this node has gone to 0, withdraw exported prefix - */ - if (!wcb->node->info) - { - /* see if the struct rfapi_it_extra is empty and can be freed */ - rfapiMonitorExtraPrune (SAFI_MPLS_VPN, wcb->node); - vnc_direct_bgp_del_prefix (bgp, wcb->import_table, wcb->node); - vnc_zebra_del_prefix (bgp, wcb->import_table, wcb->node); - } - else - { - /* - * nexthop change event - * vnc_direct_bgp_add_prefix() will recompute the VN addr ecommunity - */ - vnc_direct_bgp_add_prefix (bgp, wcb->import_table, wcb->node); - } - - RFAPI_CHECK_REFCOUNT (wcb->node, SAFI_MPLS_VPN, 1 + wcb->lockoffset); - route_unlock_node (wcb->node); /* decr ref count */ - XFREE (MTYPE_RFAPI_WITHDRAW, wcb); - return 0; + /* + * Free VPN bi + */ + rfapiBgpInfoFree(bi); + wcb->info = NULL; + + /* + * If route count at this node has gone to 0, withdraw exported prefix + */ + if (!wcb->node->info) { + /* see if the struct rfapi_it_extra is empty and can be freed */ + rfapiMonitorExtraPrune(SAFI_MPLS_VPN, wcb->node); + vnc_direct_bgp_del_prefix(bgp, wcb->import_table, wcb->node); + vnc_zebra_del_prefix(bgp, wcb->import_table, wcb->node); + } else { + /* + * nexthop change event + * vnc_direct_bgp_add_prefix() will recompute the VN addr + * ecommunity + */ + vnc_direct_bgp_add_prefix(bgp, wcb->import_table, wcb->node); + } + + RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_MPLS_VPN, 1 + wcb->lockoffset); + route_unlock_node(wcb->node); /* decr ref count */ + XFREE(MTYPE_RFAPI_WITHDRAW, wcb); + return 0; } /* * This works for multiprotocol extension, but not for plain ol' * unicast IPv4 because that nexthop is stored in attr->nexthop */ -void -rfapiNexthop2Prefix (struct attr *attr, struct prefix *p) +void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p) { - assert (p); - assert (attr); - - memset (p, 0, sizeof (struct prefix)); - - switch (p->family = BGP_MP_NEXTHOP_FAMILY (attr->mp_nexthop_len)) - { - case AF_INET: - p->u.prefix4 = attr->mp_nexthop_global_in; - p->prefixlen = 32; - break; - - case AF_INET6: - p->u.prefix6 = attr->mp_nexthop_global; - p->prefixlen = 128; - break; - - default: - vnc_zlog_debug_verbose ("%s: Family is unknown = %d", - __func__, p->family); - } + assert(p); + assert(attr); + + memset(p, 0, sizeof(struct prefix)); + + switch (p->family = BGP_MP_NEXTHOP_FAMILY(attr->mp_nexthop_len)) { + case AF_INET: + p->u.prefix4 = attr->mp_nexthop_global_in; + p->prefixlen = 32; + break; + + case AF_INET6: + p->u.prefix6 = attr->mp_nexthop_global; + p->prefixlen = 128; + break; + + default: + vnc_zlog_debug_verbose("%s: Family is unknown = %d", __func__, + p->family); + } } -void -rfapiUnicastNexthop2Prefix (afi_t afi, struct attr *attr, struct prefix *p) +void rfapiUnicastNexthop2Prefix(afi_t afi, struct attr *attr, struct prefix *p) { - if (afi == AFI_IP) - { - p->family = AF_INET; - p->prefixlen = 32; - p->u.prefix4 = attr->nexthop; - } - else - { - rfapiNexthop2Prefix (attr, p); - } + if (afi == AFI_IP) { + p->family = AF_INET; + p->prefixlen = 32; + p->u.prefix4 = attr->nexthop; + } else { + rfapiNexthop2Prefix(attr, p); + } } -static int -rfapiAttrNexthopAddrDifferent (struct prefix *p1, struct prefix *p2) +static int rfapiAttrNexthopAddrDifferent(struct prefix *p1, struct prefix *p2) { - if (!p1 || !p2) - { - vnc_zlog_debug_verbose ("%s: p1 or p2 is NULL", __func__); - return 1; - } - - /* - * Are address families the same? - */ - if (p1->family != p2->family) - { - return 1; - } - - switch (p1->family) - { - case AF_INET: - if (IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4)) - return 0; - break; - - case AF_INET6: - if (IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6)) - return 0; - break; - - default: - assert (1); - - } - - return 1; + if (!p1 || !p2) { + vnc_zlog_debug_verbose("%s: p1 or p2 is NULL", __func__); + return 1; + } + + /* + * Are address families the same? + */ + if (p1->family != p2->family) { + return 1; + } + + switch (p1->family) { + case AF_INET: + if (IPV4_ADDR_SAME(&p1->u.prefix4, &p2->u.prefix4)) + return 0; + break; + + case AF_INET6: + if (IPV6_ADDR_SAME(&p1->u.prefix6, &p2->u.prefix6)) + return 0; + break; + + default: + assert(1); + } + + return 1; } -static void -rfapiCopyUnEncap2VPN (struct bgp_info *encap_bi, struct bgp_info *vpn_bi) +static void rfapiCopyUnEncap2VPN(struct bgp_info *encap_bi, + struct bgp_info *vpn_bi) { - if (!encap_bi->attr) - { - zlog_warn ("%s: no encap bi attr/extra, can't copy UN address", - __func__); - return; - } - - if (!vpn_bi || !vpn_bi->extra) - { - zlog_warn ("%s: no vpn bi attr/extra, can't copy UN address", - __func__); - return; - } - - switch (BGP_MP_NEXTHOP_FAMILY (encap_bi->attr->mp_nexthop_len)) - { - case AF_INET: - - /* - * instrumentation to debug segfault of 091127 - */ - vnc_zlog_debug_verbose ("%s: vpn_bi=%p", __func__, vpn_bi); - if (vpn_bi) - { - vnc_zlog_debug_verbose ("%s: vpn_bi->extra=%p", __func__, vpn_bi->extra); - } - - vpn_bi->extra->vnc.import.un_family = AF_INET; - vpn_bi->extra->vnc.import.un.addr4 = encap_bi->attr->mp_nexthop_global_in; - break; - - case AF_INET6: - vpn_bi->extra->vnc.import.un_family = AF_INET6; - vpn_bi->extra->vnc.import.un.addr6 = encap_bi->attr->mp_nexthop_global; - break; - - default: - zlog_warn ("%s: invalid encap nexthop length: %d", - __func__, encap_bi->attr->mp_nexthop_len); - vpn_bi->extra->vnc.import.un_family = 0; - break; - } + if (!encap_bi->attr) { + zlog_warn("%s: no encap bi attr/extra, can't copy UN address", + __func__); + return; + } + + if (!vpn_bi || !vpn_bi->extra) { + zlog_warn("%s: no vpn bi attr/extra, can't copy UN address", + __func__); + return; + } + + switch (BGP_MP_NEXTHOP_FAMILY(encap_bi->attr->mp_nexthop_len)) { + case AF_INET: + + /* + * instrumentation to debug segfault of 091127 + */ + vnc_zlog_debug_verbose("%s: vpn_bi=%p", __func__, vpn_bi); + if (vpn_bi) { + vnc_zlog_debug_verbose("%s: vpn_bi->extra=%p", __func__, + vpn_bi->extra); + } + + vpn_bi->extra->vnc.import.un_family = AF_INET; + vpn_bi->extra->vnc.import.un.addr4 = + encap_bi->attr->mp_nexthop_global_in; + break; + + case AF_INET6: + vpn_bi->extra->vnc.import.un_family = AF_INET6; + vpn_bi->extra->vnc.import.un.addr6 = + encap_bi->attr->mp_nexthop_global; + break; + + default: + zlog_warn("%s: invalid encap nexthop length: %d", __func__, + encap_bi->attr->mp_nexthop_len); + vpn_bi->extra->vnc.import.un_family = 0; + break; + } } /* * returns 0 on success, nonzero on error */ -static int -rfapiWithdrawEncapUpdateCachedUn ( - struct rfapi_import_table *import_table, - struct bgp_info *encap_bi, - struct route_node *vpn_rn, - struct bgp_info *vpn_bi) +static int rfapiWithdrawEncapUpdateCachedUn( + struct rfapi_import_table *import_table, struct bgp_info *encap_bi, + struct route_node *vpn_rn, struct bgp_info *vpn_bi) { - if (!encap_bi) - { - - /* - * clear cached UN address - */ - if (!vpn_bi || !vpn_bi->extra) - { - zlog_warn ("%s: missing VPN bi/extra, can't clear UN addr", - __func__); - return 1; - } - vpn_bi->extra->vnc.import.un_family = 0; - memset (&vpn_bi->extra->vnc.import.un, 0, - sizeof (vpn_bi->extra->vnc.import.un)); - if (CHECK_FLAG (vpn_bi->flags, BGP_INFO_VALID)) - { - if (rfapiGetVncTunnelUnAddr (vpn_bi->attr, NULL)) - { - UNSET_FLAG (vpn_bi->flags, BGP_INFO_VALID); - if (VALID_INTERIOR_TYPE (vpn_bi->type)) - RFAPI_MONITOR_EXTERIOR (vpn_rn)->valid_interior_count--; - /* signal interior route withdrawal to import-exterior */ - vnc_import_bgp_exterior_del_route_interior (bgp_get_default (), - import_table, - vpn_rn, vpn_bi); - } - } - - } - else - { - if (!vpn_bi) - { - zlog_warn ("%s: missing VPN bi, can't clear UN addr", __func__); - return 1; - } - rfapiCopyUnEncap2VPN (encap_bi, vpn_bi); - if (!CHECK_FLAG (vpn_bi->flags, BGP_INFO_VALID)) - { - SET_FLAG (vpn_bi->flags, BGP_INFO_VALID); - if (VALID_INTERIOR_TYPE (vpn_bi->type)) - RFAPI_MONITOR_EXTERIOR (vpn_rn)->valid_interior_count++; - /* signal interior route withdrawal to import-exterior */ - vnc_import_bgp_exterior_add_route_interior (bgp_get_default (), - import_table, - vpn_rn, vpn_bi); - } - } - return 0; + if (!encap_bi) { + + /* + * clear cached UN address + */ + if (!vpn_bi || !vpn_bi->extra) { + zlog_warn( + "%s: missing VPN bi/extra, can't clear UN addr", + __func__); + return 1; + } + vpn_bi->extra->vnc.import.un_family = 0; + memset(&vpn_bi->extra->vnc.import.un, 0, + sizeof(vpn_bi->extra->vnc.import.un)); + if (CHECK_FLAG(vpn_bi->flags, BGP_INFO_VALID)) { + if (rfapiGetVncTunnelUnAddr(vpn_bi->attr, NULL)) { + UNSET_FLAG(vpn_bi->flags, BGP_INFO_VALID); + if (VALID_INTERIOR_TYPE(vpn_bi->type)) + RFAPI_MONITOR_EXTERIOR(vpn_rn) + ->valid_interior_count--; + /* signal interior route withdrawal to + * import-exterior */ + vnc_import_bgp_exterior_del_route_interior( + bgp_get_default(), import_table, vpn_rn, + vpn_bi); + } + } + + } else { + if (!vpn_bi) { + zlog_warn("%s: missing VPN bi, can't clear UN addr", + __func__); + return 1; + } + rfapiCopyUnEncap2VPN(encap_bi, vpn_bi); + if (!CHECK_FLAG(vpn_bi->flags, BGP_INFO_VALID)) { + SET_FLAG(vpn_bi->flags, BGP_INFO_VALID); + if (VALID_INTERIOR_TYPE(vpn_bi->type)) + RFAPI_MONITOR_EXTERIOR(vpn_rn) + ->valid_interior_count++; + /* signal interior route withdrawal to import-exterior + */ + vnc_import_bgp_exterior_add_route_interior( + bgp_get_default(), import_table, vpn_rn, + vpn_bi); + } + } + return 0; } -static int -rfapiWithdrawTimerEncap (struct thread *t) +static int rfapiWithdrawTimerEncap(struct thread *t) { - struct rfapi_withdraw *wcb = t->arg; - struct bgp_info *bi = wcb->info; - int was_first_route = 0; - struct rfapi_monitor_encap *em; - struct skiplist *vpn_node_sl = skiplist_new (0, NULL, NULL); - - assert (wcb->node); - assert (bi); - assert (wcb->import_table); - - RFAPI_CHECK_REFCOUNT (wcb->node, SAFI_ENCAP, 0); - - if (wcb->node->info == bi) - was_first_route = 1; - - /* - * Remove the route/bi and free it - */ - rfapiBgpInfoDetach (wcb->node, bi); - rfapiBgpInfoFree (bi); - - if (!was_first_route) - goto done; - - for (em = RFAPI_MONITOR_ENCAP (wcb->node); em; em = em->next) - { - - /* - * Update monitoring VPN BIs with new encap info at the - * head of the encap bi chain (which could be NULL after - * removing the expiring bi above) - */ - if (rfapiWithdrawEncapUpdateCachedUn - (wcb->import_table, wcb->node->info, em->node, em->bi)) - continue; - - /* - * Build a list of unique VPN nodes referenced by these monitors. - * Use a skiplist for speed. - */ - skiplist_insert (vpn_node_sl, em->node, em->node); - } - - - /* - * for each VPN node referenced in the ENCAP monitors: - */ - struct route_node *rn; - while (!skiplist_first (vpn_node_sl, (void **) &rn, NULL)) - { - if (!wcb->node->info) - { - struct rfapi_monitor_vpn *moved; - - moved = rfapiMonitorMoveShorter (rn, 0); - if (moved) - { - //rfapiDoRouteCallback(wcb->import_table, moved->node, moved); - rfapiMonitorMovedUp (wcb->import_table, rn, moved->node, moved); - } - } - else - { - //rfapiDoRouteCallback(wcb->import_table, rn, NULL); - rfapiMonitorItNodeChanged (wcb->import_table, rn, NULL); - } - skiplist_delete_first (vpn_node_sl); - } + struct rfapi_withdraw *wcb = t->arg; + struct bgp_info *bi = wcb->info; + int was_first_route = 0; + struct rfapi_monitor_encap *em; + struct skiplist *vpn_node_sl = skiplist_new(0, NULL, NULL); + + assert(wcb->node); + assert(bi); + assert(wcb->import_table); + + RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_ENCAP, 0); + + if (wcb->node->info == bi) + was_first_route = 1; + + /* + * Remove the route/bi and free it + */ + rfapiBgpInfoDetach(wcb->node, bi); + rfapiBgpInfoFree(bi); + + if (!was_first_route) + goto done; + + for (em = RFAPI_MONITOR_ENCAP(wcb->node); em; em = em->next) { + + /* + * Update monitoring VPN BIs with new encap info at the + * head of the encap bi chain (which could be NULL after + * removing the expiring bi above) + */ + if (rfapiWithdrawEncapUpdateCachedUn(wcb->import_table, + wcb->node->info, em->node, + em->bi)) + continue; + + /* + * Build a list of unique VPN nodes referenced by these + * monitors. + * Use a skiplist for speed. + */ + skiplist_insert(vpn_node_sl, em->node, em->node); + } + + + /* + * for each VPN node referenced in the ENCAP monitors: + */ + struct route_node *rn; + while (!skiplist_first(vpn_node_sl, (void **)&rn, NULL)) { + if (!wcb->node->info) { + struct rfapi_monitor_vpn *moved; + + moved = rfapiMonitorMoveShorter(rn, 0); + if (moved) { + // rfapiDoRouteCallback(wcb->import_table, + // moved->node, moved); + rfapiMonitorMovedUp(wcb->import_table, rn, + moved->node, moved); + } + } else { + // rfapiDoRouteCallback(wcb->import_table, rn, NULL); + rfapiMonitorItNodeChanged(wcb->import_table, rn, NULL); + } + skiplist_delete_first(vpn_node_sl); + } done: - RFAPI_CHECK_REFCOUNT (wcb->node, SAFI_ENCAP, 1); - route_unlock_node (wcb->node); /* decr ref count */ - XFREE (MTYPE_RFAPI_WITHDRAW, wcb); - skiplist_free (vpn_node_sl); - return 0; + RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_ENCAP, 1); + route_unlock_node(wcb->node); /* decr ref count */ + XFREE(MTYPE_RFAPI_WITHDRAW, wcb); + skiplist_free(vpn_node_sl); + return 0; } @@ -2965,1391 +2793,1272 @@ done: * in each case */ static void -rfapiBiStartWithdrawTimer ( - struct rfapi_import_table *import_table, - struct route_node *rn, - struct bgp_info *bi, - afi_t afi, - safi_t safi, - int (*timer_service_func) (struct thread *)) +rfapiBiStartWithdrawTimer(struct rfapi_import_table *import_table, + struct route_node *rn, struct bgp_info *bi, afi_t afi, + safi_t safi, + int (*timer_service_func)(struct thread *)) { - uint32_t lifetime; - struct rfapi_withdraw *wcb; - - if CHECK_FLAG - (bi->flags, BGP_INFO_REMOVED) - { - /* - * Already on the path to being withdrawn, - * should already have a timer set up to - * delete it. - */ - vnc_zlog_debug_verbose ("%s: already being withdrawn, do nothing", __func__); - return; - } - - rfapiGetVncLifetime (bi->attr, &lifetime); - vnc_zlog_debug_verbose ("%s: VNC lifetime is %u", __func__, lifetime); - - /* - * withdrawn routes get to hang around for a while - */ - SET_FLAG (bi->flags, BGP_INFO_REMOVED); - - /* set timer to remove the route later */ - lifetime = rfapiGetHolddownFromLifetime (lifetime); - vnc_zlog_debug_verbose ("%s: using timeout %u", __func__, lifetime); - - /* - * Stash import_table, node, and info for use by timer - * service routine, which is supposed to free the wcb. - */ - wcb = XCALLOC (MTYPE_RFAPI_WITHDRAW, sizeof (struct rfapi_withdraw)); - assert (wcb); - wcb->node = rn; - wcb->info = bi; - wcb->import_table = import_table; - bgp_attr_intern (bi->attr); - - if (VNC_DEBUG(VERBOSE)) - { - vnc_zlog_debug_verbose - ("%s: wcb values: node=%p, info=%p, import_table=%p (bi follows)", - __func__, wcb->node, wcb->info, wcb->import_table); - rfapiPrintBi (NULL, bi); - } - - - assert (bi->extra); - if (lifetime > UINT32_MAX / 1001) - { - /* sub-optimal case, but will probably never happen */ - bi->extra->vnc.import.timer = NULL; - thread_add_timer(bm->master, timer_service_func, wcb, lifetime, - &bi->extra->vnc.import.timer); - } - else - { - static uint32_t jitter; - uint32_t lifetime_msec; - - /* - * the goal here is to spread out the timers so they are - * sortable in the skip list - */ - if (++jitter >= 1000) - jitter = 0; - - lifetime_msec = (lifetime * 1000) + jitter; - - bi->extra->vnc.import.timer = NULL; - thread_add_timer_msec(bm->master, timer_service_func, wcb, lifetime_msec, - &bi->extra->vnc.import.timer); - } - - /* re-sort route list (BGP_INFO_REMOVED routes are last) */ - if (((struct bgp_info *) rn->info)->next) - { - rfapiBgpInfoDetach (rn, bi); - rfapiBgpInfoAttachSorted (rn, bi, afi, safi); - } + uint32_t lifetime; + struct rfapi_withdraw *wcb; + + if + CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) + { + /* + * Already on the path to being withdrawn, + * should already have a timer set up to + * delete it. + */ + vnc_zlog_debug_verbose( + "%s: already being withdrawn, do nothing", + __func__); + return; + } + + rfapiGetVncLifetime(bi->attr, &lifetime); + vnc_zlog_debug_verbose("%s: VNC lifetime is %u", __func__, lifetime); + + /* + * withdrawn routes get to hang around for a while + */ + SET_FLAG(bi->flags, BGP_INFO_REMOVED); + + /* set timer to remove the route later */ + lifetime = rfapiGetHolddownFromLifetime(lifetime); + vnc_zlog_debug_verbose("%s: using timeout %u", __func__, lifetime); + + /* + * Stash import_table, node, and info for use by timer + * service routine, which is supposed to free the wcb. + */ + wcb = XCALLOC(MTYPE_RFAPI_WITHDRAW, sizeof(struct rfapi_withdraw)); + assert(wcb); + wcb->node = rn; + wcb->info = bi; + wcb->import_table = import_table; + bgp_attr_intern(bi->attr); + + if (VNC_DEBUG(VERBOSE)) { + vnc_zlog_debug_verbose( + "%s: wcb values: node=%p, info=%p, import_table=%p (bi follows)", + __func__, wcb->node, wcb->info, wcb->import_table); + rfapiPrintBi(NULL, bi); + } + + + assert(bi->extra); + if (lifetime > UINT32_MAX / 1001) { + /* sub-optimal case, but will probably never happen */ + bi->extra->vnc.import.timer = NULL; + thread_add_timer(bm->master, timer_service_func, wcb, lifetime, + &bi->extra->vnc.import.timer); + } else { + static uint32_t jitter; + uint32_t lifetime_msec; + + /* + * the goal here is to spread out the timers so they are + * sortable in the skip list + */ + if (++jitter >= 1000) + jitter = 0; + + lifetime_msec = (lifetime * 1000) + jitter; + + bi->extra->vnc.import.timer = NULL; + thread_add_timer_msec(bm->master, timer_service_func, wcb, + lifetime_msec, + &bi->extra->vnc.import.timer); + } + + /* re-sort route list (BGP_INFO_REMOVED routes are last) */ + if (((struct bgp_info *)rn->info)->next) { + rfapiBgpInfoDetach(rn, bi); + rfapiBgpInfoAttachSorted(rn, bi, afi, safi); + } } -typedef void (rfapi_bi_filtered_import_f) (struct rfapi_import_table *, - int, - struct peer *, - void *, - struct prefix *, - struct prefix *, - afi_t, - struct prefix_rd *, - struct attr *, - u_char, u_char, uint32_t *); +typedef void(rfapi_bi_filtered_import_f)(struct rfapi_import_table *, int, + struct peer *, void *, struct prefix *, + struct prefix *, afi_t, + struct prefix_rd *, struct attr *, + u_char, u_char, uint32_t *); -static void -rfapiExpireEncapNow ( - struct rfapi_import_table *it, - struct route_node *rn, - struct bgp_info *bi) +static void rfapiExpireEncapNow(struct rfapi_import_table *it, + struct route_node *rn, struct bgp_info *bi) { - struct rfapi_withdraw *wcb; - struct thread t; - - /* - * pretend we're an expiring timer - */ - wcb = XCALLOC (MTYPE_RFAPI_WITHDRAW, sizeof (struct rfapi_withdraw)); - wcb->info = bi; - wcb->node = rn; - wcb->import_table = it; - memset (&t, 0, sizeof (t)); - t.arg = wcb; - rfapiWithdrawTimerEncap (&t); /* frees wcb */ + struct rfapi_withdraw *wcb; + struct thread t; + + /* + * pretend we're an expiring timer + */ + wcb = XCALLOC(MTYPE_RFAPI_WITHDRAW, sizeof(struct rfapi_withdraw)); + wcb->info = bi; + wcb->node = rn; + wcb->import_table = it; + memset(&t, 0, sizeof(t)); + t.arg = wcb; + rfapiWithdrawTimerEncap(&t); /* frees wcb */ } -static int -rfapiGetNexthop (struct attr *attr, struct prefix *prefix) +static int rfapiGetNexthop(struct attr *attr, struct prefix *prefix) { - switch (BGP_MP_NEXTHOP_FAMILY (attr->mp_nexthop_len)) - { - case AF_INET: - prefix->family = AF_INET; - prefix->prefixlen = 32; - prefix->u.prefix4 = attr->mp_nexthop_global_in; - break; - case AF_INET6: - prefix->family = AF_INET6; - prefix->prefixlen = 128; - prefix->u.prefix6 = attr->mp_nexthop_global; - break; - default: - vnc_zlog_debug_verbose ("%s: unknown attr->mp_nexthop_len %d", __func__, - attr->mp_nexthop_len); - return EINVAL; - } - return 0; + switch (BGP_MP_NEXTHOP_FAMILY(attr->mp_nexthop_len)) { + case AF_INET: + prefix->family = AF_INET; + prefix->prefixlen = 32; + prefix->u.prefix4 = attr->mp_nexthop_global_in; + break; + case AF_INET6: + prefix->family = AF_INET6; + prefix->prefixlen = 128; + prefix->u.prefix6 = attr->mp_nexthop_global; + break; + default: + vnc_zlog_debug_verbose("%s: unknown attr->mp_nexthop_len %d", + __func__, attr->mp_nexthop_len); + return EINVAL; + } + return 0; } -/* +/* * import a bgp_info if its route target list intersects with the * import table's route target list */ -static void -rfapiBgpInfoFilteredImportEncap ( - struct rfapi_import_table *import_table, - int action, - struct peer *peer, - void *rfd, /* set for looped back routes */ - struct prefix *p, - struct prefix *aux_prefix, /* Unused for encap routes */ - afi_t afi, - struct prefix_rd *prd, - struct attr *attr, /* part of bgp_info */ - u_char type, /* part of bgp_info */ - u_char sub_type, /* part of bgp_info */ - uint32_t *label) /* part of bgp_info */ +static void rfapiBgpInfoFilteredImportEncap( + struct rfapi_import_table *import_table, int action, struct peer *peer, + void *rfd, /* set for looped back routes */ + struct prefix *p, + struct prefix *aux_prefix, /* Unused for encap routes */ + afi_t afi, struct prefix_rd *prd, + struct attr *attr, /* part of bgp_info */ + u_char type, /* part of bgp_info */ + u_char sub_type, /* part of bgp_info */ + uint32_t *label) /* part of bgp_info */ { - struct route_table *rt = NULL; - struct route_node *rn; - struct bgp_info *info_new; - struct bgp_info *bi; - struct bgp_info *next; - char buf[BUFSIZ]; - - struct prefix p_firstbi_old; - struct prefix p_firstbi_new; - int replacing = 0; - const char *action_str = NULL; - struct prefix un_prefix; - - struct bgp *bgp; - bgp = bgp_get_default (); /* assume 1 instance for now */ - - switch (action) - { - case FIF_ACTION_UPDATE: - action_str = "update"; - break; - case FIF_ACTION_WITHDRAW: - action_str = "withdraw"; - break; - case FIF_ACTION_KILL: - action_str = "kill"; - break; - default: - assert (0); - break; - } - - vnc_zlog_debug_verbose ("%s: entry: %s: prefix %s/%d", __func__, - action_str, - inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); - - memset (&p_firstbi_old, 0, sizeof (p_firstbi_old)); - memset (&p_firstbi_new, 0, sizeof (p_firstbi_new)); - - if (action == FIF_ACTION_UPDATE) - { - /* - * Compare rt lists. If no intersection, don't import this route - * On a withdraw, peer and RD are sufficient to determine if - * we should act. - */ - if (!attr || !attr->ecommunity) - { - - vnc_zlog_debug_verbose ("%s: attr, extra, or ecommunity missing, not importing", - __func__); - return; - } + struct route_table *rt = NULL; + struct route_node *rn; + struct bgp_info *info_new; + struct bgp_info *bi; + struct bgp_info *next; + char buf[BUFSIZ]; + + struct prefix p_firstbi_old; + struct prefix p_firstbi_new; + int replacing = 0; + const char *action_str = NULL; + struct prefix un_prefix; + + struct bgp *bgp; + bgp = bgp_get_default(); /* assume 1 instance for now */ + + switch (action) { + case FIF_ACTION_UPDATE: + action_str = "update"; + break; + case FIF_ACTION_WITHDRAW: + action_str = "withdraw"; + break; + case FIF_ACTION_KILL: + action_str = "kill"; + break; + default: + assert(0); + break; + } + + vnc_zlog_debug_verbose( + "%s: entry: %s: prefix %s/%d", __func__, action_str, + inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); + + memset(&p_firstbi_old, 0, sizeof(p_firstbi_old)); + memset(&p_firstbi_new, 0, sizeof(p_firstbi_new)); + + if (action == FIF_ACTION_UPDATE) { + /* + * Compare rt lists. If no intersection, don't import this route + * On a withdraw, peer and RD are sufficient to determine if + * we should act. + */ + if (!attr || !attr->ecommunity) { + + vnc_zlog_debug_verbose( + "%s: attr, extra, or ecommunity missing, not importing", + __func__); + return; + } #if RFAPI_REQUIRE_ENCAP_BEEC - if (!rfapiEcommunitiesMatchBeec (attr->ecommunity)) - { - vnc_zlog_debug_verbose ("%s: it=%p: no match for BGP Encapsulation ecommunity", - __func__, import_table); - return; - } + if (!rfapiEcommunitiesMatchBeec(attr->ecommunity)) { + vnc_zlog_debug_verbose( + "%s: it=%p: no match for BGP Encapsulation ecommunity", + __func__, import_table); + return; + } #endif - if (!rfapiEcommunitiesIntersect (import_table->rt_import_list, - attr->ecommunity)) - { - - vnc_zlog_debug_verbose ("%s: it=%p: no ecommunity intersection", - __func__, import_table); - return; - } - - /* - * Updates must also have a nexthop address - */ - memset (&un_prefix, 0, sizeof (un_prefix)); /* keep valgrind happy */ - if (rfapiGetNexthop (attr, &un_prefix)) - { - vnc_zlog_debug_verbose ("%s: missing nexthop address", __func__); - return; - } - } - - /* - * Figure out which radix tree the route would go into - */ - switch (afi) - { - case AFI_IP: - case AFI_IP6: - rt = import_table->imported_encap[afi]; - break; - - default: - zlog_err ("%s: bad afi %d", __func__, afi); - return; - } - - /* - * route_node_lookup returns a node only if there is at least - * one route attached. - */ - rn = route_node_lookup (rt, p); + if (!rfapiEcommunitiesIntersect(import_table->rt_import_list, + attr->ecommunity)) { + + vnc_zlog_debug_verbose( + "%s: it=%p: no ecommunity intersection", + __func__, import_table); + return; + } + + /* + * Updates must also have a nexthop address + */ + memset(&un_prefix, 0, + sizeof(un_prefix)); /* keep valgrind happy */ + if (rfapiGetNexthop(attr, &un_prefix)) { + vnc_zlog_debug_verbose("%s: missing nexthop address", + __func__); + return; + } + } + + /* + * Figure out which radix tree the route would go into + */ + switch (afi) { + case AFI_IP: + case AFI_IP6: + rt = import_table->imported_encap[afi]; + break; + + default: + zlog_err("%s: bad afi %d", __func__, afi); + return; + } + + /* + * route_node_lookup returns a node only if there is at least + * one route attached. + */ + rn = route_node_lookup(rt, p); #if DEBUG_ENCAP_MONITOR - vnc_zlog_debug_verbose ("%s: initial encap lookup(it=%p) rn=%p", - __func__, import_table, rn); + vnc_zlog_debug_verbose("%s: initial encap lookup(it=%p) rn=%p", + __func__, import_table, rn); #endif - if (rn) - { - - RFAPI_CHECK_REFCOUNT (rn, SAFI_ENCAP, 1); - route_unlock_node (rn); /* undo lock in route_node_lookup */ - - - /* - * capture nexthop of first bi - */ - if (rn->info) - { - rfapiNexthop2Prefix (((struct bgp_info *) (rn->info))->attr, - &p_firstbi_old); - } - - for (bi = rn->info; bi; bi = bi->next) - { - - /* - * Does this bgp_info refer to the same route - * as we are trying to add? - */ - vnc_zlog_debug_verbose ("%s: comparing BI %p", __func__, bi); - - - /* - * Compare RDs - * - * RD of import table bi is in bi->extra->vnc.import.rd - * RD of info_orig is in prd - */ - if (!bi->extra) - { - vnc_zlog_debug_verbose ("%s: no bi->extra", __func__); - continue; - } - if (prefix_cmp ((struct prefix *) &bi->extra->vnc.import.rd, - (struct prefix *) prd)) - { - - vnc_zlog_debug_verbose ("%s: prd does not match", __func__); - continue; - } - - /* - * Compare peers - */ - if (bi->peer != peer) - { - vnc_zlog_debug_verbose ("%s: peer does not match", __func__); - continue; - } - - vnc_zlog_debug_verbose ("%s: found matching bi", __func__); - - /* Same route. Delete this bi, replace with new one */ - - if (action == FIF_ACTION_WITHDRAW) - { - - vnc_zlog_debug_verbose ("%s: withdrawing at prefix %s/%d", - __func__, - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, - BUFSIZ), rn->p.prefixlen); - - rfapiBiStartWithdrawTimer (import_table, rn, bi, - afi, SAFI_ENCAP, - rfapiWithdrawTimerEncap); - - } - else - { - vnc_zlog_debug_verbose ("%s: %s at prefix %s/%d", - __func__, - ((action == - FIF_ACTION_KILL) ? "killing" : "replacing"), - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, - BUFSIZ), rn->p.prefixlen); - - /* - * If this route is waiting to be deleted because of - * a previous withdraw, we must cancel its timer. - */ - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) - && bi->extra->vnc.import.timer) - { - - struct thread *t = - (struct thread *) bi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; - - XFREE (MTYPE_RFAPI_WITHDRAW, wcb); - thread_cancel (t); - } - - if (action == FIF_ACTION_UPDATE) - { - rfapiBgpInfoDetach (rn, bi); - rfapiBgpInfoFree (bi); - replacing = 1; - } - else - { - /* - * Kill: do export stuff when removing bi - */ - struct rfapi_withdraw *wcb; - struct thread t; - - /* - * pretend we're an expiring timer - */ - wcb = - XCALLOC (MTYPE_RFAPI_WITHDRAW, - sizeof (struct rfapi_withdraw)); - wcb->info = bi; - wcb->node = rn; - wcb->import_table = import_table; - memset (&t, 0, sizeof (t)); - t.arg = wcb; - rfapiWithdrawTimerEncap (&t); /* frees wcb */ - } - } - - break; - } - } - - if (rn) - RFAPI_CHECK_REFCOUNT (rn, SAFI_ENCAP, replacing ? 1 : 0); - - if (action == FIF_ACTION_WITHDRAW || action == FIF_ACTION_KILL) - return; - - info_new = rfapiBgpInfoCreate (attr, peer, rfd, prd, type, sub_type, NULL); - - if (rn) - { - if (!replacing) - route_lock_node (rn); /* incr ref count for new BI */ - } - else - { - rn = route_node_get (rt, p); - } - - vnc_zlog_debug_verbose ("%s: (afi=%d, rn=%p) inserting at prefix %s/%d", - __func__, - afi, - rn, - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), - rn->p.prefixlen); - - rfapiBgpInfoAttachSorted (rn, info_new, afi, SAFI_ENCAP); - - /* - * Delete holddown routes from same NVE. See details in - * rfapiBgpInfoFilteredImportVPN() - */ - for (bi = info_new->next; bi; bi = next) - { - - struct prefix pfx_un; - int un_match = 0; - - next = bi->next; - if (!CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; - - /* - * We already match the VN address (it is the prefix - * of the route node) - */ - - if (!rfapiGetNexthop (bi->attr, &pfx_un) && - prefix_same (&pfx_un, &un_prefix)) - { - - un_match = 1; - } - - if (!un_match) - continue; - - vnc_zlog_debug_verbose ("%s: removing holddown bi matching NVE of new route", - __func__); - if (bi->extra->vnc.import.timer) - { - struct thread *t = (struct thread *) bi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; - - XFREE (MTYPE_RFAPI_WITHDRAW, wcb); - thread_cancel (t); - } - rfapiExpireEncapNow (import_table, rn, bi); - } - - rfapiNexthop2Prefix (((struct bgp_info *) (rn->info))->attr, - &p_firstbi_new); - - /* - * If the nexthop address of the selected Encap route (i.e., - * the UN address) has changed, then we must update the VPN - * routes that refer to this Encap route and possibly force - * rfapi callbacks. - */ - if (rfapiAttrNexthopAddrDifferent (&p_firstbi_old, &p_firstbi_new)) - { - - struct rfapi_monitor_encap *m; - struct rfapi_monitor_encap *mnext; - - struct route_node *referenced_vpn_prefix; - - /* - * Optimized approach: build radix tree on the fly to - * hold list of VPN nodes referenced by the ENCAP monitors - * - * The nodes in this table correspond to prefixes of VPN routes. - * The "info" pointer of the node points to a chain of - * struct rfapi_monitor_encap, each of which refers to a - * specific VPN node. - */ - struct route_table *referenced_vpn_table; - - referenced_vpn_table = route_table_init (); - assert (referenced_vpn_table); - - /* - * iterate over the set of monitors at this ENCAP node. - */ + if (rn) { + + RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 1); + route_unlock_node(rn); /* undo lock in route_node_lookup */ + + + /* + * capture nexthop of first bi + */ + if (rn->info) { + rfapiNexthop2Prefix( + ((struct bgp_info *)(rn->info))->attr, + &p_firstbi_old); + } + + for (bi = rn->info; bi; bi = bi->next) { + + /* + * Does this bgp_info refer to the same route + * as we are trying to add? + */ + vnc_zlog_debug_verbose("%s: comparing BI %p", __func__, + bi); + + + /* + * Compare RDs + * + * RD of import table bi is in bi->extra->vnc.import.rd + * RD of info_orig is in prd + */ + if (!bi->extra) { + vnc_zlog_debug_verbose("%s: no bi->extra", + __func__); + continue; + } + if (prefix_cmp( + (struct prefix *)&bi->extra->vnc.import.rd, + (struct prefix *)prd)) { + + vnc_zlog_debug_verbose("%s: prd does not match", + __func__); + continue; + } + + /* + * Compare peers + */ + if (bi->peer != peer) { + vnc_zlog_debug_verbose( + "%s: peer does not match", __func__); + continue; + } + + vnc_zlog_debug_verbose("%s: found matching bi", + __func__); + + /* Same route. Delete this bi, replace with new one */ + + if (action == FIF_ACTION_WITHDRAW) { + + vnc_zlog_debug_verbose( + "%s: withdrawing at prefix %s/%d", + __func__, + inet_ntop(rn->p.family, &rn->p.u.prefix, + buf, BUFSIZ), + rn->p.prefixlen); + + rfapiBiStartWithdrawTimer( + import_table, rn, bi, afi, SAFI_ENCAP, + rfapiWithdrawTimerEncap); + + } else { + vnc_zlog_debug_verbose( + "%s: %s at prefix %s/%d", __func__, + ((action == FIF_ACTION_KILL) + ? "killing" + : "replacing"), + inet_ntop(rn->p.family, &rn->p.u.prefix, + buf, BUFSIZ), + rn->p.prefixlen); + + /* + * If this route is waiting to be deleted + * because of + * a previous withdraw, we must cancel its + * timer. + */ + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) + && bi->extra->vnc.import.timer) { + + struct thread *t = + (struct thread *)bi->extra->vnc + .import.timer; + struct rfapi_withdraw *wcb = t->arg; + + XFREE(MTYPE_RFAPI_WITHDRAW, wcb); + thread_cancel(t); + } + + if (action == FIF_ACTION_UPDATE) { + rfapiBgpInfoDetach(rn, bi); + rfapiBgpInfoFree(bi); + replacing = 1; + } else { + /* + * Kill: do export stuff when removing + * bi + */ + struct rfapi_withdraw *wcb; + struct thread t; + + /* + * pretend we're an expiring timer + */ + wcb = XCALLOC( + MTYPE_RFAPI_WITHDRAW, + sizeof(struct rfapi_withdraw)); + wcb->info = bi; + wcb->node = rn; + wcb->import_table = import_table; + memset(&t, 0, sizeof(t)); + t.arg = wcb; + rfapiWithdrawTimerEncap( + &t); /* frees wcb */ + } + } + + break; + } + } + + if (rn) + RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, replacing ? 1 : 0); + + if (action == FIF_ACTION_WITHDRAW || action == FIF_ACTION_KILL) + return; + + info_new = + rfapiBgpInfoCreate(attr, peer, rfd, prd, type, sub_type, NULL); + + if (rn) { + if (!replacing) + route_lock_node(rn); /* incr ref count for new BI */ + } else { + rn = route_node_get(rt, p); + } + + vnc_zlog_debug_verbose( + "%s: (afi=%d, rn=%p) inserting at prefix %s/%d", __func__, afi, + rn, inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), + rn->p.prefixlen); + + rfapiBgpInfoAttachSorted(rn, info_new, afi, SAFI_ENCAP); + + /* + * Delete holddown routes from same NVE. See details in + * rfapiBgpInfoFilteredImportVPN() + */ + for (bi = info_new->next; bi; bi = next) { + + struct prefix pfx_un; + int un_match = 0; + + next = bi->next; + if (!CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + continue; + + /* + * We already match the VN address (it is the prefix + * of the route node) + */ + + if (!rfapiGetNexthop(bi->attr, &pfx_un) + && prefix_same(&pfx_un, &un_prefix)) { + + un_match = 1; + } + + if (!un_match) + continue; + + vnc_zlog_debug_verbose( + "%s: removing holddown bi matching NVE of new route", + __func__); + if (bi->extra->vnc.import.timer) { + struct thread *t = + (struct thread *)bi->extra->vnc.import.timer; + struct rfapi_withdraw *wcb = t->arg; + + XFREE(MTYPE_RFAPI_WITHDRAW, wcb); + thread_cancel(t); + } + rfapiExpireEncapNow(import_table, rn, bi); + } + + rfapiNexthop2Prefix(((struct bgp_info *)(rn->info))->attr, + &p_firstbi_new); + + /* + * If the nexthop address of the selected Encap route (i.e., + * the UN address) has changed, then we must update the VPN + * routes that refer to this Encap route and possibly force + * rfapi callbacks. + */ + if (rfapiAttrNexthopAddrDifferent(&p_firstbi_old, &p_firstbi_new)) { + + struct rfapi_monitor_encap *m; + struct rfapi_monitor_encap *mnext; + + struct route_node *referenced_vpn_prefix; + + /* + * Optimized approach: build radix tree on the fly to + * hold list of VPN nodes referenced by the ENCAP monitors + * + * The nodes in this table correspond to prefixes of VPN routes. + * The "info" pointer of the node points to a chain of + * struct rfapi_monitor_encap, each of which refers to a + * specific VPN node. + */ + struct route_table *referenced_vpn_table; + + referenced_vpn_table = route_table_init(); + assert(referenced_vpn_table); + +/* + * iterate over the set of monitors at this ENCAP node. + */ #if DEBUG_ENCAP_MONITOR - vnc_zlog_debug_verbose ("%s: examining monitors at rn=%p", __func__, rn); + vnc_zlog_debug_verbose("%s: examining monitors at rn=%p", + __func__, rn); #endif - for (m = RFAPI_MONITOR_ENCAP (rn); m; m = m->next) - { - - /* - * For each referenced bi/route, copy the ENCAP route's - * nexthop to the VPN route's cached UN address field and set - * the address family of the cached UN address field. - */ - rfapiCopyUnEncap2VPN (info_new, m->bi); - if (!CHECK_FLAG (m->bi->flags, BGP_INFO_VALID)) - { - SET_FLAG (m->bi->flags, BGP_INFO_VALID); - if (VALID_INTERIOR_TYPE (m->bi->type)) - RFAPI_MONITOR_EXTERIOR (m->node)->valid_interior_count++; - vnc_import_bgp_exterior_add_route_interior (bgp, - import_table, - m->node, m->bi); - } - - /* - * Build a list of unique VPN nodes referenced by these monitors - * - * There could be more than one VPN node here with a given - * prefix. Those are currently in an unsorted linear list - * per prefix. - */ - - referenced_vpn_prefix = - route_node_get (referenced_vpn_table, &m->node->p); - assert (referenced_vpn_prefix); - for (mnext = referenced_vpn_prefix->info; mnext; - mnext = mnext->next) - { - - if (mnext->node == m->node) - break; - } - - if (mnext) - { - /* - * already have an entry for this VPN node - */ - route_unlock_node (referenced_vpn_prefix); - } - else - { - mnext = XCALLOC (MTYPE_RFAPI_MONITOR_ENCAP, - sizeof (struct rfapi_monitor_encap)); - assert (mnext); - mnext->node = m->node; - mnext->next = referenced_vpn_prefix->info; - referenced_vpn_prefix->info = mnext; - } - - } - - /* - * for each VPN node referenced in the ENCAP monitors: - */ - for (referenced_vpn_prefix = route_top (referenced_vpn_table); - referenced_vpn_prefix; - referenced_vpn_prefix = route_next (referenced_vpn_prefix)) - { - - while ((m = referenced_vpn_prefix->info)) - { - - struct route_node *n; - - rfapiMonitorMoveLonger (m->node); - for (n = m->node; n; n = n->parent) - { - //rfapiDoRouteCallback(import_table, n, NULL); - } - rfapiMonitorItNodeChanged (import_table, m->node, NULL); - - referenced_vpn_prefix->info = m->next; - route_unlock_node (referenced_vpn_prefix); - XFREE (MTYPE_RFAPI_MONITOR_ENCAP, m); - } - - } - route_table_finish (referenced_vpn_table); - } - - RFAPI_CHECK_REFCOUNT (rn, SAFI_ENCAP, 0); + for (m = RFAPI_MONITOR_ENCAP(rn); m; m = m->next) { + + /* + * For each referenced bi/route, copy the ENCAP route's + * nexthop to the VPN route's cached UN address field + * and set + * the address family of the cached UN address field. + */ + rfapiCopyUnEncap2VPN(info_new, m->bi); + if (!CHECK_FLAG(m->bi->flags, BGP_INFO_VALID)) { + SET_FLAG(m->bi->flags, BGP_INFO_VALID); + if (VALID_INTERIOR_TYPE(m->bi->type)) + RFAPI_MONITOR_EXTERIOR(m->node) + ->valid_interior_count++; + vnc_import_bgp_exterior_add_route_interior( + bgp, import_table, m->node, m->bi); + } + + /* + * Build a list of unique VPN nodes referenced by these + * monitors + * + * There could be more than one VPN node here with a + * given + * prefix. Those are currently in an unsorted linear + * list + * per prefix. + */ + + referenced_vpn_prefix = route_node_get( + referenced_vpn_table, &m->node->p); + assert(referenced_vpn_prefix); + for (mnext = referenced_vpn_prefix->info; mnext; + mnext = mnext->next) { + + if (mnext->node == m->node) + break; + } + + if (mnext) { + /* + * already have an entry for this VPN node + */ + route_unlock_node(referenced_vpn_prefix); + } else { + mnext = XCALLOC( + MTYPE_RFAPI_MONITOR_ENCAP, + sizeof(struct rfapi_monitor_encap)); + assert(mnext); + mnext->node = m->node; + mnext->next = referenced_vpn_prefix->info; + referenced_vpn_prefix->info = mnext; + } + } + + /* + * for each VPN node referenced in the ENCAP monitors: + */ + for (referenced_vpn_prefix = route_top(referenced_vpn_table); + referenced_vpn_prefix; referenced_vpn_prefix = route_next( + referenced_vpn_prefix)) { + + while ((m = referenced_vpn_prefix->info)) { + + struct route_node *n; + + rfapiMonitorMoveLonger(m->node); + for (n = m->node; n; n = n->parent) { + // rfapiDoRouteCallback(import_table, n, + // NULL); + } + rfapiMonitorItNodeChanged(import_table, m->node, + NULL); + + referenced_vpn_prefix->info = m->next; + route_unlock_node(referenced_vpn_prefix); + XFREE(MTYPE_RFAPI_MONITOR_ENCAP, m); + } + } + route_table_finish(referenced_vpn_table); + } + + RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 0); } -static void -rfapiExpireVpnNow ( - struct rfapi_import_table *it, - struct route_node *rn, - struct bgp_info *bi, - int lockoffset) +static void rfapiExpireVpnNow(struct rfapi_import_table *it, + struct route_node *rn, struct bgp_info *bi, + int lockoffset) { - struct rfapi_withdraw *wcb; - struct thread t; - - /* - * pretend we're an expiring timer - */ - wcb = XCALLOC (MTYPE_RFAPI_WITHDRAW, sizeof (struct rfapi_withdraw)); - wcb->info = bi; - wcb->node = rn; - wcb->import_table = it; - wcb->lockoffset = lockoffset; - memset (&t, 0, sizeof (t)); - t.arg = wcb; - rfapiWithdrawTimerVPN (&t); /* frees wcb */ + struct rfapi_withdraw *wcb; + struct thread t; + + /* + * pretend we're an expiring timer + */ + wcb = XCALLOC(MTYPE_RFAPI_WITHDRAW, sizeof(struct rfapi_withdraw)); + wcb->info = bi; + wcb->node = rn; + wcb->import_table = it; + wcb->lockoffset = lockoffset; + memset(&t, 0, sizeof(t)); + t.arg = wcb; + rfapiWithdrawTimerVPN(&t); /* frees wcb */ } -/* +/* * import a bgp_info if its route target list intersects with the * import table's route target list */ -void -rfapiBgpInfoFilteredImportVPN ( - struct rfapi_import_table *import_table, - int action, - struct peer *peer, - void *rfd, /* set for looped back routes */ - struct prefix *p, - struct prefix *aux_prefix, /* AFI_L2VPN: optional IP */ - afi_t afi, - struct prefix_rd *prd, - struct attr *attr, /* part of bgp_info */ - u_char type, /* part of bgp_info */ - u_char sub_type, /* part of bgp_info */ - uint32_t *label) /* part of bgp_info */ +void rfapiBgpInfoFilteredImportVPN( + struct rfapi_import_table *import_table, int action, struct peer *peer, + void *rfd, /* set for looped back routes */ + struct prefix *p, + struct prefix *aux_prefix, /* AFI_L2VPN: optional IP */ + afi_t afi, struct prefix_rd *prd, + struct attr *attr, /* part of bgp_info */ + u_char type, /* part of bgp_info */ + u_char sub_type, /* part of bgp_info */ + uint32_t *label) /* part of bgp_info */ { - struct route_table *rt = NULL; - struct route_node *rn; - struct route_node *n; - struct bgp_info *info_new; - struct bgp_info *bi; - struct bgp_info *next; - char buf[BUFSIZ]; - struct prefix vn_prefix; - struct prefix un_prefix; - int un_prefix_valid = 0; - struct route_node *ern; - int replacing = 0; - int original_had_routes = 0; - struct prefix original_nexthop; - const char *action_str = NULL; - int is_it_ce = 0; - - struct bgp *bgp; - bgp = bgp_get_default (); /* assume 1 instance for now */ - - switch (action) - { - case FIF_ACTION_UPDATE: - action_str = "update"; - break; - case FIF_ACTION_WITHDRAW: - action_str = "withdraw"; - break; - case FIF_ACTION_KILL: - action_str = "kill"; - break; - default: - assert (0); - break; - } - - if (import_table == bgp->rfapi->it_ce) - is_it_ce = 1; - - vnc_zlog_debug_verbose ("%s: entry: %s%s: prefix %s/%d: it %p, afi %s", __func__, - (is_it_ce ? "CE-IT " : ""), - action_str, - rfapi_ntop (p->family, &p->u.prefix, buf, BUFSIZ), - p->prefixlen, import_table, afi2str (afi)); - - VNC_ITRCCK; - - /* - * Compare rt lists. If no intersection, don't import this route - * On a withdraw, peer and RD are sufficient to determine if - * we should act. - */ - if (action == FIF_ACTION_UPDATE) - { - if (!attr || !attr->ecommunity) - { - - vnc_zlog_debug_verbose ("%s: attr, extra, or ecommunity missing, not importing", - __func__); - return; - } - if ((import_table != bgp->rfapi->it_ce) && - !rfapiEcommunitiesIntersect (import_table->rt_import_list, - attr->ecommunity)) - { - - vnc_zlog_debug_verbose ("%s: it=%p: no ecommunity intersection", - __func__, import_table); - return; - } - - memset (&vn_prefix, 0, sizeof (vn_prefix)); /* keep valgrind happy */ - if (rfapiGetNexthop (attr, &vn_prefix)) - { - /* missing nexthop address would be a bad, bad thing */ - vnc_zlog_debug_verbose ("%s: missing nexthop", __func__); - return; - } - } - - /* - * Figure out which radix tree the route would go into - */ - switch (afi) - { - case AFI_IP: - case AFI_IP6: - case AFI_L2VPN: - rt = import_table->imported_vpn[afi]; - break; - - default: - zlog_err ("%s: bad afi %d", __func__, afi); - return; - } - - /* clear it */ - memset (&original_nexthop, 0, sizeof (original_nexthop)); - - /* - * route_node_lookup returns a node only if there is at least - * one route attached. - */ - rn = route_node_lookup (rt, p); - - vnc_zlog_debug_verbose ("%s: rn=%p", __func__, rn); - - if (rn) - { - - RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, 1); - route_unlock_node (rn); /* undo lock in route_node_lookup */ - - if (rn->info) - original_had_routes = 1; - - if (VNC_DEBUG(VERBOSE)) - { - vnc_zlog_debug_verbose ("%s: showing IT node on entry", __func__); - rfapiShowItNode (NULL, rn); /* debug */ - } - - /* - * Look for same route (will have same RD and peer) - */ - bi = rfapiItBiIndexSearch (rn, prd, peer, aux_prefix); - - if (bi) - { - - /* - * This was an old test when we iterated over the - * BIs linearly. Since we're now looking up with - * RD and peer, comparing types should not be - * needed. Changed to assertion. - * - * Compare types. Doing so prevents a RFP-originated - * route from matching an imported route, for example. - */ - assert (bi->type == type); - - vnc_zlog_debug_verbose ("%s: found matching bi", __func__); - - /* - * In the special CE table, withdrawals occur without holddown - */ - if (import_table == bgp->rfapi->it_ce) - { - vnc_direct_bgp_del_route_ce (bgp, rn, bi); - if (action == FIF_ACTION_WITHDRAW) - action = FIF_ACTION_KILL; - } - - if (action == FIF_ACTION_WITHDRAW) - { - - int washolddown = CHECK_FLAG (bi->flags, BGP_INFO_REMOVED); - - vnc_zlog_debug_verbose ("%s: withdrawing at prefix %s/%d%s", - __func__, - rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, - BUFSIZ), rn->p.prefixlen, - (washolddown ? " (already being withdrawn)" : "")); - - VNC_ITRCCK; - if (!washolddown) - { - rfapiBiStartWithdrawTimer (import_table, rn, bi, - afi, SAFI_MPLS_VPN, - rfapiWithdrawTimerVPN); - - RFAPI_UPDATE_ITABLE_COUNT (bi, import_table, afi, -1); - import_table->holddown_count[afi] += 1; - } - VNC_ITRCCK; - } - else - { - vnc_zlog_debug_verbose ("%s: %s at prefix %s/%d", - __func__, - ((action == - FIF_ACTION_KILL) ? "killing" : "replacing"), - rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, - BUFSIZ), rn->p.prefixlen); - - /* - * If this route is waiting to be deleted because of - * a previous withdraw, we must cancel its timer. - */ - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && - bi->extra->vnc.import.timer) - { - - struct thread *t = - (struct thread *) bi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; - - XFREE (MTYPE_RFAPI_WITHDRAW, wcb); - thread_cancel (t); - - import_table->holddown_count[afi] -= 1; - RFAPI_UPDATE_ITABLE_COUNT (bi, import_table, afi, 1); - } - /* - * decrement remote count (if route is remote) because - * we are going to remove it below - */ - RFAPI_UPDATE_ITABLE_COUNT (bi, import_table, afi, -1); - if (action == FIF_ACTION_UPDATE) - { - replacing = 1; - - /* - * make copy of original nexthop so we can see if it changed - */ - rfapiGetNexthop (bi->attr, &original_nexthop); - - /* - * remove bi without doing any export processing - */ - if (CHECK_FLAG (bi->flags, BGP_INFO_VALID) - && VALID_INTERIOR_TYPE (bi->type)) - RFAPI_MONITOR_EXTERIOR (rn)->valid_interior_count--; - rfapiItBiIndexDel (rn, bi); - rfapiBgpInfoDetach (rn, bi); - rfapiMonitorEncapDelete (bi); - vnc_import_bgp_exterior_del_route_interior (bgp, - import_table, - rn, bi); - rfapiBgpInfoFree (bi); - } - else - { - /* Kill */ - /* - * remove bi and do export processing - */ - import_table->holddown_count[afi] += 1; - rfapiExpireVpnNow (import_table, rn, bi, 0); - } - - } - } - - } - - if (rn) - RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, replacing ? 1 : 0); - - if (action == FIF_ACTION_WITHDRAW || action == FIF_ACTION_KILL) - { - VNC_ITRCCK; - return; - } - - info_new = rfapiBgpInfoCreate (attr, peer, rfd, prd, type, sub_type, label); - - /* - * lookup un address in encap table - */ - ern = route_node_match (import_table->imported_encap[afi], &vn_prefix); - if (ern) - { - rfapiCopyUnEncap2VPN (ern->info, info_new); - route_unlock_node (ern); /* undo lock in route_note_match */ - } - else - { - char buf[BUFSIZ]; - prefix2str (&vn_prefix, buf, sizeof (buf)); - buf[BUFSIZ - 1] = 0; - /* Not a big deal, just means VPN route got here first */ - vnc_zlog_debug_verbose ("%s: no encap route for vn addr %s", __func__, buf); - info_new->extra->vnc.import.un_family = 0; - } - - if (rn) - { - if (!replacing) - route_lock_node (rn); - } - else - { - /* - * No need to increment reference count, so only "get" - * if the node is not there already - */ - rn = route_node_get (rt, p); - } - - /* - * For ethernet routes, if there is an accompanying IP address, - * save it in the bi - */ - if ((AFI_L2VPN == afi) && aux_prefix) - { - - vnc_zlog_debug_verbose ("%s: setting BI's aux_prefix", __func__); - info_new->extra->vnc.import.aux_prefix = *aux_prefix; - } - - vnc_zlog_debug_verbose ("%s: inserting bi %p at prefix %s/%d #%d", - __func__, - info_new, - rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), - rn->p.prefixlen, rn->lock); - - rfapiBgpInfoAttachSorted (rn, info_new, afi, SAFI_MPLS_VPN); - rfapiItBiIndexAdd (rn, info_new); - if (!rfapiGetUnAddrOfVpnBi (info_new, NULL)) - { - if (VALID_INTERIOR_TYPE (info_new->type)) - RFAPI_MONITOR_EXTERIOR (rn)->valid_interior_count++; - SET_FLAG (info_new->flags, BGP_INFO_VALID); - } - RFAPI_UPDATE_ITABLE_COUNT (info_new, import_table, afi, 1); - vnc_import_bgp_exterior_add_route_interior (bgp, import_table, rn, - info_new); - - if (import_table == bgp->rfapi->it_ce) - vnc_direct_bgp_add_route_ce (bgp, rn, info_new); - - if (VNC_DEBUG(VERBOSE)) - { - vnc_zlog_debug_verbose ("%s: showing IT node", __func__); - rfapiShowItNode (NULL, rn); /* debug */ - } - - rfapiMonitorEncapAdd (import_table, &vn_prefix, rn, info_new); - - if (!rfapiGetUnAddrOfVpnBi (info_new, &un_prefix)) - { - - /* - * if we have a valid UN address (either via Encap route - * or via tunnel attribute), then we should attempt - * to move any monitors at less-specific nodes to this node - */ - rfapiMonitorMoveLonger (rn); - - un_prefix_valid = 1; - - } - - /* - * 101129 Enhancement: if we add a route (implication: it is not - * in holddown), delete all other routes from this nve at this - * node that are in holddown, regardless of peer. - * - * Reasons it's OK to do that: - * - * - if the holddown route being deleted originally came from BGP VPN, - * it is already gone from BGP (implication of holddown), so there - * won't be any added inconsistency with the BGP RIB. - * - * - once a fresh route is added at a prefix, any routes in holddown - * at that prefix will not show up in RFP responses, so deleting - * the holddown routes won't affect the contents of responses. - * - * - lifetimes are supposed to be consistent, so there should not - * be a case where the fresh route has a shorter lifetime than - * the holddown route, so we don't expect the fresh route to - * disappear and complete its holddown time before the existing - * holddown routes time out. Therefore, we won't have a situation - * where we expect the existing holddown routes to be hidden and - * then to reappear sometime later (as holddown routes) in a - * RFP response. - * - * Among other things, this would enable us to skirt the problem - * of local holddown routes that refer to NVE descriptors that - * have already been closed (if the same NVE triggers a subsequent - * rfapi_open(), the new peer is different and doesn't match the - * peer of the holddown route, so the stale holddown route still - * hangs around until it times out instead of just being replaced - * by the fresh route). - */ - /* - * We know that the new bi will have been inserted before any routes - * in holddown, so we can skip any that came before it - */ - for (bi = info_new->next; bi; bi = next) - { - - struct prefix pfx_vn; - struct prefix pfx_un; - int un_match = 0; - int remote_peer_match = 0; - - next = bi->next; - - /* - * Must be holddown - */ - if (!CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; - - /* - * Must match VN address (nexthop of VPN route) - */ - if (rfapiGetNexthop (bi->attr, &pfx_vn)) - continue; - if (!prefix_same (&pfx_vn, &vn_prefix)) - continue; - - if (un_prefix_valid && /* new route UN addr */ - !rfapiGetUnAddrOfVpnBi (bi, &pfx_un) && /* old route UN addr */ - prefix_same (&pfx_un, &un_prefix)) - { /* compare */ - un_match = 1; - } - if (!RFAPI_LOCAL_BI (bi) && !RFAPI_LOCAL_BI (info_new) && - sockunion_same (&bi->peer->su, &info_new->peer->su)) - { - /* old & new are both remote, same peer */ - remote_peer_match = 1; - } - - if (!un_match & !remote_peer_match) - continue; - - vnc_zlog_debug_verbose ("%s: removing holddown bi matching NVE of new route", - __func__); - if (bi->extra->vnc.import.timer) - { - struct thread *t = (struct thread *) bi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; - - XFREE (MTYPE_RFAPI_WITHDRAW, wcb); - thread_cancel (t); - } - rfapiExpireVpnNow (import_table, rn, bi, 0); - } - - if (!original_had_routes) - { - /* - * We went from 0 usable routes to 1 usable route. Perform the - * "Adding a Route" export process. - */ - vnc_direct_bgp_add_prefix (bgp, import_table, rn); - vnc_zebra_add_prefix (bgp, import_table, rn); - } - else - { - /* - * Check for nexthop change event - * Note: the prefix_same() test below detects two situations: - * 1. route is replaced, new route has different nexthop - * 2. new route is added (original_nexthop is 0) - */ - struct prefix new_nexthop; - - rfapiGetNexthop (attr, &new_nexthop); - if (!prefix_same (&original_nexthop, &new_nexthop)) - { - /* - * nexthop change event - * vnc_direct_bgp_add_prefix() will recompute VN addr ecommunity - */ - vnc_direct_bgp_add_prefix (bgp, import_table, rn); - } - } - - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) - { - for (n = rn; n; n = n->parent) - { - //rfapiDoRouteCallback(import_table, n, NULL); - } - rfapiMonitorItNodeChanged (import_table, rn, NULL); - } - RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, 0); - VNC_ITRCCK; + struct route_table *rt = NULL; + struct route_node *rn; + struct route_node *n; + struct bgp_info *info_new; + struct bgp_info *bi; + struct bgp_info *next; + char buf[BUFSIZ]; + struct prefix vn_prefix; + struct prefix un_prefix; + int un_prefix_valid = 0; + struct route_node *ern; + int replacing = 0; + int original_had_routes = 0; + struct prefix original_nexthop; + const char *action_str = NULL; + int is_it_ce = 0; + + struct bgp *bgp; + bgp = bgp_get_default(); /* assume 1 instance for now */ + + switch (action) { + case FIF_ACTION_UPDATE: + action_str = "update"; + break; + case FIF_ACTION_WITHDRAW: + action_str = "withdraw"; + break; + case FIF_ACTION_KILL: + action_str = "kill"; + break; + default: + assert(0); + break; + } + + if (import_table == bgp->rfapi->it_ce) + is_it_ce = 1; + + vnc_zlog_debug_verbose("%s: entry: %s%s: prefix %s/%d: it %p, afi %s", + __func__, (is_it_ce ? "CE-IT " : ""), action_str, + rfapi_ntop(p->family, &p->u.prefix, buf, BUFSIZ), + p->prefixlen, import_table, afi2str(afi)); + + VNC_ITRCCK; + + /* + * Compare rt lists. If no intersection, don't import this route + * On a withdraw, peer and RD are sufficient to determine if + * we should act. + */ + if (action == FIF_ACTION_UPDATE) { + if (!attr || !attr->ecommunity) { + + vnc_zlog_debug_verbose( + "%s: attr, extra, or ecommunity missing, not importing", + __func__); + return; + } + if ((import_table != bgp->rfapi->it_ce) + && !rfapiEcommunitiesIntersect(import_table->rt_import_list, + attr->ecommunity)) { + + vnc_zlog_debug_verbose( + "%s: it=%p: no ecommunity intersection", + __func__, import_table); + return; + } + + memset(&vn_prefix, 0, + sizeof(vn_prefix)); /* keep valgrind happy */ + if (rfapiGetNexthop(attr, &vn_prefix)) { + /* missing nexthop address would be a bad, bad thing */ + vnc_zlog_debug_verbose("%s: missing nexthop", __func__); + return; + } + } + + /* + * Figure out which radix tree the route would go into + */ + switch (afi) { + case AFI_IP: + case AFI_IP6: + case AFI_L2VPN: + rt = import_table->imported_vpn[afi]; + break; + + default: + zlog_err("%s: bad afi %d", __func__, afi); + return; + } + + /* clear it */ + memset(&original_nexthop, 0, sizeof(original_nexthop)); + + /* + * route_node_lookup returns a node only if there is at least + * one route attached. + */ + rn = route_node_lookup(rt, p); + + vnc_zlog_debug_verbose("%s: rn=%p", __func__, rn); + + if (rn) { + + RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 1); + route_unlock_node(rn); /* undo lock in route_node_lookup */ + + if (rn->info) + original_had_routes = 1; + + if (VNC_DEBUG(VERBOSE)) { + vnc_zlog_debug_verbose("%s: showing IT node on entry", + __func__); + rfapiShowItNode(NULL, rn); /* debug */ + } + + /* + * Look for same route (will have same RD and peer) + */ + bi = rfapiItBiIndexSearch(rn, prd, peer, aux_prefix); + + if (bi) { + + /* + * This was an old test when we iterated over the + * BIs linearly. Since we're now looking up with + * RD and peer, comparing types should not be + * needed. Changed to assertion. + * + * Compare types. Doing so prevents a RFP-originated + * route from matching an imported route, for example. + */ + assert(bi->type == type); + + vnc_zlog_debug_verbose("%s: found matching bi", + __func__); + + /* + * In the special CE table, withdrawals occur without + * holddown + */ + if (import_table == bgp->rfapi->it_ce) { + vnc_direct_bgp_del_route_ce(bgp, rn, bi); + if (action == FIF_ACTION_WITHDRAW) + action = FIF_ACTION_KILL; + } + + if (action == FIF_ACTION_WITHDRAW) { + + int washolddown = + CHECK_FLAG(bi->flags, BGP_INFO_REMOVED); + + vnc_zlog_debug_verbose( + "%s: withdrawing at prefix %s/%d%s", + __func__, rfapi_ntop(rn->p.family, + &rn->p.u.prefix, + buf, BUFSIZ), + rn->p.prefixlen, + (washolddown + ? " (already being withdrawn)" + : "")); + + VNC_ITRCCK; + if (!washolddown) { + rfapiBiStartWithdrawTimer( + import_table, rn, bi, afi, + SAFI_MPLS_VPN, + rfapiWithdrawTimerVPN); + + RFAPI_UPDATE_ITABLE_COUNT( + bi, import_table, afi, -1); + import_table->holddown_count[afi] += 1; + } + VNC_ITRCCK; + } else { + vnc_zlog_debug_verbose( + "%s: %s at prefix %s/%d", __func__, + ((action == FIF_ACTION_KILL) + ? "killing" + : "replacing"), + rfapi_ntop(rn->p.family, + &rn->p.u.prefix, buf, + BUFSIZ), + rn->p.prefixlen); + + /* + * If this route is waiting to be deleted + * because of + * a previous withdraw, we must cancel its + * timer. + */ + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) + && bi->extra->vnc.import.timer) { + + struct thread *t = + (struct thread *)bi->extra->vnc + .import.timer; + struct rfapi_withdraw *wcb = t->arg; + + XFREE(MTYPE_RFAPI_WITHDRAW, wcb); + thread_cancel(t); + + import_table->holddown_count[afi] -= 1; + RFAPI_UPDATE_ITABLE_COUNT( + bi, import_table, afi, 1); + } + /* + * decrement remote count (if route is remote) + * because + * we are going to remove it below + */ + RFAPI_UPDATE_ITABLE_COUNT(bi, import_table, afi, + -1); + if (action == FIF_ACTION_UPDATE) { + replacing = 1; + + /* + * make copy of original nexthop so we + * can see if it changed + */ + rfapiGetNexthop(bi->attr, + &original_nexthop); + + /* + * remove bi without doing any export + * processing + */ + if (CHECK_FLAG(bi->flags, + BGP_INFO_VALID) + && VALID_INTERIOR_TYPE(bi->type)) + RFAPI_MONITOR_EXTERIOR(rn) + ->valid_interior_count--; + rfapiItBiIndexDel(rn, bi); + rfapiBgpInfoDetach(rn, bi); + rfapiMonitorEncapDelete(bi); + vnc_import_bgp_exterior_del_route_interior( + bgp, import_table, rn, bi); + rfapiBgpInfoFree(bi); + } else { + /* Kill */ + /* + * remove bi and do export processing + */ + import_table->holddown_count[afi] += 1; + rfapiExpireVpnNow(import_table, rn, bi, + 0); + } + } + } + } + + if (rn) + RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, replacing ? 1 : 0); + + if (action == FIF_ACTION_WITHDRAW || action == FIF_ACTION_KILL) { + VNC_ITRCCK; + return; + } + + info_new = + rfapiBgpInfoCreate(attr, peer, rfd, prd, type, sub_type, label); + + /* + * lookup un address in encap table + */ + ern = route_node_match(import_table->imported_encap[afi], &vn_prefix); + if (ern) { + rfapiCopyUnEncap2VPN(ern->info, info_new); + route_unlock_node(ern); /* undo lock in route_note_match */ + } else { + char buf[BUFSIZ]; + prefix2str(&vn_prefix, buf, sizeof(buf)); + buf[BUFSIZ - 1] = 0; + /* Not a big deal, just means VPN route got here first */ + vnc_zlog_debug_verbose("%s: no encap route for vn addr %s", + __func__, buf); + info_new->extra->vnc.import.un_family = 0; + } + + if (rn) { + if (!replacing) + route_lock_node(rn); + } else { + /* + * No need to increment reference count, so only "get" + * if the node is not there already + */ + rn = route_node_get(rt, p); + } + + /* + * For ethernet routes, if there is an accompanying IP address, + * save it in the bi + */ + if ((AFI_L2VPN == afi) && aux_prefix) { + + vnc_zlog_debug_verbose("%s: setting BI's aux_prefix", __func__); + info_new->extra->vnc.import.aux_prefix = *aux_prefix; + } + + vnc_zlog_debug_verbose( + "%s: inserting bi %p at prefix %s/%d #%d", __func__, info_new, + rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), + rn->p.prefixlen, rn->lock); + + rfapiBgpInfoAttachSorted(rn, info_new, afi, SAFI_MPLS_VPN); + rfapiItBiIndexAdd(rn, info_new); + if (!rfapiGetUnAddrOfVpnBi(info_new, NULL)) { + if (VALID_INTERIOR_TYPE(info_new->type)) + RFAPI_MONITOR_EXTERIOR(rn)->valid_interior_count++; + SET_FLAG(info_new->flags, BGP_INFO_VALID); + } + RFAPI_UPDATE_ITABLE_COUNT(info_new, import_table, afi, 1); + vnc_import_bgp_exterior_add_route_interior(bgp, import_table, rn, + info_new); + + if (import_table == bgp->rfapi->it_ce) + vnc_direct_bgp_add_route_ce(bgp, rn, info_new); + + if (VNC_DEBUG(VERBOSE)) { + vnc_zlog_debug_verbose("%s: showing IT node", __func__); + rfapiShowItNode(NULL, rn); /* debug */ + } + + rfapiMonitorEncapAdd(import_table, &vn_prefix, rn, info_new); + + if (!rfapiGetUnAddrOfVpnBi(info_new, &un_prefix)) { + + /* + * if we have a valid UN address (either via Encap route + * or via tunnel attribute), then we should attempt + * to move any monitors at less-specific nodes to this node + */ + rfapiMonitorMoveLonger(rn); + + un_prefix_valid = 1; + } + + /* + * 101129 Enhancement: if we add a route (implication: it is not + * in holddown), delete all other routes from this nve at this + * node that are in holddown, regardless of peer. + * + * Reasons it's OK to do that: + * + * - if the holddown route being deleted originally came from BGP VPN, + * it is already gone from BGP (implication of holddown), so there + * won't be any added inconsistency with the BGP RIB. + * + * - once a fresh route is added at a prefix, any routes in holddown + * at that prefix will not show up in RFP responses, so deleting + * the holddown routes won't affect the contents of responses. + * + * - lifetimes are supposed to be consistent, so there should not + * be a case where the fresh route has a shorter lifetime than + * the holddown route, so we don't expect the fresh route to + * disappear and complete its holddown time before the existing + * holddown routes time out. Therefore, we won't have a situation + * where we expect the existing holddown routes to be hidden and + * then to reappear sometime later (as holddown routes) in a + * RFP response. + * + * Among other things, this would enable us to skirt the problem + * of local holddown routes that refer to NVE descriptors that + * have already been closed (if the same NVE triggers a subsequent + * rfapi_open(), the new peer is different and doesn't match the + * peer of the holddown route, so the stale holddown route still + * hangs around until it times out instead of just being replaced + * by the fresh route). + */ + /* + * We know that the new bi will have been inserted before any routes + * in holddown, so we can skip any that came before it + */ + for (bi = info_new->next; bi; bi = next) { + + struct prefix pfx_vn; + struct prefix pfx_un; + int un_match = 0; + int remote_peer_match = 0; + + next = bi->next; + + /* + * Must be holddown + */ + if (!CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + continue; + + /* + * Must match VN address (nexthop of VPN route) + */ + if (rfapiGetNexthop(bi->attr, &pfx_vn)) + continue; + if (!prefix_same(&pfx_vn, &vn_prefix)) + continue; + + if (un_prefix_valid && /* new route UN addr */ + !rfapiGetUnAddrOfVpnBi(bi, &pfx_un) + && /* old route UN addr */ + prefix_same(&pfx_un, &un_prefix)) { /* compare */ + un_match = 1; + } + if (!RFAPI_LOCAL_BI(bi) && !RFAPI_LOCAL_BI(info_new) + && sockunion_same(&bi->peer->su, &info_new->peer->su)) { + /* old & new are both remote, same peer */ + remote_peer_match = 1; + } + + if (!un_match & !remote_peer_match) + continue; + + vnc_zlog_debug_verbose( + "%s: removing holddown bi matching NVE of new route", + __func__); + if (bi->extra->vnc.import.timer) { + struct thread *t = + (struct thread *)bi->extra->vnc.import.timer; + struct rfapi_withdraw *wcb = t->arg; + + XFREE(MTYPE_RFAPI_WITHDRAW, wcb); + thread_cancel(t); + } + rfapiExpireVpnNow(import_table, rn, bi, 0); + } + + if (!original_had_routes) { + /* + * We went from 0 usable routes to 1 usable route. Perform the + * "Adding a Route" export process. + */ + vnc_direct_bgp_add_prefix(bgp, import_table, rn); + vnc_zebra_add_prefix(bgp, import_table, rn); + } else { + /* + * Check for nexthop change event + * Note: the prefix_same() test below detects two situations: + * 1. route is replaced, new route has different nexthop + * 2. new route is added (original_nexthop is 0) + */ + struct prefix new_nexthop; + + rfapiGetNexthop(attr, &new_nexthop); + if (!prefix_same(&original_nexthop, &new_nexthop)) { + /* + * nexthop change event + * vnc_direct_bgp_add_prefix() will recompute VN addr + * ecommunity + */ + vnc_direct_bgp_add_prefix(bgp, import_table, rn); + } + } + + if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { + for (n = rn; n; n = n->parent) { + // rfapiDoRouteCallback(import_table, n, NULL); + } + rfapiMonitorItNodeChanged(import_table, rn, NULL); + } + RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 0); + VNC_ITRCCK; } static rfapi_bi_filtered_import_f * -rfapiBgpInfoFilteredImportFunction (safi_t safi) +rfapiBgpInfoFilteredImportFunction(safi_t safi) { - switch (safi) - { - case SAFI_MPLS_VPN: - return rfapiBgpInfoFilteredImportVPN; - - case SAFI_ENCAP: - return rfapiBgpInfoFilteredImportEncap; - } - zlog_err ("%s: bad safi %d", __func__, safi); - return NULL; + switch (safi) { + case SAFI_MPLS_VPN: + return rfapiBgpInfoFilteredImportVPN; + + case SAFI_ENCAP: + return rfapiBgpInfoFilteredImportEncap; + } + zlog_err("%s: bad safi %d", __func__, safi); + return NULL; } -void -rfapiProcessUpdate ( - struct peer *peer, - void *rfd, /* set when looped from RFP/RFAPI */ - struct prefix *p, - struct prefix_rd *prd, - struct attr *attr, - afi_t afi, - safi_t safi, - u_char type, - u_char sub_type, - uint32_t *label) +void rfapiProcessUpdate(struct peer *peer, + void *rfd, /* set when looped from RFP/RFAPI */ + struct prefix *p, struct prefix_rd *prd, + struct attr *attr, afi_t afi, safi_t safi, u_char type, + u_char sub_type, uint32_t *label) { - struct bgp *bgp; - struct rfapi *h; - struct rfapi_import_table *it; - int has_ip_route = 1; - uint32_t lni = 0; - - bgp = bgp_get_default (); /* assume 1 instance for now */ - assert (bgp); - - h = bgp->rfapi; - assert (h); - - /* - * look at high-order byte of RD. FF means MAC - * address is present (VNC L2VPN) - */ - if ((safi == SAFI_MPLS_VPN) && - (decode_rd_type(prd->val) == RD_TYPE_VNC_ETH)) - { - struct prefix pfx_mac_buf; - struct prefix pfx_nexthop_buf; - int rc; - - /* - * Set flag if prefix and nexthop are the same - don't - * add the route to normal IP-based import tables - */ - if (!rfapiGetNexthop (attr, &pfx_nexthop_buf)) - { - if (!prefix_cmp (&pfx_nexthop_buf, p)) - { - has_ip_route = 0; - } - } - - memset (&pfx_mac_buf, 0, sizeof (pfx_mac_buf)); - pfx_mac_buf.family = AF_ETHERNET; - pfx_mac_buf.prefixlen = 48; - memcpy (&pfx_mac_buf.u.prefix_eth.octet, prd->val + 2, 6); - - /* - * Find rt containing LNI (Logical Network ID), which - * _should_ always be present when mac address is present - */ - rc = rfapiEcommunityGetLNI (attr->ecommunity, &lni); - - vnc_zlog_debug_verbose - ("%s: rfapiEcommunityGetLNI returned %d, lni=%d, attr=%p", - __func__, rc, lni, attr); - if (attr && !rc) - { - it = rfapiMacImportTableGet (bgp, lni); - - rfapiBgpInfoFilteredImportVPN ( - it, - FIF_ACTION_UPDATE, - peer, - rfd, - &pfx_mac_buf, /* prefix */ - p, /* aux prefix: IP addr */ - AFI_L2VPN, - prd, - attr, - type, - sub_type, - label); - } - - } - - if (!has_ip_route) - return; - - /* - * Iterate over all import tables; do a filtered import - * for the afi/safi combination - */ - for (it = h->imports; it; it = it->next) - { - (*rfapiBgpInfoFilteredImportFunction (safi)) ( - it, - FIF_ACTION_UPDATE, - peer, - rfd, - p, /* prefix */ - NULL, - afi, - prd, - attr, - type, - sub_type, - label); - } - - if (safi == SAFI_MPLS_VPN) - { - vnc_direct_bgp_rh_add_route (bgp, afi, p, peer, attr); - } - - if (safi == SAFI_MPLS_VPN) - { - rfapiBgpInfoFilteredImportVPN ( - bgp->rfapi->it_ce, - FIF_ACTION_UPDATE, - peer, - rfd, - p, /* prefix */ - NULL, - afi, - prd, - attr, - type, - sub_type, - label); - } + struct bgp *bgp; + struct rfapi *h; + struct rfapi_import_table *it; + int has_ip_route = 1; + uint32_t lni = 0; + + bgp = bgp_get_default(); /* assume 1 instance for now */ + assert(bgp); + + h = bgp->rfapi; + assert(h); + + /* + * look at high-order byte of RD. FF means MAC + * address is present (VNC L2VPN) + */ + if ((safi == SAFI_MPLS_VPN) + && (decode_rd_type(prd->val) == RD_TYPE_VNC_ETH)) { + struct prefix pfx_mac_buf; + struct prefix pfx_nexthop_buf; + int rc; + + /* + * Set flag if prefix and nexthop are the same - don't + * add the route to normal IP-based import tables + */ + if (!rfapiGetNexthop(attr, &pfx_nexthop_buf)) { + if (!prefix_cmp(&pfx_nexthop_buf, p)) { + has_ip_route = 0; + } + } + + memset(&pfx_mac_buf, 0, sizeof(pfx_mac_buf)); + pfx_mac_buf.family = AF_ETHERNET; + pfx_mac_buf.prefixlen = 48; + memcpy(&pfx_mac_buf.u.prefix_eth.octet, prd->val + 2, 6); + + /* + * Find rt containing LNI (Logical Network ID), which + * _should_ always be present when mac address is present + */ + rc = rfapiEcommunityGetLNI(attr->ecommunity, &lni); + + vnc_zlog_debug_verbose( + "%s: rfapiEcommunityGetLNI returned %d, lni=%d, attr=%p", + __func__, rc, lni, attr); + if (attr && !rc) { + it = rfapiMacImportTableGet(bgp, lni); + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_UPDATE, peer, rfd, + &pfx_mac_buf, /* prefix */ + p, /* aux prefix: IP addr */ + AFI_L2VPN, prd, attr, type, sub_type, label); + } + } + + if (!has_ip_route) + return; + + /* + * Iterate over all import tables; do a filtered import + * for the afi/safi combination + */ + for (it = h->imports; it; it = it->next) { + (*rfapiBgpInfoFilteredImportFunction(safi))( + it, FIF_ACTION_UPDATE, peer, rfd, p, /* prefix */ + NULL, afi, prd, attr, type, sub_type, label); + } + + if (safi == SAFI_MPLS_VPN) { + vnc_direct_bgp_rh_add_route(bgp, afi, p, peer, attr); + } + + if (safi == SAFI_MPLS_VPN) { + rfapiBgpInfoFilteredImportVPN( + bgp->rfapi->it_ce, FIF_ACTION_UPDATE, peer, rfd, + p, /* prefix */ + NULL, afi, prd, attr, type, sub_type, label); + } } -void -rfapiProcessWithdraw ( - struct peer *peer, - void *rfd, - struct prefix *p, - struct prefix_rd *prd, - struct attr *attr, - afi_t afi, - safi_t safi, - u_char type, - int kill) +void rfapiProcessWithdraw(struct peer *peer, void *rfd, struct prefix *p, + struct prefix_rd *prd, struct attr *attr, afi_t afi, + safi_t safi, u_char type, int kill) { - struct bgp *bgp; - struct rfapi *h; - struct rfapi_import_table *it; - - bgp = bgp_get_default (); /* assume 1 instance for now */ - assert (bgp); - - h = bgp->rfapi; - assert (h); - - /* - * look at high-order byte of RD. FF means MAC - * address is present (VNC L2VPN) - */ - if (h->import_mac != NULL && safi == SAFI_MPLS_VPN && - decode_rd_type(prd->val) == RD_TYPE_VNC_ETH) - { - struct prefix pfx_mac_buf; - void *cursor = NULL; - int rc; - - memset (&pfx_mac_buf, 0, sizeof (pfx_mac_buf)); - pfx_mac_buf.family = AF_ETHERNET; - pfx_mac_buf.prefixlen = 48; - memcpy (&pfx_mac_buf.u.prefix_eth, prd->val + 2, 6); - - /* - * withdraw does not contain attrs, so we don't have - * access to the route's LNI, which would ordinarily - * select the specific mac-based import table. Instead, - * we must iterate over all mac-based tables and rely - * on the RD to match. - * - * If this approach is too slow, add an index where - * key is {RD, peer} and value is the import table - */ - for (rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); - rc == 0; - rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) - { + struct bgp *bgp; + struct rfapi *h; + struct rfapi_import_table *it; + + bgp = bgp_get_default(); /* assume 1 instance for now */ + assert(bgp); + + h = bgp->rfapi; + assert(h); + + /* + * look at high-order byte of RD. FF means MAC + * address is present (VNC L2VPN) + */ + if (h->import_mac != NULL && safi == SAFI_MPLS_VPN + && decode_rd_type(prd->val) == RD_TYPE_VNC_ETH) { + struct prefix pfx_mac_buf; + void *cursor = NULL; + int rc; + + memset(&pfx_mac_buf, 0, sizeof(pfx_mac_buf)); + pfx_mac_buf.family = AF_ETHERNET; + pfx_mac_buf.prefixlen = 48; + memcpy(&pfx_mac_buf.u.prefix_eth, prd->val + 2, 6); + + /* + * withdraw does not contain attrs, so we don't have + * access to the route's LNI, which would ordinarily + * select the specific mac-based import table. Instead, + * we must iterate over all mac-based tables and rely + * on the RD to match. + * + * If this approach is too slow, add an index where + * key is {RD, peer} and value is the import table + */ + for (rc = skiplist_next(h->import_mac, NULL, (void **)&it, + &cursor); + rc == 0; rc = skiplist_next(h->import_mac, NULL, + (void **)&it, &cursor)) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose - ("%s: calling rfapiBgpInfoFilteredImportVPN(it=%p, afi=AFI_L2VPN)", - __func__, it); + vnc_zlog_debug_verbose( + "%s: calling rfapiBgpInfoFilteredImportVPN(it=%p, afi=AFI_L2VPN)", + __func__, it); #endif - rfapiBgpInfoFilteredImportVPN ( - it, - (kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), - peer, - rfd, - &pfx_mac_buf, /* prefix */ - p, /* aux_prefix: IP */ - AFI_L2VPN, - prd, - attr, - type, - 0, - NULL); /* sub_type & label unused for withdraw */ - } - } - - /* - * XXX For the case where the withdraw involves an L2 - * route with no IP information, we rely on the lack - * of RT-list intersection to filter out the withdraw - * from the IP-based import tables below - */ - - /* - * Iterate over all import tables; do a filtered import - * for the afi/safi combination - */ - - for (it = h->imports; it; it = it->next) - { - (*rfapiBgpInfoFilteredImportFunction (safi)) ( - it, - (kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), - peer, - rfd, - p, /* prefix */ - NULL, - afi, - prd, - attr, - type, - 0, - NULL); /* sub_type & label unused for withdraw */ - } - - /* TBD the deletion should happen after the lifetime expires */ - if (safi == SAFI_MPLS_VPN) - vnc_direct_bgp_rh_del_route (bgp, afi, p, peer); - - if (safi == SAFI_MPLS_VPN) - { - rfapiBgpInfoFilteredImportVPN ( - bgp->rfapi->it_ce, - (kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), - peer, - rfd, - p, /* prefix */ - NULL, - afi, - prd, - attr, - type, - 0, - NULL); /* sub_type & label unused for withdraw */ - } + rfapiBgpInfoFilteredImportVPN( + it, + (kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), + peer, rfd, &pfx_mac_buf, /* prefix */ + p, /* aux_prefix: IP */ + AFI_L2VPN, prd, attr, type, 0, + NULL); /* sub_type & label unused for withdraw + */ + } + } + + /* + * XXX For the case where the withdraw involves an L2 + * route with no IP information, we rely on the lack + * of RT-list intersection to filter out the withdraw + * from the IP-based import tables below + */ + + /* + * Iterate over all import tables; do a filtered import + * for the afi/safi combination + */ + + for (it = h->imports; it; it = it->next) { + (*rfapiBgpInfoFilteredImportFunction(safi))( + it, (kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), + peer, rfd, p, /* prefix */ + NULL, afi, prd, attr, type, 0, + NULL); /* sub_type & label unused for withdraw */ + } + + /* TBD the deletion should happen after the lifetime expires */ + if (safi == SAFI_MPLS_VPN) + vnc_direct_bgp_rh_del_route(bgp, afi, p, peer); + + if (safi == SAFI_MPLS_VPN) { + rfapiBgpInfoFilteredImportVPN( + bgp->rfapi->it_ce, + (kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), peer, + rfd, p, /* prefix */ + NULL, afi, prd, attr, type, 0, + NULL); /* sub_type & label unused for withdraw */ + } } /* @@ -4378,65 +4087,57 @@ rfapiProcessWithdraw ( /* surprise, this gets called from peer_delete(), from rfapi_close() */ -static void -rfapiProcessPeerDownRt ( - struct peer *peer, - struct rfapi_import_table *import_table, - afi_t afi, - safi_t safi) +static void rfapiProcessPeerDownRt(struct peer *peer, + struct rfapi_import_table *import_table, + afi_t afi, safi_t safi) { - struct route_node *rn; - struct bgp_info *bi; - struct route_table *rt; - int (*timer_service_func) (struct thread *); - - assert (afi == AFI_IP || afi == AFI_IP6); - - VNC_ITRCCK; - - switch (safi) - { - case SAFI_MPLS_VPN: - rt = import_table->imported_vpn[afi]; - timer_service_func = rfapiWithdrawTimerVPN; - break; - case SAFI_ENCAP: - rt = import_table->imported_encap[afi]; - timer_service_func = rfapiWithdrawTimerEncap; - break; - default: - assert (0); - } - - - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - for (bi = rn->info; bi; bi = bi->next) - { - if (bi->peer == peer) - { - - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - { - /* already in holddown, skip */ - continue; - } - - if (safi == SAFI_MPLS_VPN) - { - RFAPI_UPDATE_ITABLE_COUNT (bi, import_table, afi, -1); - import_table->holddown_count[afi] += 1; - } - rfapiBiStartWithdrawTimer (import_table, rn, bi, - afi, safi, - timer_service_func); - } - } - } - VNC_ITRCCK; + struct route_node *rn; + struct bgp_info *bi; + struct route_table *rt; + int (*timer_service_func)(struct thread *); + + assert(afi == AFI_IP || afi == AFI_IP6); + + VNC_ITRCCK; + + switch (safi) { + case SAFI_MPLS_VPN: + rt = import_table->imported_vpn[afi]; + timer_service_func = rfapiWithdrawTimerVPN; + break; + case SAFI_ENCAP: + rt = import_table->imported_encap[afi]; + timer_service_func = rfapiWithdrawTimerEncap; + break; + default: + assert(0); + } + + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + for (bi = rn->info; bi; bi = bi->next) { + if (bi->peer == peer) { + + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { + /* already in holddown, skip */ + continue; + } + + if (safi == SAFI_MPLS_VPN) { + RFAPI_UPDATE_ITABLE_COUNT( + bi, import_table, afi, -1); + import_table->holddown_count[afi] += 1; + } + rfapiBiStartWithdrawTimer(import_table, rn, bi, + afi, safi, + timer_service_func); + } + } + } + VNC_ITRCCK; } -/* +/* * This gets called when a peer connection drops. We have to remove * all the routes from this peer. * @@ -4444,49 +4145,46 @@ rfapiProcessPeerDownRt ( * grouping withdrawn routes so we can generate callbacks more * efficiently. */ -void -rfapiProcessPeerDown (struct peer *peer) +void rfapiProcessPeerDown(struct peer *peer) { - struct bgp *bgp; - struct rfapi *h; - struct rfapi_import_table *it; - - /* - * If this peer is a "dummy" peer structure atached to a RFAPI - * nve_descriptor, we don't need to walk the import tables - * because the routes are already withdrawn by rfapi_close() - */ - if (CHECK_FLAG (peer->flags, PEER_FLAG_IS_RFAPI_HD)) - return; - - /* - * 1. Visit all BIs in all ENCAP import tables. - * Start withdraw timer on the BIs that match peer. - * - * 2. Visit All BIs in all VPN import tables. - * Start withdraw timer on the BIs that match peer. - */ - - bgp = bgp_get_default (); /* assume 1 instance for now */ - if (!bgp) - return; - - h = bgp->rfapi; - assert (h); - - for (it = h->imports; it; it = it->next) - { - rfapiProcessPeerDownRt (peer, it, AFI_IP, SAFI_ENCAP); - rfapiProcessPeerDownRt (peer, it, AFI_IP6, SAFI_ENCAP); - rfapiProcessPeerDownRt (peer, it, AFI_IP, SAFI_MPLS_VPN); - rfapiProcessPeerDownRt (peer, it, AFI_IP6, SAFI_MPLS_VPN); - } - - if (h->it_ce) - { - rfapiProcessPeerDownRt (peer, h->it_ce, AFI_IP, SAFI_MPLS_VPN); - rfapiProcessPeerDownRt (peer, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); - } + struct bgp *bgp; + struct rfapi *h; + struct rfapi_import_table *it; + + /* + * If this peer is a "dummy" peer structure atached to a RFAPI + * nve_descriptor, we don't need to walk the import tables + * because the routes are already withdrawn by rfapi_close() + */ + if (CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) + return; + + /* + * 1. Visit all BIs in all ENCAP import tables. + * Start withdraw timer on the BIs that match peer. + * + * 2. Visit All BIs in all VPN import tables. + * Start withdraw timer on the BIs that match peer. + */ + + bgp = bgp_get_default(); /* assume 1 instance for now */ + if (!bgp) + return; + + h = bgp->rfapi; + assert(h); + + for (it = h->imports; it; it = it->next) { + rfapiProcessPeerDownRt(peer, it, AFI_IP, SAFI_ENCAP); + rfapiProcessPeerDownRt(peer, it, AFI_IP6, SAFI_ENCAP); + rfapiProcessPeerDownRt(peer, it, AFI_IP, SAFI_MPLS_VPN); + rfapiProcessPeerDownRt(peer, it, AFI_IP6, SAFI_MPLS_VPN); + } + + if (h->it_ce) { + rfapiProcessPeerDownRt(peer, h->it_ce, AFI_IP, SAFI_MPLS_VPN); + rfapiProcessPeerDownRt(peer, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); + } } /* @@ -4494,445 +4192,431 @@ rfapiProcessPeerDown (struct peer *peer) * filtered according to the import table's RT list * * TBD: does this function need additions to match rfapiProcessUpdate() - * for, e.g., L2 handling? + * for, e.g., L2 handling? */ -static void -rfapiBgpTableFilteredImport ( - struct bgp *bgp, - struct rfapi_import_table *it, - afi_t afi, - safi_t safi) +static void rfapiBgpTableFilteredImport(struct bgp *bgp, + struct rfapi_import_table *it, + afi_t afi, safi_t safi) { - struct bgp_node *rn1; - struct bgp_node *rn2; - - /* Only these SAFIs have 2-level RIBS */ - assert (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP); - - /* - * Now visit all the rd nodes and the nodes of all the - * route tables attached to them, and import the routes - * if they have matching route targets - */ - for (rn1 = bgp_table_top (bgp->rib[afi][safi]); - rn1; rn1 = bgp_route_next (rn1)) - { - - if (rn1->info) - { - for (rn2 = bgp_table_top (rn1->info); - rn2; rn2 = bgp_route_next (rn2)) - { - - struct bgp_info *bi; - - for (bi = rn2->info; bi; bi = bi->next) - { - u_int32_t label = 0; - - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; - - if (bi->extra) - label = decode_label (&bi->extra->label); - (*rfapiBgpInfoFilteredImportFunction (safi)) ( - it, /* which import table */ - FIF_ACTION_UPDATE, - bi->peer, - NULL, - &rn2->p, /* prefix */ - NULL, - afi, - (struct prefix_rd *) &rn1->p, - bi->attr, - bi->type, - bi->sub_type, - &label); - } - } - } - } + struct bgp_node *rn1; + struct bgp_node *rn2; + + /* Only these SAFIs have 2-level RIBS */ + assert(safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP); + + /* + * Now visit all the rd nodes and the nodes of all the + * route tables attached to them, and import the routes + * if they have matching route targets + */ + for (rn1 = bgp_table_top(bgp->rib[afi][safi]); rn1; + rn1 = bgp_route_next(rn1)) { + + if (rn1->info) { + for (rn2 = bgp_table_top(rn1->info); rn2; + rn2 = bgp_route_next(rn2)) { + + struct bgp_info *bi; + + for (bi = rn2->info; bi; bi = bi->next) { + u_int32_t label = 0; + + if (CHECK_FLAG(bi->flags, + BGP_INFO_REMOVED)) + continue; + + if (bi->extra) + label = decode_label( + &bi->extra->label); + (*rfapiBgpInfoFilteredImportFunction( + safi))( + it, /* which import table */ + FIF_ACTION_UPDATE, bi->peer, + NULL, &rn2->p, /* prefix */ + NULL, afi, + (struct prefix_rd *)&rn1->p, + bi->attr, bi->type, + bi->sub_type, &label); + } + } + } + } } /* per-bgp-instance rfapi data */ -struct rfapi * -bgp_rfapi_new (struct bgp *bgp) +struct rfapi *bgp_rfapi_new(struct bgp *bgp) { - struct rfapi *h; - int afi; - struct rfapi_rfp_cfg *cfg = NULL; - struct rfapi_rfp_cb_methods *cbm = NULL; - - assert (bgp->rfapi_cfg == NULL); - - h = (struct rfapi *) XCALLOC (MTYPE_RFAPI, sizeof (struct rfapi)); - - for (afi = AFI_IP; afi < AFI_MAX; afi++) - { - /* ugly, to deal with addition of delegates, part of 0.99.24.1 merge */ - h->un[afi].delegate = route_table_get_default_delegate (); - } - - /* - * initialize the ce import table - */ - h->it_ce = - XCALLOC (MTYPE_RFAPI_IMPORTTABLE, sizeof (struct rfapi_import_table)); - h->it_ce->imported_vpn[AFI_IP] = route_table_init (); - h->it_ce->imported_vpn[AFI_IP6] = route_table_init (); - h->it_ce->imported_encap[AFI_IP] = route_table_init (); - h->it_ce->imported_encap[AFI_IP6] = route_table_init (); - rfapiBgpTableFilteredImport (bgp, h->it_ce, AFI_IP, SAFI_MPLS_VPN); - rfapiBgpTableFilteredImport (bgp, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); - - /* - * Set up work queue for deferred rfapi_close operations - */ - h->deferred_close_q = work_queue_new (bm->master, "rfapi deferred close"); - h->deferred_close_q->spec.workfunc = rfapi_deferred_close_workfunc; - h->deferred_close_q->spec.data = h; - - h->rfp = rfp_start (bm->master, &cfg, &cbm); - bgp->rfapi_cfg = bgp_rfapi_cfg_new (cfg); - if (cbm != NULL) - { - h->rfp_methods = *cbm; - } - return h; + struct rfapi *h; + int afi; + struct rfapi_rfp_cfg *cfg = NULL; + struct rfapi_rfp_cb_methods *cbm = NULL; + + assert(bgp->rfapi_cfg == NULL); + + h = (struct rfapi *)XCALLOC(MTYPE_RFAPI, sizeof(struct rfapi)); + + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + /* ugly, to deal with addition of delegates, part of 0.99.24.1 + * merge */ + h->un[afi].delegate = route_table_get_default_delegate(); + } + + /* + * initialize the ce import table + */ + h->it_ce = XCALLOC(MTYPE_RFAPI_IMPORTTABLE, + sizeof(struct rfapi_import_table)); + h->it_ce->imported_vpn[AFI_IP] = route_table_init(); + h->it_ce->imported_vpn[AFI_IP6] = route_table_init(); + h->it_ce->imported_encap[AFI_IP] = route_table_init(); + h->it_ce->imported_encap[AFI_IP6] = route_table_init(); + rfapiBgpTableFilteredImport(bgp, h->it_ce, AFI_IP, SAFI_MPLS_VPN); + rfapiBgpTableFilteredImport(bgp, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); + + /* + * Set up work queue for deferred rfapi_close operations + */ + h->deferred_close_q = + work_queue_new(bm->master, "rfapi deferred close"); + h->deferred_close_q->spec.workfunc = rfapi_deferred_close_workfunc; + h->deferred_close_q->spec.data = h; + + h->rfp = rfp_start(bm->master, &cfg, &cbm); + bgp->rfapi_cfg = bgp_rfapi_cfg_new(cfg); + if (cbm != NULL) { + h->rfp_methods = *cbm; + } + return h; } -void -bgp_rfapi_destroy (struct bgp *bgp, struct rfapi *h) +void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h) { - if (bgp == NULL || h == NULL) - return; - - if (h->resolve_nve_nexthop) - { - skiplist_free (h->resolve_nve_nexthop); - h->resolve_nve_nexthop = NULL; - } - - route_table_finish (h->it_ce->imported_vpn[AFI_IP]); - route_table_finish (h->it_ce->imported_vpn[AFI_IP6]); - route_table_finish (h->it_ce->imported_encap[AFI_IP]); - route_table_finish (h->it_ce->imported_encap[AFI_IP6]); - - if (h->import_mac) - { - struct rfapi_import_table *it; - void *cursor; - int rc; - - for (cursor = NULL, - rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); - !rc; - rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) - { - - rfapiImportTableFlush (it); - XFREE (MTYPE_RFAPI_IMPORTTABLE, it); - } - skiplist_free (h->import_mac); - h->import_mac = NULL; - } - - work_queue_free (h->deferred_close_q); - - if (h->rfp != NULL) - rfp_stop (h->rfp); - XFREE (MTYPE_RFAPI_IMPORTTABLE, h->it_ce); - XFREE (MTYPE_RFAPI, h); + if (bgp == NULL || h == NULL) + return; + + if (h->resolve_nve_nexthop) { + skiplist_free(h->resolve_nve_nexthop); + h->resolve_nve_nexthop = NULL; + } + + route_table_finish(h->it_ce->imported_vpn[AFI_IP]); + route_table_finish(h->it_ce->imported_vpn[AFI_IP6]); + route_table_finish(h->it_ce->imported_encap[AFI_IP]); + route_table_finish(h->it_ce->imported_encap[AFI_IP6]); + + if (h->import_mac) { + struct rfapi_import_table *it; + void *cursor; + int rc; + + for (cursor = NULL, + rc = skiplist_next(h->import_mac, NULL, (void **)&it, + &cursor); + !rc; rc = skiplist_next(h->import_mac, NULL, (void **)&it, + &cursor)) { + + rfapiImportTableFlush(it); + XFREE(MTYPE_RFAPI_IMPORTTABLE, it); + } + skiplist_free(h->import_mac); + h->import_mac = NULL; + } + + work_queue_free(h->deferred_close_q); + + if (h->rfp != NULL) + rfp_stop(h->rfp); + XFREE(MTYPE_RFAPI_IMPORTTABLE, h->it_ce); + XFREE(MTYPE_RFAPI, h); } struct rfapi_import_table * -rfapiImportTableRefAdd (struct bgp *bgp, struct ecommunity *rt_import_list, - struct rfapi_nve_group_cfg *rfg) +rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list, + struct rfapi_nve_group_cfg *rfg) { - struct rfapi *h; - struct rfapi_import_table *it; - afi_t afi; - - h = bgp->rfapi; - assert (h); - - for (it = h->imports; it; it = it->next) - { - if (ecommunity_cmp (it->rt_import_list, rt_import_list)) - break; - } - - vnc_zlog_debug_verbose ("%s: matched it=%p", __func__, it); - - if (!it) - { - it = - XCALLOC (MTYPE_RFAPI_IMPORTTABLE, sizeof (struct rfapi_import_table)); - assert (it); - it->next = h->imports; - h->imports = it; - - it->rt_import_list = ecommunity_dup (rt_import_list); - it->rfg = rfg; - it->monitor_exterior_orphans = - skiplist_new (0, NULL, (void (*)(void *)) prefix_free); - - /* - * fill import route tables from RIBs - * - * Potential area for optimization. If this occurs when - * tables are large (e.g., the operator adds a nve group - * with a new RT list to a running system), it could take - * a while. - * - */ - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - it->imported_vpn[afi] = route_table_init (); - it->imported_encap[afi] = route_table_init (); - - rfapiBgpTableFilteredImport (bgp, it, afi, SAFI_MPLS_VPN); - rfapiBgpTableFilteredImport (bgp, it, afi, SAFI_ENCAP); - - vnc_import_bgp_exterior_redist_enable_it (bgp, afi, it); - } - } - - it->refcount += 1; - - return it; + struct rfapi *h; + struct rfapi_import_table *it; + afi_t afi; + + h = bgp->rfapi; + assert(h); + + for (it = h->imports; it; it = it->next) { + if (ecommunity_cmp(it->rt_import_list, rt_import_list)) + break; + } + + vnc_zlog_debug_verbose("%s: matched it=%p", __func__, it); + + if (!it) { + it = XCALLOC(MTYPE_RFAPI_IMPORTTABLE, + sizeof(struct rfapi_import_table)); + assert(it); + it->next = h->imports; + h->imports = it; + + it->rt_import_list = ecommunity_dup(rt_import_list); + it->rfg = rfg; + it->monitor_exterior_orphans = + skiplist_new(0, NULL, (void (*)(void *))prefix_free); + + /* + * fill import route tables from RIBs + * + * Potential area for optimization. If this occurs when + * tables are large (e.g., the operator adds a nve group + * with a new RT list to a running system), it could take + * a while. + * + */ + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + it->imported_vpn[afi] = route_table_init(); + it->imported_encap[afi] = route_table_init(); + + rfapiBgpTableFilteredImport(bgp, it, afi, + SAFI_MPLS_VPN); + rfapiBgpTableFilteredImport(bgp, it, afi, SAFI_ENCAP); + + vnc_import_bgp_exterior_redist_enable_it(bgp, afi, it); + } + } + + it->refcount += 1; + + return it; } /* * skiplist element free function */ -static void -delete_rem_pfx_na_free (void *na) +static void delete_rem_pfx_na_free(void *na) { - uint32_t *pCounter = ((struct rfapi_nve_addr *) na)->info; + uint32_t *pCounter = ((struct rfapi_nve_addr *)na)->info; - *pCounter += 1; - XFREE (MTYPE_RFAPI_NVE_ADDR, na); + *pCounter += 1; + XFREE(MTYPE_RFAPI_NVE_ADDR, na); } /* * Common deleter for IP and MAC import tables */ -static void -rfapiDeleteRemotePrefixesIt ( - struct bgp *bgp, - struct rfapi_import_table *it, - struct prefix *un, - struct prefix *vn, - struct prefix *p, - int delete_active, - int delete_holddown, - uint32_t *pARcount, - uint32_t *pAHcount, - uint32_t *pHRcount, - uint32_t *pHHcount, - struct skiplist *uniq_active_nves, - struct skiplist *uniq_holddown_nves) +static void rfapiDeleteRemotePrefixesIt( + struct bgp *bgp, struct rfapi_import_table *it, struct prefix *un, + struct prefix *vn, struct prefix *p, int delete_active, + int delete_holddown, uint32_t *pARcount, uint32_t *pAHcount, + uint32_t *pHRcount, uint32_t *pHHcount, + struct skiplist *uniq_active_nves, struct skiplist *uniq_holddown_nves) { - afi_t afi; + afi_t afi; #if DEBUG_L2_EXTRA - { - char buf_pfx[BUFSIZ]; - - if (p) - { - prefix2str (p, buf_pfx, BUFSIZ); - } - else - { - buf_pfx[0] = '*'; - buf_pfx[1] = 0; - } - - vnc_zlog_debug_verbose ("%s: entry, p=%s, delete_active=%d, delete_holddown=%d", - __func__, buf_pfx, delete_active, delete_holddown); - } + { + char buf_pfx[BUFSIZ]; + + if (p) { + prefix2str(p, buf_pfx, BUFSIZ); + } else { + buf_pfx[0] = '*'; + buf_pfx[1] = 0; + } + + vnc_zlog_debug_verbose( + "%s: entry, p=%s, delete_active=%d, delete_holddown=%d", + __func__, buf_pfx, delete_active, delete_holddown); + } #endif - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - struct route_table *rt; - struct route_node *rn; - - if (p && (family2afi (p->family) != afi)) - { - continue; - } - - rt = it->imported_vpn[afi]; - if (!rt) - continue; - - vnc_zlog_debug_verbose ("%s: scanning rt for afi=%d", __func__, afi); - - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - struct bgp_info *bi; - struct bgp_info *next; - - if (VNC_DEBUG(IMPORT_DEL_REMOTE)) - { - char p1line[BUFSIZ]; - char p2line[BUFSIZ]; - - prefix2str (p, p1line, BUFSIZ); - prefix2str (&rn->p, p2line, BUFSIZ); - vnc_zlog_debug_any ("%s: want %s, have %s", __func__, p1line, p2line); - } - - if (p && prefix_cmp (p, &rn->p)) - continue; - - { - char buf_pfx[BUFSIZ]; - prefix2str (&rn->p, buf_pfx, BUFSIZ); - vnc_zlog_debug_verbose ("%s: rn pfx=%s", __func__, buf_pfx); - } - - /* TBD is this valid for afi == AFI_L2VPN? */ - RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, 1); - - for (bi = rn->info; bi; bi = next) - { - next = bi->next; - - struct prefix qpt; - struct prefix qct; - int qpt_valid = 0; - int qct_valid = 0; - int is_active = 0; - - vnc_zlog_debug_verbose ("%s: examining bi %p", __func__, bi); - - if (bi->attr) - { - if (!rfapiGetNexthop (bi->attr, &qpt)) - qpt_valid = 1; - } - if (vn) - { - if (!qpt_valid || !prefix_match (vn, &qpt)) - { + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + struct route_table *rt; + struct route_node *rn; + + if (p && (family2afi(p->family) != afi)) { + continue; + } + + rt = it->imported_vpn[afi]; + if (!rt) + continue; + + vnc_zlog_debug_verbose("%s: scanning rt for afi=%d", __func__, + afi); + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + struct bgp_info *bi; + struct bgp_info *next; + + if (VNC_DEBUG(IMPORT_DEL_REMOTE)) { + char p1line[BUFSIZ]; + char p2line[BUFSIZ]; + + prefix2str(p, p1line, BUFSIZ); + prefix2str(&rn->p, p2line, BUFSIZ); + vnc_zlog_debug_any("%s: want %s, have %s", + __func__, p1line, p2line); + } + + if (p && prefix_cmp(p, &rn->p)) + continue; + + { + char buf_pfx[BUFSIZ]; + prefix2str(&rn->p, buf_pfx, BUFSIZ); + vnc_zlog_debug_verbose("%s: rn pfx=%s", + __func__, buf_pfx); + } + + /* TBD is this valid for afi == AFI_L2VPN? */ + RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 1); + + for (bi = rn->info; bi; bi = next) { + next = bi->next; + + struct prefix qpt; + struct prefix qct; + int qpt_valid = 0; + int qct_valid = 0; + int is_active = 0; + + vnc_zlog_debug_verbose("%s: examining bi %p", + __func__, bi); + + if (bi->attr) { + if (!rfapiGetNexthop(bi->attr, &qpt)) + qpt_valid = 1; + } + if (vn) { + if (!qpt_valid + || !prefix_match(vn, &qpt)) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose - ("%s: continue at vn && !qpt_valid || !prefix_match(vn, &qpt)", - __func__); + vnc_zlog_debug_verbose( + "%s: continue at vn && !qpt_valid || !prefix_match(vn, &qpt)", + __func__); #endif - continue; - } - } + continue; + } + } - if (!rfapiGetUnAddrOfVpnBi (bi, &qct)) - qct_valid = 1; + if (!rfapiGetUnAddrOfVpnBi(bi, &qct)) + qct_valid = 1; - if (un) - { - if (!qct_valid || !prefix_match (un, &qct)) - { + if (un) { + if (!qct_valid + || !prefix_match(un, &qct)) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose - ("%s: continue at un && !qct_valid || !prefix_match(un, &qct)", - __func__); + vnc_zlog_debug_verbose( + "%s: continue at un && !qct_valid || !prefix_match(un, &qct)", + __func__); #endif - continue; - } - } - - - /* - * Blow bi away - */ - /* - * If this route is waiting to be deleted because of - * a previous withdraw, we must cancel its timer. - */ - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - { - if (!delete_holddown) - continue; - if (bi->extra->vnc.import.timer) - { - - struct thread *t = - (struct thread *) bi->extra->vnc.import.timer; - struct rfapi_withdraw *wcb = t->arg; - - wcb->import_table->holddown_count[afi] -= 1; - RFAPI_UPDATE_ITABLE_COUNT (bi, wcb->import_table, afi, - 1); - XFREE (MTYPE_RFAPI_WITHDRAW, wcb); - thread_cancel (t); - } - } - else - { - if (!delete_active) - continue; - is_active = 1; - } - - vnc_zlog_debug_verbose - ("%s: deleting bi %p (qct_valid=%d, qpt_valid=%d, delete_holddown=%d, delete_active=%d)", - __func__, bi, qct_valid, qpt_valid, delete_holddown, - delete_active); - - - /* - * add nve to list - */ - if (qct_valid && qpt_valid) - { - - struct rfapi_nve_addr na; - struct rfapi_nve_addr *nap; - - memset (&na, 0, sizeof (na)); - assert (!rfapiQprefix2Raddr (&qct, &na.un)); - assert (!rfapiQprefix2Raddr (&qpt, &na.vn)); - - if (skiplist_search ((is_active ? uniq_active_nves : - uniq_holddown_nves), &na, - (void **) &nap)) - { - char line[BUFSIZ]; - - nap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, - sizeof (struct rfapi_nve_addr)); - assert (nap); - *nap = na; - nap->info = is_active ? pAHcount : pHHcount; - skiplist_insert ((is_active ? uniq_active_nves : - uniq_holddown_nves), nap, nap); - - rfapiNveAddr2Str (nap, line, BUFSIZ); - } - } - - vnc_direct_bgp_rh_del_route (bgp, afi, &rn->p, bi->peer); - - RFAPI_UPDATE_ITABLE_COUNT (bi, it, afi, -1); - it->holddown_count[afi] += 1; - rfapiExpireVpnNow (it, rn, bi, 1); - - vnc_zlog_debug_verbose ("%s: incrementing count (is_active=%d)", - __func__, is_active); - - if (is_active) - ++ * pARcount; - else - ++ * pHRcount; - } - } - } + continue; + } + } + + + /* + * Blow bi away + */ + /* + * If this route is waiting to be deleted + * because of + * a previous withdraw, we must cancel its + * timer. + */ + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { + if (!delete_holddown) + continue; + if (bi->extra->vnc.import.timer) { + + struct thread *t = + (struct thread *)bi + ->extra->vnc + .import.timer; + struct rfapi_withdraw *wcb = + t->arg; + + wcb->import_table + ->holddown_count[afi] -= + 1; + RFAPI_UPDATE_ITABLE_COUNT( + bi, wcb->import_table, + afi, 1); + XFREE(MTYPE_RFAPI_WITHDRAW, + wcb); + thread_cancel(t); + } + } else { + if (!delete_active) + continue; + is_active = 1; + } + + vnc_zlog_debug_verbose( + "%s: deleting bi %p (qct_valid=%d, qpt_valid=%d, delete_holddown=%d, delete_active=%d)", + __func__, bi, qct_valid, qpt_valid, + delete_holddown, delete_active); + + + /* + * add nve to list + */ + if (qct_valid && qpt_valid) { + + struct rfapi_nve_addr na; + struct rfapi_nve_addr *nap; + + memset(&na, 0, sizeof(na)); + assert(!rfapiQprefix2Raddr(&qct, + &na.un)); + assert(!rfapiQprefix2Raddr(&qpt, + &na.vn)); + + if (skiplist_search( + (is_active + ? uniq_active_nves + : uniq_holddown_nves), + &na, (void **)&nap)) { + char line[BUFSIZ]; + + nap = XCALLOC( + MTYPE_RFAPI_NVE_ADDR, + sizeof(struct + rfapi_nve_addr)); + assert(nap); + *nap = na; + nap->info = is_active + ? pAHcount + : pHHcount; + skiplist_insert( + (is_active + ? uniq_active_nves + : uniq_holddown_nves), + nap, nap); + + rfapiNveAddr2Str(nap, line, + BUFSIZ); + } + } + + vnc_direct_bgp_rh_del_route(bgp, afi, &rn->p, + bi->peer); + + RFAPI_UPDATE_ITABLE_COUNT(bi, it, afi, -1); + it->holddown_count[afi] += 1; + rfapiExpireVpnNow(it, rn, bi, 1); + + vnc_zlog_debug_verbose( + "%s: incrementing count (is_active=%d)", + __func__, is_active); + + if (is_active) + ++*pARcount; + else + ++*pHRcount; + } + } + } } @@ -4944,7 +4628,7 @@ rfapiDeleteRemotePrefixesIt ( * * UI helper: For use by the "clear vnc prefixes" command * - * input: + * input: * un if set, tunnel must match this prefix * vn if set, nexthop prefix must match this prefix * p if set, prefix must match this prefix @@ -4959,133 +4643,110 @@ rfapiDeleteRemotePrefixesIt ( * return value: * void --------------------------------------------*/ -void -rfapiDeleteRemotePrefixes ( - struct prefix *un, - struct prefix *vn, - struct prefix *p, - struct rfapi_import_table *arg_it, - int delete_active, - int delete_holddown, - uint32_t *pARcount, - uint32_t *pAHcount, - uint32_t *pHRcount, - uint32_t *pHHcount) +void rfapiDeleteRemotePrefixes(struct prefix *un, struct prefix *vn, + struct prefix *p, + struct rfapi_import_table *arg_it, + int delete_active, int delete_holddown, + uint32_t *pARcount, uint32_t *pAHcount, + uint32_t *pHRcount, uint32_t *pHHcount) { - struct bgp *bgp; - struct rfapi *h; - struct rfapi_import_table *it; - uint32_t deleted_holddown_route_count = 0; - uint32_t deleted_active_route_count = 0; - uint32_t deleted_holddown_nve_count = 0; - uint32_t deleted_active_nve_count = 0; - struct skiplist *uniq_holddown_nves; - struct skiplist *uniq_active_nves; - - VNC_ITRCCK; - - bgp = bgp_get_default (); /* assume 1 instance for now */ - /* If no bgp instantiated yet, no vnc prefixes exist */ - if (!bgp) - return; - - h = bgp->rfapi; - assert (h); - - uniq_holddown_nves = - skiplist_new (0, rfapi_nve_addr_cmp, delete_rem_pfx_na_free); - uniq_active_nves = - skiplist_new (0, rfapi_nve_addr_cmp, delete_rem_pfx_na_free); - - /* - * Iterate over all import tables; do a filtered import - * for the afi/safi combination - */ - - if (arg_it) - it = arg_it; - else - it = h->imports; - for (; it; ) - { - - vnc_zlog_debug_verbose - ("%s: calling rfapiDeleteRemotePrefixesIt() on (IP) import %p", - __func__, it); - - rfapiDeleteRemotePrefixesIt ( - bgp, - it, - un, - vn, - p, - delete_active, - delete_holddown, - &deleted_active_route_count, - &deleted_active_nve_count, - &deleted_holddown_route_count, - &deleted_holddown_nve_count, - uniq_active_nves, - uniq_holddown_nves); - - if (arg_it) - it = NULL; - else - it = it->next; - } - - /* - * Now iterate over L2 import tables - */ - if (h->import_mac && !(p && (p->family != AF_ETHERNET))) - { - - void *cursor = NULL; - int rc; - - for (cursor = NULL, - rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); - !rc; - rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) - { - - vnc_zlog_debug_verbose - ("%s: calling rfapiDeleteRemotePrefixesIt() on import_mac %p", - __func__, it); - - rfapiDeleteRemotePrefixesIt ( - bgp, - it, - un, - vn, - p, - delete_active, - delete_holddown, - &deleted_active_route_count, - &deleted_active_nve_count, - &deleted_holddown_route_count, - &deleted_holddown_nve_count, - uniq_active_nves, - uniq_holddown_nves); - } - } - - /* - * our custom element freeing function above counts as it deletes - */ - skiplist_free (uniq_holddown_nves); - skiplist_free (uniq_active_nves); - - if (pARcount) - *pARcount = deleted_active_route_count; - if (pAHcount) - *pAHcount = deleted_active_nve_count; - if (pHRcount) - *pHRcount = deleted_holddown_route_count; - if (pHHcount) - *pHHcount = deleted_holddown_nve_count; - - VNC_ITRCCK; + struct bgp *bgp; + struct rfapi *h; + struct rfapi_import_table *it; + uint32_t deleted_holddown_route_count = 0; + uint32_t deleted_active_route_count = 0; + uint32_t deleted_holddown_nve_count = 0; + uint32_t deleted_active_nve_count = 0; + struct skiplist *uniq_holddown_nves; + struct skiplist *uniq_active_nves; + + VNC_ITRCCK; + + bgp = bgp_get_default(); /* assume 1 instance for now */ + /* If no bgp instantiated yet, no vnc prefixes exist */ + if (!bgp) + return; + + h = bgp->rfapi; + assert(h); + + uniq_holddown_nves = + skiplist_new(0, rfapi_nve_addr_cmp, delete_rem_pfx_na_free); + uniq_active_nves = + skiplist_new(0, rfapi_nve_addr_cmp, delete_rem_pfx_na_free); + + /* + * Iterate over all import tables; do a filtered import + * for the afi/safi combination + */ + + if (arg_it) + it = arg_it; + else + it = h->imports; + for (; it;) { + + vnc_zlog_debug_verbose( + "%s: calling rfapiDeleteRemotePrefixesIt() on (IP) import %p", + __func__, it); + + rfapiDeleteRemotePrefixesIt( + bgp, it, un, vn, p, delete_active, delete_holddown, + &deleted_active_route_count, &deleted_active_nve_count, + &deleted_holddown_route_count, + &deleted_holddown_nve_count, uniq_active_nves, + uniq_holddown_nves); + + if (arg_it) + it = NULL; + else + it = it->next; + } + + /* + * Now iterate over L2 import tables + */ + if (h->import_mac && !(p && (p->family != AF_ETHERNET))) { + + void *cursor = NULL; + int rc; + + for (cursor = NULL, + rc = skiplist_next(h->import_mac, NULL, (void **)&it, + &cursor); + !rc; rc = skiplist_next(h->import_mac, NULL, (void **)&it, + &cursor)) { + + vnc_zlog_debug_verbose( + "%s: calling rfapiDeleteRemotePrefixesIt() on import_mac %p", + __func__, it); + + rfapiDeleteRemotePrefixesIt( + bgp, it, un, vn, p, delete_active, + delete_holddown, &deleted_active_route_count, + &deleted_active_nve_count, + &deleted_holddown_route_count, + &deleted_holddown_nve_count, uniq_active_nves, + uniq_holddown_nves); + } + } + + /* + * our custom element freeing function above counts as it deletes + */ + skiplist_free(uniq_holddown_nves); + skiplist_free(uniq_active_nves); + + if (pARcount) + *pARcount = deleted_active_route_count; + if (pAHcount) + *pAHcount = deleted_active_nve_count; + if (pHRcount) + *pHRcount = deleted_holddown_route_count; + if (pHHcount) + *pHHcount = deleted_holddown_nve_count; + + VNC_ITRCCK; } /*------------------------------------------ @@ -5093,7 +4754,7 @@ rfapiDeleteRemotePrefixes ( * * UI helper: count VRF routes from BGP side * - * input: + * input: * * output * pALRcount count of active local routes @@ -5104,83 +4765,73 @@ rfapiDeleteRemotePrefixes ( * return value: * void --------------------------------------------*/ -void -rfapiCountAllItRoutes (int *pALRcount, /* active local routes */ - int *pARRcount, /* active remote routes */ - int *pHRcount, /* holddown routes */ - int *pIRcount) /* imported routes */ +void rfapiCountAllItRoutes(int *pALRcount, /* active local routes */ + int *pARRcount, /* active remote routes */ + int *pHRcount, /* holddown routes */ + int *pIRcount) /* imported routes */ { - struct bgp *bgp; - struct rfapi *h; - struct rfapi_import_table *it; - afi_t afi; - - int total_active_local = 0; - int total_active_remote = 0; - int total_holddown = 0; - int total_imported = 0; - - bgp = bgp_get_default (); /* assume 1 instance for now */ - assert (bgp); - - h = bgp->rfapi; - assert (h); - - /* - * Iterate over all import tables; do a filtered import - * for the afi/safi combination - */ - - for (it = h->imports; it; it = it->next) - { - - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - total_active_local += it->local_count[afi]; - total_active_remote += it->remote_count[afi]; - total_holddown += it->holddown_count[afi]; - total_imported += it->imported_count[afi]; - - } - } - - void *cursor; - int rc; - - if (h->import_mac) - { - for (cursor = NULL, - rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); - !rc; - rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) - { - - total_active_local += it->local_count[AFI_L2VPN]; - total_active_remote += it->remote_count[AFI_L2VPN]; - total_holddown += it->holddown_count[AFI_L2VPN]; - total_imported += it->imported_count[AFI_L2VPN]; - - } - } - - - if (pALRcount) - { - *pALRcount = total_active_local; - } - if (pARRcount) - { - *pARRcount = total_active_remote; - } - if (pHRcount) - { - *pHRcount = total_holddown; - } - if (pIRcount) - { - *pIRcount = total_imported; - } + struct bgp *bgp; + struct rfapi *h; + struct rfapi_import_table *it; + afi_t afi; + + int total_active_local = 0; + int total_active_remote = 0; + int total_holddown = 0; + int total_imported = 0; + + bgp = bgp_get_default(); /* assume 1 instance for now */ + assert(bgp); + + h = bgp->rfapi; + assert(h); + + /* + * Iterate over all import tables; do a filtered import + * for the afi/safi combination + */ + + for (it = h->imports; it; it = it->next) { + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + total_active_local += it->local_count[afi]; + total_active_remote += it->remote_count[afi]; + total_holddown += it->holddown_count[afi]; + total_imported += it->imported_count[afi]; + } + } + + void *cursor; + int rc; + + if (h->import_mac) { + for (cursor = NULL, + rc = skiplist_next(h->import_mac, NULL, (void **)&it, + &cursor); + !rc; rc = skiplist_next(h->import_mac, NULL, (void **)&it, + &cursor)) { + + total_active_local += it->local_count[AFI_L2VPN]; + total_active_remote += it->remote_count[AFI_L2VPN]; + total_holddown += it->holddown_count[AFI_L2VPN]; + total_imported += it->imported_count[AFI_L2VPN]; + } + } + + + if (pALRcount) { + *pALRcount = total_active_local; + } + if (pARRcount) { + *pARRcount = total_active_remote; + } + if (pHRcount) { + *pHRcount = total_holddown; + } + if (pIRcount) { + *pIRcount = total_imported; + } } /*------------------------------------------ @@ -5188,7 +4839,7 @@ rfapiCountAllItRoutes (int *pALRcount, /* active local routes */ * * calculate holddown value based on lifetime * - * input: + * input: * lifetime lifetime * * return value: @@ -5197,22 +4848,21 @@ rfapiCountAllItRoutes (int *pALRcount, /* active local routes */ * --------------------------------------------*/ /* hold down time maxes out at RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY */ -uint32_t -rfapiGetHolddownFromLifetime (uint32_t lifetime) +uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime) { - uint32_t factor; - struct bgp *bgp; - - bgp = bgp_get_default (); - if (bgp && bgp->rfapi_cfg) - factor = bgp->rfapi_cfg->rfp_cfg.holddown_factor; - else - factor = RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR; - - if (factor < 100 || lifetime < RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) - lifetime = lifetime * factor / 100; - if (lifetime < RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) - return lifetime; - else - return RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; + uint32_t factor; + struct bgp *bgp; + + bgp = bgp_get_default(); + if (bgp && bgp->rfapi_cfg) + factor = bgp->rfapi_cfg->rfp_cfg.holddown_factor; + else + factor = RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR; + + if (factor < 100 || lifetime < RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) + lifetime = lifetime * factor / 100; + if (lifetime < RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) + return lifetime; + else + return RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; } diff --git a/bgpd/rfapi/rfapi_import.h b/bgpd/rfapi/rfapi_import.h index 1888d5f25d..fc5bb01cef 100644 --- a/bgpd/rfapi/rfapi_import.h +++ b/bgpd/rfapi/rfapi_import.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -34,72 +34,60 @@ * routes are not segregated by RD - the RD is stored in bgp_info_extra * and is needed to determine if two prefixes are the same. */ -struct rfapi_import_table -{ - struct rfapi_import_table *next; - struct rfapi_nve_group_cfg *rfg; - struct ecommunity *rt_import_list; /* copied from nve grp */ - int refcount; /* nve grps and nves */ - uint32_t l2_logical_net_id; /* L2 only: EVPN Eth Seg Id */ - struct route_table *imported_vpn[AFI_MAX]; - struct rfapi_monitor_vpn *vpn0_queries[AFI_MAX]; - struct rfapi_monitor_eth *eth0_queries; - struct route_table *imported_encap[AFI_MAX]; - struct skiplist *monitor_exterior_orphans; - int local_count[AFI_MAX]; - int remote_count[AFI_MAX]; - int holddown_count[AFI_MAX]; - int imported_count[AFI_MAX]; +struct rfapi_import_table { + struct rfapi_import_table *next; + struct rfapi_nve_group_cfg *rfg; + struct ecommunity *rt_import_list; /* copied from nve grp */ + int refcount; /* nve grps and nves */ + uint32_t l2_logical_net_id; /* L2 only: EVPN Eth Seg Id */ + struct route_table *imported_vpn[AFI_MAX]; + struct rfapi_monitor_vpn *vpn0_queries[AFI_MAX]; + struct rfapi_monitor_eth *eth0_queries; + struct route_table *imported_encap[AFI_MAX]; + struct skiplist *monitor_exterior_orphans; + int local_count[AFI_MAX]; + int remote_count[AFI_MAX]; + int holddown_count[AFI_MAX]; + int imported_count[AFI_MAX]; }; -#define RFAPI_LOCAL_BI(bi) \ - (((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP)) +#define RFAPI_LOCAL_BI(bi) \ + (((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP)) -#define RFAPI_DIRECT_IMPORT_BI(bi) \ - (((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) || ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT)) +#define RFAPI_DIRECT_IMPORT_BI(bi) \ + (((bi)->type == ZEBRA_ROUTE_BGP_DIRECT) \ + || ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT)) -#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \ - if (RFAPI_LOCAL_BI(bi)) { \ - (itable)->local_count[(afi)] += (cnt); \ - } else { \ - if (RFAPI_DIRECT_IMPORT_BI(bi)) \ - (itable)->imported_count[(afi)] += (cnt); \ - else \ - (itable)->remote_count[(afi)] += (cnt); \ - } +#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \ + if (RFAPI_LOCAL_BI(bi)) { \ + (itable)->local_count[(afi)] += (cnt); \ + } else { \ + if (RFAPI_DIRECT_IMPORT_BI(bi)) \ + (itable)->imported_count[(afi)] += (cnt); \ + else \ + (itable)->remote_count[(afi)] += (cnt); \ + } -extern uint8_t -rfapiRfpCost (struct attr *attr); +extern uint8_t rfapiRfpCost(struct attr *attr); -extern void -rfapiDebugBacktrace (void); +extern void rfapiDebugBacktrace(void); -extern void -rfapiCheckRouteCount (void); +extern void rfapiCheckRouteCount(void); /* * Print BI in an Import Table */ -extern void -rfapiPrintBi (void *stream, struct bgp_info *bi); +extern void rfapiPrintBi(void *stream, struct bgp_info *bi); -extern void -rfapiShowImportTable ( - void *stream, - const char *label, - struct route_table *rt, - int isvpn); +extern void rfapiShowImportTable(void *stream, const char *label, + struct route_table *rt, int isvpn); extern struct rfapi_import_table * -rfapiImportTableRefAdd ( - struct bgp *bgp, - struct ecommunity *rt_import_list, - struct rfapi_nve_group_cfg *rfg); +rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list, + struct rfapi_nve_group_cfg *rfg); -extern void -rfapiImportTableRefDelByIt ( - struct bgp *bgp, - struct rfapi_import_table *it_target); +extern void rfapiImportTableRefDelByIt(struct bgp *bgp, + struct rfapi_import_table *it_target); /* @@ -111,106 +99,78 @@ rfapiImportTableRefDelByIt ( * then return those, and also include all the non-removed routes from the * next less-specific node (i.e., this node's parent) at the end. */ -extern struct rfapi_next_hop_entry * -rfapiRouteNode2NextHopList ( - struct route_node *rn, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload this NVE rib table */ - struct prefix *pfx_target_original); /* query target */ - -extern struct rfapi_next_hop_entry * -rfapiRouteTable2NextHopList ( - struct route_table *rt, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rfd_rib_table, /* preload this NVE rib table */ - struct prefix *pfx_target_original); /* query target */ - -extern struct rfapi_next_hop_entry * -rfapiEthRouteTable2NextHopList ( - uint32_t logical_net_id, - struct rfapi_ip_prefix *rprefix, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rib_route_table,/* preload NVE rib node */ - struct prefix *pfx_target_original); /* query target */ - -extern int -rfapiEcommunitiesIntersect (struct ecommunity *e1, struct ecommunity *e2); - -extern void -rfapiCheckRefcount (struct route_node *rn, safi_t safi, int lockoffset); - -extern int -rfapiHasNonRemovedRoutes (struct route_node *rn); - -extern int -rfapiProcessDeferredClose (struct thread *t); - -extern int -rfapiGetUnAddrOfVpnBi (struct bgp_info *bi, struct prefix *p); - -extern void -rfapiNexthop2Prefix (struct attr *attr, struct prefix *p); - -extern void -rfapiUnicastNexthop2Prefix ( - afi_t afi, - struct attr *attr, - struct prefix *p); +extern struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( + struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rfd_rib_table, /* preload this NVE rib table */ + struct prefix *pfx_target_original); /* query target */ + +extern struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList( + struct route_table *rt, + uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rfd_rib_table, /* preload this NVE rib table */ + struct prefix *pfx_target_original); /* query target */ + +extern struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList( + uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix, + uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rib_route_table, /* preload NVE rib node */ + struct prefix *pfx_target_original); /* query target */ + +extern int rfapiEcommunitiesIntersect(struct ecommunity *e1, + struct ecommunity *e2); + +extern void rfapiCheckRefcount(struct route_node *rn, safi_t safi, + int lockoffset); + +extern int rfapiHasNonRemovedRoutes(struct route_node *rn); + +extern int rfapiProcessDeferredClose(struct thread *t); + +extern int rfapiGetUnAddrOfVpnBi(struct bgp_info *bi, struct prefix *p); + +extern void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p); + +extern void rfapiUnicastNexthop2Prefix(afi_t afi, struct attr *attr, + struct prefix *p); /* Filtered Import Function actions */ #define FIF_ACTION_UPDATE 0 #define FIF_ACTION_WITHDRAW 1 #define FIF_ACTION_KILL 2 -extern void -rfapiBgpInfoFilteredImportVPN ( - struct rfapi_import_table *import_table, - int action, - struct peer *peer, - void *rfd, /* set for looped back routes */ - struct prefix *p, - struct prefix *aux_prefix, /* AFI_ETHER: optional IP */ - afi_t afi, - struct prefix_rd *prd, - struct attr *attr, /* part of bgp_info */ - u_char type, /* part of bgp_info */ - u_char sub_type, /* part of bgp_info */ - uint32_t *label); /* part of bgp_info */ - -extern struct rfapi_next_hop_entry * -rfapiEthRouteNode2NextHopList ( - struct route_node *rn, - struct rfapi_ip_prefix *rprefix, - uint32_t lifetime, /* put into nexthop entries */ - struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ - struct route_table *rib_route_table,/* preload NVE rib table */ - struct prefix *pfx_target_original); /* query target */ +extern void rfapiBgpInfoFilteredImportVPN( + struct rfapi_import_table *import_table, int action, struct peer *peer, + void *rfd, /* set for looped back routes */ + struct prefix *p, + struct prefix *aux_prefix, /* AFI_ETHER: optional IP */ + afi_t afi, struct prefix_rd *prd, + struct attr *attr, /* part of bgp_info */ + u_char type, /* part of bgp_info */ + u_char sub_type, /* part of bgp_info */ + uint32_t *label); /* part of bgp_info */ -extern struct rfapi_import_table * -rfapiMacImportTableGetNoAlloc ( - struct bgp *bgp, - uint32_t lni); +extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList( + struct route_node *rn, struct rfapi_ip_prefix *rprefix, + uint32_t lifetime, /* put into nexthop entries */ + struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ + struct route_table *rib_route_table, /* preload NVE rib table */ + struct prefix *pfx_target_original); /* query target */ -extern struct rfapi_import_table * -rfapiMacImportTableGet ( - struct bgp *bgp, - uint32_t lni); +extern struct rfapi_import_table *rfapiMacImportTableGetNoAlloc(struct bgp *bgp, + uint32_t lni); + +extern struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp, + uint32_t lni); -extern int -rfapiGetL2o ( - struct attr *attr, - struct rfapi_l2address_option *l2o); +extern int rfapiGetL2o(struct attr *attr, struct rfapi_l2address_option *l2o); -extern int rfapiEcommunityGetLNI ( - struct ecommunity *ecom, - uint32_t *lni); +extern int rfapiEcommunityGetLNI(struct ecommunity *ecom, uint32_t *lni); -extern int rfapiEcommunityGetEthernetTag ( - struct ecommunity *ecom, - uint16_t * tag_id); +extern int rfapiEcommunityGetEthernetTag(struct ecommunity *ecom, + uint16_t *tag_id); /* enable for debugging; disable for performance */ #if 0 @@ -224,7 +184,7 @@ extern int rfapiEcommunityGetEthernetTag ( * * UI helper: For use by the "clear vnc prefixes" command * - * input: + * input: * un if set, tunnel must match this prefix * vn if set, nexthop prefix must match this prefix * p if set, prefix must match this prefix @@ -239,25 +199,21 @@ extern int rfapiEcommunityGetEthernetTag ( * return value: * void --------------------------------------------*/ -extern void -rfapiDeleteRemotePrefixes ( - struct prefix *un, - struct prefix *vn, - struct prefix *p, - struct rfapi_import_table *it, - int delete_active, - int delete_holddown, - uint32_t *pARcount, /* active routes */ - uint32_t *pAHcount, /* active nves */ - uint32_t *pHRcount, /* holddown routes */ - uint32_t *pHHcount); /* holddown nves */ +extern void rfapiDeleteRemotePrefixes(struct prefix *un, struct prefix *vn, + struct prefix *p, + struct rfapi_import_table *it, + int delete_active, int delete_holddown, + uint32_t *pARcount, /* active routes */ + uint32_t *pAHcount, /* active nves */ + uint32_t *pHRcount, /* holddown routes */ + uint32_t *pHHcount); /* holddown nves */ /*------------------------------------------ * rfapiCountAllItRoutes * * UI helper: count VRF routes from BGP side * - * input: + * input: * * output * pARcount count of active routes @@ -267,19 +223,17 @@ rfapiDeleteRemotePrefixes ( * return value: * void --------------------------------------------*/ -extern void -rfapiCountAllItRoutes ( - int *pALRcount, /* active local routes */ - int *pARRcount, /* active remote routes */ - int *pHRcount, /* holddown routes */ - int *pIRcount); /* direct imported routes */ +extern void rfapiCountAllItRoutes(int *pALRcount, /* active local routes */ + int *pARRcount, /* active remote routes */ + int *pHRcount, /* holddown routes */ + int *pIRcount); /* direct imported routes */ /*------------------------------------------ * rfapiGetHolddownFromLifetime * * calculate holddown value based on lifetime * - * input: + * input: * lifetime lifetime * * return value: @@ -287,7 +241,6 @@ rfapiCountAllItRoutes ( * and RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY * --------------------------------------------*/ -extern uint32_t -rfapiGetHolddownFromLifetime (uint32_t lifetime); +extern uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime); #endif /* QUAGGA_HGP_RFAPI_IMPORT_H */ diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c index 275e448967..9c0d9da6ff 100644 --- a/bgpd/rfapi/rfapi_monitor.c +++ b/bgpd/rfapi/rfapi_monitor.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -54,49 +54,44 @@ #define DEBUG_DUP_CHECK 0 #define DEBUG_ETH_SL 0 -static void -rfapiMonitorTimerRestart (struct rfapi_monitor_vpn *m); +static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m); -static void -rfapiMonitorEthTimerRestart (struct rfapi_monitor_eth *m); +static void rfapiMonitorEthTimerRestart(struct rfapi_monitor_eth *m); /* * Forward declarations */ -static void -rfapiMonitorEthDetachImport (struct bgp *bgp, struct rfapi_monitor_eth *mon); +static void rfapiMonitorEthDetachImport(struct bgp *bgp, + struct rfapi_monitor_eth *mon); #if DEBUG_ETH_SL /* * Debug function, special case */ -void -rfapiMonitorEthSlCheck( - struct route_node *rn, - const char *tag1, - const char *tag2) +void rfapiMonitorEthSlCheck(struct route_node *rn, const char *tag1, + const char *tag2) { - struct route_node *rn_saved = NULL; - static struct skiplist *sl_saved = NULL; - struct skiplist *sl; - - if (!rn) - return; - - if (rn_saved && (rn != rn_saved)) - return; - - if (!rn_saved) - rn_saved = rn; - - sl = RFAPI_MONITOR_ETH(rn); - if (sl || sl_saved) - { - vnc_zlog_debug_verbose("%s[%s%s]: rn=%p, rn->lock=%d, old sl=%p, new sl=%p", - __func__, (tag1? tag1: ""), (tag2? tag2: ""), rn, rn->lock, - sl_saved, sl); - sl_saved = sl; - } + struct route_node *rn_saved = NULL; + static struct skiplist *sl_saved = NULL; + struct skiplist *sl; + + if (!rn) + return; + + if (rn_saved && (rn != rn_saved)) + return; + + if (!rn_saved) + rn_saved = rn; + + sl = RFAPI_MONITOR_ETH(rn); + if (sl || sl_saved) { + vnc_zlog_debug_verbose( + "%s[%s%s]: rn=%p, rn->lock=%d, old sl=%p, new sl=%p", + __func__, (tag1 ? tag1 : ""), (tag2 ? tag2 : ""), rn, + rn->lock, sl_saved, sl); + sl_saved = sl; + } } #endif @@ -104,13 +99,12 @@ rfapiMonitorEthSlCheck( * Debugging function that aborts when it finds monitors whose * "next" pointer * references themselves */ -void -rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain) +void rfapiMonitorLoopCheck(struct rfapi_monitor_vpn *mchain) { - struct rfapi_monitor_vpn *m; + struct rfapi_monitor_vpn *m; - for (m = mchain; m; m = m->next) - assert (m != m->next); + for (m = mchain; m; m = m->next) + assert(m != m->next); } #if DEBUG_DUP_CHECK @@ -118,381 +112,349 @@ rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain) * Debugging code: see if a monitor is mentioned more than once * in a HD's monitor list */ -void -rfapiMonitorDupCheck (struct bgp *bgp) +void rfapiMonitorDupCheck(struct bgp *bgp) { - struct listnode *hnode; - struct rfapi_descriptor *rfd; - - for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, hnode, rfd)) - { - struct route_node *mrn; - - if (!rfd->mon) - continue; - - for (mrn = route_top (rfd->mon); mrn; mrn = route_next (mrn)) - { - struct rfapi_monitor_vpn *m; - for (m = (struct rfapi_monitor_vpn *) (mrn->info); m; m = m->next) - m->dcount = 0; - } - } - - for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, hnode, rfd)) - { - struct route_node *mrn; - - if (!rfd->mon) - continue; - - for (mrn = route_top (rfd->mon); mrn; mrn = route_next (mrn)) - { - struct rfapi_monitor_vpn *m; - - for (m = (struct rfapi_monitor_vpn *) (mrn->info); m; m = m->next) - assert (++m->dcount == 1); - } - } + struct listnode *hnode; + struct rfapi_descriptor *rfd; + + for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { + struct route_node *mrn; + + if (!rfd->mon) + continue; + + for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { + struct rfapi_monitor_vpn *m; + for (m = (struct rfapi_monitor_vpn *)(mrn->info); m; + m = m->next) + m->dcount = 0; + } + } + + for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { + struct route_node *mrn; + + if (!rfd->mon) + continue; + + for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { + struct rfapi_monitor_vpn *m; + + for (m = (struct rfapi_monitor_vpn *)(mrn->info); m; + m = m->next) + assert(++m->dcount == 1); + } + } } #endif /* debug */ -void -rfapiMonitorCleanCheck (struct bgp *bgp) +void rfapiMonitorCleanCheck(struct bgp *bgp) { - struct listnode *hnode; - struct rfapi_descriptor *rfd; + struct listnode *hnode; + struct rfapi_descriptor *rfd; - for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, hnode, rfd)) - { - assert (!rfd->import_table->vpn0_queries[AFI_IP]); - assert (!rfd->import_table->vpn0_queries[AFI_IP6]); + for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { + assert(!rfd->import_table->vpn0_queries[AFI_IP]); + assert(!rfd->import_table->vpn0_queries[AFI_IP6]); - struct route_node *rn; + struct route_node *rn; - for (rn = route_top (rfd->import_table->imported_vpn[AFI_IP]); rn; - rn = route_next (rn)) - { + for (rn = route_top(rfd->import_table->imported_vpn[AFI_IP]); + rn; rn = route_next(rn)) { - assert (!RFAPI_MONITOR_VPN (rn)); - } - for (rn = route_top (rfd->import_table->imported_vpn[AFI_IP6]); rn; - rn = route_next (rn)) - { + assert(!RFAPI_MONITOR_VPN(rn)); + } + for (rn = route_top(rfd->import_table->imported_vpn[AFI_IP6]); + rn; rn = route_next(rn)) { - assert (!RFAPI_MONITOR_VPN (rn)); - } - } + assert(!RFAPI_MONITOR_VPN(rn)); + } + } } /* debug */ -void -rfapiMonitorCheckAttachAllowed (void) +void rfapiMonitorCheckAttachAllowed(void) { - struct bgp *bgp = bgp_get_default (); - assert (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)); + struct bgp *bgp = bgp_get_default(); + assert(!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)); } -void -rfapiMonitorExtraFlush (safi_t safi, struct route_node *rn) +void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn) { - struct rfapi_it_extra *hie; - struct rfapi_monitor_vpn *v; - struct rfapi_monitor_vpn *v_next; - struct rfapi_monitor_encap *e = NULL; - struct rfapi_monitor_encap *e_next = NULL; - - if (!rn) - return; - - if (!rn->aggregate) - return; - - hie = (struct rfapi_it_extra *) (rn->aggregate); - - switch (safi) - { - case SAFI_ENCAP: - for (e = hie->u.encap.e; e; e = e_next) - { - e_next = e->next; - e->next = NULL; - XFREE (MTYPE_RFAPI_MONITOR_ENCAP, e); - route_unlock_node (rn); - } - hie->u.encap.e = NULL; - break; - - case SAFI_MPLS_VPN: - for (v = hie->u.vpn.v; v; v = v_next) - { - v_next = v->next; - v->next = NULL; - XFREE (MTYPE_RFAPI_MONITOR, e); - route_unlock_node (rn); - } - hie->u.vpn.v = NULL; - if (hie->u.vpn.e.source) - { - while (!skiplist_delete_first (hie->u.vpn.e.source)) - { - route_unlock_node (rn); - } - skiplist_free (hie->u.vpn.e.source); - hie->u.vpn.e.source = NULL; - route_unlock_node (rn); - } - if (hie->u.vpn.idx_rd) - { - /* looping through bi->extra->vnc.import.rd is tbd */ - while (!skiplist_delete_first (hie->u.vpn.idx_rd)) - { - route_unlock_node (rn); - } - skiplist_free (hie->u.vpn.idx_rd); - hie->u.vpn.idx_rd = NULL; - route_unlock_node (rn); - } - if (hie->u.vpn.mon_eth) - { - while (!skiplist_delete_first (hie->u.vpn.mon_eth)) - { - route_unlock_node (rn); - } - skiplist_free (hie->u.vpn.mon_eth); - hie->u.vpn.mon_eth = NULL; - route_unlock_node (rn); - } - break; - - default: - assert (0); - } - XFREE (MTYPE_RFAPI_IT_EXTRA, hie); - rn->aggregate = NULL; - route_unlock_node (rn); + struct rfapi_it_extra *hie; + struct rfapi_monitor_vpn *v; + struct rfapi_monitor_vpn *v_next; + struct rfapi_monitor_encap *e = NULL; + struct rfapi_monitor_encap *e_next = NULL; + + if (!rn) + return; + + if (!rn->aggregate) + return; + + hie = (struct rfapi_it_extra *)(rn->aggregate); + + switch (safi) { + case SAFI_ENCAP: + for (e = hie->u.encap.e; e; e = e_next) { + e_next = e->next; + e->next = NULL; + XFREE(MTYPE_RFAPI_MONITOR_ENCAP, e); + route_unlock_node(rn); + } + hie->u.encap.e = NULL; + break; + + case SAFI_MPLS_VPN: + for (v = hie->u.vpn.v; v; v = v_next) { + v_next = v->next; + v->next = NULL; + XFREE(MTYPE_RFAPI_MONITOR, e); + route_unlock_node(rn); + } + hie->u.vpn.v = NULL; + if (hie->u.vpn.e.source) { + while (!skiplist_delete_first(hie->u.vpn.e.source)) { + route_unlock_node(rn); + } + skiplist_free(hie->u.vpn.e.source); + hie->u.vpn.e.source = NULL; + route_unlock_node(rn); + } + if (hie->u.vpn.idx_rd) { + /* looping through bi->extra->vnc.import.rd is tbd */ + while (!skiplist_delete_first(hie->u.vpn.idx_rd)) { + route_unlock_node(rn); + } + skiplist_free(hie->u.vpn.idx_rd); + hie->u.vpn.idx_rd = NULL; + route_unlock_node(rn); + } + if (hie->u.vpn.mon_eth) { + while (!skiplist_delete_first(hie->u.vpn.mon_eth)) { + route_unlock_node(rn); + } + skiplist_free(hie->u.vpn.mon_eth); + hie->u.vpn.mon_eth = NULL; + route_unlock_node(rn); + } + break; + + default: + assert(0); + } + XFREE(MTYPE_RFAPI_IT_EXTRA, hie); + rn->aggregate = NULL; + route_unlock_node(rn); } /* * If the child lists are empty, release the rfapi_it_extra struct */ -void -rfapiMonitorExtraPrune (safi_t safi, struct route_node *rn) +void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn) { - struct rfapi_it_extra *hie; - - if (!rn) - return; - - if (!rn->aggregate) - return; - - hie = (struct rfapi_it_extra *) (rn->aggregate); - - switch (safi) - { - case SAFI_ENCAP: - if (hie->u.encap.e) - return; - break; - - case SAFI_MPLS_VPN: - if (hie->u.vpn.v) - return; - if (hie->u.vpn.mon_eth) - { - if (skiplist_count (hie->u.vpn.mon_eth)) - return; - skiplist_free (hie->u.vpn.mon_eth); - hie->u.vpn.mon_eth = NULL; - route_unlock_node (rn); /* uncount skiplist */ - } - if (hie->u.vpn.e.source) - { - if (skiplist_count (hie->u.vpn.e.source)) - return; - skiplist_free (hie->u.vpn.e.source); - hie->u.vpn.e.source = NULL; - route_unlock_node (rn); - } - if (hie->u.vpn.idx_rd) - { - if (skiplist_count (hie->u.vpn.idx_rd)) - return; - skiplist_free (hie->u.vpn.idx_rd); - hie->u.vpn.idx_rd = NULL; - route_unlock_node (rn); - } - if (hie->u.vpn.mon_eth) - { - if (skiplist_count (hie->u.vpn.mon_eth)) - return; - skiplist_free (hie->u.vpn.mon_eth); - hie->u.vpn.mon_eth = NULL; - route_unlock_node (rn); - } - break; - - default: - assert (0); - } - XFREE (MTYPE_RFAPI_IT_EXTRA, hie); - rn->aggregate = NULL; - route_unlock_node (rn); + struct rfapi_it_extra *hie; + + if (!rn) + return; + + if (!rn->aggregate) + return; + + hie = (struct rfapi_it_extra *)(rn->aggregate); + + switch (safi) { + case SAFI_ENCAP: + if (hie->u.encap.e) + return; + break; + + case SAFI_MPLS_VPN: + if (hie->u.vpn.v) + return; + if (hie->u.vpn.mon_eth) { + if (skiplist_count(hie->u.vpn.mon_eth)) + return; + skiplist_free(hie->u.vpn.mon_eth); + hie->u.vpn.mon_eth = NULL; + route_unlock_node(rn); /* uncount skiplist */ + } + if (hie->u.vpn.e.source) { + if (skiplist_count(hie->u.vpn.e.source)) + return; + skiplist_free(hie->u.vpn.e.source); + hie->u.vpn.e.source = NULL; + route_unlock_node(rn); + } + if (hie->u.vpn.idx_rd) { + if (skiplist_count(hie->u.vpn.idx_rd)) + return; + skiplist_free(hie->u.vpn.idx_rd); + hie->u.vpn.idx_rd = NULL; + route_unlock_node(rn); + } + if (hie->u.vpn.mon_eth) { + if (skiplist_count(hie->u.vpn.mon_eth)) + return; + skiplist_free(hie->u.vpn.mon_eth); + hie->u.vpn.mon_eth = NULL; + route_unlock_node(rn); + } + break; + + default: + assert(0); + } + XFREE(MTYPE_RFAPI_IT_EXTRA, hie); + rn->aggregate = NULL; + route_unlock_node(rn); } /* * returns locked node */ -struct route_node * -rfapiMonitorGetAttachNode (struct rfapi_descriptor *rfd, struct prefix *p) +struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, + struct prefix *p) { - afi_t afi; - struct route_node *rn; - - if (RFAPI_0_PREFIX (p)) - { - assert (1); - } - - afi = family2afi (p->family); - assert (afi); - - /* - * It's possible that even though there is a route at this node, - * there are no routes with valid UN addresses (i.e,. with no - * valid tunnel routes). Check for that and walk back up the - * tree if necessary. - * - * When the outer loop completes, the matched node, if any, is - * locked (i.e., its reference count has been incremented) to - * account for the VPN monitor we are about to attach. - * - * if a monitor is moved to another node, there must be - * corresponding unlock/locks - */ - for (rn = route_node_match (rfd->import_table->imported_vpn[afi], p); rn;) - { - - struct bgp_info *bi; - struct prefix pfx_dummy; - - /* TBD update this code to use new valid_interior_count */ - for (bi = rn->info; bi; bi = bi->next) - { - /* - * If there is a cached ENCAP UN address, it's a usable - * VPN route - */ - if (bi->extra && bi->extra->vnc.import.un_family) - { - break; - } - - /* - * Or if there is a valid Encap Attribute tunnel subtlv address, - * it's a usable VPN route. - */ - if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_dummy)) - { - break; - } - } - if (bi) - break; - - route_unlock_node (rn); - if ((rn = rn->parent)) - { - route_lock_node (rn); - } - } - - if (!rn) - { - struct prefix pfx_default; - - memset (&pfx_default, 0, sizeof (pfx_default)); - pfx_default.family = p->family; - - /* creates default node if none exists, and increments ref count */ - rn = - route_node_get (rfd->import_table->imported_vpn[afi], &pfx_default); - } - - return rn; + afi_t afi; + struct route_node *rn; + + if (RFAPI_0_PREFIX(p)) { + assert(1); + } + + afi = family2afi(p->family); + assert(afi); + + /* + * It's possible that even though there is a route at this node, + * there are no routes with valid UN addresses (i.e,. with no + * valid tunnel routes). Check for that and walk back up the + * tree if necessary. + * + * When the outer loop completes, the matched node, if any, is + * locked (i.e., its reference count has been incremented) to + * account for the VPN monitor we are about to attach. + * + * if a monitor is moved to another node, there must be + * corresponding unlock/locks + */ + for (rn = route_node_match(rfd->import_table->imported_vpn[afi], p); + rn;) { + + struct bgp_info *bi; + struct prefix pfx_dummy; + + /* TBD update this code to use new valid_interior_count */ + for (bi = rn->info; bi; bi = bi->next) { + /* + * If there is a cached ENCAP UN address, it's a usable + * VPN route + */ + if (bi->extra && bi->extra->vnc.import.un_family) { + break; + } + + /* + * Or if there is a valid Encap Attribute tunnel subtlv + * address, + * it's a usable VPN route. + */ + if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_dummy)) { + break; + } + } + if (bi) + break; + + route_unlock_node(rn); + if ((rn = rn->parent)) { + route_lock_node(rn); + } + } + + if (!rn) { + struct prefix pfx_default; + + memset(&pfx_default, 0, sizeof(pfx_default)); + pfx_default.family = p->family; + + /* creates default node if none exists, and increments ref count + */ + rn = route_node_get(rfd->import_table->imported_vpn[afi], + &pfx_default); + } + + return rn; } -/* +/* * If this function happens to attach the monitor to a radix tree * node (as opposed to the 0-prefix list), the node pointer is * returned (for the benefit of caller which might like to use it * to generate an immediate query response). */ -static struct route_node * -rfapiMonitorAttachImport (struct rfapi_descriptor *rfd, - struct rfapi_monitor_vpn *m) +static struct route_node *rfapiMonitorAttachImport(struct rfapi_descriptor *rfd, + struct rfapi_monitor_vpn *m) { - struct route_node *rn; - - rfapiMonitorCheckAttachAllowed (); - - if (RFAPI_0_PREFIX (&m->p)) - { - /* - * Add new monitor entry to vpn0 list - */ - afi_t afi; - - afi = family2afi (m->p.family); - assert (afi); - - m->next = rfd->import_table->vpn0_queries[afi]; - rfd->import_table->vpn0_queries[afi] = m; - vnc_zlog_debug_verbose ("%s: attached monitor %p to vpn0 list", __func__, m); - return NULL; - } - - /* - * Attach new monitor entry to import table node - */ - rn = rfapiMonitorGetAttachNode (rfd, &m->p); /* returns locked rn */ - m->node = rn; - m->next = RFAPI_MONITOR_VPN (rn); - RFAPI_MONITOR_VPN_W_ALLOC (rn) = m; - RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, 0); - vnc_zlog_debug_verbose ("%s: attached monitor %p to rn %p", __func__, m, rn); - return rn; + struct route_node *rn; + + rfapiMonitorCheckAttachAllowed(); + + if (RFAPI_0_PREFIX(&m->p)) { + /* + * Add new monitor entry to vpn0 list + */ + afi_t afi; + + afi = family2afi(m->p.family); + assert(afi); + + m->next = rfd->import_table->vpn0_queries[afi]; + rfd->import_table->vpn0_queries[afi] = m; + vnc_zlog_debug_verbose("%s: attached monitor %p to vpn0 list", + __func__, m); + return NULL; + } + + /* + * Attach new monitor entry to import table node + */ + rn = rfapiMonitorGetAttachNode(rfd, &m->p); /* returns locked rn */ + m->node = rn; + m->next = RFAPI_MONITOR_VPN(rn); + RFAPI_MONITOR_VPN_W_ALLOC(rn) = m; + RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 0); + vnc_zlog_debug_verbose("%s: attached monitor %p to rn %p", __func__, m, + rn); + return rn; } /* * reattach monitors for this HD to import table */ -void -rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd) +void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd) { - struct route_node *mrn; - - if (!rfd->mon) - { - /* - * No monitors for this HD - */ - return; - } - - for (mrn = route_top (rfd->mon); mrn; mrn = route_next (mrn)) - { - - if (!mrn->info) - continue; - - (void) rfapiMonitorAttachImport (rfd, - (struct rfapi_monitor_vpn - *) (mrn->info)); - } + struct route_node *mrn; + + if (!rfd->mon) { + /* + * No monitors for this HD + */ + return; + } + + for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { + + if (!mrn->info) + continue; + + (void)rfapiMonitorAttachImport( + rfd, (struct rfapi_monitor_vpn *)(mrn->info)); + } } /* @@ -506,1198 +468,1123 @@ rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd) * caller will have to do its own lookup. */ struct route_node * -rfapiMonitorAdd ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *p) +rfapiMonitorAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *p) { - struct rfapi_monitor_vpn *m; - struct route_node *rn; - - /* - * Initialize nve's monitor list if needed - * NB use the same radix tree for IPv4 and IPv6 targets. - * The prefix will always have full-length mask (/32, /128) - * or be 0/0 so they won't get mixed up. - */ - if (!rfd->mon) - { - rfd->mon = route_table_init (); - } - rn = route_node_get (rfd->mon, p); - if (rn->info) - { - /* - * received this query before, no further action needed - */ - rfapiMonitorTimerRestart ((struct rfapi_monitor_vpn *) rn->info); - route_unlock_node (rn); - return NULL; - } - - /* - * New query for this nve, record it in the HD - */ - rn->info = XCALLOC (MTYPE_RFAPI_MONITOR, sizeof (struct rfapi_monitor_vpn)); - m = (struct rfapi_monitor_vpn *) (rn->info); - m->rfd = rfd; - prefix_copy (&m->p, p); - - ++rfd->monitor_count; - ++bgp->rfapi->monitor_count; - - rfapiMonitorTimerRestart (m); - - if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) - { - /* - * callbacks turned off, so don't attach monitor to import table - */ - return NULL; - } - - - /* - * attach to import table - */ - return rfapiMonitorAttachImport (rfd, m); + struct rfapi_monitor_vpn *m; + struct route_node *rn; + + /* + * Initialize nve's monitor list if needed + * NB use the same radix tree for IPv4 and IPv6 targets. + * The prefix will always have full-length mask (/32, /128) + * or be 0/0 so they won't get mixed up. + */ + if (!rfd->mon) { + rfd->mon = route_table_init(); + } + rn = route_node_get(rfd->mon, p); + if (rn->info) { + /* + * received this query before, no further action needed + */ + rfapiMonitorTimerRestart((struct rfapi_monitor_vpn *)rn->info); + route_unlock_node(rn); + return NULL; + } + + /* + * New query for this nve, record it in the HD + */ + rn->info = + XCALLOC(MTYPE_RFAPI_MONITOR, sizeof(struct rfapi_monitor_vpn)); + m = (struct rfapi_monitor_vpn *)(rn->info); + m->rfd = rfd; + prefix_copy(&m->p, p); + + ++rfd->monitor_count; + ++bgp->rfapi->monitor_count; + + rfapiMonitorTimerRestart(m); + + if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) { + /* + * callbacks turned off, so don't attach monitor to import table + */ + return NULL; + } + + + /* + * attach to import table + */ + return rfapiMonitorAttachImport(rfd, m); } /* * returns monitor pointer if found, NULL if not */ static struct rfapi_monitor_vpn * -rfapiMonitorDetachImport (struct rfapi_monitor_vpn *m) +rfapiMonitorDetachImport(struct rfapi_monitor_vpn *m) { - struct rfapi_monitor_vpn *prev; - struct rfapi_monitor_vpn *this = NULL; - - if (RFAPI_0_PREFIX (&m->p)) - { - afi_t afi; - - /* - * 0-prefix monitors are stored in a special list and not - * in the import VPN tree - */ - - afi = family2afi (m->p.family); - assert (afi); - - if (m->rfd->import_table) - { - for (prev = NULL, this = m->rfd->import_table->vpn0_queries[afi]; - this; prev = this, this = this->next) - { - - if (this == m) - break; - } - if (this) - { - if (!prev) - { - m->rfd->import_table->vpn0_queries[afi] = this->next; - } - else - { - prev->next = this->next; - } - } - } - } - else - { - - if (m->node) - { - for (prev = NULL, - this = RFAPI_MONITOR_VPN (m->node); - this; prev = this, this = this->next) - { - - if (this == m) - break; - } - if (this) - { - if (prev) - { - prev->next = this->next; - } - else - { - RFAPI_MONITOR_VPN_W_ALLOC (m->node) = this->next; - } - RFAPI_CHECK_REFCOUNT (m->node, SAFI_MPLS_VPN, 1); - route_unlock_node (m->node); - } - m->node = NULL; - } - } - return this; + struct rfapi_monitor_vpn *prev; + struct rfapi_monitor_vpn *this = NULL; + + if (RFAPI_0_PREFIX(&m->p)) { + afi_t afi; + + /* + * 0-prefix monitors are stored in a special list and not + * in the import VPN tree + */ + + afi = family2afi(m->p.family); + assert(afi); + + if (m->rfd->import_table) { + for (prev = NULL, + this = m->rfd->import_table->vpn0_queries[afi]; + this; prev = this, this = this->next) { + + if (this == m) + break; + } + if (this) { + if (!prev) { + m->rfd->import_table + ->vpn0_queries[afi] = + this->next; + } else { + prev->next = this->next; + } + } + } + } else { + + if (m->node) { + for (prev = NULL, this = RFAPI_MONITOR_VPN(m->node); + this; prev = this, this = this->next) { + + if (this == m) + break; + } + if (this) { + if (prev) { + prev->next = this->next; + } else { + RFAPI_MONITOR_VPN_W_ALLOC(m->node) = + this->next; + } + RFAPI_CHECK_REFCOUNT(m->node, SAFI_MPLS_VPN, 1); + route_unlock_node(m->node); + } + m->node = NULL; + } + } + return this; } -void -rfapiMonitorDetachImportHd (struct rfapi_descriptor *rfd) +void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd) { - struct route_node *rn; - - if (!rfd->mon) - return; - - for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) - { - if (rn->info) - { - rfapiMonitorDetachImport ((struct rfapi_monitor_vpn *) (rn->info)); - } - } + struct route_node *rn; + + if (!rfd->mon) + return; + + for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { + if (rn->info) { + rfapiMonitorDetachImport( + (struct rfapi_monitor_vpn *)(rn->info)); + } + } } -void -rfapiMonitorDel ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *p) +void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct prefix *p) { - struct route_node *rn; - struct rfapi_monitor_vpn *m; - - assert (rfd->mon); - rn = route_node_get (rfd->mon, p); /* locks node */ - m = rn->info; - - assert (m); - - /* - * remove from import table - */ - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) - { - rfapiMonitorDetachImport (m); - } - - if (m->timer) - { - thread_cancel (m->timer); - m->timer = NULL; - } - - /* - * remove from rfd list - */ - XFREE (MTYPE_RFAPI_MONITOR, m); - rn->info = NULL; - route_unlock_node (rn); /* undo original lock when created */ - route_unlock_node (rn); /* undo lock in route_node_get */ - - --rfd->monitor_count; - --bgp->rfapi->monitor_count; + struct route_node *rn; + struct rfapi_monitor_vpn *m; + + assert(rfd->mon); + rn = route_node_get(rfd->mon, p); /* locks node */ + m = rn->info; + + assert(m); + + /* + * remove from import table + */ + if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { + rfapiMonitorDetachImport(m); + } + + if (m->timer) { + thread_cancel(m->timer); + m->timer = NULL; + } + + /* + * remove from rfd list + */ + XFREE(MTYPE_RFAPI_MONITOR, m); + rn->info = NULL; + route_unlock_node(rn); /* undo original lock when created */ + route_unlock_node(rn); /* undo lock in route_node_get */ + + --rfd->monitor_count; + --bgp->rfapi->monitor_count; } /* * returns count of monitors deleted */ -int -rfapiMonitorDelHd (struct rfapi_descriptor *rfd) +int rfapiMonitorDelHd(struct rfapi_descriptor *rfd) { - struct route_node *rn; - struct bgp *bgp; - int count = 0; - - vnc_zlog_debug_verbose ("%s: entry rfd=%p", __func__, rfd); - - bgp = bgp_get_default (); - - if (rfd->mon) - { - for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) - { - struct rfapi_monitor_vpn *m; - if ((m = rn->info)) - { - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) - { - rfapiMonitorDetachImport (m); - } - - if (m->timer) - { - thread_cancel (m->timer); - m->timer = NULL; - } - - XFREE (MTYPE_RFAPI_MONITOR, m); - rn->info = NULL; - route_unlock_node (rn); /* undo original lock when created */ - ++count; - --rfd->monitor_count; - --bgp->rfapi->monitor_count; - } - } - route_table_finish (rfd->mon); - rfd->mon = NULL; - } - - if (rfd->mon_eth) - { - - struct rfapi_monitor_eth *mon_eth; - - while (!skiplist_first (rfd->mon_eth, NULL, (void **) &mon_eth)) - { - - int rc; - - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) - { - rfapiMonitorEthDetachImport (bgp, mon_eth); - } - else - { + struct route_node *rn; + struct bgp *bgp; + int count = 0; + + vnc_zlog_debug_verbose("%s: entry rfd=%p", __func__, rfd); + + bgp = bgp_get_default(); + + if (rfd->mon) { + for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { + struct rfapi_monitor_vpn *m; + if ((m = rn->info)) { + if (!(bgp->rfapi_cfg->flags + & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { + rfapiMonitorDetachImport(m); + } + + if (m->timer) { + thread_cancel(m->timer); + m->timer = NULL; + } + + XFREE(MTYPE_RFAPI_MONITOR, m); + rn->info = NULL; + route_unlock_node(rn); /* undo original lock + when created */ + ++count; + --rfd->monitor_count; + --bgp->rfapi->monitor_count; + } + } + route_table_finish(rfd->mon); + rfd->mon = NULL; + } + + if (rfd->mon_eth) { + + struct rfapi_monitor_eth *mon_eth; + + while (!skiplist_first(rfd->mon_eth, NULL, (void **)&mon_eth)) { + + int rc; + + if (!(bgp->rfapi_cfg->flags + & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { + rfapiMonitorEthDetachImport(bgp, mon_eth); + } else { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose - ("%s: callbacks disabled, not attempting to detach mon_eth %p", - __func__, mon_eth); + vnc_zlog_debug_verbose( + "%s: callbacks disabled, not attempting to detach mon_eth %p", + __func__, mon_eth); #endif - } - - if (mon_eth->timer) - { - thread_cancel (mon_eth->timer); - mon_eth->timer = NULL; - } - - /* - * remove from rfd list - */ - rc = skiplist_delete (rfd->mon_eth, mon_eth, mon_eth); - assert (!rc); - - vnc_zlog_debug_verbose ("%s: freeing mon_eth %p", __func__, mon_eth); - XFREE (MTYPE_RFAPI_MONITOR_ETH, mon_eth); - - ++count; - --rfd->monitor_count; - --bgp->rfapi->monitor_count; - } - skiplist_free (rfd->mon_eth); - rfd->mon_eth = NULL; - - } - - return count; + } + + if (mon_eth->timer) { + thread_cancel(mon_eth->timer); + mon_eth->timer = NULL; + } + + /* + * remove from rfd list + */ + rc = skiplist_delete(rfd->mon_eth, mon_eth, mon_eth); + assert(!rc); + + vnc_zlog_debug_verbose("%s: freeing mon_eth %p", + __func__, mon_eth); + XFREE(MTYPE_RFAPI_MONITOR_ETH, mon_eth); + + ++count; + --rfd->monitor_count; + --bgp->rfapi->monitor_count; + } + skiplist_free(rfd->mon_eth); + rfd->mon_eth = NULL; + } + + return count; } -void -rfapiMonitorResponseRemovalOff (struct bgp *bgp) +void rfapiMonitorResponseRemovalOff(struct bgp *bgp) { - if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE) - { - return; - } - bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; + if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE) { + return; + } + bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; } -void -rfapiMonitorResponseRemovalOn (struct bgp *bgp) +void rfapiMonitorResponseRemovalOn(struct bgp *bgp) { - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) - { - return; - } - bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; + if (!(bgp->rfapi_cfg->flags + & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) { + return; + } + bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; } -static int -rfapiMonitorTimerExpire (struct thread *t) +static int rfapiMonitorTimerExpire(struct thread *t) { - struct rfapi_monitor_vpn *m = t->arg; + struct rfapi_monitor_vpn *m = t->arg; - /* forget reference to thread, it's gone */ - m->timer = NULL; + /* forget reference to thread, it's gone */ + m->timer = NULL; - /* delete the monitor */ - rfapiMonitorDel (bgp_get_default (), m->rfd, &m->p); + /* delete the monitor */ + rfapiMonitorDel(bgp_get_default(), m->rfd, &m->p); - return 0; + return 0; } -static void -rfapiMonitorTimerRestart (struct rfapi_monitor_vpn *m) +static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m) { - if (m->timer) - { - unsigned long remain = thread_timer_remain_second (m->timer); - - /* unexpected case, but avoid wraparound problems below */ - if (remain > m->rfd->response_lifetime) - return; - - /* don't restart if we just restarted recently */ - if (m->rfd->response_lifetime - remain < 2) - return; - - thread_cancel (m->timer); - m->timer = NULL; - } - - { - char buf[BUFSIZ]; - - vnc_zlog_debug_verbose ("%s: target %s life %u", __func__, - rfapi_ntop (m->p.family, m->p.u.val, buf, BUFSIZ), - m->rfd->response_lifetime); - } - m->timer = NULL; - thread_add_timer(bm->master, rfapiMonitorTimerExpire, m, m->rfd->response_lifetime, - &m->timer); + if (m->timer) { + unsigned long remain = thread_timer_remain_second(m->timer); + + /* unexpected case, but avoid wraparound problems below */ + if (remain > m->rfd->response_lifetime) + return; + + /* don't restart if we just restarted recently */ + if (m->rfd->response_lifetime - remain < 2) + return; + + thread_cancel(m->timer); + m->timer = NULL; + } + + { + char buf[BUFSIZ]; + + vnc_zlog_debug_verbose( + "%s: target %s life %u", __func__, + rfapi_ntop(m->p.family, m->p.u.val, buf, BUFSIZ), + m->rfd->response_lifetime); + } + m->timer = NULL; + thread_add_timer(bm->master, rfapiMonitorTimerExpire, m, + m->rfd->response_lifetime, &m->timer); } -/* +/* * called when an updated response is sent to the NVE. Per * ticket 255, restart timers for any monitors that could have * been responsible for the response, i.e., any monitors for * the exact prefix or a parent of it. */ -void -rfapiMonitorTimersRestart (struct rfapi_descriptor *rfd, struct prefix *p) +void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p) { - struct route_node *rn; - - if (AF_ETHERNET == p->family) - { - struct rfapi_monitor_eth *mon_eth; - int rc; - void *cursor; - - /* - * XXX match any LNI - */ - for (cursor = NULL, - rc = - skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, &cursor); - rc == 0; - rc = - skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, &cursor)) - { - - if (!memcmp (mon_eth->macaddr.octet, p->u.prefix_eth.octet, - ETHER_ADDR_LEN)) - { - - rfapiMonitorEthTimerRestart (mon_eth); - - } - } - - } - else - { - for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) - { - struct rfapi_monitor_vpn *m; - - if (!((m = rn->info))) - continue; - - /* NB order of test is significant ! */ - if (!m->node || prefix_match (&m->node->p, p)) - { - rfapiMonitorTimerRestart (m); - } - } - } + struct route_node *rn; + + if (AF_ETHERNET == p->family) { + struct rfapi_monitor_eth *mon_eth; + int rc; + void *cursor; + + /* + * XXX match any LNI + */ + for (cursor = NULL, + rc = skiplist_next(rfd->mon_eth, NULL, (void **)&mon_eth, + &cursor); + rc == 0; rc = skiplist_next(rfd->mon_eth, NULL, + (void **)&mon_eth, &cursor)) { + + if (!memcmp(mon_eth->macaddr.octet, + p->u.prefix_eth.octet, ETHER_ADDR_LEN)) { + + rfapiMonitorEthTimerRestart(mon_eth); + } + } + + } else { + for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { + struct rfapi_monitor_vpn *m; + + if (!((m = rn->info))) + continue; + + /* NB order of test is significant ! */ + if (!m->node || prefix_match(&m->node->p, p)) { + rfapiMonitorTimerRestart(m); + } + } + } } /* * Find monitors at this node and all its parents. Call * rfapiRibUpdatePendingNode with this node and all corresponding NVEs. */ -void -rfapiMonitorItNodeChanged ( - struct rfapi_import_table *import_table, - struct route_node *it_node, - struct rfapi_monitor_vpn *monitor_list) /* for base it node, NULL=all */ +void rfapiMonitorItNodeChanged( + struct rfapi_import_table *import_table, struct route_node *it_node, + struct rfapi_monitor_vpn *monitor_list) /* for base it node, NULL=all */ { - struct skiplist *nves_seen; - struct route_node *rn = it_node; - struct bgp *bgp = bgp_get_default (); - afi_t afi = family2afi (rn->p.family); + struct skiplist *nves_seen; + struct route_node *rn = it_node; + struct bgp *bgp = bgp_get_default(); + afi_t afi = family2afi(rn->p.family); #if DEBUG_L2_EXTRA - char buf_prefix[BUFSIZ]; + char buf_prefix[BUFSIZ]; #endif - assert (bgp); - assert (import_table); + assert(bgp); + assert(import_table); - nves_seen = skiplist_new (0, NULL, NULL); + nves_seen = skiplist_new(0, NULL, NULL); #if DEBUG_L2_EXTRA - prefix2str (&it_node->p, buf_prefix, BUFSIZ); - vnc_zlog_debug_verbose ("%s: it=%p, it_node=%p, it_node->prefix=%s", - __func__, import_table, it_node, buf_prefix); + prefix2str(&it_node->p, buf_prefix, BUFSIZ); + vnc_zlog_debug_verbose("%s: it=%p, it_node=%p, it_node->prefix=%s", + __func__, import_table, it_node, buf_prefix); #endif - if (AFI_L2VPN == afi) - { - struct rfapi_monitor_eth *m; - struct skiplist *sl; - void *cursor; - int rc; - - if ((sl = RFAPI_MONITOR_ETH (rn))) - { - - for (cursor = NULL, - rc = skiplist_next (sl, NULL, (void **) &m, (void **) &cursor); - !rc; - rc = skiplist_next (sl, NULL, (void **) &m, (void **) &cursor)) - { - - if (skiplist_search (nves_seen, m->rfd, NULL)) - { - /* - * Haven't done this NVE yet. Add to "seen" list. - */ - assert (!skiplist_insert (nves_seen, m->rfd, NULL)); - - /* - * update its RIB - */ - rfapiRibUpdatePendingNode(bgp, m->rfd, import_table, - it_node, m->rfd->response_lifetime); - } - } - } - - } - else - { - - struct rfapi_monitor_vpn *m; - - if (monitor_list) - { - m = monitor_list; - } - else - { - m = RFAPI_MONITOR_VPN (rn); - } - - do - { - /* - * If we have reached the root node (parent==NULL) and there - * are no routes here (info==NULL), and the IT node that - * changed was not the root node (it_node->parent != NULL), - * then any monitors at this node are here because they had - * no match at all. Therefore, do not send route updates to them - * because we haven't sent them an initial route. - */ - if (!rn->parent && !rn->info && it_node->parent) - break; - - for (; m; m = m->next) - { - - if (RFAPI_0_PREFIX (&m->p)) - { - /* shouldn't happen, but be safe */ - continue; - } - if (skiplist_search (nves_seen, m->rfd, NULL)) - { - /* - * Haven't done this NVE yet. Add to "seen" list. - */ - assert (!skiplist_insert (nves_seen, m->rfd, NULL)); - - { - char buf_attach_pfx[BUFSIZ]; - char buf_target_pfx[BUFSIZ]; - - prefix2str (&m->node->p, buf_attach_pfx, BUFSIZ); - prefix2str (&m->p, buf_target_pfx, BUFSIZ); - vnc_zlog_debug_verbose - ("%s: update rfd %p attached to pfx %s (targ=%s)", - __func__, m->rfd, buf_attach_pfx, buf_target_pfx); - } - - /* - * update its RIB - */ - rfapiRibUpdatePendingNode(bgp, m->rfd, import_table, - it_node, m->rfd->response_lifetime); - } - } - rn = rn->parent; - if (rn) - m = RFAPI_MONITOR_VPN (rn); - } - while (rn); - } - - /* - * All-routes L2 monitors - */ - if (AFI_L2VPN == afi) - { - struct rfapi_monitor_eth *e; + if (AFI_L2VPN == afi) { + struct rfapi_monitor_eth *m; + struct skiplist *sl; + void *cursor; + int rc; + + if ((sl = RFAPI_MONITOR_ETH(rn))) { + + for (cursor = NULL, + rc = skiplist_next(sl, NULL, (void **)&m, + (void **)&cursor); + !rc; rc = skiplist_next(sl, NULL, (void **)&m, + (void **)&cursor)) { + + if (skiplist_search(nves_seen, m->rfd, NULL)) { + /* + * Haven't done this NVE yet. Add to + * "seen" list. + */ + assert(!skiplist_insert(nves_seen, + m->rfd, NULL)); + + /* + * update its RIB + */ + rfapiRibUpdatePendingNode( + bgp, m->rfd, import_table, + it_node, + m->rfd->response_lifetime); + } + } + } + + } else { + + struct rfapi_monitor_vpn *m; + + if (monitor_list) { + m = monitor_list; + } else { + m = RFAPI_MONITOR_VPN(rn); + } + + do { + /* + * If we have reached the root node (parent==NULL) and + * there + * are no routes here (info==NULL), and the IT node that + * changed was not the root node (it_node->parent != + * NULL), + * then any monitors at this node are here because they + * had + * no match at all. Therefore, do not send route updates + * to them + * because we haven't sent them an initial route. + */ + if (!rn->parent && !rn->info && it_node->parent) + break; + + for (; m; m = m->next) { + + if (RFAPI_0_PREFIX(&m->p)) { + /* shouldn't happen, but be safe */ + continue; + } + if (skiplist_search(nves_seen, m->rfd, NULL)) { + /* + * Haven't done this NVE yet. Add to + * "seen" list. + */ + assert(!skiplist_insert(nves_seen, + m->rfd, NULL)); + + { + char buf_attach_pfx[BUFSIZ]; + char buf_target_pfx[BUFSIZ]; + + prefix2str(&m->node->p, + buf_attach_pfx, + BUFSIZ); + prefix2str(&m->p, + buf_target_pfx, + BUFSIZ); + vnc_zlog_debug_verbose( + "%s: update rfd %p attached to pfx %s (targ=%s)", + __func__, m->rfd, + buf_attach_pfx, + buf_target_pfx); + } + + /* + * update its RIB + */ + rfapiRibUpdatePendingNode( + bgp, m->rfd, import_table, + it_node, + m->rfd->response_lifetime); + } + } + rn = rn->parent; + if (rn) + m = RFAPI_MONITOR_VPN(rn); + } while (rn); + } + + /* + * All-routes L2 monitors + */ + if (AFI_L2VPN == afi) { + struct rfapi_monitor_eth *e; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: checking L2 all-routes monitors", __func__); + vnc_zlog_debug_verbose("%s: checking L2 all-routes monitors", + __func__); #endif - for (e = import_table->eth0_queries; e; e = e->next) - { + for (e = import_table->eth0_queries; e; e = e->next) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: checking eth0 mon=%p", __func__, e); + vnc_zlog_debug_verbose("%s: checking eth0 mon=%p", + __func__, e); #endif - if (skiplist_search (nves_seen, e->rfd, NULL)) - { - /* - * Haven't done this NVE yet. Add to "seen" list. - */ - assert (!skiplist_insert (nves_seen, e->rfd, NULL)); - - /* - * update its RIB - */ + if (skiplist_search(nves_seen, e->rfd, NULL)) { + /* + * Haven't done this NVE yet. Add to "seen" + * list. + */ + assert(!skiplist_insert(nves_seen, e->rfd, + NULL)); + +/* + * update its RIB + */ #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: found L2 all-routes monitor %p", __func__, e); + vnc_zlog_debug_verbose( + "%s: found L2 all-routes monitor %p", + __func__, e); #endif - rfapiRibUpdatePendingNode (bgp, e->rfd, import_table, it_node, - e->rfd->response_lifetime); - } - } - } - else - { - struct rfapi_monitor_vpn *m; - - /* - * All-routes IPv4. IPv6 monitors - */ - for (m = import_table->vpn0_queries[afi]; m; m = m->next) - { - if (skiplist_search (nves_seen, m->rfd, NULL)) - { - /* - * Haven't done this NVE yet. Add to "seen" list. - */ - assert (!skiplist_insert (nves_seen, m->rfd, NULL)); - - /* - * update its RIB - */ - rfapiRibUpdatePendingNode (bgp, m->rfd, import_table, it_node, - m->rfd->response_lifetime); - } - } - } - - skiplist_free (nves_seen); + rfapiRibUpdatePendingNode( + bgp, e->rfd, import_table, it_node, + e->rfd->response_lifetime); + } + } + } else { + struct rfapi_monitor_vpn *m; + + /* + * All-routes IPv4. IPv6 monitors + */ + for (m = import_table->vpn0_queries[afi]; m; m = m->next) { + if (skiplist_search(nves_seen, m->rfd, NULL)) { + /* + * Haven't done this NVE yet. Add to "seen" + * list. + */ + assert(!skiplist_insert(nves_seen, m->rfd, + NULL)); + + /* + * update its RIB + */ + rfapiRibUpdatePendingNode( + bgp, m->rfd, import_table, it_node, + m->rfd->response_lifetime); + } + } + } + + skiplist_free(nves_seen); } /* * For the listed monitors, update new node and its subtree, but * omit old node and its subtree */ -void -rfapiMonitorMovedUp ( - struct rfapi_import_table *import_table, - struct route_node *old_node, - struct route_node *new_node, - struct rfapi_monitor_vpn *monitor_list) +void rfapiMonitorMovedUp(struct rfapi_import_table *import_table, + struct route_node *old_node, + struct route_node *new_node, + struct rfapi_monitor_vpn *monitor_list) { - struct bgp *bgp = bgp_get_default (); - struct rfapi_monitor_vpn *m; - - assert (new_node); - assert (old_node); - assert (new_node != old_node); - - /* - * If new node is 0/0 and there is no route there, don't - * generate an update because it will not contain any - * routes including the target. - */ - if (!new_node->parent && !new_node->info) - { - vnc_zlog_debug_verbose ("%s: new monitor at 0/0 and no routes, no updates", - __func__); - return; - } - - for (m = monitor_list; m; m = m->next) - { - rfapiRibUpdatePendingNode (bgp, m->rfd, import_table, new_node, - m->rfd->response_lifetime); - rfapiRibUpdatePendingNodeSubtree (bgp, m->rfd, import_table, new_node, - old_node, m->rfd->response_lifetime); - } + struct bgp *bgp = bgp_get_default(); + struct rfapi_monitor_vpn *m; + + assert(new_node); + assert(old_node); + assert(new_node != old_node); + + /* + * If new node is 0/0 and there is no route there, don't + * generate an update because it will not contain any + * routes including the target. + */ + if (!new_node->parent && !new_node->info) { + vnc_zlog_debug_verbose( + "%s: new monitor at 0/0 and no routes, no updates", + __func__); + return; + } + + for (m = monitor_list; m; m = m->next) { + rfapiRibUpdatePendingNode(bgp, m->rfd, import_table, new_node, + m->rfd->response_lifetime); + rfapiRibUpdatePendingNodeSubtree(bgp, m->rfd, import_table, + new_node, old_node, + m->rfd->response_lifetime); + } } -static int -rfapiMonitorEthTimerExpire (struct thread *t) +static int rfapiMonitorEthTimerExpire(struct thread *t) { - struct rfapi_monitor_eth *m = t->arg; + struct rfapi_monitor_eth *m = t->arg; - /* forget reference to thread, it's gone */ - m->timer = NULL; + /* forget reference to thread, it's gone */ + m->timer = NULL; - /* delete the monitor */ - rfapiMonitorEthDel (bgp_get_default (), m->rfd, &m->macaddr, - m->logical_net_id); + /* delete the monitor */ + rfapiMonitorEthDel(bgp_get_default(), m->rfd, &m->macaddr, + m->logical_net_id); - return 0; + return 0; } -static void -rfapiMonitorEthTimerRestart (struct rfapi_monitor_eth *m) +static void rfapiMonitorEthTimerRestart(struct rfapi_monitor_eth *m) { - if (m->timer) - { - unsigned long remain = thread_timer_remain_second (m->timer); - - /* unexpected case, but avoid wraparound problems below */ - if (remain > m->rfd->response_lifetime) - return; - - /* don't restart if we just restarted recently */ - if (m->rfd->response_lifetime - remain < 2) - return; - - thread_cancel (m->timer); - m->timer = NULL; - } - - { - char buf[BUFSIZ]; - - vnc_zlog_debug_verbose ("%s: target %s life %u", __func__, - rfapiEthAddr2Str (&m->macaddr, buf, BUFSIZ), - m->rfd->response_lifetime); - } - m->timer = NULL; - thread_add_timer(bm->master, rfapiMonitorEthTimerExpire, m, m->rfd->response_lifetime, - &m->timer); + if (m->timer) { + unsigned long remain = thread_timer_remain_second(m->timer); + + /* unexpected case, but avoid wraparound problems below */ + if (remain > m->rfd->response_lifetime) + return; + + /* don't restart if we just restarted recently */ + if (m->rfd->response_lifetime - remain < 2) + return; + + thread_cancel(m->timer); + m->timer = NULL; + } + + { + char buf[BUFSIZ]; + + vnc_zlog_debug_verbose( + "%s: target %s life %u", __func__, + rfapiEthAddr2Str(&m->macaddr, buf, BUFSIZ), + m->rfd->response_lifetime); + } + m->timer = NULL; + thread_add_timer(bm->master, rfapiMonitorEthTimerExpire, m, + m->rfd->response_lifetime, &m->timer); } -static int -mon_eth_cmp (void *a, void *b) +static int mon_eth_cmp(void *a, void *b) { - struct rfapi_monitor_eth *m1; - struct rfapi_monitor_eth *m2; - - int i; - - m1 = (struct rfapi_monitor_eth *) a; - m2 = (struct rfapi_monitor_eth *) b; - - /* - * compare ethernet addresses - */ - for (i = 0; i < ETHER_ADDR_LEN; ++i) - { - if (m1->macaddr.octet[i] != m2->macaddr.octet[i]) - return (m1->macaddr.octet[i] - m2->macaddr.octet[i]); - } - - /* - * compare LNIs - */ - return (m1->logical_net_id - m2->logical_net_id); + struct rfapi_monitor_eth *m1; + struct rfapi_monitor_eth *m2; + + int i; + + m1 = (struct rfapi_monitor_eth *)a; + m2 = (struct rfapi_monitor_eth *)b; + + /* + * compare ethernet addresses + */ + for (i = 0; i < ETHER_ADDR_LEN; ++i) { + if (m1->macaddr.octet[i] != m2->macaddr.octet[i]) + return (m1->macaddr.octet[i] - m2->macaddr.octet[i]); + } + + /* + * compare LNIs + */ + return (m1->logical_net_id - m2->logical_net_id); } -static void -rfapiMonitorEthAttachImport ( - struct rfapi_import_table *it, - struct route_node *rn, /* it node attach point if non-0 */ - struct rfapi_monitor_eth *mon) /* monitor struct to attach */ +static void rfapiMonitorEthAttachImport( + struct rfapi_import_table *it, + struct route_node *rn, /* it node attach point if non-0 */ + struct rfapi_monitor_eth *mon) /* monitor struct to attach */ { - struct skiplist *sl; - int rc; + struct skiplist *sl; + int rc; - vnc_zlog_debug_verbose ("%s: it=%p", __func__, it); + vnc_zlog_debug_verbose("%s: it=%p", __func__, it); - rfapiMonitorCheckAttachAllowed (); + rfapiMonitorCheckAttachAllowed(); - if (RFAPI_0_ETHERADDR (&mon->macaddr)) - { - /* - * These go on a different list - */ - mon->next = it->eth0_queries; - it->eth0_queries = mon; + if (RFAPI_0_ETHERADDR(&mon->macaddr)) { + /* + * These go on a different list + */ + mon->next = it->eth0_queries; + it->eth0_queries = mon; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: attached monitor %p to eth0 list", __func__, mon); + vnc_zlog_debug_verbose("%s: attached monitor %p to eth0 list", + __func__, mon); #endif - return; - } + return; + } - if (rn == NULL) - { + if (rn == NULL) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: rn is null!", __func__); + vnc_zlog_debug_verbose("%s: rn is null!", __func__); #endif - return; - } - - /* - * Get sl to attach to - */ - sl = RFAPI_MONITOR_ETH_W_ALLOC (rn); - if (!sl) - { - sl = RFAPI_MONITOR_ETH_W_ALLOC (rn) = skiplist_new (0, NULL, NULL); - route_lock_node(rn); /* count skiplist mon_eth */ - } + return; + } + + /* + * Get sl to attach to + */ + sl = RFAPI_MONITOR_ETH_W_ALLOC(rn); + if (!sl) { + sl = RFAPI_MONITOR_ETH_W_ALLOC(rn) = + skiplist_new(0, NULL, NULL); + route_lock_node(rn); /* count skiplist mon_eth */ + } #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: rn=%p, rn->lock=%d, sl=%p, attaching eth mon %p", - __func__, rn, rn->lock, sl, mon); + vnc_zlog_debug_verbose( + "%s: rn=%p, rn->lock=%d, sl=%p, attaching eth mon %p", __func__, + rn, rn->lock, sl, mon); #endif - rc = skiplist_insert (sl, (void *) mon, (void *) mon); - assert (!rc); + rc = skiplist_insert(sl, (void *)mon, (void *)mon); + assert(!rc); - /* count eth monitor */ - route_lock_node(rn); + /* count eth monitor */ + route_lock_node(rn); } /* * reattach monitors for this HD to import table */ -static void -rfapiMonitorEthAttachImportHd (struct bgp *bgp, struct rfapi_descriptor *rfd) +static void rfapiMonitorEthAttachImportHd(struct bgp *bgp, + struct rfapi_descriptor *rfd) { - void *cursor; - struct rfapi_monitor_eth *mon; - int rc; - - if (!rfd->mon_eth) - { - /* - * No monitors for this HD - */ - return; - } - - for (cursor = NULL, - rc = skiplist_next (rfd->mon_eth, NULL, (void **) &mon, &cursor); - rc == 0; - rc = skiplist_next (rfd->mon_eth, NULL, (void **) &mon, &cursor)) - { - - struct rfapi_import_table *it; - struct prefix pfx_mac_buf; - struct route_node *rn; - - it = rfapiMacImportTableGet (bgp, mon->logical_net_id); - assert (it); - - memset ((void *) &pfx_mac_buf, 0, sizeof (struct prefix)); - pfx_mac_buf.family = AF_ETHERNET; - pfx_mac_buf.prefixlen = 48; - pfx_mac_buf.u.prefix_eth = mon->macaddr; - - rn = route_node_get (it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); - assert (rn); - - (void) rfapiMonitorEthAttachImport (it, rn, mon); - } + void *cursor; + struct rfapi_monitor_eth *mon; + int rc; + + if (!rfd->mon_eth) { + /* + * No monitors for this HD + */ + return; + } + + for (cursor = NULL, + rc = skiplist_next(rfd->mon_eth, NULL, (void **)&mon, &cursor); + rc == 0; + rc = skiplist_next(rfd->mon_eth, NULL, (void **)&mon, &cursor)) { + + struct rfapi_import_table *it; + struct prefix pfx_mac_buf; + struct route_node *rn; + + it = rfapiMacImportTableGet(bgp, mon->logical_net_id); + assert(it); + + memset((void *)&pfx_mac_buf, 0, sizeof(struct prefix)); + pfx_mac_buf.family = AF_ETHERNET; + pfx_mac_buf.prefixlen = 48; + pfx_mac_buf.u.prefix_eth = mon->macaddr; + + rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); + assert(rn); + + (void)rfapiMonitorEthAttachImport(it, rn, mon); + } } -static void -rfapiMonitorEthDetachImport ( - struct bgp *bgp, - struct rfapi_monitor_eth *mon) /* monitor struct to detach */ +static void rfapiMonitorEthDetachImport( + struct bgp *bgp, + struct rfapi_monitor_eth *mon) /* monitor struct to detach */ { - struct rfapi_import_table *it; - struct prefix pfx_mac_buf; - struct skiplist *sl; - struct route_node *rn; - int rc; - - it = rfapiMacImportTableGet (bgp, mon->logical_net_id); - assert (it); - - if (RFAPI_0_ETHERADDR (&mon->macaddr)) - { - struct rfapi_monitor_eth *prev; - struct rfapi_monitor_eth *this = NULL; - - for (prev = NULL, - this = it->eth0_queries; this; prev = this, this = this->next) - { - - if (this == mon) - break; - } - if (this) - { - if (!prev) - { - it->eth0_queries = this->next; - } - else - { - prev->next = this->next; - } - } + struct rfapi_import_table *it; + struct prefix pfx_mac_buf; + struct skiplist *sl; + struct route_node *rn; + int rc; + + it = rfapiMacImportTableGet(bgp, mon->logical_net_id); + assert(it); + + if (RFAPI_0_ETHERADDR(&mon->macaddr)) { + struct rfapi_monitor_eth *prev; + struct rfapi_monitor_eth *this = NULL; + + for (prev = NULL, this = it->eth0_queries; this; + prev = this, this = this->next) { + + if (this == mon) + break; + } + if (this) { + if (!prev) { + it->eth0_queries = this->next; + } else { + prev->next = this->next; + } + } #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: it=%p, LNI=%d, detached eth0 mon %p", - __func__, it, mon->logical_net_id, mon); + vnc_zlog_debug_verbose( + "%s: it=%p, LNI=%d, detached eth0 mon %p", __func__, it, + mon->logical_net_id, mon); #endif - return; - } + return; + } - memset ((void *) &pfx_mac_buf, 0, sizeof (struct prefix)); - pfx_mac_buf.family = AF_ETHERNET; - pfx_mac_buf.prefixlen = 48; - pfx_mac_buf.u.prefix_eth = mon->macaddr; + memset((void *)&pfx_mac_buf, 0, sizeof(struct prefix)); + pfx_mac_buf.family = AF_ETHERNET; + pfx_mac_buf.prefixlen = 48; + pfx_mac_buf.u.prefix_eth = mon->macaddr; - rn = route_node_get (it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); - assert (rn); + rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); + assert(rn); #if DEBUG_L2_EXTRA - char buf_prefix[BUFSIZ]; - prefix2str (&rn->p, buf_prefix, BUFSIZ); + char buf_prefix[BUFSIZ]; + prefix2str(&rn->p, buf_prefix, BUFSIZ); #endif - /* - * Get sl to detach from - */ - sl = RFAPI_MONITOR_ETH (rn); + /* + * Get sl to detach from + */ + sl = RFAPI_MONITOR_ETH(rn); #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: it=%p, rn=%p, rn->lock=%d, sl=%p, pfx=%s, LNI=%d, detaching eth mon %p", - __func__, it, rn, rn->lock, sl, buf_prefix, mon->logical_net_id, mon); + vnc_zlog_debug_verbose( + "%s: it=%p, rn=%p, rn->lock=%d, sl=%p, pfx=%s, LNI=%d, detaching eth mon %p", + __func__, it, rn, rn->lock, sl, buf_prefix, mon->logical_net_id, + mon); #endif - assert (sl); + assert(sl); - rc = skiplist_delete (sl, (void *) mon, (void *) mon); - assert (!rc); + rc = skiplist_delete(sl, (void *)mon, (void *)mon); + assert(!rc); - /* uncount eth monitor */ - route_unlock_node(rn); + /* uncount eth monitor */ + route_unlock_node(rn); } -struct route_node * -rfapiMonitorEthAdd ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct ethaddr *macaddr, - uint32_t logical_net_id) +struct route_node *rfapiMonitorEthAdd(struct bgp *bgp, + struct rfapi_descriptor *rfd, + struct ethaddr *macaddr, + uint32_t logical_net_id) { - int rc; - struct rfapi_monitor_eth mon_buf; - struct rfapi_monitor_eth *val; - struct rfapi_import_table *it; - struct route_node *rn = NULL; - struct prefix pfx_mac_buf; - - if (!rfd->mon_eth) - { - rfd->mon_eth = skiplist_new (0, mon_eth_cmp, NULL); - } - - it = rfapiMacImportTableGet (bgp, logical_net_id); - assert (it); - - /* - * Get route node in import table. Here is where we attach the - * monitor. - * - * Look it up now because we return it to caller regardless of - * whether we create a new monitor or not. - */ - memset ((void *) &pfx_mac_buf, 0, sizeof (struct prefix)); - pfx_mac_buf.family = AF_ETHERNET; - pfx_mac_buf.prefixlen = 48; - pfx_mac_buf.u.prefix_eth = *macaddr; - - if (!RFAPI_0_ETHERADDR (macaddr)) - { - rn = route_node_get (it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); - assert (rn); - } - - memset ((void *) &mon_buf, 0, sizeof (mon_buf)); - mon_buf.rfd = rfd; - mon_buf.macaddr = *macaddr; - mon_buf.logical_net_id = logical_net_id; - - { - char buf[BUFSIZ]; - - vnc_zlog_debug_verbose ("%s: LNI=%d: rfd=%p, pfx=%s", - __func__, logical_net_id, rfd, - rfapi_ntop (pfx_mac_buf.family, pfx_mac_buf.u.val, buf, - BUFSIZ)); - } - - - /* - * look up query - */ - rc = skiplist_search (rfd->mon_eth, (void *) &mon_buf, (void **) &val); - if (!rc) - { - /* - * Found monitor - we have seen this query before - * restart timer - */ - vnc_zlog_debug_verbose ("%s: already present in rfd->mon_eth, not adding", - __func__); - rfapiMonitorEthTimerRestart (val); - return rn; - } - - /* - * New query - */ - val = XCALLOC (MTYPE_RFAPI_MONITOR_ETH, sizeof (struct rfapi_monitor_eth)); - assert (val); - *val = mon_buf; - - ++rfd->monitor_count; - ++bgp->rfapi->monitor_count; - - rc = skiplist_insert (rfd->mon_eth, val, val); + int rc; + struct rfapi_monitor_eth mon_buf; + struct rfapi_monitor_eth *val; + struct rfapi_import_table *it; + struct route_node *rn = NULL; + struct prefix pfx_mac_buf; + + if (!rfd->mon_eth) { + rfd->mon_eth = skiplist_new(0, mon_eth_cmp, NULL); + } + + it = rfapiMacImportTableGet(bgp, logical_net_id); + assert(it); + + /* + * Get route node in import table. Here is where we attach the + * monitor. + * + * Look it up now because we return it to caller regardless of + * whether we create a new monitor or not. + */ + memset((void *)&pfx_mac_buf, 0, sizeof(struct prefix)); + pfx_mac_buf.family = AF_ETHERNET; + pfx_mac_buf.prefixlen = 48; + pfx_mac_buf.u.prefix_eth = *macaddr; + + if (!RFAPI_0_ETHERADDR(macaddr)) { + rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); + assert(rn); + } + + memset((void *)&mon_buf, 0, sizeof(mon_buf)); + mon_buf.rfd = rfd; + mon_buf.macaddr = *macaddr; + mon_buf.logical_net_id = logical_net_id; + + { + char buf[BUFSIZ]; + + vnc_zlog_debug_verbose( + "%s: LNI=%d: rfd=%p, pfx=%s", __func__, logical_net_id, + rfd, rfapi_ntop(pfx_mac_buf.family, pfx_mac_buf.u.val, + buf, BUFSIZ)); + } + + + /* + * look up query + */ + rc = skiplist_search(rfd->mon_eth, (void *)&mon_buf, (void **)&val); + if (!rc) { + /* + * Found monitor - we have seen this query before + * restart timer + */ + vnc_zlog_debug_verbose( + "%s: already present in rfd->mon_eth, not adding", + __func__); + rfapiMonitorEthTimerRestart(val); + return rn; + } + + /* + * New query + */ + val = XCALLOC(MTYPE_RFAPI_MONITOR_ETH, + sizeof(struct rfapi_monitor_eth)); + assert(val); + *val = mon_buf; + + ++rfd->monitor_count; + ++bgp->rfapi->monitor_count; + + rc = skiplist_insert(rfd->mon_eth, val, val); #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: inserted rfd=%p mon_eth=%p, rc=%d", __func__, rfd, val, - rc); + vnc_zlog_debug_verbose("%s: inserted rfd=%p mon_eth=%p, rc=%d", + __func__, rfd, val, rc); #endif - /* - * start timer - */ - rfapiMonitorEthTimerRestart (val); + /* + * start timer + */ + rfapiMonitorEthTimerRestart(val); - if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) - { - /* - * callbacks turned off, so don't attach monitor to import table - */ + if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) { +/* + * callbacks turned off, so don't attach monitor to import table + */ #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose - ("%s: callbacks turned off, not attaching mon_eth %p to import table", - __func__, val); + vnc_zlog_debug_verbose( + "%s: callbacks turned off, not attaching mon_eth %p to import table", + __func__, val); #endif - return rn; - } + return rn; + } - /* - * attach to import table - */ - rfapiMonitorEthAttachImport (it, rn, val); + /* + * attach to import table + */ + rfapiMonitorEthAttachImport(it, rn, val); - return rn; + return rn; } -void -rfapiMonitorEthDel ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct ethaddr *macaddr, - uint32_t logical_net_id) +void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct ethaddr *macaddr, uint32_t logical_net_id) { - struct rfapi_monitor_eth *val; - struct rfapi_monitor_eth mon_buf; - int rc; + struct rfapi_monitor_eth *val; + struct rfapi_monitor_eth mon_buf; + int rc; - vnc_zlog_debug_verbose ("%s: entry rfd=%p", __func__, rfd); + vnc_zlog_debug_verbose("%s: entry rfd=%p", __func__, rfd); - assert (rfd->mon_eth); + assert(rfd->mon_eth); - memset ((void *) &mon_buf, 0, sizeof (mon_buf)); - mon_buf.macaddr = *macaddr; - mon_buf.logical_net_id = logical_net_id; + memset((void *)&mon_buf, 0, sizeof(mon_buf)); + mon_buf.macaddr = *macaddr; + mon_buf.logical_net_id = logical_net_id; - rc = skiplist_search (rfd->mon_eth, (void *) &mon_buf, (void **) &val); - assert (!rc); + rc = skiplist_search(rfd->mon_eth, (void *)&mon_buf, (void **)&val); + assert(!rc); - /* - * remove from import table - */ - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) - { - rfapiMonitorEthDetachImport (bgp, val); - } + /* + * remove from import table + */ + if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { + rfapiMonitorEthDetachImport(bgp, val); + } - if (val->timer) - { - thread_cancel (val->timer); - val->timer = NULL; - } + if (val->timer) { + thread_cancel(val->timer); + val->timer = NULL; + } - /* - * remove from rfd list - */ - rc = skiplist_delete (rfd->mon_eth, val, val); - assert (!rc); + /* + * remove from rfd list + */ + rc = skiplist_delete(rfd->mon_eth, val, val); + assert(!rc); #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: freeing mon_eth %p", __func__, val); + vnc_zlog_debug_verbose("%s: freeing mon_eth %p", __func__, val); #endif - XFREE (MTYPE_RFAPI_MONITOR_ETH, val); + XFREE(MTYPE_RFAPI_MONITOR_ETH, val); - --rfd->monitor_count; - --bgp->rfapi->monitor_count; + --rfd->monitor_count; + --bgp->rfapi->monitor_count; } -void -rfapiMonitorCallbacksOff (struct bgp *bgp) +void rfapiMonitorCallbacksOff(struct bgp *bgp) { - struct rfapi_import_table *it; - afi_t afi; - struct route_table *rt; - struct route_node *rn; - void *cursor; - int rc; - struct rfapi *h = bgp->rfapi; - - if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) - { - /* - * Already off. - */ - return; - } - bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE; + struct rfapi_import_table *it; + afi_t afi; + struct route_table *rt; + struct route_node *rn; + void *cursor; + int rc; + struct rfapi *h = bgp->rfapi; + + if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) { + /* + * Already off. + */ + return; + } + bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: turned off callbacks", __func__); + vnc_zlog_debug_verbose("%s: turned off callbacks", __func__); #endif - if (h == NULL) - return; - /* - * detach monitors from import VPN tables. The monitors - * will still be linked in per-nve monitor lists. - */ - for (it = h->imports; it; it = it->next) - { - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - struct rfapi_monitor_vpn *m; - struct rfapi_monitor_vpn *next; - - rt = it->imported_vpn[afi]; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - m = RFAPI_MONITOR_VPN (rn); - if (RFAPI_MONITOR_VPN (rn)) - RFAPI_MONITOR_VPN_W_ALLOC (rn) = NULL; - for (; m; m = next) - { - next = m->next; - m->next = NULL; /* gratuitous safeness */ - m->node = NULL; - route_unlock_node (rn); /* uncount */ - } - } - - for (m = it->vpn0_queries[afi]; m; m = next) - { - next = m->next; - m->next = NULL; /* gratuitous safeness */ - m->node = NULL; - } - it->vpn0_queries[afi] = NULL; /* detach first monitor */ - } - } - - /* - * detach monitors from import Eth tables. The monitors - * will still be linked in per-nve monitor lists. - */ - - /* - * Loop over ethernet import tables - */ - for (cursor = NULL, - rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); - !rc; rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) - { - struct rfapi_monitor_eth *e; - struct rfapi_monitor_eth *enext; - - /* - * The actual route table - */ - rt = it->imported_vpn[AFI_L2VPN]; - - /* - * Find non-0 monitors (i.e., actual addresses, not FTD monitors) - */ - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - struct skiplist *sl; - - sl = RFAPI_MONITOR_ETH (rn); - while (!skiplist_delete_first(sl)) - { - route_unlock_node (rn); /* uncount monitor */ - } - } - - /* - * Find 0-monitors (FTD queries) - */ - for (e = it->eth0_queries; e; e = enext) - { + if (h == NULL) + return; + /* + * detach monitors from import VPN tables. The monitors + * will still be linked in per-nve monitor lists. + */ + for (it = h->imports; it; it = it->next) { + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + struct rfapi_monitor_vpn *m; + struct rfapi_monitor_vpn *next; + + rt = it->imported_vpn[afi]; + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + m = RFAPI_MONITOR_VPN(rn); + if (RFAPI_MONITOR_VPN(rn)) + RFAPI_MONITOR_VPN_W_ALLOC(rn) = NULL; + for (; m; m = next) { + next = m->next; + m->next = + NULL; /* gratuitous safeness */ + m->node = NULL; + route_unlock_node(rn); /* uncount */ + } + } + + for (m = it->vpn0_queries[afi]; m; m = next) { + next = m->next; + m->next = NULL; /* gratuitous safeness */ + m->node = NULL; + } + it->vpn0_queries[afi] = NULL; /* detach first monitor */ + } + } + + /* + * detach monitors from import Eth tables. The monitors + * will still be linked in per-nve monitor lists. + */ + + /* + * Loop over ethernet import tables + */ + for (cursor = NULL, + rc = skiplist_next(h->import_mac, NULL, (void **)&it, &cursor); + !rc; + rc = skiplist_next(h->import_mac, NULL, (void **)&it, &cursor)) { + struct rfapi_monitor_eth *e; + struct rfapi_monitor_eth *enext; + + /* + * The actual route table + */ + rt = it->imported_vpn[AFI_L2VPN]; + + /* + * Find non-0 monitors (i.e., actual addresses, not FTD + * monitors) + */ + for (rn = route_top(rt); rn; rn = route_next(rn)) { + struct skiplist *sl; + + sl = RFAPI_MONITOR_ETH(rn); + while (!skiplist_delete_first(sl)) { + route_unlock_node(rn); /* uncount monitor */ + } + } + + /* + * Find 0-monitors (FTD queries) + */ + for (e = it->eth0_queries; e; e = enext) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: detaching eth0 mon %p", __func__, e); + vnc_zlog_debug_verbose("%s: detaching eth0 mon %p", + __func__, e); #endif - enext = e->next; - e->next = NULL; /* gratuitous safeness */ - } - it->eth0_queries = NULL; /* detach first monitor */ - } + enext = e->next; + e->next = NULL; /* gratuitous safeness */ + } + it->eth0_queries = NULL; /* detach first monitor */ + } } -void -rfapiMonitorCallbacksOn (struct bgp *bgp) +void rfapiMonitorCallbacksOn(struct bgp *bgp) { - struct listnode *hnode; - struct rfapi_descriptor *rfd; - - if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) - { - /* - * Already on. It's important that we don't try to reattach - * monitors that are already attached because, in the interest - * of performance, there is no checking at the lower level - * whether a monitor is already attached. It leads to - * corrupted chains (e.g., looped pointers) - */ - return; - } - bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE; + struct listnode *hnode; + struct rfapi_descriptor *rfd; + + if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { + /* + * Already on. It's important that we don't try to reattach + * monitors that are already attached because, in the interest + * of performance, there is no checking at the lower level + * whether a monitor is already attached. It leads to + * corrupted chains (e.g., looped pointers) + */ + return; + } + bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: turned on callbacks", __func__); + vnc_zlog_debug_verbose("%s: turned on callbacks", __func__); #endif - if (bgp->rfapi == NULL) - return; - - /* - * reattach monitors - */ - for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, hnode, rfd)) - { - - rfapiMonitorAttachImportHd (rfd); - rfapiMonitorEthAttachImportHd (bgp, rfd); - } + if (bgp->rfapi == NULL) + return; + + /* + * reattach monitors + */ + for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { + + rfapiMonitorAttachImportHd(rfd); + rfapiMonitorEthAttachImportHd(bgp, rfd); + } } diff --git a/bgpd/rfapi/rfapi_monitor.h b/bgpd/rfapi/rfapi_monitor.h index 667d61ec1d..edc9744cdb 100644 --- a/bgpd/rfapi/rfapi_monitor.h +++ b/bgpd/rfapi/rfapi_monitor.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -29,35 +29,32 @@ * These get attached to the nodes in an import table (using "aggregate" ptr) * to indicate which nves are interested in a prefix/target */ -struct rfapi_monitor_vpn -{ - struct rfapi_monitor_vpn *next; /* chain from struct route_node */ - struct rfapi_descriptor *rfd; /* which NVE requested the route */ - struct prefix p; /* constant: pfx in original request */ - struct route_node *node; /* node we're currently attached to */ - uint32_t flags; +struct rfapi_monitor_vpn { + struct rfapi_monitor_vpn *next; /* chain from struct route_node */ + struct rfapi_descriptor *rfd; /* which NVE requested the route */ + struct prefix p; /* constant: pfx in original request */ + struct route_node *node; /* node we're currently attached to */ + uint32_t flags; #define RFAPI_MON_FLAG_NEEDCALLBACK 0x00000001 /* deferred callback */ - //int dcount; /* debugging counter */ - struct thread *timer; + // int dcount; /* debugging counter */ + struct thread *timer; }; -struct rfapi_monitor_encap -{ - struct rfapi_monitor_encap *next; - struct rfapi_monitor_encap *prev; - struct route_node *node; /* VPN node */ - struct bgp_info *bi; /* VPN bi */ - struct route_node *rn; /* parent node */ +struct rfapi_monitor_encap { + struct rfapi_monitor_encap *next; + struct rfapi_monitor_encap *prev; + struct route_node *node; /* VPN node */ + struct bgp_info *bi; /* VPN bi */ + struct route_node *rn; /* parent node */ }; -struct rfapi_monitor_eth -{ - struct rfapi_monitor_eth *next; /* for use in vpn0_queries list */ - struct rfapi_descriptor *rfd; /* which NVE requested the route */ - struct ethaddr macaddr; - uint32_t logical_net_id; - struct thread *timer; +struct rfapi_monitor_eth { + struct rfapi_monitor_eth *next; /* for use in vpn0_queries list */ + struct rfapi_descriptor *rfd; /* which NVE requested the route */ + struct ethaddr macaddr; + uint32_t logical_net_id; + struct thread *timer; }; /* @@ -75,142 +72,119 @@ struct rfapi_monitor_eth * - one lock per chained struct rfapi_monitor_encap * */ -struct rfapi_it_extra -{ - union - { - struct - { - struct rfapi_monitor_vpn *v; - struct skiplist *idx_rd; /* RD index */ - struct skiplist *mon_eth; /* ether queries */ - struct - { - /* routes with UN addrs, either cached encap or Encap TLV */ - int valid_interior_count; - - /* unicast exterior routes, key=bi, val=allocated prefix */ - struct skiplist *source; - } e; - } vpn; - struct - { - struct rfapi_monitor_encap *e; - } encap; - } u; +struct rfapi_it_extra { + union { + struct { + struct rfapi_monitor_vpn *v; + struct skiplist *idx_rd; /* RD index */ + struct skiplist *mon_eth; /* ether queries */ + struct { + /* routes with UN addrs, either cached encap or + * Encap TLV */ + int valid_interior_count; + + /* unicast exterior routes, key=bi, + * val=allocated prefix */ + struct skiplist *source; + } e; + } vpn; + struct { + struct rfapi_monitor_encap *e; + } encap; + } u; }; -#define RFAPI_IT_EXTRA_GET(rn) ((struct rfapi_it_extra *)( \ - (rn)->aggregate? (rn)->aggregate: \ - (route_lock_node(rn), (rn)->aggregate = \ - XCALLOC(MTYPE_RFAPI_IT_EXTRA,sizeof(struct rfapi_it_extra))))) +#define RFAPI_IT_EXTRA_GET(rn) \ + ((struct rfapi_it_extra \ + *)((rn)->aggregate \ + ? (rn)->aggregate \ + : (route_lock_node(rn), \ + (rn)->aggregate = XCALLOC( \ + MTYPE_RFAPI_IT_EXTRA, \ + sizeof(struct rfapi_it_extra))))) -#define RFAPI_RDINDEX(rn) \ - ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd : NULL) +#define RFAPI_RDINDEX(rn) \ + ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd : NULL) #define RFAPI_RDINDEX_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd) -#define RFAPI_MONITOR_ETH(rn) \ - ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.mon_eth : NULL) +#define RFAPI_MONITOR_ETH(rn) \ + ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.mon_eth : NULL) #define RFAPI_MONITOR_ETH_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.mon_eth) -#define RFAPI_MONITOR_VPN(rn) \ - ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.v : NULL) +#define RFAPI_MONITOR_VPN(rn) \ + ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.v : NULL) #define RFAPI_MONITOR_VPN_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.v) -#define RFAPI_MONITOR_ENCAP(rn) \ - ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.encap.e : NULL) +#define RFAPI_MONITOR_ENCAP(rn) \ + ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.encap.e : NULL) #define RFAPI_MONITOR_ENCAP_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.encap.e) #define RFAPI_MONITOR_EXTERIOR(rn) (&(RFAPI_IT_EXTRA_GET(rn)->u.vpn.e)) -#define RFAPI_HAS_MONITOR_EXTERIOR(rn) (rn && rn->aggregate && \ - ((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source && \ - !skiplist_first(((struct rfapi_it_extra *)(rn->aggregate))-> \ - u.vpn.e.source, NULL, NULL)) +#define RFAPI_HAS_MONITOR_EXTERIOR(rn) \ + (rn && rn->aggregate \ + && ((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source \ + && !skiplist_first(((struct rfapi_it_extra *)(rn->aggregate)) \ + ->u.vpn.e.source, \ + NULL, NULL)) -extern void -rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain); +extern void rfapiMonitorLoopCheck(struct rfapi_monitor_vpn *mchain); -extern void -rfapiMonitorCleanCheck (struct bgp *bgp); +extern void rfapiMonitorCleanCheck(struct bgp *bgp); -extern void -rfapiMonitorCheckAttachAllowed (void); +extern void rfapiMonitorCheckAttachAllowed(void); -extern void -rfapiMonitorExtraFlush (safi_t safi, struct route_node *rn); +extern void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn); extern struct route_node * -rfapiMonitorGetAttachNode (struct rfapi_descriptor *rfd, struct prefix *p); +rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, struct prefix *p); -extern void -rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd); +extern void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd); -extern struct route_node * -rfapiMonitorAdd ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *p); +extern struct route_node *rfapiMonitorAdd(struct bgp *bgp, + struct rfapi_descriptor *rfd, + struct prefix *p); -extern void -rfapiMonitorDetachImportHd (struct rfapi_descriptor *rfd); +extern void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd); -extern void -rfapiMonitorDel ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *p); +extern void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct prefix *p); -extern int -rfapiMonitorDelHd (struct rfapi_descriptor *rfd); +extern int rfapiMonitorDelHd(struct rfapi_descriptor *rfd); -extern void -rfapiMonitorCallbacksOff (struct bgp *bgp); +extern void rfapiMonitorCallbacksOff(struct bgp *bgp); -extern void -rfapiMonitorCallbacksOn (struct bgp *bgp); +extern void rfapiMonitorCallbacksOn(struct bgp *bgp); -extern void -rfapiMonitorResponseRemovalOff (struct bgp *bgp); +extern void rfapiMonitorResponseRemovalOff(struct bgp *bgp); -extern void -rfapiMonitorResponseRemovalOn (struct bgp *bgp); +extern void rfapiMonitorResponseRemovalOn(struct bgp *bgp); -extern void -rfapiMonitorExtraPrune (safi_t safi, struct route_node *rn); +extern void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn); -extern void -rfapiMonitorTimersRestart (struct rfapi_descriptor *rfd, struct prefix *p); +extern void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, + struct prefix *p); -extern void -rfapiMonitorItNodeChanged ( - struct rfapi_import_table *import_table, - struct route_node *it_node, - struct rfapi_monitor_vpn *monitor_list); +extern void rfapiMonitorItNodeChanged(struct rfapi_import_table *import_table, + struct route_node *it_node, + struct rfapi_monitor_vpn *monitor_list); -extern void -rfapiMonitorMovedUp ( - struct rfapi_import_table *import_table, - struct route_node *old_node, - struct route_node *new_node, - struct rfapi_monitor_vpn *monitor_list); +extern void rfapiMonitorMovedUp(struct rfapi_import_table *import_table, + struct route_node *old_node, + struct route_node *new_node, + struct rfapi_monitor_vpn *monitor_list); -extern struct route_node * -rfapiMonitorEthAdd ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct ethaddr *macaddr, - uint32_t logical_net_id); - -extern void -rfapiMonitorEthDel ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct ethaddr *macaddr, - uint32_t logical_net_id); +extern struct route_node *rfapiMonitorEthAdd(struct bgp *bgp, + struct rfapi_descriptor *rfd, + struct ethaddr *macaddr, + uint32_t logical_net_id); + +extern void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct ethaddr *macaddr, + uint32_t logical_net_id); #endif /* QUAGGA_HGP_RFAPI_MONITOR_H */ diff --git a/bgpd/rfapi/rfapi_nve_addr.c b/bgpd/rfapi/rfapi_nve_addr.c index f80455bbed..0fb887912c 100644 --- a/bgpd/rfapi/rfapi_nve_addr.c +++ b/bgpd/rfapi/rfapi_nve_addr.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -41,135 +41,118 @@ #define DEBUG_NVE_ADDR 0 -void rfapiNveAddr2Str (struct rfapi_nve_addr *, char *, int); +void rfapiNveAddr2Str(struct rfapi_nve_addr *, char *, int); #if DEBUG_NVE_ADDR -static void -logdifferent (const char *tag, - struct rfapi_nve_addr *a, struct rfapi_nve_addr *b) +static void logdifferent(const char *tag, struct rfapi_nve_addr *a, + struct rfapi_nve_addr *b) { - char a_str[BUFSIZ]; - char b_str[BUFSIZ]; + char a_str[BUFSIZ]; + char b_str[BUFSIZ]; - rfapiNveAddr2Str (a, a_str, BUFSIZ); - rfapiNveAddr2Str (b, b_str, BUFSIZ); - vnc_zlog_debug_verbose ("%s: [%s] [%s]", tag, a_str, b_str); + rfapiNveAddr2Str(a, a_str, BUFSIZ); + rfapiNveAddr2Str(b, b_str, BUFSIZ); + vnc_zlog_debug_verbose("%s: [%s] [%s]", tag, a_str, b_str); } #endif -int -rfapi_nve_addr_cmp (void *k1, void *k2) +int rfapi_nve_addr_cmp(void *k1, void *k2) { - struct rfapi_nve_addr *a = (struct rfapi_nve_addr *) k1; - struct rfapi_nve_addr *b = (struct rfapi_nve_addr *) k2; - int ret = 0; + struct rfapi_nve_addr *a = (struct rfapi_nve_addr *)k1; + struct rfapi_nve_addr *b = (struct rfapi_nve_addr *)k2; + int ret = 0; - if (!a || !b) - { + if (!a || !b) { #if DEBUG_NVE_ADDR - vnc_zlog_debug_verbose ("%s: missing address a=%p b=%p", __func__, a, b); + vnc_zlog_debug_verbose("%s: missing address a=%p b=%p", + __func__, a, b); #endif - return (a - b); - } - if (a->un.addr_family != b->un.addr_family) - { + return (a - b); + } + if (a->un.addr_family != b->un.addr_family) { #if DEBUG_NVE_ADDR - vnc_zlog_debug_verbose ("diff: UN addr fam a->un.af=%d, b->un.af=%d", - a->un.addr_family, b->un.addr_family); + vnc_zlog_debug_verbose( + "diff: UN addr fam a->un.af=%d, b->un.af=%d", + a->un.addr_family, b->un.addr_family); #endif - return (a->un.addr_family - b->un.addr_family); - } - if (a->un.addr_family == AF_INET) - { - ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4); - if (ret != 0) - { + return (a->un.addr_family - b->un.addr_family); + } + if (a->un.addr_family == AF_INET) { + ret = IPV4_ADDR_CMP(&a->un.addr.v4, &b->un.addr.v4); + if (ret != 0) { #if DEBUG_NVE_ADDR - logdifferent ("diff: UN addr", a, b); + logdifferent("diff: UN addr", a, b); #endif - return ret; - } - } - else if (a->un.addr_family == AF_INET6) - { - ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6); - if (ret == 0) - { + return ret; + } + } else if (a->un.addr_family == AF_INET6) { + ret = IPV6_ADDR_CMP(&a->un.addr.v6, &b->un.addr.v6); + if (ret == 0) { #if DEBUG_NVE_ADDR - logdifferent ("diff: UN addr", a, b); + logdifferent("diff: UN addr", a, b); #endif - return ret; - } - } - else - { - assert (0); - } - if (a->vn.addr_family != b->vn.addr_family) - { + return ret; + } + } else { + assert(0); + } + if (a->vn.addr_family != b->vn.addr_family) { #if DEBUG_NVE_ADDR - vnc_zlog_debug_verbose ("diff: pT addr fam a->vn.af=%d, b->vn.af=%d", - a->vn.addr_family, b->vn.addr_family); + vnc_zlog_debug_verbose( + "diff: pT addr fam a->vn.af=%d, b->vn.af=%d", + a->vn.addr_family, b->vn.addr_family); #endif - return (a->vn.addr_family - b->vn.addr_family); - } - if (a->vn.addr_family == AF_INET) - { - ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4); - if (ret != 0) - { + return (a->vn.addr_family - b->vn.addr_family); + } + if (a->vn.addr_family == AF_INET) { + ret = IPV4_ADDR_CMP(&a->vn.addr.v4, &b->vn.addr.v4); + if (ret != 0) { #if DEBUG_NVE_ADDR - logdifferent ("diff: VN addr", a, b); + logdifferent("diff: VN addr", a, b); #endif - return ret; - } - } - else if (a->vn.addr_family == AF_INET6) - { - ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6); - if (ret == 0) - { + return ret; + } + } else if (a->vn.addr_family == AF_INET6) { + ret = IPV6_ADDR_CMP(&a->vn.addr.v6, &b->vn.addr.v6); + if (ret == 0) { #if DEBUG_NVE_ADDR - logdifferent ("diff: VN addr", a, b); + logdifferent("diff: VN addr", a, b); #endif - return ret; - } - } - else - { - assert (0); - } - return 0; + return ret; + } + } else { + assert(0); + } + return 0; } -void -rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize) +void rfapiNveAddr2Str(struct rfapi_nve_addr *na, char *buf, int bufsize) { - char *p = buf; - int r; + char *p = buf; + int r; #define REMAIN (bufsize - (p-buf)) #define INCP {p += (r > REMAIN)? REMAIN: r;} - if (bufsize < 1) - return; + if (bufsize < 1) + return; - r = snprintf (p, REMAIN, "VN="); - INCP; + r = snprintf(p, REMAIN, "VN="); + INCP; - if (!rfapiRfapiIpAddr2Str (&na->vn, p, REMAIN)) - goto done; + if (!rfapiRfapiIpAddr2Str(&na->vn, p, REMAIN)) + goto done; - buf[bufsize - 1] = 0; - p = buf + strlen (buf); + buf[bufsize - 1] = 0; + p = buf + strlen(buf); - r = snprintf (p, REMAIN, ", UN="); - INCP; + r = snprintf(p, REMAIN, ", UN="); + INCP; - rfapiRfapiIpAddr2Str (&na->un, p, REMAIN); + rfapiRfapiIpAddr2Str(&na->un, p, REMAIN); done: - buf[bufsize - 1] = 0; + buf[bufsize - 1] = 0; } diff --git a/bgpd/rfapi/rfapi_nve_addr.h b/bgpd/rfapi/rfapi_nve_addr.h index f2159d1063..2d54d4a3cc 100644 --- a/bgpd/rfapi/rfapi_nve_addr.h +++ b/bgpd/rfapi/rfapi_nve_addr.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -23,20 +23,16 @@ #include "rfapi.h" -struct rfapi_nve_addr -{ - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - void *info; +struct rfapi_nve_addr { + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + void *info; }; -extern int -rfapi_nve_addr_cmp (void *k1, void *k2); - -extern void -rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize); +extern int rfapi_nve_addr_cmp(void *k1, void *k2); +extern void rfapiNveAddr2Str(struct rfapi_nve_addr *na, char *buf, int bufsize); #endif /* _QUAGGA_BGP_RFAPI_NVE_ADDR_H */ diff --git a/bgpd/rfapi/rfapi_private.h b/bgpd/rfapi/rfapi_private.h index 5a6936fcce..e7a3e5aae3 100644 --- a/bgpd/rfapi/rfapi_private.h +++ b/bgpd/rfapi/rfapi_private.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* +/* * Internal definitions for RFAPI. Not for use by other code */ @@ -40,96 +40,94 @@ * 1. each is referenced in by_lifetime * 2. each is referenced by exactly one of: ipN_by_prefix, ip0_by_ether */ -struct rfapi_advertised_prefixes -{ - struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */ - struct skiplist *ip0_by_ether; /* ip prefix 0/32, 0/128 */ - struct skiplist *by_lifetime; /* all */ +struct rfapi_advertised_prefixes { + struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */ + struct skiplist *ip0_by_ether; /* ip prefix 0/32, 0/128 */ + struct skiplist *by_lifetime; /* all */ }; -struct rfapi_descriptor -{ - struct route_node *un_node; /* backref to un table */ - - struct rfapi_descriptor *next; /* next vn_addr */ - - /* supplied by client */ - struct bgp *bgp; /* from rfp_start_val */ - struct rfapi_ip_addr vn_addr; - struct rfapi_ip_addr un_addr; - rfapi_response_cb_t *response_cb; /* override per-bgp response_cb */ - void *cookie; /* for callbacks */ - struct rfapi_tunneltype_option default_tunneltype_option; - - /* supplied by matched configuration */ - struct prefix_rd rd; - struct ecommunity *rt_export_list; - uint32_t response_lifetime; - - /* list of prefixes currently being advertised by this nve */ - struct rfapi_advertised_prefixes advertised; - - time_t open_time; - - uint32_t max_prefix_lifetime; - uint32_t min_prefix_lifetime; - - /* reference to this nve's import table */ - struct rfapi_import_table *import_table; - - uint32_t monitor_count; - struct route_table *mon; /* rfapi_monitors */ - struct skiplist *mon_eth; /* ethernet monitors */ - - /* - * rib RIB as seen by NVE - * rib_pending RIB containing nodes with updated info chains - * rsp_times last time we sent response containing pfx - */ - uint32_t rib_prefix_count; /* pfxes with routes */ - struct route_table *rib[AFI_MAX]; - struct route_table *rib_pending[AFI_MAX]; - struct work_queue *updated_responses_queue; - struct route_table *rsp_times[AFI_MAX]; - - uint32_t rsp_counter; /* dedup initial rsp */ - time_t rsp_time; /* dedup initial rsp */ - time_t ftd_last_allowed_time; /* FTD filter */ - - unsigned int stat_count_nh_reachable; - unsigned int stat_count_nh_removal; - - /* - * points to the original nve group structure that matched - * when this nve_descriptor was created. We use this pointer - * in rfapi_close() to find the nve group structure and - * delete its reference back to us. - * - * If the nve group structure is deleted (via configuration - * change) while this nve_descriptor exists, this rfg pointer - * will be set to NULL. - */ - struct rfapi_nve_group_cfg *rfg; - - /* - * This ~7kB structure is here to permit multiple routes for - * a prefix to be injected to BGP. There are at least two - * situations where such conditions obtain: - * - * When an VNC route is exported to BGP on behalf of the set of - * NVEs that belong to the export NVE group, it is replicated - * so that there is one route per NVE (and the route's nexthop - * is the NVE's VN address). - * - * Each of these routes being injected to BGP must have a distinct - * peer pointer (otherwise, if they have the same peer pointer, each - * route will be considered an implicit waithdraw of the previous - * route injected from that peer, and the new route will replace - * rather than augment the old one(s)). - */ - struct peer *peer; - - uint32_t flags; +struct rfapi_descriptor { + struct route_node *un_node; /* backref to un table */ + + struct rfapi_descriptor *next; /* next vn_addr */ + + /* supplied by client */ + struct bgp *bgp; /* from rfp_start_val */ + struct rfapi_ip_addr vn_addr; + struct rfapi_ip_addr un_addr; + rfapi_response_cb_t *response_cb; /* override per-bgp response_cb */ + void *cookie; /* for callbacks */ + struct rfapi_tunneltype_option default_tunneltype_option; + + /* supplied by matched configuration */ + struct prefix_rd rd; + struct ecommunity *rt_export_list; + uint32_t response_lifetime; + + /* list of prefixes currently being advertised by this nve */ + struct rfapi_advertised_prefixes advertised; + + time_t open_time; + + uint32_t max_prefix_lifetime; + uint32_t min_prefix_lifetime; + + /* reference to this nve's import table */ + struct rfapi_import_table *import_table; + + uint32_t monitor_count; + struct route_table *mon; /* rfapi_monitors */ + struct skiplist *mon_eth; /* ethernet monitors */ + + /* + * rib RIB as seen by NVE + * rib_pending RIB containing nodes with updated info chains + * rsp_times last time we sent response containing pfx + */ + uint32_t rib_prefix_count; /* pfxes with routes */ + struct route_table *rib[AFI_MAX]; + struct route_table *rib_pending[AFI_MAX]; + struct work_queue *updated_responses_queue; + struct route_table *rsp_times[AFI_MAX]; + + uint32_t rsp_counter; /* dedup initial rsp */ + time_t rsp_time; /* dedup initial rsp */ + time_t ftd_last_allowed_time; /* FTD filter */ + + unsigned int stat_count_nh_reachable; + unsigned int stat_count_nh_removal; + + /* + * points to the original nve group structure that matched + * when this nve_descriptor was created. We use this pointer + * in rfapi_close() to find the nve group structure and + * delete its reference back to us. + * + * If the nve group structure is deleted (via configuration + * change) while this nve_descriptor exists, this rfg pointer + * will be set to NULL. + */ + struct rfapi_nve_group_cfg *rfg; + + /* + * This ~7kB structure is here to permit multiple routes for + * a prefix to be injected to BGP. There are at least two + * situations where such conditions obtain: + * + * When an VNC route is exported to BGP on behalf of the set of + * NVEs that belong to the export NVE group, it is replicated + * so that there is one route per NVE (and the route's nexthop + * is the NVE's VN address). + * + * Each of these routes being injected to BGP must have a distinct + * peer pointer (otherwise, if they have the same peer pointer, each + * route will be considered an implicit waithdraw of the previous + * route injected from that peer, and the new route will replace + * rather than augment the old one(s)). + */ + struct peer *peer; + + uint32_t flags; #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP 0x00000001 #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 0x00000002 #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN 0x00000004 @@ -138,30 +136,32 @@ struct rfapi_descriptor #define RFAPI_HD_FLAG_IS_VRF 0x00000012 }; -#define RFAPI_QUEUED_FLAG(afi) ( \ - ((afi) == AFI_IP)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP: \ - (((afi) == AFI_IP6)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6: \ - (((afi) == AFI_L2VPN)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN: \ - (assert(0), 0) ))) +#define RFAPI_QUEUED_FLAG(afi) \ + (((afi) == AFI_IP) \ + ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP \ + : (((afi) == AFI_IP6) \ + ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6 \ + : (((afi) == AFI_L2VPN) \ + ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN \ + : (assert(0), 0)))) -struct rfapi_global_stats -{ - time_t last_reset; - unsigned int max_descriptors; +struct rfapi_global_stats { + time_t last_reset; + unsigned int max_descriptors; - unsigned int count_unknown_nves; + unsigned int count_unknown_nves; - unsigned int count_queries; - unsigned int count_queries_failed; + unsigned int count_queries; + unsigned int count_queries_failed; - unsigned int max_responses; /* semantics? */ + unsigned int max_responses; /* semantics? */ - unsigned int count_registrations; - unsigned int count_registrations_failed; + unsigned int count_registrations; + unsigned int count_registrations_failed; - unsigned int count_updated_response_updates; - unsigned int count_updated_response_deletes; + unsigned int count_updated_response_updates; + unsigned int count_updated_response_deletes; }; /* @@ -170,220 +170,187 @@ struct rfapi_global_stats * Radix tree is indexed by un address; follow chain and * check vn address to get exact match. */ -struct rfapi -{ - struct route_table un[AFI_MAX]; - struct rfapi_import_table *imports; /* IPv4, IPv6 */ - struct list descriptors;/* debug & resolve-nve imports */ - - struct rfapi_global_stats stat; - - /* - * callbacks into RFP, set at startup time (bgp_rfapi_new() gets - * values from rfp_start()) or via rfapi_rfp_set_cb_methods() - * (otherwise NULL). Note that the response_cb method can also - * be overridden per-rfd (currently used only for debug/test scenarios) - */ - struct rfapi_rfp_cb_methods rfp_methods; - - /* - * Import tables for Ethernet over IPSEC - * - * The skiplist keys are LNIs. Values are pointers - * to struct rfapi_import_table. - */ - struct skiplist *import_mac; /* L2 */ - - /* - * when exporting plain routes ("registered-nve" mode) to - * bgp unicast or zebra, we need to keep track of information - * related to expiring the routes according to the VNC lifetime - */ - struct route_table *rt_export_bgp[AFI_MAX]; - struct route_table *rt_export_zebra[AFI_MAX]; - - /* - * For VNC->BGP unicast exports in CE mode, we need a - * routing table that collects all of the VPN routes - * in a single tree. The VPN rib is split up according - * to RD first, so we can't use that. This is an import - * table that matches all RTs. - */ - struct rfapi_import_table *it_ce; - - /* - * when importing bgp-direct routes in resolve-nve mode, - * this list maps unicast route nexthops to their bgp_infos - * in the unicast table - */ - struct skiplist *resolve_nve_nexthop; - - /* - * Descriptors for which rfapi_close() was called during a callback. - * They will be closed after the callback finishes. - */ - struct work_queue *deferred_close_q; - - /* - * For "show vnc responses" - */ - uint32_t response_immediate_count; - uint32_t response_updated_count; - uint32_t monitor_count; - - uint32_t rib_prefix_count_total; - uint32_t rib_prefix_count_total_max; - - uint32_t flags; +struct rfapi { + struct route_table un[AFI_MAX]; + struct rfapi_import_table *imports; /* IPv4, IPv6 */ + struct list descriptors; /* debug & resolve-nve imports */ + + struct rfapi_global_stats stat; + + /* + * callbacks into RFP, set at startup time (bgp_rfapi_new() gets + * values from rfp_start()) or via rfapi_rfp_set_cb_methods() + * (otherwise NULL). Note that the response_cb method can also + * be overridden per-rfd (currently used only for debug/test scenarios) + */ + struct rfapi_rfp_cb_methods rfp_methods; + + /* + * Import tables for Ethernet over IPSEC + * + * The skiplist keys are LNIs. Values are pointers + * to struct rfapi_import_table. + */ + struct skiplist *import_mac; /* L2 */ + + /* + * when exporting plain routes ("registered-nve" mode) to + * bgp unicast or zebra, we need to keep track of information + * related to expiring the routes according to the VNC lifetime + */ + struct route_table *rt_export_bgp[AFI_MAX]; + struct route_table *rt_export_zebra[AFI_MAX]; + + /* + * For VNC->BGP unicast exports in CE mode, we need a + * routing table that collects all of the VPN routes + * in a single tree. The VPN rib is split up according + * to RD first, so we can't use that. This is an import + * table that matches all RTs. + */ + struct rfapi_import_table *it_ce; + + /* + * when importing bgp-direct routes in resolve-nve mode, + * this list maps unicast route nexthops to their bgp_infos + * in the unicast table + */ + struct skiplist *resolve_nve_nexthop; + + /* + * Descriptors for which rfapi_close() was called during a callback. + * They will be closed after the callback finishes. + */ + struct work_queue *deferred_close_q; + + /* + * For "show vnc responses" + */ + uint32_t response_immediate_count; + uint32_t response_updated_count; + uint32_t monitor_count; + + uint32_t rib_prefix_count_total; + uint32_t rib_prefix_count_total_max; + + uint32_t flags; #define RFAPI_INCALLBACK 0x00000001 - void *rfp; /* from rfp_start */ + void *rfp; /* from rfp_start */ }; -#define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) do { \ - ++(rfd)->rib_prefix_count; \ - ++(rfapi)->rib_prefix_count_total; \ - if ((rfapi)->rib_prefix_count_total > (rfapi)->rib_prefix_count_total_max) \ - ++(rfapi)->rib_prefix_count_total_max; \ - } while (0) - -#define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi) do { \ - --(rfd)->rib_prefix_count; \ - --(rfapi)->rib_prefix_count_total; \ - } while (0) - -#define RFAPI_0_PREFIX(prefix) ( \ - (((prefix)->family == AF_INET)? (prefix)->u.prefix4.s_addr == 0: \ - (((prefix)->family == AF_INET6)? \ - (IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) : 0)) \ -) - -#define RFAPI_0_ETHERADDR(ea) ( \ - ((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | \ - (ea)->octet[3] | (ea)->octet[4] | (ea)->octet[5]) == 0) - -#define RFAPI_HOST_PREFIX(prefix) ( \ - ((prefix)->family == AF_INET)? ((prefix)->prefixlen == 32): \ - (((prefix)->family == AF_INET6)? ((prefix)->prefixlen == 128): 0) ) - -extern void -rfapiQprefix2Rprefix ( - struct prefix *qprefix, - struct rfapi_ip_prefix *rprefix); - -extern int -rfapi_find_rfd ( - struct bgp *bgp, - struct rfapi_ip_addr *vn_addr, - struct rfapi_ip_addr *un_addr, - struct rfapi_descriptor **rfd); +#define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) \ + do { \ + ++(rfd)->rib_prefix_count; \ + ++(rfapi)->rib_prefix_count_total; \ + if ((rfapi)->rib_prefix_count_total \ + > (rfapi)->rib_prefix_count_total_max) \ + ++(rfapi)->rib_prefix_count_total_max; \ + } while (0) + +#define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi) \ + do { \ + --(rfd)->rib_prefix_count; \ + --(rfapi)->rib_prefix_count_total; \ + } while (0) + +#define RFAPI_0_PREFIX(prefix) \ + ((((prefix)->family == AF_INET) \ + ? (prefix)->u.prefix4.s_addr == 0 \ + : (((prefix)->family == AF_INET6) \ + ? (IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) \ + : 0))) + +#define RFAPI_0_ETHERADDR(ea) \ + (((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | (ea)->octet[3] \ + | (ea)->octet[4] | (ea)->octet[5]) \ + == 0) + +#define RFAPI_HOST_PREFIX(prefix) \ + (((prefix)->family == AF_INET) \ + ? ((prefix)->prefixlen == 32) \ + : (((prefix)->family == AF_INET6) \ + ? ((prefix)->prefixlen == 128) \ + : 0)) + +extern void rfapiQprefix2Rprefix(struct prefix *qprefix, + struct rfapi_ip_prefix *rprefix); + +extern int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, + struct rfapi_ip_addr *un_addr, + struct rfapi_descriptor **rfd); extern void -add_vnc_route ( - struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */ - struct bgp *bgp, - int safi, - struct prefix *p, - struct prefix_rd *prd, - struct rfapi_ip_addr *nexthop, - uint32_t *local_pref, /* host byte order */ - uint32_t *lifetime, /* host byte order */ - struct bgp_tea_options *rfp_options, - struct rfapi_un_option *options_un, - struct rfapi_vn_option *options_vn, - struct ecommunity *rt_export_list, - uint32_t *med, - uint32_t *label, - uint8_t type, - uint8_t sub_type, - int flags); +add_vnc_route(struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */ + struct bgp *bgp, int safi, struct prefix *p, + struct prefix_rd *prd, struct rfapi_ip_addr *nexthop, + uint32_t *local_pref, /* host byte order */ + uint32_t *lifetime, /* host byte order */ + struct bgp_tea_options *rfp_options, + struct rfapi_un_option *options_un, + struct rfapi_vn_option *options_vn, + struct ecommunity *rt_export_list, uint32_t *med, uint32_t *label, + uint8_t type, uint8_t sub_type, int flags); #define RFAPI_AHR_NO_TUNNEL_SUBTLV 0x00000001 #define RFAPI_AHR_RFPOPT_IS_VNCTLV 0x00000002 /* hack! */ -#if 0 /* unused? */ +#if 0 /* unused? */ # define RFAPI_AHR_SET_PFX_TO_NEXTHOP 0x00000004 #endif -extern void -del_vnc_route ( - struct rfapi_descriptor *rfd, - struct peer *peer, - struct bgp *bgp, - safi_t safi, - struct prefix *p, - struct prefix_rd *prd, - uint8_t type, - uint8_t sub_type, - struct rfapi_nexthop *lnh, - int kill); +extern void del_vnc_route(struct rfapi_descriptor *rfd, struct peer *peer, + struct bgp *bgp, safi_t safi, struct prefix *p, + struct prefix_rd *prd, uint8_t type, uint8_t sub_type, + struct rfapi_nexthop *lnh, int kill); -extern int -rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p); +extern int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, + struct prefix *p); -extern int -rfapiGetVncLifetime (struct attr *attr, uint32_t * lifetime); +extern int rfapiGetVncLifetime(struct attr *attr, uint32_t *lifetime); -extern int -rfapiGetTunnelType (struct attr *attr, bgp_encap_types *type); +extern int rfapiGetTunnelType(struct attr *attr, bgp_encap_types *type); -extern int -rfapiGetVncTunnelUnAddr (struct attr *attr, struct prefix *p); +extern int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p); -extern int -rfapi_reopen (struct rfapi_descriptor *rfd, struct bgp *bgp); +extern int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp); -extern void -vnc_import_bgp_add_rfp_host_route_mode_resolve_nve ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *prefix); +extern void vnc_import_bgp_add_rfp_host_route_mode_resolve_nve( + struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix); -extern void -vnc_import_bgp_del_rfp_host_route_mode_resolve_nve ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *prefix); +extern void vnc_import_bgp_del_rfp_host_route_mode_resolve_nve( + struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix); -extern void -rfapiFreeBgpTeaOptionChain (struct bgp_tea_options *p); +extern void rfapiFreeBgpTeaOptionChain(struct bgp_tea_options *p); -extern struct rfapi_vn_option * -rfapiVnOptionsDup (struct rfapi_vn_option *orig); +extern struct rfapi_vn_option *rfapiVnOptionsDup(struct rfapi_vn_option *orig); -extern struct rfapi_un_option * -rfapiUnOptionsDup (struct rfapi_un_option *orig); +extern struct rfapi_un_option *rfapiUnOptionsDup(struct rfapi_un_option *orig); -extern struct bgp_tea_options * -rfapiOptionsDup (struct bgp_tea_options *orig); +extern struct bgp_tea_options *rfapiOptionsDup(struct bgp_tea_options *orig); -extern int -rfapi_ip_addr_cmp (struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2); +extern int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1, + struct rfapi_ip_addr *a2); -extern uint32_t -rfp_cost_to_localpref (uint8_t cost); +extern uint32_t rfp_cost_to_localpref(uint8_t cost); -extern int -rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn); +extern int rfapi_set_autord_from_vn(struct prefix_rd *rd, + struct rfapi_ip_addr *vn); -extern struct rfapi_nexthop * -rfapi_nexthop_new (struct rfapi_nexthop *copyme); +extern struct rfapi_nexthop *rfapi_nexthop_new(struct rfapi_nexthop *copyme); -extern void -rfapi_nexthop_free (void *goner); +extern void rfapi_nexthop_free(void *goner); extern struct rfapi_vn_option * -rfapi_vn_options_dup (struct rfapi_vn_option *existing); +rfapi_vn_options_dup(struct rfapi_vn_option *existing); -extern void -rfapi_un_options_free (struct rfapi_un_option *goner); +extern void rfapi_un_options_free(struct rfapi_un_option *goner); -extern void -rfapi_vn_options_free (struct rfapi_vn_option *goner); +extern void rfapi_vn_options_free(struct rfapi_vn_option *goner); /*------------------------------------------ * rfapi_extract_l2o * - * Find Layer 2 options in an option chain + * Find Layer 2 options in an option chain * - * input: + * input: * pHop option chain * * output: @@ -394,17 +361,16 @@ rfapi_vn_options_free (struct rfapi_vn_option *goner); * 1 no options found * --------------------------------------------*/ -extern int -rfapi_extract_l2o ( - struct bgp_tea_options *pHop, /* chain of options */ - struct rfapi_l2address_option *l2o); /* return extracted value */ +extern int rfapi_extract_l2o( + struct bgp_tea_options *pHop, /* chain of options */ + struct rfapi_l2address_option *l2o); /* return extracted value */ -/* +/* * compaitibility to old quagga_time call - * time_t value in terms of stabilised absolute time. + * time_t value in terms of stabilised absolute time. * replacement for POSIX time() */ -extern time_t rfapi_time (time_t *t); +extern time_t rfapi_time(time_t *t); DECLARE_MGROUP(RFAPI) DECLARE_MTYPE(RFAPI_CFG) @@ -441,10 +407,7 @@ DECLARE_MTYPE(RFAPI_MONITOR_ETH) * The advertised_prefixes[] array elements should be NULL to * have this function set them to newly-allocated radix trees. */ -extern int -rfapi_init_and_open( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct rfapi_nve_group_cfg *rfg); +extern int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct rfapi_nve_group_cfg *rfg); #endif /* _QUAGGA_BGP_RFAPI_PRIVATE_H */ diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 902e702079..a414df1ab4 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -58,8 +58,8 @@ /* forward decl */ #if DEBUG_NHL -static void -rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl); +static void rfapiRibShowRibSl(void *stream, struct prefix *pfx, + struct skiplist *sl); #endif /* @@ -121,330 +121,295 @@ rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl); /* * iterate over RIB to count responses, compare with running counters */ -void -rfapiRibCheckCounts ( - int checkstats, /* validate rfd & global counts */ - unsigned int offset) /* number of ri's held separately */ +void rfapiRibCheckCounts( + int checkstats, /* validate rfd & global counts */ + unsigned int offset) /* number of ri's held separately */ { - struct rfapi_descriptor *rfd; - struct listnode *node; - - struct bgp *bgp = bgp_get_default (); - - uint32_t t_pfx_active = 0; - uint32_t t_pfx_deleted = 0; - - uint32_t t_ri_active = 0; - uint32_t t_ri_deleted = 0; - uint32_t t_ri_pend = 0; - - unsigned int alloc_count; - - /* - * loop over NVEs - */ - for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) - { - - afi_t afi; - uint32_t pfx_active = 0; - uint32_t pfx_deleted = 0; - - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - struct route_node *rn; - - for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) - { - - struct skiplist *sl = rn->info; - struct skiplist *dsl = rn->aggregate; - uint32_t ri_active = 0; - uint32_t ri_deleted = 0; - - if (sl) - { - ri_active = skiplist_count (sl); - assert (ri_active); - t_ri_active += ri_active; - ++pfx_active; - ++t_pfx_active; - } - - if (dsl) - { - ri_deleted = skiplist_count (dsl); - t_ri_deleted += ri_deleted; - ++pfx_deleted; - ++t_pfx_deleted; - } - } - for (rn = route_top (rfd->rib_pending[afi]); rn; - rn = route_next (rn)) - { - - struct list *l = rn->info; /* sorted by cost */ - struct skiplist *sl = rn->aggregate; - uint32_t ri_pend_cost = 0; - uint32_t ri_pend_uniq = 0; - - if (sl) - { - ri_pend_uniq = skiplist_count (sl); - } - - if (l && (l != (void *) 1)) - { - ri_pend_cost = l->count; - t_ri_pend += l->count; - } - - assert (ri_pend_uniq == ri_pend_cost); - } - } - - if (checkstats) - { - if (pfx_active != rfd->rib_prefix_count) - { - vnc_zlog_debug_verbose ("%s: rfd %p actual pfx count %u != running %u", - __func__, rfd, pfx_active, rfd->rib_prefix_count); - assert (0); - } - } - } - - if (checkstats && bgp && bgp->rfapi) - { - if (t_pfx_active != bgp->rfapi->rib_prefix_count_total) - { - vnc_zlog_debug_verbose ("%s: actual total pfx count %u != running %u", - __func__, t_pfx_active, - bgp->rfapi->rib_prefix_count_total); - assert (0); - } - } - - /* - * Check against memory allocation count - */ - alloc_count = mtype_stats_alloc (MTYPE_RFAPI_INFO); - assert (t_ri_active + t_ri_deleted + t_ri_pend + offset == alloc_count); + struct rfapi_descriptor *rfd; + struct listnode *node; + + struct bgp *bgp = bgp_get_default(); + + uint32_t t_pfx_active = 0; + uint32_t t_pfx_deleted = 0; + + uint32_t t_ri_active = 0; + uint32_t t_ri_deleted = 0; + uint32_t t_ri_pend = 0; + + unsigned int alloc_count; + + /* + * loop over NVEs + */ + for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { + + afi_t afi; + uint32_t pfx_active = 0; + uint32_t pfx_deleted = 0; + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + struct route_node *rn; + + for (rn = route_top(rfd->rib[afi]); rn; + rn = route_next(rn)) { + + struct skiplist *sl = rn->info; + struct skiplist *dsl = rn->aggregate; + uint32_t ri_active = 0; + uint32_t ri_deleted = 0; + + if (sl) { + ri_active = skiplist_count(sl); + assert(ri_active); + t_ri_active += ri_active; + ++pfx_active; + ++t_pfx_active; + } + + if (dsl) { + ri_deleted = skiplist_count(dsl); + t_ri_deleted += ri_deleted; + ++pfx_deleted; + ++t_pfx_deleted; + } + } + for (rn = route_top(rfd->rib_pending[afi]); rn; + rn = route_next(rn)) { + + struct list *l = rn->info; /* sorted by cost */ + struct skiplist *sl = rn->aggregate; + uint32_t ri_pend_cost = 0; + uint32_t ri_pend_uniq = 0; + + if (sl) { + ri_pend_uniq = skiplist_count(sl); + } + + if (l && (l != (void *)1)) { + ri_pend_cost = l->count; + t_ri_pend += l->count; + } + + assert(ri_pend_uniq == ri_pend_cost); + } + } + + if (checkstats) { + if (pfx_active != rfd->rib_prefix_count) { + vnc_zlog_debug_verbose( + "%s: rfd %p actual pfx count %u != running %u", + __func__, rfd, pfx_active, + rfd->rib_prefix_count); + assert(0); + } + } + } + + if (checkstats && bgp && bgp->rfapi) { + if (t_pfx_active != bgp->rfapi->rib_prefix_count_total) { + vnc_zlog_debug_verbose( + "%s: actual total pfx count %u != running %u", + __func__, t_pfx_active, + bgp->rfapi->rib_prefix_count_total); + assert(0); + } + } + + /* + * Check against memory allocation count + */ + alloc_count = mtype_stats_alloc(MTYPE_RFAPI_INFO); + assert(t_ri_active + t_ri_deleted + t_ri_pend + offset == alloc_count); } -static struct rfapi_info * -rfapi_info_new () +static struct rfapi_info *rfapi_info_new() { - return XCALLOC (MTYPE_RFAPI_INFO, sizeof (struct rfapi_info)); + return XCALLOC(MTYPE_RFAPI_INFO, sizeof(struct rfapi_info)); } -void -rfapiFreeRfapiUnOptionChain (struct rfapi_un_option *p) +void rfapiFreeRfapiUnOptionChain(struct rfapi_un_option *p) { - while (p) - { - struct rfapi_un_option *next; - - next = p->next; - XFREE (MTYPE_RFAPI_UN_OPTION, p); - p = next; - } + while (p) { + struct rfapi_un_option *next; + + next = p->next; + XFREE(MTYPE_RFAPI_UN_OPTION, p); + p = next; + } } -void -rfapiFreeRfapiVnOptionChain (struct rfapi_vn_option *p) +void rfapiFreeRfapiVnOptionChain(struct rfapi_vn_option *p) { - while (p) - { - struct rfapi_vn_option *next; - - next = p->next; - XFREE (MTYPE_RFAPI_VN_OPTION, p); - p = next; - } + while (p) { + struct rfapi_vn_option *next; + + next = p->next; + XFREE(MTYPE_RFAPI_VN_OPTION, p); + p = next; + } } -static void -rfapi_info_free (struct rfapi_info *goner) +static void rfapi_info_free(struct rfapi_info *goner) { - if (goner) - { - if (goner->tea_options) - { - rfapiFreeBgpTeaOptionChain (goner->tea_options); - goner->tea_options = NULL; - } - if (goner->un_options) - { - rfapiFreeRfapiUnOptionChain (goner->un_options); - goner->un_options = NULL; - } - if (goner->vn_options) - { - rfapiFreeRfapiVnOptionChain (goner->vn_options); - goner->vn_options = NULL; - } - if (goner->timer) - { - struct rfapi_rib_tcb *tcb; - - tcb = ((struct thread *) goner->timer)->arg; - thread_cancel ((struct thread *) goner->timer); - XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); - goner->timer = NULL; - } - XFREE (MTYPE_RFAPI_INFO, goner); - } + if (goner) { + if (goner->tea_options) { + rfapiFreeBgpTeaOptionChain(goner->tea_options); + goner->tea_options = NULL; + } + if (goner->un_options) { + rfapiFreeRfapiUnOptionChain(goner->un_options); + goner->un_options = NULL; + } + if (goner->vn_options) { + rfapiFreeRfapiVnOptionChain(goner->vn_options); + goner->vn_options = NULL; + } + if (goner->timer) { + struct rfapi_rib_tcb *tcb; + + tcb = ((struct thread *)goner->timer)->arg; + thread_cancel((struct thread *)goner->timer); + XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); + goner->timer = NULL; + } + XFREE(MTYPE_RFAPI_INFO, goner); + } } /* * Timer control block for recently-deleted and expired routes */ -struct rfapi_rib_tcb -{ - struct rfapi_descriptor *rfd; - struct skiplist *sl; - struct rfapi_info *ri; - struct route_node *rn; - int flags; +struct rfapi_rib_tcb { + struct rfapi_descriptor *rfd; + struct skiplist *sl; + struct rfapi_info *ri; + struct route_node *rn; + int flags; #define RFAPI_RIB_TCB_FLAG_DELETED 0x00000001 }; /* * remove route from rib */ -static int -rfapiRibExpireTimer (struct thread *t) +static int rfapiRibExpireTimer(struct thread *t) { - struct rfapi_rib_tcb *tcb = t->arg; - - RFAPI_RIB_CHECK_COUNTS (1, 0); - - /* - * Forget reference to thread. Otherwise rfapi_info_free() will - * attempt to free thread pointer as an option chain - */ - tcb->ri->timer = NULL; - - /* "deleted" skiplist frees ri, "active" doesn't */ - assert (!skiplist_delete (tcb->sl, &tcb->ri->rk, NULL)); - if (!tcb->sl->del) - { - /* - * XXX in this case, skiplist has no delete function: we must - * therefore delete rfapi_info explicitly. - */ - rfapi_info_free (tcb->ri); - } - - if (skiplist_empty (tcb->sl)) - { - if (CHECK_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED)) - tcb->rn->aggregate = NULL; - else - { - struct bgp *bgp = bgp_get_default (); - tcb->rn->info = NULL; - RFAPI_RIB_PREFIX_COUNT_DECR (tcb->rfd, bgp->rfapi); - } - skiplist_free (tcb->sl); - route_unlock_node (tcb->rn); - } - - XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); - - RFAPI_RIB_CHECK_COUNTS (1, 0); - - return 0; + struct rfapi_rib_tcb *tcb = t->arg; + + RFAPI_RIB_CHECK_COUNTS(1, 0); + + /* + * Forget reference to thread. Otherwise rfapi_info_free() will + * attempt to free thread pointer as an option chain + */ + tcb->ri->timer = NULL; + + /* "deleted" skiplist frees ri, "active" doesn't */ + assert(!skiplist_delete(tcb->sl, &tcb->ri->rk, NULL)); + if (!tcb->sl->del) { + /* + * XXX in this case, skiplist has no delete function: we must + * therefore delete rfapi_info explicitly. + */ + rfapi_info_free(tcb->ri); + } + + if (skiplist_empty(tcb->sl)) { + if (CHECK_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED)) + tcb->rn->aggregate = NULL; + else { + struct bgp *bgp = bgp_get_default(); + tcb->rn->info = NULL; + RFAPI_RIB_PREFIX_COUNT_DECR(tcb->rfd, bgp->rfapi); + } + skiplist_free(tcb->sl); + route_unlock_node(tcb->rn); + } + + XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); + + RFAPI_RIB_CHECK_COUNTS(1, 0); + + return 0; } static void -rfapiRibStartTimer ( - struct rfapi_descriptor *rfd, - struct rfapi_info *ri, - struct route_node *rn, /* route node attached to */ - int deleted) +rfapiRibStartTimer(struct rfapi_descriptor *rfd, struct rfapi_info *ri, + struct route_node *rn, /* route node attached to */ + int deleted) { - struct thread *t = ri->timer; - struct rfapi_rib_tcb *tcb = NULL; - char buf_prefix[BUFSIZ]; - - if (t) - { - tcb = t->arg; - thread_cancel (t); - ri->timer = NULL; - } - else - { - tcb = - XCALLOC (MTYPE_RFAPI_RECENT_DELETE, sizeof (struct rfapi_rib_tcb)); - } - tcb->rfd = rfd; - tcb->ri = ri; - tcb->rn = rn; - if (deleted) - { - tcb->sl = (struct skiplist *) rn->aggregate; - SET_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); - } - else - { - tcb->sl = (struct skiplist *) rn->info; - UNSET_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); - } - - prefix2str (&rn->p, buf_prefix, BUFSIZ); - vnc_zlog_debug_verbose ("%s: rfd %p pfx %s life %u", __func__, rfd, buf_prefix, - ri->lifetime); - ri->timer = NULL; - thread_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime, - &ri->timer); - assert (ri->timer); + struct thread *t = ri->timer; + struct rfapi_rib_tcb *tcb = NULL; + char buf_prefix[BUFSIZ]; + + if (t) { + tcb = t->arg; + thread_cancel(t); + ri->timer = NULL; + } else { + tcb = XCALLOC(MTYPE_RFAPI_RECENT_DELETE, + sizeof(struct rfapi_rib_tcb)); + } + tcb->rfd = rfd; + tcb->ri = ri; + tcb->rn = rn; + if (deleted) { + tcb->sl = (struct skiplist *)rn->aggregate; + SET_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); + } else { + tcb->sl = (struct skiplist *)rn->info; + UNSET_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); + } + + prefix2str(&rn->p, buf_prefix, BUFSIZ); + vnc_zlog_debug_verbose("%s: rfd %p pfx %s life %u", __func__, rfd, + buf_prefix, ri->lifetime); + ri->timer = NULL; + thread_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime, + &ri->timer); + assert(ri->timer); } -extern void -rfapi_rib_key_init (struct prefix *prefix, /* may be NULL */ - struct prefix_rd *rd, /* may be NULL */ - struct prefix *aux, /* may be NULL */ - struct rfapi_rib_key *rk) - +extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */ + struct prefix_rd *rd, /* may be NULL */ + struct prefix *aux, /* may be NULL */ + struct rfapi_rib_key *rk) + { - memset((void *)rk, 0, sizeof(struct rfapi_rib_key)); - if (prefix) - rk->vn = *prefix; - if (rd) - rk->rd = *rd; - if (aux) - rk->aux_prefix = *aux; + memset((void *)rk, 0, sizeof(struct rfapi_rib_key)); + if (prefix) + rk->vn = *prefix; + if (rd) + rk->rd = *rd; + if (aux) + rk->aux_prefix = *aux; } /* * Compares two <struct rfapi_rib_key>s */ -int -rfapi_rib_key_cmp (void *k1, void *k2) +int rfapi_rib_key_cmp(void *k1, void *k2) { - struct rfapi_rib_key *a = (struct rfapi_rib_key *) k1; - struct rfapi_rib_key *b = (struct rfapi_rib_key *) k2; - int ret; + struct rfapi_rib_key *a = (struct rfapi_rib_key *)k1; + struct rfapi_rib_key *b = (struct rfapi_rib_key *)k2; + int ret; - if (!a || !b) - return (a - b); + if (!a || !b) + return (a - b); - ret = vnc_prefix_cmp (&a->vn, &b->vn); - if (ret) - return ret; + ret = vnc_prefix_cmp(&a->vn, &b->vn); + if (ret) + return ret; - ret = vnc_prefix_cmp(&a->rd, &b->rd); - if (ret) - return ret; + ret = vnc_prefix_cmp(&a->rd, &b->rd); + if (ret) + return ret; - ret = vnc_prefix_cmp (&a->aux_prefix, &b->aux_prefix); + ret = vnc_prefix_cmp(&a->aux_prefix, &b->aux_prefix); - return ret; + return ret; } @@ -459,295 +424,296 @@ rfapi_rib_key_cmp (void *k1, void *k2) * thoroughly, but it's not clear that the extra compuation would * be worth it. */ -static int -bgp_tea_options_cmp (struct bgp_tea_options *a, struct bgp_tea_options *b) +static int bgp_tea_options_cmp(struct bgp_tea_options *a, + struct bgp_tea_options *b) { - int rc; - - if (!a || !b) - { - return (a - b); - } - - if (a->type != b->type) - return (a->type - b->type); - if (a->length != b->length) - return (a->length = b->length); - if ((rc = memcmp (a->value, b->value, a->length))) - return rc; - if (!a->next != !b->next) - { /* logical xor */ - return (a->next - b->next); - } - if (a->next) - return bgp_tea_options_cmp (a->next, b->next); - return 0; + int rc; + + if (!a || !b) { + return (a - b); + } + if (a->type != b->type) + return (a->type - b->type); + if (a->length != b->length) + return (a->length = b->length); + if ((rc = memcmp(a->value, b->value, a->length))) + return rc; + if (!a->next != !b->next) { /* logical xor */ + return (a->next - b->next); + } + if (a->next) + return bgp_tea_options_cmp(a->next, b->next); + return 0; } -static int -rfapi_info_cmp (struct rfapi_info *a, struct rfapi_info *b) +static int rfapi_info_cmp(struct rfapi_info *a, struct rfapi_info *b) { - int rc; + int rc; - if (!a || !b) - return (a - b); + if (!a || !b) + return (a - b); - if ((rc = rfapi_rib_key_cmp (&a->rk, &b->rk))) - return rc; + if ((rc = rfapi_rib_key_cmp(&a->rk, &b->rk))) + return rc; - if ((rc = vnc_prefix_cmp (&a->un, &b->un))) - return rc; + if ((rc = vnc_prefix_cmp(&a->un, &b->un))) + return rc; - if (a->cost != b->cost) - return (a->cost - b->cost); + if (a->cost != b->cost) + return (a->cost - b->cost); - if (a->lifetime != b->lifetime) - return (a->lifetime - b->lifetime); + if (a->lifetime != b->lifetime) + return (a->lifetime - b->lifetime); - if ((rc = bgp_tea_options_cmp (a->tea_options, b->tea_options))) - return rc; + if ((rc = bgp_tea_options_cmp(a->tea_options, b->tea_options))) + return rc; - return 0; + return 0; } -void -rfapiRibClear (struct rfapi_descriptor *rfd) +void rfapiRibClear(struct rfapi_descriptor *rfd) { - struct bgp *bgp; - afi_t afi; + struct bgp *bgp; + afi_t afi; - if (rfd->bgp) - bgp = rfd->bgp; - else - bgp = bgp_get_default (); + if (rfd->bgp) + bgp = rfd->bgp; + else + bgp = bgp_get_default(); #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); + vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd); #endif - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - struct route_node *pn; - struct route_node *rn; - - if (rfd->rib_pending[afi]) - { - for (pn = route_top (rfd->rib_pending[afi]); pn; - pn = route_next (pn)) - { - if (pn->aggregate) - { - /* - * free references into the rfapi_info structures before - * freeing the structures themselves - */ - skiplist_free ((struct skiplist *) (pn->aggregate)); - pn->aggregate = NULL; - route_unlock_node (pn); /* skiplist deleted */ - } - /* - * free the rfapi_info structures - */ - if (pn->info) - { - if (pn->info != (void *) 1) - { - list_delete ((struct list *) (pn->info)); - } - pn->info = NULL; - route_unlock_node (pn); /* linklist or 1 deleted */ - } - } - } - if (rfd->rib[afi]) - { - for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) - { - if (rn->info) - { - - struct rfapi_info *ri; - - while (0 == - skiplist_first ((struct skiplist *) rn->info, NULL, - (void **) &ri)) - { - - rfapi_info_free (ri); - skiplist_delete_first ((struct skiplist *) rn->info); - } - skiplist_free ((struct skiplist *) rn->info); - rn->info = NULL; - route_unlock_node (rn); - RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); - } - if (rn->aggregate) - { - - struct rfapi_info *ri_del; - - /* delete skiplist & contents */ - while (!skiplist_first ((struct skiplist *) (rn->aggregate), - NULL, (void **) &ri_del)) - { - - /* sl->del takes care of ri_del */ - skiplist_delete_first ( - (struct skiplist *) (rn->aggregate)); - } - skiplist_free ((struct skiplist *) (rn->aggregate)); - - rn->aggregate = NULL; - route_unlock_node (rn); - } - } - } - } - if (rfd->updated_responses_queue) - { - work_queue_free (rfd->updated_responses_queue); - rfd->updated_responses_queue = NULL; - } + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + struct route_node *pn; + struct route_node *rn; + + if (rfd->rib_pending[afi]) { + for (pn = route_top(rfd->rib_pending[afi]); pn; + pn = route_next(pn)) { + if (pn->aggregate) { + /* + * free references into the rfapi_info + * structures before + * freeing the structures themselves + */ + skiplist_free( + (struct skiplist + *)(pn->aggregate)); + pn->aggregate = NULL; + route_unlock_node( + pn); /* skiplist deleted */ + } + /* + * free the rfapi_info structures + */ + if (pn->info) { + if (pn->info != (void *)1) { + list_delete( + (struct list + *)(pn->info)); + } + pn->info = NULL; + route_unlock_node( + pn); /* linklist or 1 deleted */ + } + } + } + if (rfd->rib[afi]) { + for (rn = route_top(rfd->rib[afi]); rn; + rn = route_next(rn)) { + if (rn->info) { + + struct rfapi_info *ri; + + while (0 == skiplist_first( + (struct skiplist *) + rn->info, + NULL, + (void **)&ri)) { + + rfapi_info_free(ri); + skiplist_delete_first( + (struct skiplist *) + rn->info); + } + skiplist_free( + (struct skiplist *)rn->info); + rn->info = NULL; + route_unlock_node(rn); + RFAPI_RIB_PREFIX_COUNT_DECR(rfd, + bgp->rfapi); + } + if (rn->aggregate) { + + struct rfapi_info *ri_del; + + /* delete skiplist & contents */ + while (!skiplist_first( + (struct skiplist + *)(rn->aggregate), + NULL, (void **)&ri_del)) { + + /* sl->del takes care of ri_del + */ + skiplist_delete_first(( + struct skiplist + *)(rn->aggregate)); + } + skiplist_free( + (struct skiplist + *)(rn->aggregate)); + + rn->aggregate = NULL; + route_unlock_node(rn); + } + } + } + } + if (rfd->updated_responses_queue) { + work_queue_free(rfd->updated_responses_queue); + rfd->updated_responses_queue = NULL; + } } /* * Release all dynamically-allocated memory that is part of an HD's RIB */ -void -rfapiRibFree (struct rfapi_descriptor *rfd) +void rfapiRibFree(struct rfapi_descriptor *rfd) { - afi_t afi; + afi_t afi; - /* - * NB rfd is typically detached from master list, so is not included - * in the count performed by RFAPI_RIB_CHECK_COUNTS - */ + /* + * NB rfd is typically detached from master list, so is not included + * in the count performed by RFAPI_RIB_CHECK_COUNTS + */ - /* - * Free routes attached to radix trees - */ - rfapiRibClear (rfd); + /* + * Free routes attached to radix trees + */ + rfapiRibClear(rfd); - /* Now the uncounted rfapi_info's are freed, so the check should succeed */ - RFAPI_RIB_CHECK_COUNTS (1, 0); + /* Now the uncounted rfapi_info's are freed, so the check should succeed + */ + RFAPI_RIB_CHECK_COUNTS(1, 0); - /* - * Free radix trees - */ - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - route_table_finish (rfd->rib_pending[afi]); - rfd->rib_pending[afi] = NULL; + /* + * Free radix trees + */ + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + route_table_finish(rfd->rib_pending[afi]); + rfd->rib_pending[afi] = NULL; - route_table_finish (rfd->rib[afi]); - rfd->rib[afi] = NULL; + route_table_finish(rfd->rib[afi]); + rfd->rib[afi] = NULL; - /* NB route_table_finish frees only prefix nodes, not chained info */ - route_table_finish (rfd->rsp_times[afi]); - rfd->rib[afi] = NULL; - } + /* NB route_table_finish frees only prefix nodes, not chained + * info */ + route_table_finish(rfd->rsp_times[afi]); + rfd->rib[afi] = NULL; + } } /* * Copies struct bgp_info to struct rfapi_info, except for rk fields and un */ -static void -rfapiRibBi2Ri( - struct bgp_info *bi, - struct rfapi_info *ri, - uint32_t lifetime) +static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri, + uint32_t lifetime) { - struct bgp_attr_encap_subtlv *pEncap; - - ri->cost = rfapiRfpCost (bi->attr); - ri->lifetime = lifetime; - - /* This loop based on rfapiRouteInfo2NextHopEntry() */ - for (pEncap = bi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) - { - struct bgp_tea_options *hop; - - switch (pEncap->type) - { - case BGP_VNC_SUBTLV_TYPE_LIFETIME: - /* use configured lifetime, not attr lifetime */ - break; - - case BGP_VNC_SUBTLV_TYPE_RFPOPTION: - hop = XCALLOC (MTYPE_BGP_TEA_OPTIONS, - sizeof (struct bgp_tea_options)); - assert (hop); - hop->type = pEncap->value[0]; - hop->length = pEncap->value[1]; - hop->value = XCALLOC (MTYPE_BGP_TEA_OPTIONS_VALUE, - pEncap->length - 2); - assert (hop->value); - memcpy (hop->value, pEncap->value + 2, pEncap->length - 2); - if (hop->length > pEncap->length - 2) - { - zlog_warn ("%s: VNC subtlv length mismatch: " - "RFP option says %d, attr says %d " - "(shrinking)", - __func__, hop->length, pEncap->length - 2); - hop->length = pEncap->length - 2; - } - hop->next = ri->tea_options; - ri->tea_options = hop; - break; - - default: - break; - } - } - - rfapi_un_options_free (ri->un_options); /* maybe free old version */ - ri->un_options = rfapi_encap_tlv_to_un_option (bi->attr); - - /* - * VN options - */ - if (bi->extra && - decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH) - { - /* ethernet route */ - - struct rfapi_vn_option *vo; - - vo = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); - assert (vo); - - vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; - - /* copy from RD already stored in bi, so we don't need it_node */ - memcpy (&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val+2, - ETHER_ADDR_LEN); - - if (bi->attr) - { - (void) rfapiEcommunityGetLNI (bi->attr->ecommunity, - &vo->v.l2addr.logical_net_id); - (void) rfapiEcommunityGetEthernetTag (bi->attr->ecommunity, - &vo->v.l2addr.tag_id); - } - - /* local_nve_id comes from RD */ - vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; - - /* label comes from MP_REACH_NLRI label */ - vo->v.l2addr.label = decode_label (&bi->extra->label); - - rfapi_vn_options_free (ri->vn_options); /* maybe free old version */ - ri->vn_options = vo; - } - - /* - * If there is an auxiliary IP address (L2 can have it), copy it - */ - if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) - { - ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; - } + struct bgp_attr_encap_subtlv *pEncap; + + ri->cost = rfapiRfpCost(bi->attr); + ri->lifetime = lifetime; + + /* This loop based on rfapiRouteInfo2NextHopEntry() */ + for (pEncap = bi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) { + struct bgp_tea_options *hop; + + switch (pEncap->type) { + case BGP_VNC_SUBTLV_TYPE_LIFETIME: + /* use configured lifetime, not attr lifetime */ + break; + + case BGP_VNC_SUBTLV_TYPE_RFPOPTION: + hop = XCALLOC(MTYPE_BGP_TEA_OPTIONS, + sizeof(struct bgp_tea_options)); + assert(hop); + hop->type = pEncap->value[0]; + hop->length = pEncap->value[1]; + hop->value = XCALLOC(MTYPE_BGP_TEA_OPTIONS_VALUE, + pEncap->length - 2); + assert(hop->value); + memcpy(hop->value, pEncap->value + 2, + pEncap->length - 2); + if (hop->length > pEncap->length - 2) { + zlog_warn( + "%s: VNC subtlv length mismatch: " + "RFP option says %d, attr says %d " + "(shrinking)", + __func__, hop->length, + pEncap->length - 2); + hop->length = pEncap->length - 2; + } + hop->next = ri->tea_options; + ri->tea_options = hop; + break; + + default: + break; + } + } + + rfapi_un_options_free(ri->un_options); /* maybe free old version */ + ri->un_options = rfapi_encap_tlv_to_un_option(bi->attr); + + /* + * VN options + */ + if (bi->extra + && decode_rd_type(bi->extra->vnc.import.rd.val) + == RD_TYPE_VNC_ETH) { + /* ethernet route */ + + struct rfapi_vn_option *vo; + + vo = XCALLOC(MTYPE_RFAPI_VN_OPTION, + sizeof(struct rfapi_vn_option)); + assert(vo); + + vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; + + /* copy from RD already stored in bi, so we don't need it_node + */ + memcpy(&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val + 2, + ETHER_ADDR_LEN); + + if (bi->attr) { + (void)rfapiEcommunityGetLNI( + bi->attr->ecommunity, + &vo->v.l2addr.logical_net_id); + (void)rfapiEcommunityGetEthernetTag( + bi->attr->ecommunity, &vo->v.l2addr.tag_id); + } + + /* local_nve_id comes from RD */ + vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; + + /* label comes from MP_REACH_NLRI label */ + vo->v.l2addr.label = decode_label(&bi->extra->label); + + rfapi_vn_options_free( + ri->vn_options); /* maybe free old version */ + ri->vn_options = vo; + } + + /* + * If there is an auxiliary IP address (L2 can have it), copy it + */ + if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) { + ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; + } } /* @@ -768,94 +734,86 @@ rfapiRibBi2Ri( * 0 OK to include route in response * !0 do not include route in response */ -int -rfapiRibPreloadBi( - struct route_node *rfd_rib_node, /* NULL = don't preload or filter */ - struct prefix *pfx_vn, - struct prefix *pfx_un, - uint32_t lifetime, - struct bgp_info *bi) +int rfapiRibPreloadBi( + struct route_node *rfd_rib_node, /* NULL = don't preload or filter */ + struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime, + struct bgp_info *bi) { - struct rfapi_descriptor *rfd; - struct skiplist *slRibPt = NULL; - struct rfapi_info *ori = NULL; - struct rfapi_rib_key rk; - struct route_node *trn; - afi_t afi; - - if (!rfd_rib_node) - return 0; - - afi = family2afi(rfd_rib_node->p.family); - - rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info); - - memset((void *)&rk, 0, sizeof(rk)); - rk.vn = *pfx_vn; - rk.rd = bi->extra->vnc.import.rd; - - /* - * If there is an auxiliary IP address (L2 can have it), copy it - */ - if (bi->extra->vnc.import.aux_prefix.family) - { - rk.aux_prefix = bi->extra->vnc.import.aux_prefix; - } - - /* - * is this route already in NVE's RIB? - */ - slRibPt = (struct skiplist *) rfd_rib_node->info; - - if (slRibPt && !skiplist_search (slRibPt, &rk, (void **) &ori)) - { - - if ((ori->rsp_counter == rfd->rsp_counter) && - (ori->last_sent_time == rfd->rsp_time)) - { - return -1; /* duplicate in this response */ + struct rfapi_descriptor *rfd; + struct skiplist *slRibPt = NULL; + struct rfapi_info *ori = NULL; + struct rfapi_rib_key rk; + struct route_node *trn; + afi_t afi; + + if (!rfd_rib_node) + return 0; + + afi = family2afi(rfd_rib_node->p.family); + + rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info); + + memset((void *)&rk, 0, sizeof(rk)); + rk.vn = *pfx_vn; + rk.rd = bi->extra->vnc.import.rd; + + /* + * If there is an auxiliary IP address (L2 can have it), copy it + */ + if (bi->extra->vnc.import.aux_prefix.family) { + rk.aux_prefix = bi->extra->vnc.import.aux_prefix; + } + + /* + * is this route already in NVE's RIB? + */ + slRibPt = (struct skiplist *)rfd_rib_node->info; + + if (slRibPt && !skiplist_search(slRibPt, &rk, (void **)&ori)) { + + if ((ori->rsp_counter == rfd->rsp_counter) + && (ori->last_sent_time == rfd->rsp_time)) { + return -1; /* duplicate in this response */ + } + + /* found: update contents of existing route in RIB */ + ori->un = *pfx_un; + rfapiRibBi2Ri(bi, ori, lifetime); + } else { + /* not found: add new route to RIB */ + ori = rfapi_info_new(); + ori->rk = rk; + ori->un = *pfx_un; + rfapiRibBi2Ri(bi, ori, lifetime); + + if (!slRibPt) { + slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL); + rfd_rib_node->info = slRibPt; + route_lock_node(rfd_rib_node); + RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfd->bgp->rfapi); + } + skiplist_insert(slRibPt, &ori->rk, ori); } - /* found: update contents of existing route in RIB */ - ori->un = *pfx_un; - rfapiRibBi2Ri(bi, ori, lifetime); - } - else - { - /* not found: add new route to RIB */ - ori = rfapi_info_new (); - ori->rk = rk; - ori->un = *pfx_un; - rfapiRibBi2Ri(bi, ori, lifetime); - - if (!slRibPt) - { - slRibPt = skiplist_new (0, rfapi_rib_key_cmp, NULL); - rfd_rib_node->info = slRibPt; - route_lock_node (rfd_rib_node); - RFAPI_RIB_PREFIX_COUNT_INCR (rfd, rfd->bgp->rfapi); - } - skiplist_insert (slRibPt, &ori->rk, ori); - } - - ori->last_sent_time = rfapi_time (NULL); - - /* - * poke timer - */ - RFAPI_RIB_CHECK_COUNTS (0, 0); - rfapiRibStartTimer (rfd, ori, rfd_rib_node, 0); - RFAPI_RIB_CHECK_COUNTS (0, 0); - - /* - * Update last sent time for prefix - */ - trn = route_node_get (rfd->rsp_times[afi], &rfd_rib_node->p); /* locks trn */ - trn->info = (void *) (uintptr_t) bgp_clock (); - if (trn->lock > 1) - route_unlock_node (trn); - - return 0; + ori->last_sent_time = rfapi_time(NULL); + + /* + * poke timer + */ + RFAPI_RIB_CHECK_COUNTS(0, 0); + rfapiRibStartTimer(rfd, ori, rfd_rib_node, 0); + RFAPI_RIB_CHECK_COUNTS(0, 0); + + /* + * Update last sent time for prefix + */ + trn = route_node_get(rfd->rsp_times[afi], + &rfd_rib_node->p); /* locks trn */ + trn->info = (void *)(uintptr_t)bgp_clock(); + if (trn->lock > 1) + route_unlock_node(trn); + + return 0; } /* @@ -882,617 +840,638 @@ rfapiRibPreloadBi( * * Clear pending node */ -static void -process_pending_node ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - afi_t afi, - struct route_node *pn, /* pending node */ - struct rfapi_next_hop_entry **head, - struct rfapi_next_hop_entry **tail) +static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, + afi_t afi, + struct route_node *pn, /* pending node */ + struct rfapi_next_hop_entry **head, + struct rfapi_next_hop_entry **tail) { - struct listnode *node = NULL; - struct listnode *nnode = NULL; - struct rfapi_info *ri = NULL; /* happy valgrind */ - struct rfapi_ip_prefix hp = { 0 }; /* pfx to put in NHE */ - struct route_node *rn = NULL; - struct skiplist *slRibPt = NULL; /* rib list */ - struct skiplist *slPendPt = NULL; - struct list *lPendCost = NULL; - struct list *delete_list = NULL; - int printedprefix = 0; - char buf_prefix[BUFSIZ]; - int rib_node_started_nonempty = 0; - int sendingsomeroutes = 0; + struct listnode *node = NULL; + struct listnode *nnode = NULL; + struct rfapi_info *ri = NULL; /* happy valgrind */ + struct rfapi_ip_prefix hp = {0}; /* pfx to put in NHE */ + struct route_node *rn = NULL; + struct skiplist *slRibPt = NULL; /* rib list */ + struct skiplist *slPendPt = NULL; + struct list *lPendCost = NULL; + struct list *delete_list = NULL; + int printedprefix = 0; + char buf_prefix[BUFSIZ]; + int rib_node_started_nonempty = 0; + int sendingsomeroutes = 0; #if DEBUG_PROCESS_PENDING_NODE - unsigned int count_rib_initial = 0; - unsigned int count_pend_vn_initial = 0; - unsigned int count_pend_cost_initial = 0; + unsigned int count_rib_initial = 0; + unsigned int count_pend_vn_initial = 0; + unsigned int count_pend_cost_initial = 0; #endif - assert (pn); - prefix2str (&pn->p, buf_prefix, BUFSIZ); - vnc_zlog_debug_verbose ("%s: afi=%d, %s pn->info=%p", - __func__, afi, buf_prefix, pn->info); + assert(pn); + prefix2str(&pn->p, buf_prefix, BUFSIZ); + vnc_zlog_debug_verbose("%s: afi=%d, %s pn->info=%p", __func__, afi, + buf_prefix, pn->info); - if (AFI_L2VPN != afi) - { - rfapiQprefix2Rprefix (&pn->p, &hp); - } + if (AFI_L2VPN != afi) { + rfapiQprefix2Rprefix(&pn->p, &hp); + } - RFAPI_RIB_CHECK_COUNTS (1, 0); + RFAPI_RIB_CHECK_COUNTS(1, 0); - /* - * Find corresponding RIB node - */ - rn = route_node_get (rfd->rib[afi], &pn->p); /* locks rn */ + /* + * Find corresponding RIB node + */ + rn = route_node_get(rfd->rib[afi], &pn->p); /* locks rn */ - /* - * RIB skiplist has key=rfapi_addr={vn,un}, val = rfapi_info, - * skiplist.del = NULL - */ - slRibPt = (struct skiplist *) rn->info; - if (slRibPt) - rib_node_started_nonempty = 1; + /* + * RIB skiplist has key=rfapi_addr={vn,un}, val = rfapi_info, + * skiplist.del = NULL + */ + slRibPt = (struct skiplist *)rn->info; + if (slRibPt) + rib_node_started_nonempty = 1; - slPendPt = (struct skiplist *) (pn->aggregate); - lPendCost = (struct list *) (pn->info); + slPendPt = (struct skiplist *)(pn->aggregate); + lPendCost = (struct list *)(pn->info); #if DEBUG_PROCESS_PENDING_NODE - /* debugging */ - if (slRibPt) - count_rib_initial = skiplist_count (slRibPt); + /* debugging */ + if (slRibPt) + count_rib_initial = skiplist_count(slRibPt); - if (slPendPt) - count_pend_vn_initial = skiplist_count (slPendPt); + if (slPendPt) + count_pend_vn_initial = skiplist_count(slPendPt); - if (lPendCost && lPendCost != (struct list *) 1) - count_pend_cost_initial = lPendCost->count; + if (lPendCost && lPendCost != (struct list *)1) + count_pend_cost_initial = lPendCost->count; #endif - /* - * Handle special case: delete all routes at prefix - */ - if (lPendCost == (struct list *) 1) - { - vnc_zlog_debug_verbose ("%s: lPendCost=1 => delete all", __func__); - if (slRibPt && !skiplist_empty (slRibPt)) - { - delete_list = list_new (); - while (0 == skiplist_first (slRibPt, NULL, (void **) &ri)) - { - - char buf[BUFSIZ]; - char buf2[BUFSIZ]; - - listnode_add (delete_list, ri); - vnc_zlog_debug_verbose ("%s: after listnode_add, delete_list->count=%d", - __func__, delete_list->count); - rfapiFreeBgpTeaOptionChain (ri->tea_options); - ri->tea_options = NULL; - - if (ri->timer) - { - struct rfapi_rib_tcb *tcb; - - tcb = ((struct thread *) ri->timer)->arg; - thread_cancel (ri->timer); - XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); - ri->timer = NULL; - } - - prefix2str (&ri->rk.vn, buf, BUFSIZ); - prefix2str (&ri->un, buf2, BUFSIZ); - vnc_zlog_debug_verbose - ("%s: put dl pfx=%s vn=%s un=%s cost=%d life=%d vn_options=%p", - __func__, buf_prefix, buf, buf2, ri->cost, ri->lifetime, - ri->vn_options); - - skiplist_delete_first (slRibPt); - } - - assert (skiplist_empty (slRibPt)); - - skiplist_free (slRibPt); - rn->info = slRibPt = NULL; - route_unlock_node (rn); - - lPendCost = pn->info = NULL; - route_unlock_node (pn); - - goto callback; - } - if (slRibPt) - { - skiplist_free (slRibPt); - rn->info = NULL; - route_unlock_node (rn); - } - - assert (!slPendPt); - if (slPendPt) - { /* TBD I think we can toss this block */ - skiplist_free (slPendPt); - pn->aggregate = NULL; - route_unlock_node (pn); - } - - pn->info = NULL; - route_unlock_node (pn); - - route_unlock_node (rn); /* route_node_get() */ - - if (rib_node_started_nonempty) - { - RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); - } - - RFAPI_RIB_CHECK_COUNTS (1, 0); - - return; - } - - vnc_zlog_debug_verbose ("%s: lPendCost->count=%d, slRibPt->count=%d", - __func__, - (lPendCost ? (int) lPendCost->count : -1), - (slRibPt ? (int) slRibPt->count : -1)); - - /* - * Iterate over routes at RIB Node. - * If not found at Pending Node, delete from RIB Node and add to deletelist - * If found at Pending Node - * If identical rfapi_info, delete from Pending Node - */ - if (slRibPt) - { - void *cursor = NULL; - struct rfapi_info *ori; - - /* - * Iterate over RIB List - * - */ - while (!skiplist_next (slRibPt, NULL, (void **) &ori, &cursor)) - { - - if (skiplist_search (slPendPt, &ori->rk, (void **) &ri)) - { - /* - * Not in Pending list, so it should be deleted - */ - if (!delete_list) - delete_list = list_new (); - listnode_add (delete_list, ori); - rfapiFreeBgpTeaOptionChain (ori->tea_options); - ori->tea_options = NULL; - if (ori->timer) - { - struct rfapi_rib_tcb *tcb; - - tcb = ((struct thread *) ori->timer)->arg; - thread_cancel (ori->timer); - XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); - ori->timer = NULL; - } + /* + * Handle special case: delete all routes at prefix + */ + if (lPendCost == (struct list *)1) { + vnc_zlog_debug_verbose("%s: lPendCost=1 => delete all", + __func__); + if (slRibPt && !skiplist_empty(slRibPt)) { + delete_list = list_new(); + while (0 + == skiplist_first(slRibPt, NULL, (void **)&ri)) { + + char buf[BUFSIZ]; + char buf2[BUFSIZ]; + + listnode_add(delete_list, ri); + vnc_zlog_debug_verbose( + "%s: after listnode_add, delete_list->count=%d", + __func__, delete_list->count); + rfapiFreeBgpTeaOptionChain(ri->tea_options); + ri->tea_options = NULL; + + if (ri->timer) { + struct rfapi_rib_tcb *tcb; + + tcb = ((struct thread *)ri->timer)->arg; + thread_cancel(ri->timer); + XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); + ri->timer = NULL; + } + + prefix2str(&ri->rk.vn, buf, BUFSIZ); + prefix2str(&ri->un, buf2, BUFSIZ); + vnc_zlog_debug_verbose( + "%s: put dl pfx=%s vn=%s un=%s cost=%d life=%d vn_options=%p", + __func__, buf_prefix, buf, buf2, + ri->cost, ri->lifetime, ri->vn_options); + + skiplist_delete_first(slRibPt); + } + + assert(skiplist_empty(slRibPt)); + + skiplist_free(slRibPt); + rn->info = slRibPt = NULL; + route_unlock_node(rn); + + lPendCost = pn->info = NULL; + route_unlock_node(pn); + + goto callback; + } + if (slRibPt) { + skiplist_free(slRibPt); + rn->info = NULL; + route_unlock_node(rn); + } + + assert(!slPendPt); + if (slPendPt) { /* TBD I think we can toss this block */ + skiplist_free(slPendPt); + pn->aggregate = NULL; + route_unlock_node(pn); + } + + pn->info = NULL; + route_unlock_node(pn); + + route_unlock_node(rn); /* route_node_get() */ + + if (rib_node_started_nonempty) { + RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi); + } + + RFAPI_RIB_CHECK_COUNTS(1, 0); + + return; + } + + vnc_zlog_debug_verbose("%s: lPendCost->count=%d, slRibPt->count=%d", + __func__, + (lPendCost ? (int)lPendCost->count : -1), + (slRibPt ? (int)slRibPt->count : -1)); + + /* + * Iterate over routes at RIB Node. + * If not found at Pending Node, delete from RIB Node and add to + * deletelist + * If found at Pending Node + * If identical rfapi_info, delete from Pending Node + */ + if (slRibPt) { + void *cursor = NULL; + struct rfapi_info *ori; + + /* + * Iterate over RIB List + * + */ + while (!skiplist_next(slRibPt, NULL, (void **)&ori, &cursor)) { + + if (skiplist_search(slPendPt, &ori->rk, (void **)&ri)) { + /* + * Not in Pending list, so it should be deleted + */ + if (!delete_list) + delete_list = list_new(); + listnode_add(delete_list, ori); + rfapiFreeBgpTeaOptionChain(ori->tea_options); + ori->tea_options = NULL; + if (ori->timer) { + struct rfapi_rib_tcb *tcb; + + tcb = ((struct thread *)ori->timer) + ->arg; + thread_cancel(ori->timer); + XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); + ori->timer = NULL; + } #if DEBUG_PROCESS_PENDING_NODE - /* deleted from slRibPt below, after we're done iterating */ - vnc_zlog_debug_verbose - ("%s: slRibPt ri %p not matched in pending list, delete", - __func__, ori); + /* deleted from slRibPt below, after we're done + * iterating */ + vnc_zlog_debug_verbose( + "%s: slRibPt ri %p not matched in pending list, delete", + __func__, ori); #endif - } - else - { - /* - * Found in pending list. If same lifetime, cost, options, - * then remove from pending list because the route - * hasn't changed. - */ - if (!rfapi_info_cmp (ori, ri)) - { - skiplist_delete (slPendPt, &ri->rk, NULL); - assert (lPendCost); - if (lPendCost) - { - /* linear walk: might need optimization */ - listnode_delete (lPendCost, ri); /* XXX doesn't free data! bug? */ - rfapi_info_free (ri); /* grr... */ - } - } + } else { + /* + * Found in pending list. If same lifetime, + * cost, options, + * then remove from pending list because the + * route + * hasn't changed. + */ + if (!rfapi_info_cmp(ori, ri)) { + skiplist_delete(slPendPt, &ri->rk, + NULL); + assert(lPendCost); + if (lPendCost) { + /* linear walk: might need + * optimization */ + listnode_delete(lPendCost, + ri); /* XXX + doesn't + free + data! + bug? */ + rfapi_info_free( + ri); /* grr... */ + } + } #if DEBUG_PROCESS_PENDING_NODE - vnc_zlog_debug_verbose ("%s: slRibPt ri %p matched in pending list, %s", - __func__, ori, - (same ? "same info" : "different info")); + vnc_zlog_debug_verbose( + "%s: slRibPt ri %p matched in pending list, %s", + __func__, ori, + (same ? "same info" + : "different info")); #endif - } - } - /* - * Go back and delete items from RIB - */ - if (delete_list) - { - for (ALL_LIST_ELEMENTS_RO (delete_list, node, ri)) - { - vnc_zlog_debug_verbose ("%s: deleting ri %p from slRibPt", __func__, ri); - assert (!skiplist_delete (slRibPt, &ri->rk, NULL)); - } - if (skiplist_empty (slRibPt)) - { - skiplist_free (slRibPt); - slRibPt = rn->info = NULL; - route_unlock_node (rn); - } - } - } - - RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - - /* - * Iterate over routes at Pending Node - * - * If {vn} found at RIB Node, update RIB Node route contents to match PN - * If {vn} NOT found at RIB Node, add copy to RIB Node - */ - if (lPendCost) - { - for (ALL_LIST_ELEMENTS_RO (lPendCost, node, ri)) - { - - struct rfapi_info *ori; - - if (slRibPt && !skiplist_search (slRibPt, &ri->rk, (void **) &ori)) - { - - /* found: update contents of existing route in RIB */ - ori->un = ri->un; - ori->cost = ri->cost; - ori->lifetime = ri->lifetime; - rfapiFreeBgpTeaOptionChain (ori->tea_options); - ori->tea_options = rfapiOptionsDup (ri->tea_options); - ori->last_sent_time = rfapi_time (NULL); - - rfapiFreeRfapiVnOptionChain (ori->vn_options); - ori->vn_options = rfapiVnOptionsDup (ri->vn_options); - - rfapiFreeRfapiUnOptionChain (ori->un_options); - ori->un_options = rfapiUnOptionsDup (ri->un_options); - - vnc_zlog_debug_verbose - ("%s: matched lPendCost item %p in slRibPt, rewrote", - __func__, ri); - - } - else - { - - char buf_rd[BUFSIZ]; - - /* not found: add new route to RIB */ - ori = rfapi_info_new (); - ori->rk = ri->rk; - ori->un = ri->un; - ori->cost = ri->cost; - ori->lifetime = ri->lifetime; - ori->tea_options = rfapiOptionsDup (ri->tea_options); - ori->last_sent_time = rfapi_time (NULL); - ori->vn_options = rfapiVnOptionsDup (ri->vn_options); - ori->un_options = rfapiUnOptionsDup (ri->un_options); - - if (!slRibPt) - { - slRibPt = skiplist_new (0, rfapi_rib_key_cmp, NULL); - rn->info = slRibPt; - route_lock_node (rn); - } - skiplist_insert (slRibPt, &ori->rk, ori); + } + } + /* + * Go back and delete items from RIB + */ + if (delete_list) { + for (ALL_LIST_ELEMENTS_RO(delete_list, node, ri)) { + vnc_zlog_debug_verbose( + "%s: deleting ri %p from slRibPt", + __func__, ri); + assert(!skiplist_delete(slRibPt, &ri->rk, + NULL)); + } + if (skiplist_empty(slRibPt)) { + skiplist_free(slRibPt); + slRibPt = rn->info = NULL; + route_unlock_node(rn); + } + } + } + + RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + + /* + * Iterate over routes at Pending Node + * + * If {vn} found at RIB Node, update RIB Node route contents to match PN + * If {vn} NOT found at RIB Node, add copy to RIB Node + */ + if (lPendCost) { + for (ALL_LIST_ELEMENTS_RO(lPendCost, node, ri)) { + + struct rfapi_info *ori; + + if (slRibPt + && !skiplist_search(slRibPt, &ri->rk, + (void **)&ori)) { + + /* found: update contents of existing route in + * RIB */ + ori->un = ri->un; + ori->cost = ri->cost; + ori->lifetime = ri->lifetime; + rfapiFreeBgpTeaOptionChain(ori->tea_options); + ori->tea_options = + rfapiOptionsDup(ri->tea_options); + ori->last_sent_time = rfapi_time(NULL); + + rfapiFreeRfapiVnOptionChain(ori->vn_options); + ori->vn_options = + rfapiVnOptionsDup(ri->vn_options); + + rfapiFreeRfapiUnOptionChain(ori->un_options); + ori->un_options = + rfapiUnOptionsDup(ri->un_options); + + vnc_zlog_debug_verbose( + "%s: matched lPendCost item %p in slRibPt, rewrote", + __func__, ri); + + } else { + + char buf_rd[BUFSIZ]; + + /* not found: add new route to RIB */ + ori = rfapi_info_new(); + ori->rk = ri->rk; + ori->un = ri->un; + ori->cost = ri->cost; + ori->lifetime = ri->lifetime; + ori->tea_options = + rfapiOptionsDup(ri->tea_options); + ori->last_sent_time = rfapi_time(NULL); + ori->vn_options = + rfapiVnOptionsDup(ri->vn_options); + ori->un_options = + rfapiUnOptionsDup(ri->un_options); + + if (!slRibPt) { + slRibPt = skiplist_new( + 0, rfapi_rib_key_cmp, NULL); + rn->info = slRibPt; + route_lock_node(rn); + } + skiplist_insert(slRibPt, &ori->rk, ori); #if DEBUG_RIB_SL_RD - prefix_rd2str(&ori->rk.rd, buf_rd, sizeof(buf_rd)); + prefix_rd2str(&ori->rk.rd, buf_rd, + sizeof(buf_rd)); #else - buf_rd[0] = 0; + buf_rd[0] = 0; #endif - vnc_zlog_debug_verbose ("%s: nomatch lPendCost item %p in slRibPt, added (rd=%s)", - __func__, ri, buf_rd); - } - - /* - * poke timer - */ - RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - rfapiRibStartTimer (rfd, ori, rn, 0); - RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - } - } + vnc_zlog_debug_verbose( + "%s: nomatch lPendCost item %p in slRibPt, added (rd=%s)", + __func__, ri, buf_rd); + } + + /* + * poke timer + */ + RFAPI_RIB_CHECK_COUNTS( + 0, (delete_list ? delete_list->count : 0)); + rfapiRibStartTimer(rfd, ori, rn, 0); + RFAPI_RIB_CHECK_COUNTS( + 0, (delete_list ? delete_list->count : 0)); + } + } callback: - /* - * Construct NHL as concatenation of pending list + delete list - */ - - - RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - - if (lPendCost) - { - - char buf[BUFSIZ]; - char buf2[BUFSIZ]; - - vnc_zlog_debug_verbose ("%s: lPendCost->count now %d", __func__, lPendCost->count); - vnc_zlog_debug_verbose ("%s: For prefix %s (a)", __func__, buf_prefix); - printedprefix = 1; - - for (ALL_LIST_ELEMENTS (lPendCost, node, nnode, ri)) - { - - struct rfapi_next_hop_entry *new; - struct route_node *trn; - - new = - XCALLOC (MTYPE_RFAPI_NEXTHOP, - sizeof (struct rfapi_next_hop_entry)); - assert (new); - - if (ri->rk.aux_prefix.family) - { - rfapiQprefix2Rprefix (&ri->rk.aux_prefix, &new->prefix); - } - else - { - new->prefix = hp; - if (AFI_L2VPN == afi) - { - /* hp is 0; need to set length to match AF of vn */ - new->prefix.length = - (ri->rk.vn.family == AF_INET) ? 32 : 128; - } - } - new->prefix.cost = ri->cost; - new->lifetime = ri->lifetime; - rfapiQprefix2Raddr (&ri->rk.vn, &new->vn_address); - rfapiQprefix2Raddr (&ri->un, &new->un_address); - /* free option chain from ri */ - rfapiFreeBgpTeaOptionChain (ri->tea_options); - - ri->tea_options = NULL; /* option chain was transferred to NHL */ - - new->vn_options = ri->vn_options; - ri->vn_options = NULL; /* option chain was transferred to NHL */ - - new->un_options = ri->un_options; - ri->un_options = NULL; /* option chain was transferred to NHL */ - - if (*tail) - (*tail)->next = new; - *tail = new; - if (!*head) - { - *head = new; - } - sendingsomeroutes = 1; - - ++rfd->stat_count_nh_reachable; - ++bgp->rfapi->stat.count_updated_response_updates; - - /* - * update this NVE's timestamp for this prefix - */ - trn = route_node_get (rfd->rsp_times[afi], &pn->p); /* locks trn */ - trn->info = (void *) (uintptr_t) bgp_clock (); - if (trn->lock > 1) - route_unlock_node (trn); - - rfapiRfapiIpAddr2Str (&new->vn_address, buf, BUFSIZ); - rfapiRfapiIpAddr2Str (&new->un_address, buf2, BUFSIZ); - vnc_zlog_debug_verbose ("%s: add vn=%s un=%s cost=%d life=%d", __func__, - buf, buf2, new->prefix.cost, new->lifetime); - } - } - - RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - - if (delete_list) - { - - char buf[BUFSIZ]; - char buf2[BUFSIZ]; - - if (!printedprefix) - { - vnc_zlog_debug_verbose ("%s: For prefix %s (d)", __func__, buf_prefix); - } - vnc_zlog_debug_verbose ("%s: delete_list has %d elements", - __func__, delete_list->count); - - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - if (!CHECK_FLAG (bgp->rfapi_cfg->flags, - BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) - { - - for (ALL_LIST_ELEMENTS (delete_list, node, nnode, ri)) - { - - struct rfapi_next_hop_entry *new; - struct rfapi_info *ri_del; - - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - new = XCALLOC (MTYPE_RFAPI_NEXTHOP, - sizeof (struct rfapi_next_hop_entry)); - assert (new); - - if (ri->rk.aux_prefix.family) - { - rfapiQprefix2Rprefix (&ri->rk.aux_prefix, &new->prefix); - } - else - { - new->prefix = hp; - if (AFI_L2VPN == afi) - { - /* hp is 0; need to set length to match AF of vn */ - new->prefix.length = - (ri->rk.vn.family == AF_INET) ? 32 : 128; - } - } - - new->prefix.cost = ri->cost; - new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; - rfapiQprefix2Raddr (&ri->rk.vn, &new->vn_address); - rfapiQprefix2Raddr (&ri->un, &new->un_address); - - new->vn_options = ri->vn_options; - ri->vn_options = NULL; /* option chain was transferred to NHL */ - - new->un_options = ri->un_options; - ri->un_options = NULL; /* option chain was transferred to NHL */ - - if (*tail) - (*tail)->next = new; - *tail = new; - if (!*head) - { - *head = new; - } - ++rfd->stat_count_nh_removal; - ++bgp->rfapi->stat.count_updated_response_deletes; - - rfapiRfapiIpAddr2Str (&new->vn_address, buf, BUFSIZ); - rfapiRfapiIpAddr2Str (&new->un_address, buf2, BUFSIZ); - vnc_zlog_debug_verbose ("%s: DEL vn=%s un=%s cost=%d life=%d", __func__, - buf, buf2, new->prefix.cost, new->lifetime); - - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - /* - * Update/add to list of recent deletions at this prefix - */ - if (!rn->aggregate) - { - rn->aggregate = skiplist_new (0, rfapi_rib_key_cmp, - (void (*)(void *)) - rfapi_info_free); - route_lock_node (rn); - } - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - - /* sanity check lifetime */ - if (ri->lifetime > RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) - ri->lifetime = RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; - - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - /* cancel normal expire timer */ - if (ri->timer) - { - struct rfapi_rib_tcb *tcb; - - tcb = ((struct thread *) ri->timer)->arg; - thread_cancel ((struct thread *) ri->timer); - XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); - ri->timer = NULL; - } - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - - /* - * Look in "recently-deleted" list - */ - if (skiplist_search ((struct skiplist *) (rn->aggregate), - &ri->rk, (void **) &ri_del)) - { - - int rc; - - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - /* - * NOT in "recently-deleted" list - */ - list_delete_node (delete_list, node); /* does not free ri */ - rc = skiplist_insert ((struct skiplist *) (rn->aggregate), - &ri->rk, ri); - assert (!rc); - - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - rfapiRibStartTimer (rfd, ri, rn, 1); - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - ri->last_sent_time = rfapi_time (NULL); + /* + * Construct NHL as concatenation of pending list + delete list + */ + + + RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + + if (lPendCost) { + + char buf[BUFSIZ]; + char buf2[BUFSIZ]; + + vnc_zlog_debug_verbose("%s: lPendCost->count now %d", __func__, + lPendCost->count); + vnc_zlog_debug_verbose("%s: For prefix %s (a)", __func__, + buf_prefix); + printedprefix = 1; + + for (ALL_LIST_ELEMENTS(lPendCost, node, nnode, ri)) { + + struct rfapi_next_hop_entry *new; + struct route_node *trn; + + new = XCALLOC(MTYPE_RFAPI_NEXTHOP, + sizeof(struct rfapi_next_hop_entry)); + assert(new); + + if (ri->rk.aux_prefix.family) { + rfapiQprefix2Rprefix(&ri->rk.aux_prefix, + &new->prefix); + } else { + new->prefix = hp; + if (AFI_L2VPN == afi) { + /* hp is 0; need to set length to match + * AF of vn */ + new->prefix.length = + (ri->rk.vn.family == AF_INET) + ? 32 + : 128; + } + } + new->prefix.cost = ri->cost; + new->lifetime = ri->lifetime; + rfapiQprefix2Raddr(&ri->rk.vn, &new->vn_address); + rfapiQprefix2Raddr(&ri->un, &new->un_address); + /* free option chain from ri */ + rfapiFreeBgpTeaOptionChain(ri->tea_options); + + ri->tea_options = + NULL; /* option chain was transferred to NHL */ + + new->vn_options = ri->vn_options; + ri->vn_options = + NULL; /* option chain was transferred to NHL */ + + new->un_options = ri->un_options; + ri->un_options = + NULL; /* option chain was transferred to NHL */ + + if (*tail) + (*tail)->next = new; + *tail = new; + if (!*head) { + *head = new; + } + sendingsomeroutes = 1; + + ++rfd->stat_count_nh_reachable; + ++bgp->rfapi->stat.count_updated_response_updates; + + /* + * update this NVE's timestamp for this prefix + */ + trn = route_node_get(rfd->rsp_times[afi], + &pn->p); /* locks trn */ + trn->info = (void *)(uintptr_t)bgp_clock(); + if (trn->lock > 1) + route_unlock_node(trn); + + rfapiRfapiIpAddr2Str(&new->vn_address, buf, BUFSIZ); + rfapiRfapiIpAddr2Str(&new->un_address, buf2, BUFSIZ); + vnc_zlog_debug_verbose( + "%s: add vn=%s un=%s cost=%d life=%d", + __func__, buf, buf2, new->prefix.cost, + new->lifetime); + } + } + + RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + + if (delete_list) { + + char buf[BUFSIZ]; + char buf2[BUFSIZ]; + + if (!printedprefix) { + vnc_zlog_debug_verbose("%s: For prefix %s (d)", + __func__, buf_prefix); + } + vnc_zlog_debug_verbose("%s: delete_list has %d elements", + __func__, delete_list->count); + + RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + if (!CHECK_FLAG(bgp->rfapi_cfg->flags, + BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) { + + for (ALL_LIST_ELEMENTS(delete_list, node, nnode, ri)) { + + struct rfapi_next_hop_entry *new; + struct rfapi_info *ri_del; + + RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + new = XCALLOC( + MTYPE_RFAPI_NEXTHOP, + sizeof(struct rfapi_next_hop_entry)); + assert(new); + + if (ri->rk.aux_prefix.family) { + rfapiQprefix2Rprefix(&ri->rk.aux_prefix, + &new->prefix); + } else { + new->prefix = hp; + if (AFI_L2VPN == afi) { + /* hp is 0; need to set length + * to match AF of vn */ + new->prefix.length = + (ri->rk.vn.family + == AF_INET) + ? 32 + : 128; + } + } + + new->prefix.cost = ri->cost; + new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; + rfapiQprefix2Raddr(&ri->rk.vn, + &new->vn_address); + rfapiQprefix2Raddr(&ri->un, &new->un_address); + + new->vn_options = ri->vn_options; + ri->vn_options = NULL; /* option chain was + transferred to NHL */ + + new->un_options = ri->un_options; + ri->un_options = NULL; /* option chain was + transferred to NHL */ + + if (*tail) + (*tail)->next = new; + *tail = new; + if (!*head) { + *head = new; + } + ++rfd->stat_count_nh_removal; + ++bgp->rfapi->stat + .count_updated_response_deletes; + + rfapiRfapiIpAddr2Str(&new->vn_address, buf, + BUFSIZ); + rfapiRfapiIpAddr2Str(&new->un_address, buf2, + BUFSIZ); + vnc_zlog_debug_verbose( + "%s: DEL vn=%s un=%s cost=%d life=%d", + __func__, buf, buf2, new->prefix.cost, + new->lifetime); + + RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + /* + * Update/add to list of recent deletions at + * this prefix + */ + if (!rn->aggregate) { + rn->aggregate = skiplist_new( + 0, rfapi_rib_key_cmp, + (void (*)(void *)) + rfapi_info_free); + route_lock_node(rn); + } + RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + + /* sanity check lifetime */ + if (ri->lifetime + > RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) + ri->lifetime = + RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; + + RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + /* cancel normal expire timer */ + if (ri->timer) { + struct rfapi_rib_tcb *tcb; + + tcb = ((struct thread *)ri->timer)->arg; + thread_cancel( + (struct thread *)ri->timer); + XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); + ri->timer = NULL; + } + RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + + /* + * Look in "recently-deleted" list + */ + if (skiplist_search( + (struct skiplist *)(rn->aggregate), + &ri->rk, (void **)&ri_del)) { + + int rc; + + RFAPI_RIB_CHECK_COUNTS( + 0, delete_list->count); + /* + * NOT in "recently-deleted" list + */ + list_delete_node( + delete_list, + node); /* does not free ri */ + rc = skiplist_insert( + (struct skiplist + *)(rn->aggregate), + &ri->rk, ri); + assert(!rc); + + RFAPI_RIB_CHECK_COUNTS( + 0, delete_list->count); + rfapiRibStartTimer(rfd, ri, rn, 1); + RFAPI_RIB_CHECK_COUNTS( + 0, delete_list->count); + ri->last_sent_time = rfapi_time(NULL); #if DEBUG_RIB_SL_RD - { - char buf_rd[BUFSIZ]; - prefix_rd2str(&ri->rk.rd, buf_rd, sizeof(buf_rd)); - vnc_zlog_debug_verbose("%s: move route to recently deleted list, rd=%s", - __func__, buf_rd); - } + { + char buf_rd[BUFSIZ]; + prefix_rd2str(&ri->rk.rd, + buf_rd, + sizeof(buf_rd)); + vnc_zlog_debug_verbose( + "%s: move route to recently deleted list, rd=%s", + __func__, buf_rd); + } #endif - } - else - { - /* - * IN "recently-deleted" list - */ - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - rfapiRibStartTimer (rfd, ri_del, rn, 1); - RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - ri->last_sent_time = rfapi_time (NULL); - - } - } - } - else - { - vnc_zlog_debug_verbose ("%s: response removal disabled, omitting removals", - __func__); - } - - delete_list->del = (void (*)(void *)) rfapi_info_free; - list_delete (delete_list); - } - - RFAPI_RIB_CHECK_COUNTS (0, 0); - - /* - * Reset pending lists. The final route_unlock_node() will probably - * cause the pending node to be released. - */ - if (slPendPt) - { - skiplist_free (slPendPt); - pn->aggregate = NULL; - route_unlock_node (pn); - } - if (lPendCost) - { - list_delete (lPendCost); - pn->info = NULL; - route_unlock_node (pn); - } - RFAPI_RIB_CHECK_COUNTS (0, 0); - - if (rib_node_started_nonempty) - { - if (!rn->info) - { - RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); - } - } - else - { - if (rn->info) - { - RFAPI_RIB_PREFIX_COUNT_INCR (rfd, bgp->rfapi); - } - } - - if (sendingsomeroutes) - rfapiMonitorTimersRestart (rfd, &pn->p); - - route_unlock_node (rn); /* route_node_get() */ - - RFAPI_RIB_CHECK_COUNTS (1, 0); + } else { + /* + * IN "recently-deleted" list + */ + RFAPI_RIB_CHECK_COUNTS( + 0, delete_list->count); + rfapiRibStartTimer(rfd, ri_del, rn, 1); + RFAPI_RIB_CHECK_COUNTS( + 0, delete_list->count); + ri->last_sent_time = rfapi_time(NULL); + } + } + } else { + vnc_zlog_debug_verbose( + "%s: response removal disabled, omitting removals", + __func__); + } + + delete_list->del = (void (*)(void *))rfapi_info_free; + list_delete(delete_list); + } + + RFAPI_RIB_CHECK_COUNTS(0, 0); + + /* + * Reset pending lists. The final route_unlock_node() will probably + * cause the pending node to be released. + */ + if (slPendPt) { + skiplist_free(slPendPt); + pn->aggregate = NULL; + route_unlock_node(pn); + } + if (lPendCost) { + list_delete(lPendCost); + pn->info = NULL; + route_unlock_node(pn); + } + RFAPI_RIB_CHECK_COUNTS(0, 0); + + if (rib_node_started_nonempty) { + if (!rn->info) { + RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi); + } + } else { + if (rn->info) { + RFAPI_RIB_PREFIX_COUNT_INCR(rfd, bgp->rfapi); + } + } + + if (sendingsomeroutes) + rfapiMonitorTimersRestart(rfd, &pn->p); + + route_unlock_node(rn); /* route_node_get() */ + + RFAPI_RIB_CHECK_COUNTS(1, 0); } /* @@ -1503,97 +1482,95 @@ callback: * Do callback * */ -static void -rib_do_callback_onepass (struct rfapi_descriptor *rfd, afi_t afi) +static void rib_do_callback_onepass(struct rfapi_descriptor *rfd, afi_t afi) { - struct bgp *bgp = bgp_get_default (); - struct rfapi_next_hop_entry *head = NULL; - struct rfapi_next_hop_entry *tail = NULL; - struct route_node *rn; + struct bgp *bgp = bgp_get_default(); + struct rfapi_next_hop_entry *head = NULL; + struct rfapi_next_hop_entry *tail = NULL; + struct route_node *rn; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: rfd=%p, afi=%d", __func__, rfd, afi); + vnc_zlog_debug_verbose("%s: rfd=%p, afi=%d", __func__, rfd, afi); #endif - if (!rfd->rib_pending[afi]) - return; + if (!rfd->rib_pending[afi]) + return; - assert (bgp->rfapi); + assert(bgp->rfapi); - for (rn = route_top (rfd->rib_pending[afi]); rn; rn = route_next (rn)) - { - process_pending_node (bgp, rfd, afi, rn, &head, &tail); - } + for (rn = route_top(rfd->rib_pending[afi]); rn; rn = route_next(rn)) { + process_pending_node(bgp, rfd, afi, rn, &head, &tail); + } - if (head) - { - rfapi_response_cb_t *f; + if (head) { + rfapi_response_cb_t *f; #if DEBUG_NHL - vnc_zlog_debug_verbose ("%s: response callback NHL follows:", __func__); - rfapiPrintNhl (NULL, head); + vnc_zlog_debug_verbose("%s: response callback NHL follows:", + __func__); + rfapiPrintNhl(NULL, head); #endif - if (rfd->response_cb) - f = rfd->response_cb; - else - f = bgp->rfapi->rfp_methods.response_cb; - - bgp->rfapi->flags |= RFAPI_INCALLBACK; - vnc_zlog_debug_verbose ("%s: invoking updated response callback", __func__); - (*f) (head, rfd->cookie); - bgp->rfapi->flags &= ~RFAPI_INCALLBACK; - ++bgp->rfapi->response_updated_count; - } + if (rfd->response_cb) + f = rfd->response_cb; + else + f = bgp->rfapi->rfp_methods.response_cb; + + bgp->rfapi->flags |= RFAPI_INCALLBACK; + vnc_zlog_debug_verbose("%s: invoking updated response callback", + __func__); + (*f)(head, rfd->cookie); + bgp->rfapi->flags &= ~RFAPI_INCALLBACK; + ++bgp->rfapi->response_updated_count; + } } -static wq_item_status -rfapiRibDoQueuedCallback (struct work_queue *wq, void *data) +static wq_item_status rfapiRibDoQueuedCallback(struct work_queue *wq, + void *data) { - struct rfapi_descriptor *rfd; - afi_t afi; - uint32_t queued_flag; + struct rfapi_descriptor *rfd; + afi_t afi; + uint32_t queued_flag; - RFAPI_RIB_CHECK_COUNTS (1, 0); + RFAPI_RIB_CHECK_COUNTS(1, 0); - rfd = ((struct rfapi_updated_responses_queue *) data)->rfd; - afi = ((struct rfapi_updated_responses_queue *) data)->afi; + rfd = ((struct rfapi_updated_responses_queue *)data)->rfd; + afi = ((struct rfapi_updated_responses_queue *)data)->afi; - /* Make sure the HD wasn't closed after the work item was scheduled */ - if (rfapi_check (rfd)) - return WQ_SUCCESS; + /* Make sure the HD wasn't closed after the work item was scheduled */ + if (rfapi_check(rfd)) + return WQ_SUCCESS; - rib_do_callback_onepass (rfd, afi); + rib_do_callback_onepass(rfd, afi); - queued_flag = RFAPI_QUEUED_FLAG (afi); + queued_flag = RFAPI_QUEUED_FLAG(afi); - UNSET_FLAG (rfd->flags, queued_flag); + UNSET_FLAG(rfd->flags, queued_flag); - RFAPI_RIB_CHECK_COUNTS (1, 0); + RFAPI_RIB_CHECK_COUNTS(1, 0); - return WQ_SUCCESS; + return WQ_SUCCESS; } -static void -rfapiRibQueueItemDelete (struct work_queue *wq, void *data) +static void rfapiRibQueueItemDelete(struct work_queue *wq, void *data) { - XFREE (MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, data); + XFREE(MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, data); } -static void -updated_responses_queue_init (struct rfapi_descriptor *rfd) +static void updated_responses_queue_init(struct rfapi_descriptor *rfd) { - if (rfd->updated_responses_queue) - return; - - rfd->updated_responses_queue = work_queue_new (bm->master, - "rfapi updated responses"); - assert (rfd->updated_responses_queue); - - rfd->updated_responses_queue->spec.workfunc = rfapiRibDoQueuedCallback; - rfd->updated_responses_queue->spec.del_item_data = rfapiRibQueueItemDelete; - rfd->updated_responses_queue->spec.max_retries = 0; - rfd->updated_responses_queue->spec.hold = 1; + if (rfd->updated_responses_queue) + return; + + rfd->updated_responses_queue = + work_queue_new(bm->master, "rfapi updated responses"); + assert(rfd->updated_responses_queue); + + rfd->updated_responses_queue->spec.workfunc = rfapiRibDoQueuedCallback; + rfd->updated_responses_queue->spec.del_item_data = + rfapiRibQueueItemDelete; + rfd->updated_responses_queue->spec.max_retries = 0; + rfd->updated_responses_queue->spec.hold = 1; } /* @@ -1608,219 +1585,202 @@ updated_responses_queue_init (struct rfapi_descriptor *rfd) * * Based on rfapiNhlAddNodeRoutes() */ -void -rfapiRibUpdatePendingNode ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct rfapi_import_table *it, /* needed for L2 */ - struct route_node *it_node, - uint32_t lifetime) +void rfapiRibUpdatePendingNode( + struct bgp *bgp, struct rfapi_descriptor *rfd, + struct rfapi_import_table *it, /* needed for L2 */ + struct route_node *it_node, uint32_t lifetime) { - struct prefix *prefix; - struct bgp_info *bi; - struct route_node *pn; - afi_t afi; - uint32_t queued_flag; - int count = 0; - char buf[BUFSIZ]; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - - if (CHECK_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_CALLBACK_DISABLE)) - return; - - vnc_zlog_debug_verbose ("%s: callbacks are not disabled", __func__); - - RFAPI_RIB_CHECK_COUNTS (1, 0); - - prefix = &it_node->p; - afi = family2afi (prefix->family); - prefix2str (prefix, buf, BUFSIZ); - vnc_zlog_debug_verbose ("%s: prefix=%s", __func__, buf); - - pn = route_node_get (rfd->rib_pending[afi], prefix); - assert (pn); - - vnc_zlog_debug_verbose ("%s: pn->info=%p, pn->aggregate=%p", __func__, pn->info, - pn->aggregate); - - if (pn->aggregate) - { - /* - * free references into the rfapi_info structures before - * freeing the structures themselves - */ - skiplist_free ((struct skiplist *) (pn->aggregate)); - pn->aggregate = NULL; - route_unlock_node (pn); /* skiplist deleted */ - } - - - /* - * free the rfapi_info structures - */ - if (pn->info) - { - if (pn->info != (void *) 1) - { - list_delete ((struct list *) (pn->info)); - } - pn->info = NULL; - route_unlock_node (pn); /* linklist or 1 deleted */ - } - - /* - * The BIs in the import table are already sorted by cost - */ - for (bi = it_node->info; bi; bi = bi->next) - { - - struct rfapi_info *ri; - struct prefix pfx_nh; - - if (!bi->attr) - { - /* shouldn't happen */ - /* TBD increment error stats counter */ - continue; - } - if (!bi->extra) - { - /* shouldn't happen */ - /* TBD increment error stats counter */ - continue; - } - - rfapiNexthop2Prefix (bi->attr, &pfx_nh); - - /* - * Omit route if nexthop is self - */ - if (CHECK_FLAG - (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) - { - - struct prefix pfx_vn; - - rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn); - if (prefix_same (&pfx_vn, &pfx_nh)) - continue; - } - - ri = rfapi_info_new (); - ri->rk.vn = pfx_nh; - ri->rk.rd = bi->extra->vnc.import.rd; - /* - * If there is an auxiliary IP address (L2 can have it), copy it - */ - if (bi->extra->vnc.import.aux_prefix.family) - { - ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; - } - - if (rfapiGetUnAddrOfVpnBi (bi, &ri->un)) - { - rfapi_info_free (ri); - continue; - } - - if (!pn->aggregate) - { - pn->aggregate = skiplist_new (0, rfapi_rib_key_cmp, NULL); - route_lock_node (pn); - } - - /* - * If we have already added this nexthop, the insert will fail. - * Note that the skiplist key is a pointer INTO the rfapi_info - * structure which will be added to the "info" list. - * The skiplist entry VALUE is not used for anything but - * might be useful during debugging. - */ - if (skiplist_insert ((struct skiplist *) pn->aggregate, &ri->rk, ri)) - { - - /* - * duplicate - */ - rfapi_info_free (ri); - continue; - } - - rfapiRibBi2Ri(bi, ri, lifetime); - - if (!pn->info) - { - pn->info = list_new (); - ((struct list *)(pn->info))->del = (void (*)(void *))rfapi_info_free; - route_lock_node (pn); - } - - listnode_add ((struct list *) (pn->info), ri); - } - - if (pn->info) - { - count = ((struct list *) (pn->info))->count; - } - - if (!count) - { - assert (!pn->info); - assert (!pn->aggregate); - pn->info = (void *) 1; /* magic value means this node has no routes */ - route_lock_node (pn); - } - - route_unlock_node (pn); /* route_node_get */ - - queued_flag = RFAPI_QUEUED_FLAG (afi); - - if (!CHECK_FLAG (rfd->flags, queued_flag)) - { - - struct rfapi_updated_responses_queue *urq; - - urq = XCALLOC (MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, - sizeof (struct rfapi_updated_responses_queue)); - assert (urq); - if (!rfd->updated_responses_queue) - updated_responses_queue_init (rfd); - - SET_FLAG (rfd->flags, queued_flag); - urq->rfd = rfd; - urq->afi = afi; - work_queue_add (rfd->updated_responses_queue, urq); - } - RFAPI_RIB_CHECK_COUNTS (1, 0); + struct prefix *prefix; + struct bgp_info *bi; + struct route_node *pn; + afi_t afi; + uint32_t queued_flag; + int count = 0; + char buf[BUFSIZ]; + + vnc_zlog_debug_verbose("%s: entry", __func__); + + if (CHECK_FLAG(bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_CALLBACK_DISABLE)) + return; + + vnc_zlog_debug_verbose("%s: callbacks are not disabled", __func__); + + RFAPI_RIB_CHECK_COUNTS(1, 0); + + prefix = &it_node->p; + afi = family2afi(prefix->family); + prefix2str(prefix, buf, BUFSIZ); + vnc_zlog_debug_verbose("%s: prefix=%s", __func__, buf); + + pn = route_node_get(rfd->rib_pending[afi], prefix); + assert(pn); + + vnc_zlog_debug_verbose("%s: pn->info=%p, pn->aggregate=%p", __func__, + pn->info, pn->aggregate); + + if (pn->aggregate) { + /* + * free references into the rfapi_info structures before + * freeing the structures themselves + */ + skiplist_free((struct skiplist *)(pn->aggregate)); + pn->aggregate = NULL; + route_unlock_node(pn); /* skiplist deleted */ + } + + + /* + * free the rfapi_info structures + */ + if (pn->info) { + if (pn->info != (void *)1) { + list_delete((struct list *)(pn->info)); + } + pn->info = NULL; + route_unlock_node(pn); /* linklist or 1 deleted */ + } + + /* + * The BIs in the import table are already sorted by cost + */ + for (bi = it_node->info; bi; bi = bi->next) { + + struct rfapi_info *ri; + struct prefix pfx_nh; + + if (!bi->attr) { + /* shouldn't happen */ + /* TBD increment error stats counter */ + continue; + } + if (!bi->extra) { + /* shouldn't happen */ + /* TBD increment error stats counter */ + continue; + } + + rfapiNexthop2Prefix(bi->attr, &pfx_nh); + + /* + * Omit route if nexthop is self + */ + if (CHECK_FLAG(bgp->rfapi_cfg->flags, + BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) { + + struct prefix pfx_vn; + + rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn); + if (prefix_same(&pfx_vn, &pfx_nh)) + continue; + } + + ri = rfapi_info_new(); + ri->rk.vn = pfx_nh; + ri->rk.rd = bi->extra->vnc.import.rd; + /* + * If there is an auxiliary IP address (L2 can have it), copy it + */ + if (bi->extra->vnc.import.aux_prefix.family) { + ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; + } + + if (rfapiGetUnAddrOfVpnBi(bi, &ri->un)) { + rfapi_info_free(ri); + continue; + } + + if (!pn->aggregate) { + pn->aggregate = + skiplist_new(0, rfapi_rib_key_cmp, NULL); + route_lock_node(pn); + } + + /* + * If we have already added this nexthop, the insert will fail. + * Note that the skiplist key is a pointer INTO the rfapi_info + * structure which will be added to the "info" list. + * The skiplist entry VALUE is not used for anything but + * might be useful during debugging. + */ + if (skiplist_insert((struct skiplist *)pn->aggregate, &ri->rk, + ri)) { + + /* + * duplicate + */ + rfapi_info_free(ri); + continue; + } + + rfapiRibBi2Ri(bi, ri, lifetime); + + if (!pn->info) { + pn->info = list_new(); + ((struct list *)(pn->info))->del = + (void (*)(void *))rfapi_info_free; + route_lock_node(pn); + } + + listnode_add((struct list *)(pn->info), ri); + } + + if (pn->info) { + count = ((struct list *)(pn->info))->count; + } + + if (!count) { + assert(!pn->info); + assert(!pn->aggregate); + pn->info = (void *)1; /* magic value means this node has no + routes */ + route_lock_node(pn); + } + + route_unlock_node(pn); /* route_node_get */ + + queued_flag = RFAPI_QUEUED_FLAG(afi); + + if (!CHECK_FLAG(rfd->flags, queued_flag)) { + + struct rfapi_updated_responses_queue *urq; + + urq = XCALLOC(MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, + sizeof(struct rfapi_updated_responses_queue)); + assert(urq); + if (!rfd->updated_responses_queue) + updated_responses_queue_init(rfd); + + SET_FLAG(rfd->flags, queued_flag); + urq->rfd = rfd; + urq->afi = afi; + work_queue_add(rfd->updated_responses_queue, urq); + } + RFAPI_RIB_CHECK_COUNTS(1, 0); } -void -rfapiRibUpdatePendingNodeSubtree ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct rfapi_import_table *it, - struct route_node *it_node, - struct route_node *omit_subtree, /* may be NULL */ - uint32_t lifetime) +void rfapiRibUpdatePendingNodeSubtree( + struct bgp *bgp, struct rfapi_descriptor *rfd, + struct rfapi_import_table *it, struct route_node *it_node, + struct route_node *omit_subtree, /* may be NULL */ + uint32_t lifetime) { - /* FIXME: need to find a better way here to work without sticking our - * hands in node->link */ - if (it_node->l_left && (it_node->l_left != omit_subtree)) - { - if (it_node->l_left->info) - rfapiRibUpdatePendingNode (bgp, rfd, it, it_node->l_left, lifetime); - rfapiRibUpdatePendingNodeSubtree (bgp, rfd, it, it_node->l_left, - omit_subtree, lifetime); - } - - if (it_node->l_right && (it_node->l_right != omit_subtree)) - { - if (it_node->l_right->info) - rfapiRibUpdatePendingNode (bgp, rfd, it, it_node->l_right, lifetime); - rfapiRibUpdatePendingNodeSubtree (bgp, rfd, it, it_node->l_right, - omit_subtree, lifetime); - } + /* FIXME: need to find a better way here to work without sticking our + * hands in node->link */ + if (it_node->l_left && (it_node->l_left != omit_subtree)) { + if (it_node->l_left->info) + rfapiRibUpdatePendingNode(bgp, rfd, it, it_node->l_left, + lifetime); + rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_left, + omit_subtree, lifetime); + } + + if (it_node->l_right && (it_node->l_right != omit_subtree)) { + if (it_node->l_right->info) + rfapiRibUpdatePendingNode(bgp, rfd, it, + it_node->l_right, lifetime); + rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_right, + omit_subtree, lifetime); + } } /* @@ -1829,72 +1789,72 @@ rfapiRibUpdatePendingNodeSubtree ( * 0 allow prefix to be included in response * !0 don't allow prefix to be included in response */ -int -rfapiRibFTDFilterRecentPrefix( - struct rfapi_descriptor *rfd, - struct route_node *it_rn, /* import table node */ - struct prefix *pfx_target_original) /* query target */ +int rfapiRibFTDFilterRecentPrefix( + struct rfapi_descriptor *rfd, + struct route_node *it_rn, /* import table node */ + struct prefix *pfx_target_original) /* query target */ { - struct bgp *bgp = rfd->bgp; - afi_t afi = family2afi(it_rn->p.family); - time_t prefix_time; - struct route_node *trn; - - /* - * Not in FTD mode, so allow prefix - */ - if (bgp->rfapi_cfg->rfp_cfg.download_type != RFAPI_RFP_DOWNLOAD_FULL) - return 0; - - /* - * TBD - * This matches behavior of now-obsolete rfapiRibFTDFilterRecent(), - * but we need to decide if that is correct. - */ - if (it_rn->p.family == AF_ETHERNET) - return 0; + struct bgp *bgp = rfd->bgp; + afi_t afi = family2afi(it_rn->p.family); + time_t prefix_time; + struct route_node *trn; + + /* + * Not in FTD mode, so allow prefix + */ + if (bgp->rfapi_cfg->rfp_cfg.download_type != RFAPI_RFP_DOWNLOAD_FULL) + return 0; + + /* + * TBD + * This matches behavior of now-obsolete rfapiRibFTDFilterRecent(), + * but we need to decide if that is correct. + */ + if (it_rn->p.family == AF_ETHERNET) + return 0; #if DEBUG_FTD_FILTER_RECENT - { - char buf_pfx[BUFSIZ]; + { + char buf_pfx[BUFSIZ]; - prefix2str(&it_rn->p, buf_pfx, BUFSIZ); - vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx); - } + prefix2str(&it_rn->p, buf_pfx, BUFSIZ); + vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx); + } #endif - /* - * prefix covers target address, so allow prefix - */ - if (prefix_match (&it_rn->p, pfx_target_original)) - { + /* + * prefix covers target address, so allow prefix + */ + if (prefix_match(&it_rn->p, pfx_target_original)) { #if DEBUG_FTD_FILTER_RECENT - vnc_zlog_debug_verbose("%s: prefix covers target, allowed", __func__); + vnc_zlog_debug_verbose("%s: prefix covers target, allowed", + __func__); #endif - return 0; - } + return 0; + } - /* - * check this NVE's timestamp for this prefix - */ - trn = route_node_get (rfd->rsp_times[afi], &it_rn->p); /* locks trn */ - prefix_time = (time_t) trn->info; - if (trn->lock > 1) - route_unlock_node (trn); + /* + * check this NVE's timestamp for this prefix + */ + trn = route_node_get(rfd->rsp_times[afi], &it_rn->p); /* locks trn */ + prefix_time = (time_t)trn->info; + if (trn->lock > 1) + route_unlock_node(trn); #if DEBUG_FTD_FILTER_RECENT - vnc_zlog_debug_verbose("%s: last sent time %lu, last allowed time %lu", - __func__, prefix_time, rfd->ftd_last_allowed_time); + vnc_zlog_debug_verbose("%s: last sent time %lu, last allowed time %lu", + __func__, prefix_time, + rfd->ftd_last_allowed_time); #endif - /* - * haven't sent this prefix, which doesn't cover target address, - * to NVE since ftd_advertisement_interval, so OK to send now. - */ - if (prefix_time <= rfd->ftd_last_allowed_time) - return 0; + /* + * haven't sent this prefix, which doesn't cover target address, + * to NVE since ftd_advertisement_interval, so OK to send now. + */ + if (prefix_time <= rfd->ftd_last_allowed_time) + return 0; - return 1; + return 1; } /* @@ -1905,648 +1865,626 @@ rfapiRibFTDFilterRecentPrefix( * value of nexthop chain. */ struct rfapi_next_hop_entry * -rfapiRibPreload ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct rfapi_next_hop_entry *response, - int use_eth_resolution) +rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct rfapi_next_hop_entry *response, int use_eth_resolution) { - struct rfapi_next_hop_entry *nhp; - struct rfapi_next_hop_entry *nhp_next; - struct rfapi_next_hop_entry *head = NULL; - struct rfapi_next_hop_entry *tail = NULL; - time_t new_last_sent_time; - - vnc_zlog_debug_verbose ("%s: loading response=%p, use_eth_resolution=%d", - __func__, response, use_eth_resolution); - - new_last_sent_time = rfapi_time (NULL); - - for (nhp = response; nhp; nhp = nhp_next) - { - - struct prefix pfx; - struct rfapi_rib_key rk; - afi_t afi; - struct rfapi_info *ri; - int need_insert; - struct route_node *rn; - int rib_node_started_nonempty = 0; - struct route_node *trn; - int allowed = 0; - - /* save in case we delete nhp */ - nhp_next = nhp->next; - - if (nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME) - { - /* - * weird, shouldn't happen - */ - vnc_zlog_debug_verbose - ("%s: got nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME", - __func__); - continue; - } - - - if (use_eth_resolution) - { - /* get the prefix of the ethernet address in the L2 option */ - struct rfapi_l2address_option *pL2o; - struct rfapi_vn_option *vo; - - /* - * Look for VN option of type RFAPI_VN_OPTION_TYPE_L2ADDR - */ - for (pL2o = NULL, vo = nhp->vn_options; vo; vo = vo->next) - { - if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) - { - pL2o = &vo->v.l2addr; - break; - } - } - - if (!pL2o) - { - /* - * not supposed to happen - */ - vnc_zlog_debug_verbose ("%s: missing L2 info", __func__); - continue; - } - - afi = AFI_L2VPN; - rfapiL2o2Qprefix (pL2o, &pfx); - } - else - { - rfapiRprefix2Qprefix (&nhp->prefix, &pfx); - afi = family2afi (pfx.family); - } - - /* - * TBD for ethernet, rib must know the right way to distinguish - * duplicate routes - * - * Current approach: prefix is key to radix tree; then - * each prefix has a set of routes with unique VN addrs - */ - - /* - * Look up prefix in RIB - */ - rn = route_node_get (rfd->rib[afi], &pfx); /* locks rn */ - - if (rn->info) - { - rib_node_started_nonempty = 1; - } - else - { - rn->info = skiplist_new (0, rfapi_rib_key_cmp, NULL); - route_lock_node (rn); - } - - /* - * Look up route at prefix - */ - need_insert = 0; - memset ((void *) &rk, 0, sizeof (rk)); - assert (!rfapiRaddr2Qprefix (&nhp->vn_address, &rk.vn)); - - if (use_eth_resolution) - { - /* copy what came from aux_prefix to rk.aux_prefix */ - rfapiRprefix2Qprefix (&nhp->prefix, &rk.aux_prefix); - if (RFAPI_0_PREFIX (&rk.aux_prefix) - && RFAPI_HOST_PREFIX (&rk.aux_prefix)) - { - /* mark as "none" if nhp->prefix is 0/32 or 0/128 */ - rk.aux_prefix.family = 0; - } - } + struct rfapi_next_hop_entry *nhp; + struct rfapi_next_hop_entry *nhp_next; + struct rfapi_next_hop_entry *head = NULL; + struct rfapi_next_hop_entry *tail = NULL; + time_t new_last_sent_time; + + vnc_zlog_debug_verbose("%s: loading response=%p, use_eth_resolution=%d", + __func__, response, use_eth_resolution); + + new_last_sent_time = rfapi_time(NULL); + + for (nhp = response; nhp; nhp = nhp_next) { + + struct prefix pfx; + struct rfapi_rib_key rk; + afi_t afi; + struct rfapi_info *ri; + int need_insert; + struct route_node *rn; + int rib_node_started_nonempty = 0; + struct route_node *trn; + int allowed = 0; + + /* save in case we delete nhp */ + nhp_next = nhp->next; + + if (nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME) { + /* + * weird, shouldn't happen + */ + vnc_zlog_debug_verbose( + "%s: got nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME", + __func__); + continue; + } + + + if (use_eth_resolution) { + /* get the prefix of the ethernet address in the L2 + * option */ + struct rfapi_l2address_option *pL2o; + struct rfapi_vn_option *vo; + + /* + * Look for VN option of type + * RFAPI_VN_OPTION_TYPE_L2ADDR + */ + for (pL2o = NULL, vo = nhp->vn_options; vo; + vo = vo->next) { + if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) { + pL2o = &vo->v.l2addr; + break; + } + } + + if (!pL2o) { + /* + * not supposed to happen + */ + vnc_zlog_debug_verbose("%s: missing L2 info", + __func__); + continue; + } + + afi = AFI_L2VPN; + rfapiL2o2Qprefix(pL2o, &pfx); + } else { + rfapiRprefix2Qprefix(&nhp->prefix, &pfx); + afi = family2afi(pfx.family); + } + + /* + * TBD for ethernet, rib must know the right way to distinguish + * duplicate routes + * + * Current approach: prefix is key to radix tree; then + * each prefix has a set of routes with unique VN addrs + */ + + /* + * Look up prefix in RIB + */ + rn = route_node_get(rfd->rib[afi], &pfx); /* locks rn */ + + if (rn->info) { + rib_node_started_nonempty = 1; + } else { + rn->info = skiplist_new(0, rfapi_rib_key_cmp, NULL); + route_lock_node(rn); + } + + /* + * Look up route at prefix + */ + need_insert = 0; + memset((void *)&rk, 0, sizeof(rk)); + assert(!rfapiRaddr2Qprefix(&nhp->vn_address, &rk.vn)); + + if (use_eth_resolution) { + /* copy what came from aux_prefix to rk.aux_prefix */ + rfapiRprefix2Qprefix(&nhp->prefix, &rk.aux_prefix); + if (RFAPI_0_PREFIX(&rk.aux_prefix) + && RFAPI_HOST_PREFIX(&rk.aux_prefix)) { + /* mark as "none" if nhp->prefix is 0/32 or + * 0/128 */ + rk.aux_prefix.family = 0; + } + } #if DEBUG_NHL - { - char str_vn[BUFSIZ]; - char str_aux_prefix[BUFSIZ]; - - str_vn[0] = 0; - str_aux_prefix[0] = 0; - - prefix2str (&rk.vn, str_vn, BUFSIZ); - prefix2str (&rk.aux_prefix, str_aux_prefix, BUFSIZ); - - if (!rk.aux_prefix.family) - { - - } - vnc_zlog_debug_verbose ("%s: rk.vn=%s rk.aux_prefix=%s", - __func__, str_vn, - (rk.aux_prefix.family ? str_aux_prefix : "-")); - } - vnc_zlog_debug_verbose ("%s: RIB skiplist for this prefix follows", __func__); - rfapiRibShowRibSl (NULL, &rn->p, (struct skiplist *) rn->info); + { + char str_vn[BUFSIZ]; + char str_aux_prefix[BUFSIZ]; + + str_vn[0] = 0; + str_aux_prefix[0] = 0; + + prefix2str(&rk.vn, str_vn, BUFSIZ); + prefix2str(&rk.aux_prefix, str_aux_prefix, BUFSIZ); + + if (!rk.aux_prefix.family) { + } + vnc_zlog_debug_verbose( + "%s: rk.vn=%s rk.aux_prefix=%s", __func__, + str_vn, + (rk.aux_prefix.family ? str_aux_prefix : "-")); + } + vnc_zlog_debug_verbose( + "%s: RIB skiplist for this prefix follows", __func__); + rfapiRibShowRibSl(NULL, &rn->p, (struct skiplist *)rn->info); #endif - if (!skiplist_search ((struct skiplist *) rn->info, &rk, (void **) &ri)) - { - /* - * Already have this route; make values match - */ - rfapiFreeRfapiUnOptionChain (ri->un_options); - ri->un_options = NULL; - rfapiFreeRfapiVnOptionChain (ri->vn_options); - ri->vn_options = NULL; + if (!skiplist_search((struct skiplist *)rn->info, &rk, + (void **)&ri)) { + /* + * Already have this route; make values match + */ + rfapiFreeRfapiUnOptionChain(ri->un_options); + ri->un_options = NULL; + rfapiFreeRfapiVnOptionChain(ri->vn_options); + ri->vn_options = NULL; #if DEBUG_NHL - vnc_zlog_debug_verbose ("%s: found in RIB", __func__); + vnc_zlog_debug_verbose("%s: found in RIB", __func__); #endif - /* - * Filter duplicate routes from initial response. - * Check timestamps to avoid wraparound problems - */ - if ((ri->rsp_counter != rfd->rsp_counter) || - (ri->last_sent_time != new_last_sent_time)) - { + /* + * Filter duplicate routes from initial response. + * Check timestamps to avoid wraparound problems + */ + if ((ri->rsp_counter != rfd->rsp_counter) + || (ri->last_sent_time != new_last_sent_time)) { #if DEBUG_NHL - vnc_zlog_debug_verbose ("%s: allowed due to counter/timestamp diff", - __func__); + vnc_zlog_debug_verbose( + "%s: allowed due to counter/timestamp diff", + __func__); #endif - allowed = 1; - } + allowed = 1; + } - } - else - { + } else { #if DEBUG_NHL - vnc_zlog_debug_verbose ("%s: allowed due to not yet in RIB", __func__); + vnc_zlog_debug_verbose( + "%s: allowed due to not yet in RIB", __func__); #endif - /* not found: add new route to RIB */ - ri = rfapi_info_new (); - need_insert = 1; - allowed = 1; - } - - ri->rk = rk; - assert (!rfapiRaddr2Qprefix (&nhp->un_address, &ri->un)); - ri->cost = nhp->prefix.cost; - ri->lifetime = nhp->lifetime; - ri->vn_options = rfapiVnOptionsDup (nhp->vn_options); - ri->rsp_counter = rfd->rsp_counter; - ri->last_sent_time = rfapi_time (NULL); - - if (need_insert) - { - int rc; - rc = skiplist_insert ((struct skiplist *) rn->info, &ri->rk, ri); - assert (!rc); - } - - if (!rib_node_started_nonempty) - { - RFAPI_RIB_PREFIX_COUNT_INCR (rfd, bgp->rfapi); - } - - RFAPI_RIB_CHECK_COUNTS (0, 0); - rfapiRibStartTimer (rfd, ri, rn, 0); - RFAPI_RIB_CHECK_COUNTS (0, 0); - - route_unlock_node (rn); - - /* - * update this NVE's timestamp for this prefix - */ - trn = route_node_get (rfd->rsp_times[afi], &pfx); /* locks trn */ - trn->info = (void *) (uintptr_t) bgp_clock (); - if (trn->lock > 1) - route_unlock_node (trn); - - { - char str_pfx[BUFSIZ]; - char str_pfx_vn[BUFSIZ]; - - prefix2str (&pfx, str_pfx, BUFSIZ); - prefix2str (&rk.vn, str_pfx_vn, BUFSIZ); - vnc_zlog_debug_verbose - ("%s: added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d", - __func__, str_pfx, str_pfx_vn, nhp->prefix.cost, nhp->lifetime, - allowed); - } - - if (allowed) - { - if (tail) - (tail)->next = nhp; - tail = nhp; - if (!head) - { - head = nhp; - } - } - else - { - rfapi_un_options_free (nhp->un_options); - nhp->un_options = NULL; - rfapi_vn_options_free (nhp->vn_options); - nhp->vn_options = NULL; - - XFREE (MTYPE_RFAPI_NEXTHOP, nhp); - nhp = NULL; - } - } - - if (tail) - tail->next = NULL; - return head; + /* not found: add new route to RIB */ + ri = rfapi_info_new(); + need_insert = 1; + allowed = 1; + } + + ri->rk = rk; + assert(!rfapiRaddr2Qprefix(&nhp->un_address, &ri->un)); + ri->cost = nhp->prefix.cost; + ri->lifetime = nhp->lifetime; + ri->vn_options = rfapiVnOptionsDup(nhp->vn_options); + ri->rsp_counter = rfd->rsp_counter; + ri->last_sent_time = rfapi_time(NULL); + + if (need_insert) { + int rc; + rc = skiplist_insert((struct skiplist *)rn->info, + &ri->rk, ri); + assert(!rc); + } + + if (!rib_node_started_nonempty) { + RFAPI_RIB_PREFIX_COUNT_INCR(rfd, bgp->rfapi); + } + + RFAPI_RIB_CHECK_COUNTS(0, 0); + rfapiRibStartTimer(rfd, ri, rn, 0); + RFAPI_RIB_CHECK_COUNTS(0, 0); + + route_unlock_node(rn); + + /* + * update this NVE's timestamp for this prefix + */ + trn = route_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */ + trn->info = (void *)(uintptr_t)bgp_clock(); + if (trn->lock > 1) + route_unlock_node(trn); + + { + char str_pfx[BUFSIZ]; + char str_pfx_vn[BUFSIZ]; + + prefix2str(&pfx, str_pfx, BUFSIZ); + prefix2str(&rk.vn, str_pfx_vn, BUFSIZ); + vnc_zlog_debug_verbose( + "%s: added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d", + __func__, str_pfx, str_pfx_vn, nhp->prefix.cost, + nhp->lifetime, allowed); + } + + if (allowed) { + if (tail) + (tail)->next = nhp; + tail = nhp; + if (!head) { + head = nhp; + } + } else { + rfapi_un_options_free(nhp->un_options); + nhp->un_options = NULL; + rfapi_vn_options_free(nhp->vn_options); + nhp->vn_options = NULL; + + XFREE(MTYPE_RFAPI_NEXTHOP, nhp); + nhp = NULL; + } + } + + if (tail) + tail->next = NULL; + return head; } -void -rfapiRibPendingDeleteRoute ( - struct bgp *bgp, - struct rfapi_import_table *it, - afi_t afi, - struct route_node *it_node) +void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, + afi_t afi, struct route_node *it_node) { - struct rfapi_descriptor *rfd; - struct listnode *node; - char buf[BUFSIZ]; - - prefix2str (&it_node->p, buf, BUFSIZ); - vnc_zlog_debug_verbose ("%s: entry, it=%p, afi=%d, it_node=%p, pfx=%s", - __func__, it, afi, it_node, buf); - - if (AFI_L2VPN == afi) - { - /* - * ethernet import tables are per-LNI and each ethernet monitor - * identifies the rfd that owns it. - */ - struct rfapi_monitor_eth *m; - struct route_node *rn; - struct skiplist *sl; - void *cursor; - int rc; - - /* - * route-specific monitors - */ - if ((sl = RFAPI_MONITOR_ETH (it_node))) - { - - vnc_zlog_debug_verbose ("%s: route-specific skiplist: %p", __func__, sl); - - for (cursor = NULL, rc = - skiplist_next (sl, NULL, (void **) &m, (void **) &cursor); !rc; - rc = skiplist_next (sl, NULL, (void **) &m, (void **) &cursor)) - { + struct rfapi_descriptor *rfd; + struct listnode *node; + char buf[BUFSIZ]; + + prefix2str(&it_node->p, buf, BUFSIZ); + vnc_zlog_debug_verbose("%s: entry, it=%p, afi=%d, it_node=%p, pfx=%s", + __func__, it, afi, it_node, buf); + + if (AFI_L2VPN == afi) { + /* + * ethernet import tables are per-LNI and each ethernet monitor + * identifies the rfd that owns it. + */ + struct rfapi_monitor_eth *m; + struct route_node *rn; + struct skiplist *sl; + void *cursor; + int rc; + + /* + * route-specific monitors + */ + if ((sl = RFAPI_MONITOR_ETH(it_node))) { + + vnc_zlog_debug_verbose( + "%s: route-specific skiplist: %p", __func__, + sl); + + for (cursor = NULL, + rc = skiplist_next(sl, NULL, (void **)&m, + (void **)&cursor); + !rc; rc = skiplist_next(sl, NULL, (void **)&m, + (void **)&cursor)) { #if DEBUG_PENDING_DELETE_ROUTE - vnc_zlog_debug_verbose ("%s: eth monitor rfd=%p", __func__, m->rfd); + vnc_zlog_debug_verbose("%s: eth monitor rfd=%p", + __func__, m->rfd); #endif - /* - * If we have already sent a route with this prefix to this - * NVE, it's OK to send an update with the delete - */ - if ((rn = route_node_lookup (m->rfd->rib[afi], &it_node->p))) - { - rfapiRibUpdatePendingNode (bgp, m->rfd, it, it_node, - m->rfd->response_lifetime); - route_unlock_node (rn); - } - } - } - - /* - * all-routes/FTD monitors - */ - for (m = it->eth0_queries; m; m = m->next) - { + /* + * If we have already sent a route with this + * prefix to this + * NVE, it's OK to send an update with the + * delete + */ + if ((rn = route_node_lookup(m->rfd->rib[afi], + &it_node->p))) { + rfapiRibUpdatePendingNode( + bgp, m->rfd, it, it_node, + m->rfd->response_lifetime); + route_unlock_node(rn); + } + } + } + + /* + * all-routes/FTD monitors + */ + for (m = it->eth0_queries; m; m = m->next) { #if DEBUG_PENDING_DELETE_ROUTE - vnc_zlog_debug_verbose ("%s: eth0 monitor rfd=%p", __func__, m->rfd); + vnc_zlog_debug_verbose("%s: eth0 monitor rfd=%p", + __func__, m->rfd); #endif - /* - * If we have already sent a route with this prefix to this - * NVE, it's OK to send an update with the delete - */ - if ((rn = route_node_lookup (m->rfd->rib[afi], &it_node->p))) - { - rfapiRibUpdatePendingNode (bgp, m->rfd, it, it_node, - m->rfd->response_lifetime); - } - } - - } - else - { - /* - * Find RFDs that reference this import table - */ - for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) - { - - struct route_node *rn; - - vnc_zlog_debug_verbose ("%s: comparing rfd(%p)->import_table=%p to it=%p", - __func__, rfd, rfd->import_table, it); - - if (rfd->import_table != it) - continue; - - vnc_zlog_debug_verbose ("%s: matched rfd %p", __func__, rfd); - - /* - * If we have sent a response to this NVE with this prefix - * previously, we should send an updated response. - */ - if ((rn = route_node_lookup (rfd->rib[afi], &it_node->p))) - { - rfapiRibUpdatePendingNode (bgp, rfd, it, it_node, - rfd->response_lifetime); - route_unlock_node (rn); - } - } - } + /* + * If we have already sent a route with this prefix to + * this + * NVE, it's OK to send an update with the delete + */ + if ((rn = route_node_lookup(m->rfd->rib[afi], + &it_node->p))) { + rfapiRibUpdatePendingNode( + bgp, m->rfd, it, it_node, + m->rfd->response_lifetime); + } + } + + } else { + /* + * Find RFDs that reference this import table + */ + for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, + rfd)) { + + struct route_node *rn; + + vnc_zlog_debug_verbose( + "%s: comparing rfd(%p)->import_table=%p to it=%p", + __func__, rfd, rfd->import_table, it); + + if (rfd->import_table != it) + continue; + + vnc_zlog_debug_verbose("%s: matched rfd %p", __func__, + rfd); + + /* + * If we have sent a response to this NVE with this + * prefix + * previously, we should send an updated response. + */ + if ((rn = route_node_lookup(rfd->rib[afi], + &it_node->p))) { + rfapiRibUpdatePendingNode( + bgp, rfd, it, it_node, + rfd->response_lifetime); + route_unlock_node(rn); + } + } + } } -void -rfapiRibShowResponsesSummary (void *stream) +void rfapiRibShowResponsesSummary(void *stream) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - struct bgp *bgp = bgp_get_default (); - - int nves = 0; - int nves_with_nonempty_ribs = 0; - struct rfapi_descriptor *rfd; - struct listnode *node; - - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - - fp (out, "%-24s ", "Responses: (Prefixes)"); - fp (out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total); - fp (out, "%-8s %-8u", "Maximum:", bgp->rfapi->rib_prefix_count_total_max); - fp (out, "\n"); - - fp (out, "%-24s ", " (Updated)"); - fp (out, "%-8s %-8u ", "Update:", - bgp->rfapi->stat.count_updated_response_updates); - fp (out, "%-8s %-8u", "Remove:", - bgp->rfapi->stat.count_updated_response_deletes); - fp (out, "%-8s %-8u", "Total:", - bgp->rfapi->stat.count_updated_response_updates + - bgp->rfapi->stat.count_updated_response_deletes); - fp (out, "\n"); - - fp (out, "%-24s ", " (NVEs)"); - for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) - { - ++nves; - if (rfd->rib_prefix_count) - ++nves_with_nonempty_ribs; - } - fp (out, "%-8s %-8u ", "Active:", nves_with_nonempty_ribs); - fp (out, "%-8s %-8u", "Total:", nves); - fp (out, "\n"); - + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + struct bgp *bgp = bgp_get_default(); + + int nves = 0; + int nves_with_nonempty_ribs = 0; + struct rfapi_descriptor *rfd; + struct listnode *node; + + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + fp(out, "%-24s ", "Responses: (Prefixes)"); + fp(out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total); + fp(out, "%-8s %-8u", + "Maximum:", bgp->rfapi->rib_prefix_count_total_max); + fp(out, "\n"); + + fp(out, "%-24s ", " (Updated)"); + fp(out, "%-8s %-8u ", + "Update:", bgp->rfapi->stat.count_updated_response_updates); + fp(out, "%-8s %-8u", + "Remove:", bgp->rfapi->stat.count_updated_response_deletes); + fp(out, "%-8s %-8u", "Total:", + bgp->rfapi->stat.count_updated_response_updates + + bgp->rfapi->stat.count_updated_response_deletes); + fp(out, "\n"); + + fp(out, "%-24s ", " (NVEs)"); + for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { + ++nves; + if (rfd->rib_prefix_count) + ++nves_with_nonempty_ribs; + } + fp(out, "%-8s %-8u ", "Active:", nves_with_nonempty_ribs); + fp(out, "%-8s %-8u", "Total:", nves); + fp(out, "\n"); } -void -rfapiRibShowResponsesSummaryClear (void) +void rfapiRibShowResponsesSummaryClear(void) { - struct bgp *bgp = bgp_get_default (); + struct bgp *bgp = bgp_get_default(); - bgp->rfapi->rib_prefix_count_total_max = bgp->rfapi->rib_prefix_count_total; + bgp->rfapi->rib_prefix_count_total_max = + bgp->rfapi->rib_prefix_count_total; } -static int -print_rib_sl ( - int (*fp) (void *, const char *, ...), - struct vty *vty, - void *out, - struct skiplist *sl, - int deleted, - char *str_pfx, - int *printedprefix) +static int print_rib_sl(int (*fp)(void *, const char *, ...), struct vty *vty, + void *out, struct skiplist *sl, int deleted, + char *str_pfx, int *printedprefix) { - struct rfapi_info *ri; - int rc; - void *cursor; - int routes_displayed = 0; - - cursor = NULL; - for (rc = skiplist_next (sl, NULL, (void **) &ri, &cursor); - !rc; rc = skiplist_next (sl, NULL, (void **) &ri, &cursor)) - { - - char str_vn[BUFSIZ]; - char str_un[BUFSIZ]; - char str_lifetime[BUFSIZ]; - char str_age[BUFSIZ]; - char *p; - char str_rd[BUFSIZ]; - - ++routes_displayed; - - prefix2str (&ri->rk.vn, str_vn, BUFSIZ); - p = index (str_vn, '/'); - if (p) - *p = 0; - - prefix2str (&ri->un, str_un, BUFSIZ); - p = index (str_un, '/'); - if (p) - *p = 0; - - rfapiFormatSeconds (ri->lifetime, str_lifetime, BUFSIZ); + struct rfapi_info *ri; + int rc; + void *cursor; + int routes_displayed = 0; + + cursor = NULL; + for (rc = skiplist_next(sl, NULL, (void **)&ri, &cursor); !rc; + rc = skiplist_next(sl, NULL, (void **)&ri, &cursor)) { + + char str_vn[BUFSIZ]; + char str_un[BUFSIZ]; + char str_lifetime[BUFSIZ]; + char str_age[BUFSIZ]; + char *p; + char str_rd[BUFSIZ]; + + ++routes_displayed; + + prefix2str(&ri->rk.vn, str_vn, BUFSIZ); + p = index(str_vn, '/'); + if (p) + *p = 0; + + prefix2str(&ri->un, str_un, BUFSIZ); + p = index(str_un, '/'); + if (p) + *p = 0; + + rfapiFormatSeconds(ri->lifetime, str_lifetime, BUFSIZ); #if RFAPI_REGISTRATIONS_REPORT_AGE - rfapiFormatAge (ri->last_sent_time, str_age, BUFSIZ); + rfapiFormatAge(ri->last_sent_time, str_age, BUFSIZ); #else - { - time_t now = rfapi_time (NULL); - time_t expire = ri->last_sent_time + (time_t) ri->lifetime; - /* allow for delayed/async removal */ - rfapiFormatSeconds ((expire > now ? expire - now : 1), - str_age, BUFSIZ); - } + { + time_t now = rfapi_time(NULL); + time_t expire = + ri->last_sent_time + (time_t)ri->lifetime; + /* allow for delayed/async removal */ + rfapiFormatSeconds((expire > now ? expire - now : 1), + str_age, BUFSIZ); + } #endif - str_rd[0] = 0; /* start empty */ + str_rd[0] = 0; /* start empty */ #if DEBUG_RIB_SL_RD - str_rd[0] = ' '; - prefix_rd2str(&ri->rk.rd, str_rd+1, BUFSIZ-1); + str_rd[0] = ' '; + prefix_rd2str(&ri->rk.rd, str_rd + 1, BUFSIZ - 1); #endif - fp (out, " %c %-20s %-15s %-15s %-4u %-8s %-8s%s\n", - deleted ? 'r' : ' ', - *printedprefix ? "" : str_pfx, - str_vn, str_un, ri->cost, str_lifetime, str_age, str_rd); + fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s%s\n", + deleted ? 'r' : ' ', *printedprefix ? "" : str_pfx, str_vn, + str_un, ri->cost, str_lifetime, str_age, str_rd); - if (!*printedprefix) - *printedprefix = 1; - } - return routes_displayed; + if (!*printedprefix) + *printedprefix = 1; + } + return routes_displayed; } #if DEBUG_NHL /* * This one is for debugging (set stream to NULL to send output to log) */ -static void -rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl) +static void rfapiRibShowRibSl(void *stream, struct prefix *pfx, + struct skiplist *sl) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - int nhs_displayed = 0; - char str_pfx[BUFSIZ]; - int printedprefix = 0; + int nhs_displayed = 0; + char str_pfx[BUFSIZ]; + int printedprefix = 0; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; - prefix2str (pfx, str_pfx, BUFSIZ); + prefix2str(pfx, str_pfx, BUFSIZ); - nhs_displayed += print_rib_sl (fp, vty, out, sl, - 0, str_pfx, &printedprefix); + nhs_displayed += + print_rib_sl(fp, vty, out, sl, 0, str_pfx, &printedprefix); } #endif -void -rfapiRibShowResponses ( - void *stream, - struct prefix *pfx_match, - int show_removed) +void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, + int show_removed) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - struct rfapi_descriptor *rfd; - struct listnode *node; - - struct bgp *bgp = bgp_get_default (); - int printedheader = 0; - int routes_total = 0; - int nhs_total = 0; - int prefixes_total = 0; - int prefixes_displayed = 0; - int nves_total = 0; - int nves_with_routes = 0; - int nves_displayed = 0; - int routes_displayed = 0; - int nhs_displayed = 0; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - /* - * loop over NVEs - */ - for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) - { - - int printednve = 0; - afi_t afi; - - ++nves_total; - if (rfd->rib_prefix_count) - ++nves_with_routes; - - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - struct route_node *rn; - - if (!rfd->rib[afi]) - continue; - - for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) - { - - struct skiplist *sl; - char str_pfx[BUFSIZ]; - int printedprefix = 0; - - if (!show_removed) - sl = rn->info; - else - sl = rn->aggregate; - - if (!sl) - continue; - - routes_total++; - nhs_total += skiplist_count (sl); - ++prefixes_total; - - if (pfx_match && !prefix_match (pfx_match, &rn->p) && - !prefix_match (&rn->p, pfx_match)) - continue; - - ++prefixes_displayed; - - if (!printedheader) - { - ++printedheader; - - fp (out, "\n[%s]\n", - show_removed ? "Removed" : "Active"); - fp (out, "%-15s %-15s\n", "Querying VN", "Querying UN"); - fp (out, " %-20s %-15s %-15s %4s %-8s %-8s\n", - "Prefix", "Registered VN", "Registered UN", "Cost", - "Lifetime", + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + struct rfapi_descriptor *rfd; + struct listnode *node; + + struct bgp *bgp = bgp_get_default(); + int printedheader = 0; + int routes_total = 0; + int nhs_total = 0; + int prefixes_total = 0; + int prefixes_displayed = 0; + int nves_total = 0; + int nves_with_routes = 0; + int nves_displayed = 0; + int routes_displayed = 0; + int nhs_displayed = 0; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + /* + * loop over NVEs + */ + for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { + + int printednve = 0; + afi_t afi; + + ++nves_total; + if (rfd->rib_prefix_count) + ++nves_with_routes; + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + struct route_node *rn; + + if (!rfd->rib[afi]) + continue; + + for (rn = route_top(rfd->rib[afi]); rn; + rn = route_next(rn)) { + + struct skiplist *sl; + char str_pfx[BUFSIZ]; + int printedprefix = 0; + + if (!show_removed) + sl = rn->info; + else + sl = rn->aggregate; + + if (!sl) + continue; + + routes_total++; + nhs_total += skiplist_count(sl); + ++prefixes_total; + + if (pfx_match + && !prefix_match(pfx_match, &rn->p) + && !prefix_match(&rn->p, pfx_match)) + continue; + + ++prefixes_displayed; + + if (!printedheader) { + ++printedheader; + + fp(out, "\n[%s]\n", + show_removed ? "Removed" : "Active"); + fp(out, "%-15s %-15s\n", "Querying VN", + "Querying UN"); + fp(out, + " %-20s %-15s %-15s %4s %-8s %-8s\n", + "Prefix", "Registered VN", + "Registered UN", "Cost", "Lifetime", #if RFAPI_REGISTRATIONS_REPORT_AGE - "Age" + "Age" #else - "Remaining" + "Remaining" #endif - ); - } - if (!printednve) - { - char str_vn[BUFSIZ]; - char str_un[BUFSIZ]; - - ++printednve; - ++nves_displayed; - - fp (out, "%-15s %-15s\n", - rfapiRfapiIpAddr2Str (&rfd->vn_addr, str_vn, BUFSIZ), - rfapiRfapiIpAddr2Str (&rfd->un_addr, str_un, BUFSIZ)); - - } - prefix2str (&rn->p, str_pfx, BUFSIZ); - //fp(out, " %s\n", buf); /* prefix */ - - routes_displayed++; - nhs_displayed += print_rib_sl (fp, vty, out, sl, - show_removed, str_pfx, - &printedprefix); - } - } - } - - if (routes_total) - { - fp (out, "\n"); - fp (out, "Displayed %u NVEs, and %u out of %u %s prefixes", - nves_displayed, routes_displayed, - routes_total, show_removed ? "removed" : "active"); - if (nhs_displayed != routes_displayed || nhs_total != routes_total) - fp (out, " with %u out of %u next hops", nhs_displayed, nhs_total); - fp (out, "\n"); - } + ); + } + if (!printednve) { + char str_vn[BUFSIZ]; + char str_un[BUFSIZ]; + + ++printednve; + ++nves_displayed; + + fp(out, "%-15s %-15s\n", + rfapiRfapiIpAddr2Str(&rfd->vn_addr, + str_vn, BUFSIZ), + rfapiRfapiIpAddr2Str(&rfd->un_addr, + str_un, + BUFSIZ)); + } + prefix2str(&rn->p, str_pfx, BUFSIZ); + // fp(out, " %s\n", buf); /* prefix */ + + routes_displayed++; + nhs_displayed += print_rib_sl( + fp, vty, out, sl, show_removed, str_pfx, + &printedprefix); + } + } + } + + if (routes_total) { + fp(out, "\n"); + fp(out, "Displayed %u NVEs, and %u out of %u %s prefixes", + nves_displayed, routes_displayed, routes_total, + show_removed ? "removed" : "active"); + if (nhs_displayed != routes_displayed + || nhs_total != routes_total) + fp(out, " with %u out of %u next hops", nhs_displayed, + nhs_total); + fp(out, "\n"); + } } diff --git a/bgpd/rfapi/rfapi_rib.h b/bgpd/rfapi/rfapi_rib.h index 40e4c0c2f2..0542727c2e 100644 --- a/bgpd/rfapi/rfapi_rib.h +++ b/bgpd/rfapi/rfapi_rib.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -33,16 +33,15 @@ * For L2 RIBs, it is possible to have multiple routes to a given L2 * prefix via a given VN address, but each route having a unique aux_prefix. */ -struct rfapi_rib_key -{ - struct prefix vn; - struct prefix_rd rd; - - /* - * for L2 routes: optional IP addr - * .family == 0 means "none" - */ - struct prefix aux_prefix; +struct rfapi_rib_key { + struct prefix vn; + struct prefix_rd rd; + + /* + * for L2 routes: optional IP addr + * .family == 0 means "none" + */ + struct prefix aux_prefix; }; #include "rfapi.h" @@ -51,118 +50,90 @@ struct rfapi_rib_key * * Holds NVE prefix advertisement information */ -struct rfapi_adb -{ - union { - struct { - struct prefix prefix_ip; - struct prefix_rd prd; - struct prefix prefix_eth; - } s; /* mainly for legacy use */ - struct rfapi_rib_key key; - } u; - uint32_t lifetime; - uint8_t cost; - struct rfapi_l2address_option l2o; +struct rfapi_adb { + union { + struct { + struct prefix prefix_ip; + struct prefix_rd prd; + struct prefix prefix_eth; + } s; /* mainly for legacy use */ + struct rfapi_rib_key key; + } u; + uint32_t lifetime; + uint8_t cost; + struct rfapi_l2address_option l2o; }; -struct rfapi_info -{ - struct rfapi_rib_key rk; /* NVE VN addr + aux addr */ - struct prefix un; - uint8_t cost; - uint32_t lifetime; - time_t last_sent_time; - uint32_t rsp_counter; /* dedup initial responses */ - struct bgp_tea_options *tea_options; - struct rfapi_un_option *un_options; - struct rfapi_vn_option *vn_options; - struct thread *timer; +struct rfapi_info { + struct rfapi_rib_key rk; /* NVE VN addr + aux addr */ + struct prefix un; + uint8_t cost; + uint32_t lifetime; + time_t last_sent_time; + uint32_t rsp_counter; /* dedup initial responses */ + struct bgp_tea_options *tea_options; + struct rfapi_un_option *un_options; + struct rfapi_vn_option *vn_options; + struct thread *timer; }; /* * Work item for updated responses queue */ -struct rfapi_updated_responses_queue -{ - struct rfapi_descriptor *rfd; - afi_t afi; +struct rfapi_updated_responses_queue { + struct rfapi_descriptor *rfd; + afi_t afi; }; -extern void -rfapiRibClear (struct rfapi_descriptor *rfd); +extern void rfapiRibClear(struct rfapi_descriptor *rfd); -extern void -rfapiRibFree (struct rfapi_descriptor *rfd); +extern void rfapiRibFree(struct rfapi_descriptor *rfd); -extern void -rfapiRibUpdatePendingNode ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct rfapi_import_table *it, - struct route_node *it_node, - uint32_t lifetime); +extern void rfapiRibUpdatePendingNode(struct bgp *bgp, + struct rfapi_descriptor *rfd, + struct rfapi_import_table *it, + struct route_node *it_node, + uint32_t lifetime); -extern void -rfapiRibUpdatePendingNodeSubtree ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct rfapi_import_table *it, - struct route_node *it_node, - struct route_node *omit_subtree, - uint32_t lifetime); - -extern int -rfapiRibPreloadBi( - struct route_node *rfd_rib_node, - struct prefix *pfx_vn, - struct prefix *pfx_un, - uint32_t lifetime, - struct bgp_info *bi); +extern void rfapiRibUpdatePendingNodeSubtree(struct bgp *bgp, + struct rfapi_descriptor *rfd, + struct rfapi_import_table *it, + struct route_node *it_node, + struct route_node *omit_subtree, + uint32_t lifetime); + +extern int rfapiRibPreloadBi(struct route_node *rfd_rib_node, + struct prefix *pfx_vn, struct prefix *pfx_un, + uint32_t lifetime, struct bgp_info *bi); extern struct rfapi_next_hop_entry * -rfapiRibPreload ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct rfapi_next_hop_entry *response, - int use_eth_resolution); +rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct rfapi_next_hop_entry *response, int use_eth_resolution); -extern void -rfapiRibPendingDeleteRoute ( - struct bgp *bgp, - struct rfapi_import_table *it, - afi_t afi, - struct route_node *it_node); +extern void rfapiRibPendingDeleteRoute(struct bgp *bgp, + struct rfapi_import_table *it, afi_t afi, + struct route_node *it_node); -extern void -rfapiRibShowResponsesSummary (void *stream); +extern void rfapiRibShowResponsesSummary(void *stream); -extern void -rfapiRibShowResponsesSummaryClear (void); +extern void rfapiRibShowResponsesSummaryClear(void); -extern void -rfapiRibShowResponses ( - void *stream, - struct prefix *pfx_match, - int show_removed); +extern void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, + int show_removed); -extern int -rfapiRibFTDFilterRecentPrefix( - struct rfapi_descriptor *rfd, - struct route_node *it_rn, /* import table node */ - struct prefix *pfx_target_original); /* query target */ +extern int rfapiRibFTDFilterRecentPrefix( + struct rfapi_descriptor *rfd, + struct route_node *it_rn, /* import table node */ + struct prefix *pfx_target_original); /* query target */ -extern void -rfapiFreeRfapiUnOptionChain (struct rfapi_un_option *p); +extern void rfapiFreeRfapiUnOptionChain(struct rfapi_un_option *p); -extern void -rfapiFreeRfapiVnOptionChain (struct rfapi_vn_option *p); +extern void rfapiFreeRfapiVnOptionChain(struct rfapi_vn_option *p); extern void -rfapiRibCheckCounts ( - int checkstats, /* validate rfd & global counts */ - unsigned int offset); /* number of ri's held separately */ +rfapiRibCheckCounts(int checkstats, /* validate rfd & global counts */ + unsigned int offset); /* number of ri's held separately */ /* enable for debugging; disable for performance */ #if 0 @@ -171,16 +142,13 @@ rfapiRibCheckCounts ( #define RFAPI_RIB_CHECK_COUNTS(checkstats, offset) #endif -extern void -rfapi_rib_key_init (struct prefix *prefix, /* may be NULL */ - struct prefix_rd *rd, /* may be NULL */ - struct prefix *aux, /* may be NULL */ - struct rfapi_rib_key *rk); +extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */ + struct prefix_rd *rd, /* may be NULL */ + struct prefix *aux, /* may be NULL */ + struct rfapi_rib_key *rk); -extern int -rfapi_rib_key_cmp (void *k1, void *k2); +extern int rfapi_rib_key_cmp(void *k1, void *k2); -extern void -rfapiAdbFree (struct rfapi_adb *adb); +extern void rfapiAdbFree(struct rfapi_adb *adb); #endif /* QUAGGA_HGP_RFAPI_RIB_H */ diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 103f87ed0b..98c3decbd8 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -69,68 +69,53 @@ #define FMT_DAY (24 * FMT_HOUR) #define FMT_YEAR (365 * FMT_DAY) -char * -rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len) +char *rfapiFormatSeconds(uint32_t seconds, char *buf, size_t len) { - int year, day, hour, min; - - if (seconds >= FMT_YEAR) - { - year = seconds / FMT_YEAR; - seconds -= year * FMT_YEAR; - } - else - year = 0; - - if (seconds >= FMT_DAY) - { - day = seconds / FMT_DAY; - seconds -= day * FMT_DAY; - } - else - day = 0; - - if (seconds >= FMT_HOUR) - { - hour = seconds / FMT_HOUR; - seconds -= hour * FMT_HOUR; - } - else - hour = 0; - - if (seconds >= FMT_MIN) - { - min = seconds / FMT_MIN; - seconds -= min * FMT_MIN; - } - else - min = 0; - - if (year > 0) - { - snprintf (buf, len, "%dy%dd%dh", year, day, hour); - } - else if (day > 0) - { - snprintf (buf, len, "%dd%dh%dm", day, hour, min); - } - else - { - snprintf (buf, len, "%02d:%02d:%02d", hour, min, seconds); - } - - return buf; + int year, day, hour, min; + + if (seconds >= FMT_YEAR) { + year = seconds / FMT_YEAR; + seconds -= year * FMT_YEAR; + } else + year = 0; + + if (seconds >= FMT_DAY) { + day = seconds / FMT_DAY; + seconds -= day * FMT_DAY; + } else + day = 0; + + if (seconds >= FMT_HOUR) { + hour = seconds / FMT_HOUR; + seconds -= hour * FMT_HOUR; + } else + hour = 0; + + if (seconds >= FMT_MIN) { + min = seconds / FMT_MIN; + seconds -= min * FMT_MIN; + } else + min = 0; + + if (year > 0) { + snprintf(buf, len, "%dy%dd%dh", year, day, hour); + } else if (day > 0) { + snprintf(buf, len, "%dd%dh%dm", day, hour, min); + } else { + snprintf(buf, len, "%02d:%02d:%02d", hour, min, seconds); + } + + return buf; } -char * -rfapiFormatAge (time_t age, char *buf, size_t len) +char *rfapiFormatAge(time_t age, char *buf, size_t len) { - time_t now, age_adjusted; + time_t now, age_adjusted; - now = rfapi_time (NULL); - age_adjusted = now - age; + now = rfapi_time(NULL); + age_adjusted = now - age; - return rfapiFormatSeconds (age_adjusted, buf, len); + return rfapiFormatSeconds(age_adjusted, buf, len); } @@ -138,47 +123,43 @@ rfapiFormatAge (time_t age, char *buf, size_t len) * Reimplementation of quagga/lib/prefix.c function, but * for RFAPI-style prefixes */ -void -rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix) +void rfapiRprefixApplyMask(struct rfapi_ip_prefix *rprefix) { - uint8_t *pnt; - int index; - int offset; - - static uint8_t maskbit[] = - { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; - - switch (rprefix->prefix.addr_family) - { - case AF_INET: - index = rprefix->length / 8; - if (index < 4) - { - pnt = (uint8_t *) & rprefix->prefix.addr.v4; - offset = rprefix->length % 8; - pnt[index] &= maskbit[offset]; - index++; - while (index < 4) - pnt[index++] = 0; - } - break; - - case AF_INET6: - index = rprefix->length / 8; - if (index < 16) - { - pnt = (uint8_t *) & rprefix->prefix.addr.v6; - offset = rprefix->length % 8; - pnt[index] &= maskbit[offset]; - index++; - while (index < 16) - pnt[index++] = 0; - } - break; - - default: - assert (0); - } + uint8_t *pnt; + int index; + int offset; + + static uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff}; + + switch (rprefix->prefix.addr_family) { + case AF_INET: + index = rprefix->length / 8; + if (index < 4) { + pnt = (uint8_t *)&rprefix->prefix.addr.v4; + offset = rprefix->length % 8; + pnt[index] &= maskbit[offset]; + index++; + while (index < 4) + pnt[index++] = 0; + } + break; + + case AF_INET6: + index = rprefix->length / 8; + if (index < 16) { + pnt = (uint8_t *)&rprefix->prefix.addr.v6; + offset = rprefix->length % 8; + pnt[index] &= maskbit[offset]; + index++; + while (index < 16) + pnt[index++] = 0; + } + break; + + default: + assert(0); + } } /* @@ -190,71 +171,67 @@ rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix) * 0 Success * <0 Error */ -int -rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr) +int rfapiQprefix2Raddr(struct prefix *qprefix, struct rfapi_ip_addr *raddr) { - memset (raddr, 0, sizeof (struct rfapi_ip_addr)); - raddr->addr_family = qprefix->family; - switch (qprefix->family) - { - case AF_INET: - if (qprefix->prefixlen != 32) - return -1; - raddr->addr.v4 = qprefix->u.prefix4; - break; - case AF_INET6: - if (qprefix->prefixlen != 128) - return -1; - raddr->addr.v6 = qprefix->u.prefix6; - break; - default: - return -1; - } - return 0; + memset(raddr, 0, sizeof(struct rfapi_ip_addr)); + raddr->addr_family = qprefix->family; + switch (qprefix->family) { + case AF_INET: + if (qprefix->prefixlen != 32) + return -1; + raddr->addr.v4 = qprefix->u.prefix4; + break; + case AF_INET6: + if (qprefix->prefixlen != 128) + return -1; + raddr->addr.v6 = qprefix->u.prefix6; + break; + default: + return -1; + } + return 0; } -/* +/* * Translate Quagga prefix to RFAPI prefix */ /* rprefix->cost set to 0 */ -void -rfapiQprefix2Rprefix (struct prefix *qprefix, struct rfapi_ip_prefix *rprefix) +void rfapiQprefix2Rprefix(struct prefix *qprefix, + struct rfapi_ip_prefix *rprefix) { - memset (rprefix, 0, sizeof (struct rfapi_ip_prefix)); - rprefix->length = qprefix->prefixlen; - rprefix->prefix.addr_family = qprefix->family; - switch (qprefix->family) - { - case AF_INET: - rprefix->prefix.addr.v4 = qprefix->u.prefix4; - break; - case AF_INET6: - rprefix->prefix.addr.v6 = qprefix->u.prefix6; - break; - default: - assert (0); - } + memset(rprefix, 0, sizeof(struct rfapi_ip_prefix)); + rprefix->length = qprefix->prefixlen; + rprefix->prefix.addr_family = qprefix->family; + switch (qprefix->family) { + case AF_INET: + rprefix->prefix.addr.v4 = qprefix->u.prefix4; + break; + case AF_INET6: + rprefix->prefix.addr.v6 = qprefix->u.prefix6; + break; + default: + assert(0); + } } -int -rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, struct prefix *qprefix) +int rfapiRprefix2Qprefix(struct rfapi_ip_prefix *rprefix, + struct prefix *qprefix) { - memset (qprefix, 0, sizeof (struct prefix)); - qprefix->prefixlen = rprefix->length; - qprefix->family = rprefix->prefix.addr_family; - - switch (rprefix->prefix.addr_family) - { - case AF_INET: - qprefix->u.prefix4 = rprefix->prefix.addr.v4; - break; - case AF_INET6: - qprefix->u.prefix6 = rprefix->prefix.addr.v6; - break; - default: - return EAFNOSUPPORT; - } - return 0; + memset(qprefix, 0, sizeof(struct prefix)); + qprefix->prefixlen = rprefix->length; + qprefix->family = rprefix->prefix.addr_family; + + switch (rprefix->prefix.addr_family) { + case AF_INET: + qprefix->u.prefix4 = rprefix->prefix.addr.v4; + break; + case AF_INET6: + qprefix->u.prefix6 = rprefix->prefix.addr.v6; + break; + default: + return EAFNOSUPPORT; + } + return 0; } /* @@ -264,122 +241,111 @@ rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, struct prefix *qprefix) * For paralellism with quagga/lib/prefix.c. if we need a comparison * where host bits are ignored, call that function rfapiRprefixCmp. */ -int -rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2) +int rfapiRprefixSame(struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2) { - if (hp1->prefix.addr_family != hp2->prefix.addr_family) - return 0; - if (hp1->length != hp2->length) - return 0; - if (hp1->prefix.addr_family == AF_INET) - if (IPV4_ADDR_SAME (&hp1->prefix.addr.v4, &hp2->prefix.addr.v4)) - return 1; - if (hp1->prefix.addr_family == AF_INET6) - if (IPV6_ADDR_SAME (&hp1->prefix.addr.v6, &hp2->prefix.addr.v6)) - return 1; - return 0; + if (hp1->prefix.addr_family != hp2->prefix.addr_family) + return 0; + if (hp1->length != hp2->length) + return 0; + if (hp1->prefix.addr_family == AF_INET) + if (IPV4_ADDR_SAME(&hp1->prefix.addr.v4, &hp2->prefix.addr.v4)) + return 1; + if (hp1->prefix.addr_family == AF_INET6) + if (IPV6_ADDR_SAME(&hp1->prefix.addr.v6, &hp2->prefix.addr.v6)) + return 1; + return 0; } -int -rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx) +int rfapiRaddr2Qprefix(struct rfapi_ip_addr *hia, struct prefix *pfx) { - memset (pfx, 0, sizeof (struct prefix)); - pfx->family = hia->addr_family; - - switch (hia->addr_family) - { - case AF_INET: - pfx->prefixlen = 32; - pfx->u.prefix4 = hia->addr.v4; - break; - case AF_INET6: - pfx->prefixlen = 128; - pfx->u.prefix6 = hia->addr.v6; - break; - default: - return EAFNOSUPPORT; - } - return 0; + memset(pfx, 0, sizeof(struct prefix)); + pfx->family = hia->addr_family; + + switch (hia->addr_family) { + case AF_INET: + pfx->prefixlen = 32; + pfx->u.prefix4 = hia->addr.v4; + break; + case AF_INET6: + pfx->prefixlen = 128; + pfx->u.prefix6 = hia->addr.v6; + break; + default: + return EAFNOSUPPORT; + } + return 0; } -void -rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx) +void rfapiL2o2Qprefix(struct rfapi_l2address_option *l2o, struct prefix *pfx) { - memset (pfx, 0, sizeof (struct prefix)); - pfx->family = AF_ETHERNET; - pfx->prefixlen = 48; - pfx->u.prefix_eth = l2o->macaddr; + memset(pfx, 0, sizeof(struct prefix)); + pfx->family = AF_ETHERNET; + pfx->prefixlen = 48; + pfx->u.prefix_eth = l2o->macaddr; } -char * -rfapiEthAddr2Str (const struct ethaddr *ea, char *buf, int bufsize) +char *rfapiEthAddr2Str(const struct ethaddr *ea, char *buf, int bufsize) { - return prefix_mac2str (ea, buf, bufsize); + return prefix_mac2str(ea, buf, bufsize); } -int -rfapiStr2EthAddr (const char *str, struct ethaddr *ea) +int rfapiStr2EthAddr(const char *str, struct ethaddr *ea) { - unsigned int a[6]; - int i; + unsigned int a[6]; + int i; - if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x", - a + 0, a + 1, a + 2, a + 3, a + 4, a + 5) != 6) - { + if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1, a + 2, a + 3, + a + 4, a + 5) + != 6) { - return EINVAL; - } + return EINVAL; + } - for (i = 0; i < 6; ++i) - ea->octet[i] = a[i] & 0xff; + for (i = 0; i < 6; ++i) + ea->octet[i] = a[i] & 0xff; - return 0; + return 0; } -const char * -rfapi_ntop (int af, const void *src, char *buf, socklen_t size) +const char *rfapi_ntop(int af, const void *src, char *buf, socklen_t size) { - if (af == AF_ETHERNET) - { - return rfapiEthAddr2Str ((const struct ethaddr *) src, buf, size); - } + if (af == AF_ETHERNET) { + return rfapiEthAddr2Str((const struct ethaddr *)src, buf, size); + } - return inet_ntop (af, src, buf, size); + return inet_ntop(af, src, buf, size); } -int -rfapiDebugPrintf (void *dummy, const char *format, ...) +int rfapiDebugPrintf(void *dummy, const char *format, ...) { - va_list args; - va_start (args, format); - vzlog (LOG_DEBUG, format, args); - va_end (args); - return 0; + va_list args; + va_start(args, format); + vzlog(LOG_DEBUG, format, args); + va_end(args); + return 0; } -static int -rfapiStdioPrintf (void *stream, const char *format, ...) +static int rfapiStdioPrintf(void *stream, const char *format, ...) { - FILE *file = NULL; - - va_list args; - va_start (args, format); - - switch ((uintptr_t) stream) - { - case 1: - file = stdout; - break; - case 2: - file = stderr; - break; - default: - assert (0); - } - - vfprintf (file, format, args); - va_end (args); - return 0; + FILE *file = NULL; + + va_list args; + va_start(args, format); + + switch ((uintptr_t)stream) { + case 1: + file = stdout; + break; + case 2: + file = stderr; + break; + default: + assert(0); + } + + vfprintf(file, format, args); + va_end(args); + return 0; } /* Fake out for debug logging */ @@ -387,1133 +353,1016 @@ static struct vty vty_dummy_zlog; static struct vty vty_dummy_stdio; #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n") -static const char * -str_vty_newline (struct vty *vty) +static const char *str_vty_newline(struct vty *vty) { - if (vty == &vty_dummy_zlog) - return ""; - return "\n"; + if (vty == &vty_dummy_zlog) + return ""; + return "\n"; } -int -rfapiStream2Vty ( - void *stream, /* input */ - int (**fp) (void *, const char *, ...), /* output */ - struct vty **vty, /* output */ - void **outstream, /* output */ - const char **vty_newline) /* output */ +int rfapiStream2Vty(void *stream, /* input */ + int (**fp)(void *, const char *, ...), /* output */ + struct vty **vty, /* output */ + void **outstream, /* output */ + const char **vty_newline) /* output */ { - if (!stream) - { - vty_dummy_zlog.type = VTY_SHELL; /* for VTYNL */ - *vty = &vty_dummy_zlog; - *fp = (int (*)(void *, const char *,...)) rfapiDebugPrintf; - *outstream = NULL; - *vty_newline = str_vty_newline (*vty); - return (vzlog_test (LOG_DEBUG)); - } - - if (((uintptr_t) stream == (uintptr_t) 1) || - ((uintptr_t) stream == (uintptr_t) 2)) - { - - vty_dummy_stdio.type = VTY_SHELL; /* for VTYNL */ - *vty = &vty_dummy_stdio; - *fp = (int (*)(void *, const char *,...)) rfapiStdioPrintf; - *outstream = stream; - *vty_newline = str_vty_newline (*vty); - return 1; - } - - if (stream) - { - *vty = stream; /* VTYNL requires vty to be legit */ - *fp = (int (*)(void *, const char *,...)) vty_out; - *outstream = stream; - *vty_newline = str_vty_newline (*vty); - return 1; - } - - return 0; + if (!stream) { + vty_dummy_zlog.type = VTY_SHELL; /* for VTYNL */ + *vty = &vty_dummy_zlog; + *fp = (int (*)(void *, const char *, ...))rfapiDebugPrintf; + *outstream = NULL; + *vty_newline = str_vty_newline(*vty); + return (vzlog_test(LOG_DEBUG)); + } + + if (((uintptr_t)stream == (uintptr_t)1) + || ((uintptr_t)stream == (uintptr_t)2)) { + + vty_dummy_stdio.type = VTY_SHELL; /* for VTYNL */ + *vty = &vty_dummy_stdio; + *fp = (int (*)(void *, const char *, ...))rfapiStdioPrintf; + *outstream = stream; + *vty_newline = str_vty_newline(*vty); + return 1; + } + + if (stream) { + *vty = stream; /* VTYNL requires vty to be legit */ + *fp = (int (*)(void *, const char *, ...))vty_out; + *outstream = stream; + *vty_newline = str_vty_newline(*vty); + return 1; + } + + return 0; } /* called from bgpd/bgp_vty.c'route_vty_out() */ -void -rfapi_vty_out_vncinfo ( - struct vty *vty, - struct prefix *p, - struct bgp_info *bi, - safi_t safi) +void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p, + struct bgp_info *bi, safi_t safi) { - char *s; - uint32_t lifetime; - - /* - * Print, on an indented line: - * UN address [if VPN route and VNC UN addr subtlv] - * EC list - * VNC lifetime - */ - vty_out (vty, " "); - - if (safi == SAFI_MPLS_VPN) - { - struct prefix pfx_un; - - if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un)) - { - char buf[BUFSIZ]; - vty_out (vty, "UN=%s", inet_ntop (pfx_un.family, - pfx_un.u.val, buf, BUFSIZ)); - } - } - - if (bi->attr && bi->attr->ecommunity) - { - s = ecommunity_ecom2str (bi->attr->ecommunity, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out (vty, " EC{%s}", s); - XFREE (MTYPE_ECOMMUNITY_STR, s); - } - - if (bi->extra != NULL) - vty_out (vty, " label=%u", decode_label (&bi->extra->label)); - - if (!rfapiGetVncLifetime (bi->attr, &lifetime)) - { - vty_out (vty, " life=%d", lifetime); - } - - vty_out (vty, " type=%s, subtype=%d", - zebra_route_string (bi->type), bi->sub_type); - - vty_out (vty, "%s", HVTYNL); + char *s; + uint32_t lifetime; + + /* + * Print, on an indented line: + * UN address [if VPN route and VNC UN addr subtlv] + * EC list + * VNC lifetime + */ + vty_out(vty, " "); + + if (safi == SAFI_MPLS_VPN) { + struct prefix pfx_un; + + if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) { + char buf[BUFSIZ]; + vty_out(vty, "UN=%s", + inet_ntop(pfx_un.family, pfx_un.u.val, buf, + BUFSIZ)); + } + } + + if (bi->attr && bi->attr->ecommunity) { + s = ecommunity_ecom2str(bi->attr->ecommunity, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vty_out(vty, " EC{%s}", s); + XFREE(MTYPE_ECOMMUNITY_STR, s); + } + + if (bi->extra != NULL) + vty_out(vty, " label=%u", decode_label(&bi->extra->label)); + + if (!rfapiGetVncLifetime(bi->attr, &lifetime)) { + vty_out(vty, " life=%d", lifetime); + } + + vty_out(vty, " type=%s, subtype=%d", zebra_route_string(bi->type), + bi->sub_type); + + vty_out(vty, "%s", HVTYNL); } -void -rfapiPrintAttrPtrs (void *stream, struct attr *attr) +void rfapiPrintAttrPtrs(void *stream, struct attr *attr) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - char buf[BUFSIZ]; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - - fp (out, "Attr[%p]:%s", attr, HVTYNL); - if (!attr) - return; - - /* IPv4 Nexthop */ - inet_ntop (AF_INET, &attr->nexthop, buf, BUFSIZ); - fp (out, " nexthop=%s%s", buf, HVTYNL); - - fp (out, " aspath=%p, refcnt=%d%s", attr->aspath, - (attr->aspath ? attr->aspath->refcnt : 0), HVTYNL); - fp (out, " community=%p, refcnt=%d%s", attr->community, - (attr->community ? attr->community->refcnt : 0), HVTYNL); - - fp (out, " ecommunity=%p, refcnt=%d%s", attr->ecommunity, - (attr->ecommunity ? attr->ecommunity->refcnt : 0), HVTYNL); - fp (out, " cluster=%p, refcnt=%d%s", attr->cluster, - (attr->cluster ? attr->cluster->refcnt : 0), HVTYNL); - fp (out, " transit=%p, refcnt=%d%s", attr->transit, - (attr->transit ? attr->transit->refcnt : 0), HVTYNL); + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + char buf[BUFSIZ]; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + fp(out, "Attr[%p]:%s", attr, HVTYNL); + if (!attr) + return; + + /* IPv4 Nexthop */ + inet_ntop(AF_INET, &attr->nexthop, buf, BUFSIZ); + fp(out, " nexthop=%s%s", buf, HVTYNL); + + fp(out, " aspath=%p, refcnt=%d%s", attr->aspath, + (attr->aspath ? attr->aspath->refcnt : 0), HVTYNL); + fp(out, " community=%p, refcnt=%d%s", attr->community, + (attr->community ? attr->community->refcnt : 0), HVTYNL); + + fp(out, " ecommunity=%p, refcnt=%d%s", attr->ecommunity, + (attr->ecommunity ? attr->ecommunity->refcnt : 0), HVTYNL); + fp(out, " cluster=%p, refcnt=%d%s", attr->cluster, + (attr->cluster ? attr->cluster->refcnt : 0), HVTYNL); + fp(out, " transit=%p, refcnt=%d%s", attr->transit, + (attr->transit ? attr->transit->refcnt : 0), HVTYNL); } /* * Print BI in an Import Table */ -void -rfapiPrintBi (void *stream, struct bgp_info *bi) +void rfapiPrintBi(void *stream, struct bgp_info *bi) { - char buf[BUFSIZ]; - char *s; - - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - char line[BUFSIZ]; - char *p = line; - int r; - int has_macaddr = 0; - struct ethaddr macaddr; - struct rfapi_l2address_option l2o_buf; - uint8_t l2hid=0; /* valid if has_macaddr */ + char buf[BUFSIZ]; + char *s; + + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + char line[BUFSIZ]; + char *p = line; + int r; + int has_macaddr = 0; + struct ethaddr macaddr; + struct rfapi_l2address_option l2o_buf; + uint8_t l2hid = 0; /* valid if has_macaddr */ #define REMAIN (BUFSIZ - (p-line)) #define INCP {p += (r > REMAIN)? REMAIN: r;} - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - - if (!bi) - return; - - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && bi->extra - && bi->extra->vnc.import.timer) - { - struct thread *t = (struct thread *) bi->extra->vnc.import.timer; - r = snprintf (p, REMAIN, " [%4lu] ", thread_timer_remain_second (t)); - INCP; - - } - else - { - r = snprintf (p, REMAIN, " "); - INCP; - } - - if (bi->extra) - { - /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */ - if (decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH) - { - has_macaddr = 1; - memcpy (macaddr.octet, bi->extra->vnc.import.rd.val + 2, 6); - l2hid = bi->extra->vnc.import.rd.val[1]; - } - } - - /* - * Print these items: - * type/subtype - * nexthop address - * lifetime - * RFP option sizes (they are opaque values) - * extended communities (RTs) - */ - if (bi->attr) - { - uint32_t lifetime; - int printed_1st_gol = 0; - struct bgp_attr_encap_subtlv *pEncap; - struct prefix pfx_un; - int af = BGP_MP_NEXTHOP_FAMILY (bi->attr->mp_nexthop_len); - - /* Nexthop */ - if (af == AF_INET) - { - r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET, - &bi->attr->mp_nexthop_global_in, - buf, BUFSIZ)); - INCP; - } - else if (af == AF_INET6) - { - r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET6, - &bi->attr->mp_nexthop_global, - buf, BUFSIZ)); - INCP; - } - else - { - r = snprintf (p, REMAIN, "?"); - INCP; - } - - /* - * VNC tunnel subtlv, if present, contains UN address - */ - if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un)) - { - r = snprintf (p, REMAIN, " un=%s", inet_ntop (pfx_un.family, - pfx_un.u.val, buf, - BUFSIZ)); - INCP; - - } - - /* Lifetime */ - if (rfapiGetVncLifetime (bi->attr, &lifetime)) - { - r = snprintf (p, REMAIN, " nolife"); - INCP; - } - else - { - if (lifetime == 0xffffffff) - r = snprintf (p, REMAIN, " %6s", "infini"); - else - r = snprintf (p, REMAIN, " %6u", lifetime); - INCP; - } - - /* RFP option lengths */ - for (pEncap = bi->attr->vnc_subtlvs; pEncap; - pEncap = pEncap->next) - { - - if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) - { - if (printed_1st_gol) - { - r = snprintf (p, REMAIN, ","); - INCP; - } - else - { - r = snprintf (p, REMAIN, " "); /* leading space */ - INCP; - } - r = snprintf (p, REMAIN, "%d", pEncap->length); - INCP; - printed_1st_gol = 1; - } - } - - /* RT list */ - if (bi->attr->ecommunity) - { - s = ecommunity_ecom2str (bi->attr->ecommunity, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - r = snprintf (p, REMAIN, " %s", s); - INCP; - XFREE (MTYPE_ECOMMUNITY_STR, s); - } - - } - - r = snprintf (p, REMAIN, " bi@%p", bi); - INCP; - - r = snprintf (p, REMAIN, " p@%p", bi->peer); - INCP; - - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - { - r = snprintf (p, REMAIN, " HD=yes"); - INCP; - } - else - { - r = snprintf (p, REMAIN, " HD=no"); - INCP; - } - - if (bi->attr) - { - - if (bi->attr->weight) - { - r = snprintf (p, REMAIN, " W=%d", bi->attr->weight); - INCP; - } - - if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) - { - r = snprintf (p, REMAIN, " LP=%d", bi->attr->local_pref); - INCP; - } - else - { - r = snprintf (p, REMAIN, " LP=unset"); - INCP; - } - } - - r = - snprintf (p, REMAIN, " %c:%u", zebra_route_char (bi->type), bi->sub_type); - INCP; - - fp (out, "%s%s", line, HVTYNL); - - if (has_macaddr) - { - fp (out, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s", - l2hid, - macaddr.octet[0], - macaddr.octet[1], - macaddr.octet[2], - macaddr.octet[3], macaddr.octet[4], macaddr.octet[5], HVTYNL); - } - - if (!rfapiGetL2o (bi->attr, &l2o_buf)) - { - fp (out, - " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s", - l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1], - l2o_buf.macaddr.octet[2], l2o_buf.macaddr.octet[3], - l2o_buf.macaddr.octet[4], l2o_buf.macaddr.octet[5], l2o_buf.label, - l2o_buf.logical_net_id, l2o_buf.local_nve_id, HVTYNL); - } - if (bi->extra && bi->extra->vnc.import.aux_prefix.family) - { - char buf[BUFSIZ]; - const char *sp; - - sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family, - &bi->extra->vnc.import.aux_prefix.u.prefix, - buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - if (sp) - { - fp (out, " IP: %s%s", sp, HVTYNL); - } - } - { - struct rfapi_un_option *uo = rfapi_encap_tlv_to_un_option (bi->attr); - if (uo) - { - rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel); - rfapi_un_options_free (uo); - } - } + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + if (!bi) + return; + + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra + && bi->extra->vnc.import.timer) { + struct thread *t = (struct thread *)bi->extra->vnc.import.timer; + r = snprintf(p, REMAIN, " [%4lu] ", + thread_timer_remain_second(t)); + INCP; + + } else { + r = snprintf(p, REMAIN, " "); + INCP; + } + + if (bi->extra) { + /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */ + if (decode_rd_type(bi->extra->vnc.import.rd.val) + == RD_TYPE_VNC_ETH) { + has_macaddr = 1; + memcpy(macaddr.octet, bi->extra->vnc.import.rd.val + 2, + 6); + l2hid = bi->extra->vnc.import.rd.val[1]; + } + } + + /* + * Print these items: + * type/subtype + * nexthop address + * lifetime + * RFP option sizes (they are opaque values) + * extended communities (RTs) + */ + if (bi->attr) { + uint32_t lifetime; + int printed_1st_gol = 0; + struct bgp_attr_encap_subtlv *pEncap; + struct prefix pfx_un; + int af = BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len); + + /* Nexthop */ + if (af == AF_INET) { + r = snprintf(p, REMAIN, "%s", + inet_ntop(AF_INET, + &bi->attr->mp_nexthop_global_in, + buf, BUFSIZ)); + INCP; + } else if (af == AF_INET6) { + r = snprintf(p, REMAIN, "%s", + inet_ntop(AF_INET6, + &bi->attr->mp_nexthop_global, + buf, BUFSIZ)); + INCP; + } else { + r = snprintf(p, REMAIN, "?"); + INCP; + } + + /* + * VNC tunnel subtlv, if present, contains UN address + */ + if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) { + r = snprintf(p, REMAIN, " un=%s", + inet_ntop(pfx_un.family, pfx_un.u.val, buf, + BUFSIZ)); + INCP; + } + + /* Lifetime */ + if (rfapiGetVncLifetime(bi->attr, &lifetime)) { + r = snprintf(p, REMAIN, " nolife"); + INCP; + } else { + if (lifetime == 0xffffffff) + r = snprintf(p, REMAIN, " %6s", "infini"); + else + r = snprintf(p, REMAIN, " %6u", lifetime); + INCP; + } + + /* RFP option lengths */ + for (pEncap = bi->attr->vnc_subtlvs; pEncap; + pEncap = pEncap->next) { + + if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) { + if (printed_1st_gol) { + r = snprintf(p, REMAIN, ","); + INCP; + } else { + r = snprintf(p, REMAIN, + " "); /* leading space */ + INCP; + } + r = snprintf(p, REMAIN, "%d", pEncap->length); + INCP; + printed_1st_gol = 1; + } + } + + /* RT list */ + if (bi->attr->ecommunity) { + s = ecommunity_ecom2str(bi->attr->ecommunity, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + r = snprintf(p, REMAIN, " %s", s); + INCP; + XFREE(MTYPE_ECOMMUNITY_STR, s); + } + } + + r = snprintf(p, REMAIN, " bi@%p", bi); + INCP; + + r = snprintf(p, REMAIN, " p@%p", bi->peer); + INCP; + + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { + r = snprintf(p, REMAIN, " HD=yes"); + INCP; + } else { + r = snprintf(p, REMAIN, " HD=no"); + INCP; + } + + if (bi->attr) { + + if (bi->attr->weight) { + r = snprintf(p, REMAIN, " W=%d", bi->attr->weight); + INCP; + } + + if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { + r = snprintf(p, REMAIN, " LP=%d", bi->attr->local_pref); + INCP; + } else { + r = snprintf(p, REMAIN, " LP=unset"); + INCP; + } + } + + r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bi->type), + bi->sub_type); + INCP; + + fp(out, "%s%s", line, HVTYNL); + + if (has_macaddr) { + fp(out, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s", + l2hid, macaddr.octet[0], macaddr.octet[1], macaddr.octet[2], + macaddr.octet[3], macaddr.octet[4], macaddr.octet[5], + HVTYNL); + } + + if (!rfapiGetL2o(bi->attr, &l2o_buf)) { + fp(out, + " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s", + l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1], + l2o_buf.macaddr.octet[2], l2o_buf.macaddr.octet[3], + l2o_buf.macaddr.octet[4], l2o_buf.macaddr.octet[5], + l2o_buf.label, l2o_buf.logical_net_id, l2o_buf.local_nve_id, + HVTYNL); + } + if (bi->extra && bi->extra->vnc.import.aux_prefix.family) { + char buf[BUFSIZ]; + const char *sp; + + sp = rfapi_ntop(bi->extra->vnc.import.aux_prefix.family, + &bi->extra->vnc.import.aux_prefix.u.prefix, buf, + BUFSIZ); + buf[BUFSIZ - 1] = 0; + if (sp) { + fp(out, " IP: %s%s", sp, HVTYNL); + } + } + { + struct rfapi_un_option *uo = + rfapi_encap_tlv_to_un_option(bi->attr); + if (uo) { + rfapi_print_tunneltype_option(stream, 8, &uo->v.tunnel); + rfapi_un_options_free(uo); + } + } } -char * -rfapiMonitorVpn2Str (struct rfapi_monitor_vpn *m, char *buf, int size) +char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn *m, char *buf, int size) { - char buf_pfx[BUFSIZ]; - char buf_vn[BUFSIZ]; - char buf_un[BUFSIZ]; - int rc; - - rfapiRfapiIpAddr2Str (&m->rfd->un_addr, buf_vn, BUFSIZ); - rfapiRfapiIpAddr2Str (&m->rfd->vn_addr, buf_un, BUFSIZ); - - rc = snprintf (buf, size, - "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", - m, m->next, m->rfd, buf_vn, buf_un, - inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ), - m->p.prefixlen, m->node); - buf[size - 1] = 0; - if (rc >= size) - return NULL; - return buf; + char buf_pfx[BUFSIZ]; + char buf_vn[BUFSIZ]; + char buf_un[BUFSIZ]; + int rc; + + rfapiRfapiIpAddr2Str(&m->rfd->un_addr, buf_vn, BUFSIZ); + rfapiRfapiIpAddr2Str(&m->rfd->vn_addr, buf_un, BUFSIZ); + + rc = snprintf(buf, size, + "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m, + m->next, m->rfd, buf_vn, buf_un, + inet_ntop(m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ), + m->p.prefixlen, m->node); + buf[size - 1] = 0; + if (rc >= size) + return NULL; + return buf; } -static void -rfapiDebugPrintMonitorVpn (void *stream, struct rfapi_monitor_vpn *m) +static void rfapiDebugPrintMonitorVpn(void *stream, struct rfapi_monitor_vpn *m) { - char buf[BUFSIZ]; + char buf[BUFSIZ]; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; - rfapiMonitorVpn2Str (m, buf, BUFSIZ); - fp (out, " Mon %s%s", buf, HVTYNL); + rfapiMonitorVpn2Str(m, buf, BUFSIZ); + fp(out, " Mon %s%s", buf, HVTYNL); } -static void -rfapiDebugPrintMonitorEncap (void *stream, struct rfapi_monitor_encap *m) +static void rfapiDebugPrintMonitorEncap(void *stream, + struct rfapi_monitor_encap *m) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out = NULL; - const char *vty_newline; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out = NULL; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; - fp (out, " Mon m=%p, next=%p, node=%p, bi=%p%s", - m, m->next, m->node, m->bi, HVTYNL); + fp(out, " Mon m=%p, next=%p, node=%p, bi=%p%s", m, m->next, m->node, + m->bi, HVTYNL); } -void -rfapiShowItNode (void *stream, struct route_node *rn) +void rfapiShowItNode(void *stream, struct route_node *rn) { - struct bgp_info *bi; - char buf[BUFSIZ]; + struct bgp_info *bi; + char buf[BUFSIZ]; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; - fp (out, "%s/%d @%p #%d%s", - rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), - rn->p.prefixlen, rn, rn->lock, HVTYNL); + fp(out, "%s/%d @%p #%d%s", + rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), + rn->p.prefixlen, rn, rn->lock, HVTYNL); - for (bi = rn->info; bi; bi = bi->next) - { - rfapiPrintBi (stream, bi); - } + for (bi = rn->info; bi; bi = bi->next) { + rfapiPrintBi(stream, bi); + } - /* doesn't show montors */ + /* doesn't show montors */ } -void -rfapiShowImportTable ( - void *stream, - const char *label, - struct route_table *rt, - int isvpn) +void rfapiShowImportTable(void *stream, const char *label, + struct route_table *rt, int isvpn) { - struct route_node *rn; - char buf[BUFSIZ]; - - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - - fp (out, "Import Table [%s]%s", label, HVTYNL); - - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - struct bgp_info *bi; - - if (rn->p.family == AF_ETHERNET) - { - rfapiEthAddr2Str (&rn->p.u.prefix_eth, buf, BUFSIZ); - } - else - { - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ); - } - - fp (out, "%s/%d @%p #%d%s", buf, rn->p.prefixlen, rn, rn->lock - 1, /* account for loop iterator locking */ - HVTYNL); - - for (bi = rn->info; bi; bi = bi->next) - { - rfapiPrintBi (stream, bi); - } - - if (isvpn) - { - struct rfapi_monitor_vpn *m; - for (m = RFAPI_MONITOR_VPN (rn); m; m = m->next) - { - rfapiDebugPrintMonitorVpn (stream, m); - } - } - else - { - struct rfapi_monitor_encap *m; - for (m = RFAPI_MONITOR_ENCAP (rn); m; m = m->next) - { - rfapiDebugPrintMonitorEncap (stream, m); - } - } - } + struct route_node *rn; + char buf[BUFSIZ]; + + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + fp(out, "Import Table [%s]%s", label, HVTYNL); + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + struct bgp_info *bi; + + if (rn->p.family == AF_ETHERNET) { + rfapiEthAddr2Str(&rn->p.u.prefix_eth, buf, BUFSIZ); + } else { + inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ); + } + + fp(out, "%s/%d @%p #%d%s", buf, rn->p.prefixlen, rn, + rn->lock - 1, /* account for loop iterator locking */ + HVTYNL); + + for (bi = rn->info; bi; bi = bi->next) { + rfapiPrintBi(stream, bi); + } + + if (isvpn) { + struct rfapi_monitor_vpn *m; + for (m = RFAPI_MONITOR_VPN(rn); m; m = m->next) { + rfapiDebugPrintMonitorVpn(stream, m); + } + } else { + struct rfapi_monitor_encap *m; + for (m = RFAPI_MONITOR_ENCAP(rn); m; m = m->next) { + rfapiDebugPrintMonitorEncap(stream, m); + } + } + } } -int -rfapiShowVncQueries (void *stream, struct prefix *pfx_match) +int rfapiShowVncQueries(void *stream, struct prefix *pfx_match) { - struct bgp *bgp; - struct rfapi *h; - struct listnode *node; - struct rfapi_descriptor *rfd; - - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - - int printedheader = 0; - - int nves_total = 0; - int nves_with_queries = 0; - int nves_displayed = 0; - - int queries_total = 0; - int queries_displayed = 0; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return CMD_WARNING; - - bgp = bgp_get_default (); /* assume 1 instance for now */ - if (!bgp) - { - vty_out (vty, "No BGP instance\n"); - return CMD_WARNING; - } - - h = bgp->rfapi; - if (!h) - { - vty_out (vty, "No RFAPI instance\n"); - return CMD_WARNING; - } - - for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) - { - - struct route_node *rn; - int printedquerier = 0; - - - ++nves_total; - - if (rfd->mon || (rfd->mon_eth && skiplist_count (rfd->mon_eth))) - { - ++nves_with_queries; - } - else - { - continue; - } - - /* - * IP Queries - */ - if (rfd->mon) - { - for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) - { - struct rfapi_monitor_vpn *m; - char buf_remain[BUFSIZ]; - char buf_pfx[BUFSIZ]; - - if (!rn->info) - continue; - - m = rn->info; - - ++queries_total; - - if (pfx_match && !prefix_match (pfx_match, &rn->p) && - !prefix_match (&rn->p, pfx_match)) - continue; - - ++queries_displayed; - - if (!printedheader) - { - ++printedheader; - fp (out, "\n"); - fp (out, "%-15s %-15s %-15s %-10s\n", - "VN Address", "UN Address", - "Target", "Remaining"); - } - - if (!printedquerier) - { - char buf_vn[BUFSIZ]; - char buf_un[BUFSIZ]; - - rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ); - rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ); - - fp (out, "%-15s %-15s", buf_vn, buf_un); - printedquerier = 1; - - ++nves_displayed; - } - else - fp (out, "%-15s %-15s", "", ""); - buf_remain[0] = 0; - if (m->timer) - { - rfapiFormatSeconds (thread_timer_remain_second (m->timer), - buf_remain, BUFSIZ); - } - fp (out, " %-15s %-10s\n", - inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ), - buf_remain); - } - } - - /* - * Ethernet Queries - */ - if (rfd->mon_eth && skiplist_count (rfd->mon_eth)) - { - - int rc; - void *cursor; - struct rfapi_monitor_eth *mon_eth; - - for (cursor = NULL, - rc = - skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, - &cursor); rc == 0; - rc = - skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, - &cursor)) - { - - char buf_remain[BUFSIZ]; - char buf_pfx[BUFSIZ]; - struct prefix pfx_mac; - - ++queries_total; - - vnc_zlog_debug_verbose ("%s: checking rfd=%p mon_eth=%p", __func__, rfd, - mon_eth); - - memset ((void *) &pfx_mac, 0, sizeof (struct prefix)); - pfx_mac.family = AF_ETHERNET; - pfx_mac.prefixlen = 48; - pfx_mac.u.prefix_eth = mon_eth->macaddr; - - if (pfx_match && !prefix_match (pfx_match, &pfx_mac) && - !prefix_match (&pfx_mac, pfx_match)) - continue; - - ++queries_displayed; - - if (!printedheader) - { - ++printedheader; - fp (out, "\n"); - fp (out, "%-15s %-15s %-17s %10s %-10s\n", - "VN Address", "UN Address", - "Target", "LNI", "Remaining"); - } - - if (!printedquerier) - { - char buf_vn[BUFSIZ]; - char buf_un[BUFSIZ]; - - rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ); - rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ); - - fp (out, "%-15s %-15s", buf_vn, buf_un); - printedquerier = 1; - - ++nves_displayed; - } - else - fp (out, "%-15s %-15s", "", ""); - buf_remain[0] = 0; - if (mon_eth->timer) - { - rfapiFormatSeconds (thread_timer_remain_second - (mon_eth->timer), buf_remain, BUFSIZ); - } - fp (out, " %-17s %10d %-10s\n", - rfapi_ntop (pfx_mac.family, &pfx_mac.u.prefix, buf_pfx, - BUFSIZ), mon_eth->logical_net_id, buf_remain); - } - } - } - - if (queries_total) - { - fp (out, "\n"); - fp (out, "Displayed %d out of %d total queries\n", - queries_displayed, queries_total); - } - return CMD_SUCCESS; + struct bgp *bgp; + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; + + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + int printedheader = 0; + + int nves_total = 0; + int nves_with_queries = 0; + int nves_displayed = 0; + + int queries_total = 0; + int queries_displayed = 0; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return CMD_WARNING; + + bgp = bgp_get_default(); /* assume 1 instance for now */ + if (!bgp) { + vty_out(vty, "No BGP instance\n"); + return CMD_WARNING; + } + + h = bgp->rfapi; + if (!h) { + vty_out(vty, "No RFAPI instance\n"); + return CMD_WARNING; + } + + for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { + + struct route_node *rn; + int printedquerier = 0; + + + ++nves_total; + + if (rfd->mon + || (rfd->mon_eth && skiplist_count(rfd->mon_eth))) { + ++nves_with_queries; + } else { + continue; + } + + /* + * IP Queries + */ + if (rfd->mon) { + for (rn = route_top(rfd->mon); rn; + rn = route_next(rn)) { + struct rfapi_monitor_vpn *m; + char buf_remain[BUFSIZ]; + char buf_pfx[BUFSIZ]; + + if (!rn->info) + continue; + + m = rn->info; + + ++queries_total; + + if (pfx_match + && !prefix_match(pfx_match, &rn->p) + && !prefix_match(&rn->p, pfx_match)) + continue; + + ++queries_displayed; + + if (!printedheader) { + ++printedheader; + fp(out, "\n"); + fp(out, "%-15s %-15s %-15s %-10s\n", + "VN Address", "UN Address", "Target", + "Remaining"); + } + + if (!printedquerier) { + char buf_vn[BUFSIZ]; + char buf_un[BUFSIZ]; + + rfapiRfapiIpAddr2Str(&rfd->un_addr, + buf_un, BUFSIZ); + rfapiRfapiIpAddr2Str(&rfd->vn_addr, + buf_vn, BUFSIZ); + + fp(out, "%-15s %-15s", buf_vn, buf_un); + printedquerier = 1; + + ++nves_displayed; + } else + fp(out, "%-15s %-15s", "", ""); + buf_remain[0] = 0; + if (m->timer) { + rfapiFormatSeconds( + thread_timer_remain_second( + m->timer), + buf_remain, BUFSIZ); + } + fp(out, " %-15s %-10s\n", + inet_ntop(m->p.family, &m->p.u.prefix, + buf_pfx, BUFSIZ), + buf_remain); + } + } + + /* + * Ethernet Queries + */ + if (rfd->mon_eth && skiplist_count(rfd->mon_eth)) { + + int rc; + void *cursor; + struct rfapi_monitor_eth *mon_eth; + + for (cursor = NULL, + rc = skiplist_next(rfd->mon_eth, NULL, + (void **)&mon_eth, &cursor); + rc == 0; + rc = skiplist_next(rfd->mon_eth, NULL, + (void **)&mon_eth, &cursor)) { + + char buf_remain[BUFSIZ]; + char buf_pfx[BUFSIZ]; + struct prefix pfx_mac; + + ++queries_total; + + vnc_zlog_debug_verbose( + "%s: checking rfd=%p mon_eth=%p", + __func__, rfd, mon_eth); + + memset((void *)&pfx_mac, 0, + sizeof(struct prefix)); + pfx_mac.family = AF_ETHERNET; + pfx_mac.prefixlen = 48; + pfx_mac.u.prefix_eth = mon_eth->macaddr; + + if (pfx_match + && !prefix_match(pfx_match, &pfx_mac) + && !prefix_match(&pfx_mac, pfx_match)) + continue; + + ++queries_displayed; + + if (!printedheader) { + ++printedheader; + fp(out, "\n"); + fp(out, + "%-15s %-15s %-17s %10s %-10s\n", + "VN Address", "UN Address", "Target", + "LNI", "Remaining"); + } + + if (!printedquerier) { + char buf_vn[BUFSIZ]; + char buf_un[BUFSIZ]; + + rfapiRfapiIpAddr2Str(&rfd->un_addr, + buf_un, BUFSIZ); + rfapiRfapiIpAddr2Str(&rfd->vn_addr, + buf_vn, BUFSIZ); + + fp(out, "%-15s %-15s", buf_vn, buf_un); + printedquerier = 1; + + ++nves_displayed; + } else + fp(out, "%-15s %-15s", "", ""); + buf_remain[0] = 0; + if (mon_eth->timer) { + rfapiFormatSeconds( + thread_timer_remain_second( + mon_eth->timer), + buf_remain, BUFSIZ); + } + fp(out, " %-17s %10d %-10s\n", + rfapi_ntop(pfx_mac.family, &pfx_mac.u.prefix, + buf_pfx, BUFSIZ), + mon_eth->logical_net_id, buf_remain); + } + } + } + + if (queries_total) { + fp(out, "\n"); + fp(out, "Displayed %d out of %d total queries\n", + queries_displayed, queries_total); + } + return CMD_SUCCESS; } -static int -rfapiPrintRemoteRegBi ( - struct bgp *bgp, - void *stream, - struct route_node *rn, - struct bgp_info *bi) +static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, + struct route_node *rn, struct bgp_info *bi) { - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - struct prefix pfx_un; - struct prefix pfx_vn; - uint8_t cost; - uint32_t lifetime; - bgp_encap_types tun_type; - - char buf_pfx[BUFSIZ]; - char buf_ntop[BUFSIZ]; - char buf_un[BUFSIZ]; - char buf_vn[BUFSIZ]; - char buf_lifetime[BUFSIZ]; - int nlines = 0; - - if (!stream) - return 0; /* for debug log, print into buf & call output once */ - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return 0; - - /* - * Prefix - */ - buf_pfx[0] = 0; - snprintf (buf_pfx, BUFSIZ, "%s/%d", - rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf_ntop, BUFSIZ), - rn->p.prefixlen); - buf_pfx[BUFSIZ - 1] = 0; - nlines++; - - /* - * UN addr - */ - buf_un[0] = 0; - if (!rfapiGetUnAddrOfVpnBi (bi, &pfx_un)) - { - snprintf (buf_un, BUFSIZ, "%s", - inet_ntop (pfx_un.family, &pfx_un.u.prefix, buf_ntop, - BUFSIZ)); - } - - rfapiGetTunnelType(bi->attr,&tun_type); - /* - * VN addr - */ - buf_vn[0] = 0; - rfapiNexthop2Prefix (bi->attr, &pfx_vn); - if (tun_type == BGP_ENCAP_TYPE_MPLS) - { - /* MPLS carries un in nrli next hop (same as vn for IP tunnels) */ - snprintf (buf_un, BUFSIZ, "%s", - inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); - if (bi->extra) - { - u_int32_t l = decode_label (&bi->extra->label); - snprintf (buf_vn, BUFSIZ, "Label: %d", l); - } - else /* should never happen */ - { - snprintf (buf_vn, BUFSIZ, "Label: N/A"); - } - } - else - { - snprintf (buf_vn, BUFSIZ, "%s", - inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); - } - buf_vn[BUFSIZ - 1] = 0; - buf_un[BUFSIZ - 1] = 0; - - /* - * Cost is encoded in local_pref as (255-cost) - * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion - * back to cost. - */ - if (bi->attr) - { - uint32_t local_pref; - if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) - local_pref = bi->attr->local_pref; - else - local_pref = 0; - cost = (local_pref > 255) ? 0 : 255 - local_pref; - } - else - { - cost = 0; - } - - fp (out, "%-20s ", buf_pfx); - fp (out, "%-15s ", buf_vn); - fp (out, "%-15s ", buf_un); - fp (out, "%-4d ", cost); - - /* Lifetime */ - /* NB rfapiGetVncLifetime sets infinite value when returning !0 */ - if (rfapiGetVncLifetime (bi->attr, &lifetime) || - (lifetime == RFAPI_INFINITE_LIFETIME)) - { - - fp (out, "%-10s ", "infinite"); - } - else - { - time_t t_lifetime = lifetime; - rfapiFormatSeconds (t_lifetime, buf_lifetime, BUFSIZ); - fp (out, "%-10s ", buf_lifetime); - } - - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && - bi->extra && bi->extra->vnc.import.timer) - { - - uint32_t remaining; - time_t age; - char buf_age[BUFSIZ]; - - struct thread *t = (struct thread *) bi->extra->vnc.import.timer; - remaining = thread_timer_remain_second (t); + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + struct prefix pfx_un; + struct prefix pfx_vn; + uint8_t cost; + uint32_t lifetime; + bgp_encap_types tun_type; + + char buf_pfx[BUFSIZ]; + char buf_ntop[BUFSIZ]; + char buf_un[BUFSIZ]; + char buf_vn[BUFSIZ]; + char buf_lifetime[BUFSIZ]; + int nlines = 0; + + if (!stream) + return 0; /* for debug log, print into buf & call output once */ + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return 0; + + /* + * Prefix + */ + buf_pfx[0] = 0; + snprintf(buf_pfx, BUFSIZ, "%s/%d", + rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf_ntop, BUFSIZ), + rn->p.prefixlen); + buf_pfx[BUFSIZ - 1] = 0; + nlines++; + + /* + * UN addr + */ + buf_un[0] = 0; + if (!rfapiGetUnAddrOfVpnBi(bi, &pfx_un)) { + snprintf(buf_un, BUFSIZ, "%s", + inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop, + BUFSIZ)); + } + + rfapiGetTunnelType(bi->attr, &tun_type); + /* + * VN addr + */ + buf_vn[0] = 0; + rfapiNexthop2Prefix(bi->attr, &pfx_vn); + if (tun_type == BGP_ENCAP_TYPE_MPLS) { + /* MPLS carries un in nrli next hop (same as vn for IP tunnels) + */ + snprintf(buf_un, BUFSIZ, "%s", + inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, + BUFSIZ)); + if (bi->extra) { + u_int32_t l = decode_label(&bi->extra->label); + snprintf(buf_vn, BUFSIZ, "Label: %d", l); + } else /* should never happen */ + { + snprintf(buf_vn, BUFSIZ, "Label: N/A"); + } + } else { + snprintf(buf_vn, BUFSIZ, "%s", + inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, + BUFSIZ)); + } + buf_vn[BUFSIZ - 1] = 0; + buf_un[BUFSIZ - 1] = 0; + + /* + * Cost is encoded in local_pref as (255-cost) + * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion + * back to cost. + */ + if (bi->attr) { + uint32_t local_pref; + if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) + local_pref = bi->attr->local_pref; + else + local_pref = 0; + cost = (local_pref > 255) ? 0 : 255 - local_pref; + } else { + cost = 0; + } + + fp(out, "%-20s ", buf_pfx); + fp(out, "%-15s ", buf_vn); + fp(out, "%-15s ", buf_un); + fp(out, "%-4d ", cost); + + /* Lifetime */ + /* NB rfapiGetVncLifetime sets infinite value when returning !0 */ + if (rfapiGetVncLifetime(bi->attr, &lifetime) + || (lifetime == RFAPI_INFINITE_LIFETIME)) { + + fp(out, "%-10s ", "infinite"); + } else { + time_t t_lifetime = lifetime; + rfapiFormatSeconds(t_lifetime, buf_lifetime, BUFSIZ); + fp(out, "%-10s ", buf_lifetime); + } + + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra + && bi->extra->vnc.import.timer) { + + uint32_t remaining; + time_t age; + char buf_age[BUFSIZ]; + + struct thread *t = (struct thread *)bi->extra->vnc.import.timer; + remaining = thread_timer_remain_second(t); #if RFAPI_REGISTRATIONS_REPORT_AGE - /* - * Calculate when the timer started. Doing so here saves - * us a timestamp field in "struct bgp_info". - * - * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the - * original calculation. - */ - age = rfapiGetHolddownFromLifetime (lifetime, factor) - remaining; + /* + * Calculate when the timer started. Doing so here saves + * us a timestamp field in "struct bgp_info". + * + * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the + * original calculation. + */ + age = rfapiGetHolddownFromLifetime(lifetime, factor) + - remaining; #else /* report remaining time */ - age = remaining; + age = remaining; #endif - rfapiFormatSeconds (age, buf_age, BUFSIZ); - - fp (out, "%-10s ", buf_age); - - } - else if (RFAPI_LOCAL_BI (bi)) - { - - char buf_age[BUFSIZ]; - - if (bi && bi->extra && bi->extra->vnc.import.create_time) - { - rfapiFormatAge (bi->extra->vnc.import.create_time, buf_age, BUFSIZ); - } - else - { - buf_age[0] = '?'; - buf_age[1] = 0; - } - fp (out, "%-10s ", buf_age); - } - fp (out, "%s", HVTYNL); - - if (rn->p.family == AF_ETHERNET) - { - /* - * If there is a corresponding IP address && != VN address, - * print that on the next line - */ - - if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) - { - const char *sp; - - sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family, - &bi->extra->vnc.import.aux_prefix.u.prefix, - buf_ntop, BUFSIZ); - buf_ntop[BUFSIZ - 1] = 0; - - if (sp && strcmp (buf_vn, sp) != 0) - { - fp (out, " IP: %s", sp); - if (nlines == 1) - nlines++; - } - } - } - if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra) - { - u_int32_t l = decode_label (&bi->extra->label); - if (!MPLS_LABEL_IS_NULL (l)) - { - fp (out, " Label: %d", l); - if (nlines == 1) - nlines++; - } - } - if (nlines > 1) - fp (out, "%s", HVTYNL); - - return 1; + rfapiFormatSeconds(age, buf_age, BUFSIZ); + + fp(out, "%-10s ", buf_age); + + } else if (RFAPI_LOCAL_BI(bi)) { + + char buf_age[BUFSIZ]; + + if (bi && bi->extra && bi->extra->vnc.import.create_time) { + rfapiFormatAge(bi->extra->vnc.import.create_time, + buf_age, BUFSIZ); + } else { + buf_age[0] = '?'; + buf_age[1] = 0; + } + fp(out, "%-10s ", buf_age); + } + fp(out, "%s", HVTYNL); + + if (rn->p.family == AF_ETHERNET) { + /* + * If there is a corresponding IP address && != VN address, + * print that on the next line + */ + + if (bi && bi->extra + && bi->extra->vnc.import.aux_prefix.family) { + const char *sp; + + sp = rfapi_ntop( + bi->extra->vnc.import.aux_prefix.family, + &bi->extra->vnc.import.aux_prefix.u.prefix, + buf_ntop, BUFSIZ); + buf_ntop[BUFSIZ - 1] = 0; + + if (sp && strcmp(buf_vn, sp) != 0) { + fp(out, " IP: %s", sp); + if (nlines == 1) + nlines++; + } + } + } + if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra) { + u_int32_t l = decode_label(&bi->extra->label); + if (!MPLS_LABEL_IS_NULL(l)) { + fp(out, " Label: %d", l); + if (nlines == 1) + nlines++; + } + } + if (nlines > 1) + fp(out, "%s", HVTYNL); + + return 1; } -static int -rfapiShowRemoteRegistrationsIt ( - struct bgp *bgp, - void *stream, - struct rfapi_import_table *it, - struct prefix *prefix_only, - int show_expiring, /* either/or */ - int show_local, - int show_remote, - int show_imported, /* either/or */ - uint32_t *pLni) /* AFI_L2VPN only */ +static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream, + struct rfapi_import_table *it, + struct prefix *prefix_only, + int show_expiring, /* either/or */ + int show_local, int show_remote, + int show_imported, /* either/or */ + uint32_t *pLni) /* AFI_L2VPN only */ { - afi_t afi; - int printed_rtlist_hdr = 0; - - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; - int total = 0; - int printed = 0; - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return printed; - - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - - struct route_node *rn; - - if (!it->imported_vpn[afi]) - continue; - - for (rn = route_top (it->imported_vpn[afi]); rn; rn = route_next (rn)) - { - - struct bgp_info *bi; - int count_only; - - /* allow for wider or more narrow mask from user */ - if (prefix_only && - !prefix_match (prefix_only, &rn->p) && - !prefix_match (&rn->p, prefix_only)) - count_only = 1; - else - count_only = 0; - - for (bi = rn->info; bi; bi = bi->next) - { - - if (!show_local && RFAPI_LOCAL_BI (bi)) - { - - /* local route from RFP */ - continue; - } - - if (!show_remote && !RFAPI_LOCAL_BI (bi)) - { - - /* remote route */ - continue; - } - - if (show_expiring && !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; - - if (!show_expiring && CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; - - if (bi->type == ZEBRA_ROUTE_BGP_DIRECT || - bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) - { - if (!show_imported) - continue; - } - else - { - if (show_imported) - continue; - } - - total++; - if (count_only == 1) - continue; - if (!printed_rtlist_hdr) - { - const char *agetype = ""; - char *s; - const char *type = ""; - if (show_imported) - { - type = "Imported"; - } - else - { - if (show_expiring) - { - type = "Holddown"; - } - else - { - if (RFAPI_LOCAL_BI (bi)) - { - type = "Local"; - } - else - { - type = "Remote"; - } - } - } - - s = ecommunity_ecom2str (it->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - - if (pLni) - { - fp (out, "%s[%s] L2VPN Network 0x%x (%u) RT={%s}", - HVTYNL, type, *pLni, (*pLni & 0xfff), s); - } - else - { - fp (out, "%s[%s] Prefix RT={%s}", - HVTYNL, type, s); - } - XFREE (MTYPE_ECOMMUNITY_STR, s); - - if (it->rfg && it->rfg->name) - { - fp (out, " %s \"%s\"", - (it->rfg->type == RFAPI_GROUP_CFG_VRF ? - "VRF" : "NVE group"), - it->rfg->name); - } - fp (out, "%s", HVTYNL); - if (show_expiring) - { + afi_t afi; + int printed_rtlist_hdr = 0; + + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + int total = 0; + int printed = 0; + + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return printed; + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + + struct route_node *rn; + + if (!it->imported_vpn[afi]) + continue; + + for (rn = route_top(it->imported_vpn[afi]); rn; + rn = route_next(rn)) { + + struct bgp_info *bi; + int count_only; + + /* allow for wider or more narrow mask from user */ + if (prefix_only && !prefix_match(prefix_only, &rn->p) + && !prefix_match(&rn->p, prefix_only)) + count_only = 1; + else + count_only = 0; + + for (bi = rn->info; bi; bi = bi->next) { + + if (!show_local && RFAPI_LOCAL_BI(bi)) { + + /* local route from RFP */ + continue; + } + + if (!show_remote && !RFAPI_LOCAL_BI(bi)) { + + /* remote route */ + continue; + } + + if (show_expiring + && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + continue; + + if (!show_expiring + && CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + continue; + + if (bi->type == ZEBRA_ROUTE_BGP_DIRECT + || bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) { + if (!show_imported) + continue; + } else { + if (show_imported) + continue; + } + + total++; + if (count_only == 1) + continue; + if (!printed_rtlist_hdr) { + const char *agetype = ""; + char *s; + const char *type = ""; + if (show_imported) { + type = "Imported"; + } else { + if (show_expiring) { + type = "Holddown"; + } else { + if (RFAPI_LOCAL_BI( + bi)) { + type = "Local"; + } else { + type = "Remote"; + } + } + } + + s = ecommunity_ecom2str( + it->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + + if (pLni) { + fp(out, + "%s[%s] L2VPN Network 0x%x (%u) RT={%s}", + HVTYNL, type, *pLni, + (*pLni & 0xfff), s); + } else { + fp(out, "%s[%s] Prefix RT={%s}", + HVTYNL, type, s); + } + XFREE(MTYPE_ECOMMUNITY_STR, s); + + if (it->rfg && it->rfg->name) { + fp(out, " %s \"%s\"", + (it->rfg->type == RFAPI_GROUP_CFG_VRF + ? "VRF" + : "NVE group"), + it->rfg->name); + } + fp(out, "%s", HVTYNL); + if (show_expiring) { #if RFAPI_REGISTRATIONS_REPORT_AGE - agetype = "Age"; + agetype = "Age"; #else - agetype = "Remaining"; + agetype = "Remaining"; #endif - } - else if (show_local) - { - agetype = "Age"; - } - - printed_rtlist_hdr = 1; - - fp (out, "%-20s %-15s %-15s %4s %-10s %-10s%s", - (pLni ? "L2 Address/IP" : "Prefix"), - "VN Address", "UN Address", "Cost", - "Lifetime", agetype, HVTYNL); - } - printed += rfapiPrintRemoteRegBi (bgp, stream, rn, bi); - } - } - } - - if (printed > 0) - { - - const char *type = "prefixes"; - - if (show_imported) - { - type = "imported prefixes"; - } - else - { - if (show_expiring) - { - type = "prefixes in holddown"; - } - else - { - if (show_local && !show_remote) - { - type = "locally registered prefixes"; - } - else if (!show_local && show_remote) - { - type = "remotely registered prefixes"; - } - } - } - - fp (out, "Displayed %d out of %d %s%s", - printed, total, type, HVTYNL); + } else if (show_local) { + agetype = "Age"; + } + + printed_rtlist_hdr = 1; + + fp(out, + "%-20s %-15s %-15s %4s %-10s %-10s%s", + (pLni ? "L2 Address/IP" : "Prefix"), + "VN Address", "UN Address", "Cost", + "Lifetime", agetype, HVTYNL); + } + printed += rfapiPrintRemoteRegBi(bgp, stream, + rn, bi); + } + } + } + + if (printed > 0) { + + const char *type = "prefixes"; + + if (show_imported) { + type = "imported prefixes"; + } else { + if (show_expiring) { + type = "prefixes in holddown"; + } else { + if (show_local && !show_remote) { + type = "locally registered prefixes"; + } else if (!show_local && show_remote) { + type = "remotely registered prefixes"; + } + } + } + + fp(out, "Displayed %d out of %d %s%s", printed, total, type, + HVTYNL); #if DEBUG_SHOW_EXTRA - fp(out, "IT table above: it=%p%s", it, HVTYNL); + fp(out, "IT table above: it=%p%s", it, HVTYNL); #endif - } - return printed; + } + return printed; } - /* * rfapiShowRemoteRegistrations * @@ -1521,70 +1370,56 @@ rfapiShowRemoteRegistrationsIt ( * is mean to produce the "remote" portion of the output * of "show vnc registrations". */ -int -rfapiShowRemoteRegistrations ( - void *stream, - struct prefix *prefix_only, - int show_expiring, - int show_local, - int show_remote, - int show_imported) +int rfapiShowRemoteRegistrations(void *stream, struct prefix *prefix_only, + int show_expiring, int show_local, + int show_remote, int show_imported) { - struct bgp *bgp; - struct rfapi *h; - struct rfapi_import_table *it; - int printed = 0; - - bgp = bgp_get_default (); - if (!bgp) - { - return printed; - } - - h = bgp->rfapi; - if (!h) - { - return printed; - } - - for (it = h->imports; it; it = it->next) - { - printed += - rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only, - show_expiring, show_local, - show_remote, show_imported, NULL); - } - - if (h->import_mac) - { - void *cursor = NULL; - int rc; - uintptr_t lni_as_ptr; - uint32_t lni; - uint32_t *pLni; - - for (rc = - skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, - &cursor); !rc; - rc = - skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, - &cursor)) - { - pLni = NULL; - if ((lni_as_ptr & 0xffffffff) == lni_as_ptr) - { - lni = (uint32_t) (lni_as_ptr & 0xffffffff); - pLni = &lni; - } - - printed += - rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only, - show_expiring, show_local, - show_remote, show_imported, pLni); - } - } - - return printed; + struct bgp *bgp; + struct rfapi *h; + struct rfapi_import_table *it; + int printed = 0; + + bgp = bgp_get_default(); + if (!bgp) { + return printed; + } + + h = bgp->rfapi; + if (!h) { + return printed; + } + + for (it = h->imports; it; it = it->next) { + printed += rfapiShowRemoteRegistrationsIt( + bgp, stream, it, prefix_only, show_expiring, show_local, + show_remote, show_imported, NULL); + } + + if (h->import_mac) { + void *cursor = NULL; + int rc; + uintptr_t lni_as_ptr; + uint32_t lni; + uint32_t *pLni; + + for (rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr, + (void **)&it, &cursor); + !rc; + rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr, + (void **)&it, &cursor)) { + pLni = NULL; + if ((lni_as_ptr & 0xffffffff) == lni_as_ptr) { + lni = (uint32_t)(lni_as_ptr & 0xffffffff); + pLni = &lni; + } + + printed += rfapiShowRemoteRegistrationsIt( + bgp, stream, it, prefix_only, show_expiring, + show_local, show_remote, show_imported, pLni); + } + } + + return printed; } /*------------------------------------------ @@ -1592,7 +1427,7 @@ rfapiShowRemoteRegistrations ( * * UI helper: generate string from rfapi_ip_addr * - * input: + * input: * a IP v4/v6 address * * output @@ -1603,385 +1438,342 @@ rfapiShowRemoteRegistrations ( * NULL conversion failed * non-NULL pointer to buf --------------------------------------------*/ -const char * -rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize) +const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr *a, char *buf, + int bufsize) { - const char *rc = NULL; - - switch (a->addr_family) - { - case AF_INET: - rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize); - break; - case AF_INET6: - rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize); - break; - } - return rc; + const char *rc = NULL; + + switch (a->addr_family) { + case AF_INET: + rc = inet_ntop(a->addr_family, &a->addr.v4, buf, bufsize); + break; + case AF_INET6: + rc = inet_ntop(a->addr_family, &a->addr.v6, buf, bufsize); + break; + } + return rc; } -void -rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a) +void rfapiPrintRfapiIpAddr(void *stream, struct rfapi_ip_addr *a) { - char buf[BUFSIZ]; - const char *rc = NULL; + char buf[BUFSIZ]; + const char *rc = NULL; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out = NULL; - const char *vty_newline; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out = NULL; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; - rc = rfapiRfapiIpAddr2Str (a, buf, BUFSIZ); + rc = rfapiRfapiIpAddr2Str(a, buf, BUFSIZ); - if (rc) - fp (out, "%s", buf); + if (rc) + fp(out, "%s", buf); } -const char * -rfapiRfapiIpPrefix2Str (struct rfapi_ip_prefix *p, char *buf, int bufsize) +const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix *p, char *buf, + int bufsize) { - struct rfapi_ip_addr *a = &p->prefix; - const char *rc = NULL; - - switch (a->addr_family) - { - case AF_INET: - rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize); - break; - case AF_INET6: - rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize); - break; - } - - if (rc) - { - int alen = strlen (buf); - int remaining = bufsize - alen - 1; - int slen; - - if (remaining > 0) - { - slen = snprintf (buf + alen, remaining, "/%u", p->length); - if (slen < remaining) /* see man page for snprintf(3) */ - return rc; - } - } - - return NULL; + struct rfapi_ip_addr *a = &p->prefix; + const char *rc = NULL; + + switch (a->addr_family) { + case AF_INET: + rc = inet_ntop(a->addr_family, &a->addr.v4, buf, bufsize); + break; + case AF_INET6: + rc = inet_ntop(a->addr_family, &a->addr.v6, buf, bufsize); + break; + } + + if (rc) { + int alen = strlen(buf); + int remaining = bufsize - alen - 1; + int slen; + + if (remaining > 0) { + slen = snprintf(buf + alen, remaining, "/%u", + p->length); + if (slen < remaining) /* see man page for snprintf(3) */ + return rc; + } + } + + return NULL; } -void -rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p) +void rfapiPrintRfapiIpPrefix(void *stream, struct rfapi_ip_prefix *p) { - char buf[BUFSIZ]; - const char *rc; + char buf[BUFSIZ]; + const char *rc; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out = NULL; - const char *vty_newline; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out = NULL; + const char *vty_newline; - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; - rc = rfapiRfapiIpPrefix2Str (p, buf, BUFSIZ); + rc = rfapiRfapiIpPrefix2Str(p, buf, BUFSIZ); - if (rc) - fp (out, "%s:%u", buf, p->cost); - else - fp (out, "?/?:?"); + if (rc) + fp(out, "%s:%u", buf, p->cost); + else + fp(out, "?/?:?"); } -void -rfapiPrintRd (struct vty *vty, struct prefix_rd *prd) +void rfapiPrintRd(struct vty *vty, struct prefix_rd *prd) { - char buf[BUFSIZ]; + char buf[BUFSIZ]; - buf[0] = 0; - prefix_rd2str (prd, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vty_out (vty, "%s", buf); + buf[0] = 0; + prefix_rd2str(prd, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vty_out(vty, "%s", buf); } -void -rfapiPrintAdvertisedInfo ( - struct vty *vty, - struct rfapi_descriptor *rfd, - safi_t safi, - struct prefix *p) +void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd, + safi_t safi, struct prefix *p) { - afi_t afi; /* of the VN address */ - struct bgp_node *bn; - struct bgp_info *bi; - uint8_t type = ZEBRA_ROUTE_BGP; - struct bgp *bgp; - int printed = 0; - struct prefix_rd prd0; - struct prefix_rd *prd; - - /* - * Find the bgp_info in the RIB corresponding to this - * prefix and rfd - */ - - afi = family2afi (p->family); - assert (afi == AFI_IP || afi == AFI_IP6); - - bgp = bgp_get_default (); /* assume 1 instance for now */ - assert (bgp); - - if (safi == SAFI_ENCAP) - { - memset (&prd0, 0, sizeof (prd0)); - prd0.family = AF_UNSPEC; - prd0.prefixlen = 64; - prd = &prd0; - } - else - { - prd = &rfd->rd; - } - bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); - - vty_out (vty, " bn=%p%s", bn, HVTYNL); - - for (bi = bn->info; bi; bi = bi->next) - { - if (bi->peer == rfd->peer && - bi->type == type && - bi->sub_type == BGP_ROUTE_RFP && - bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd) - { - - rfapiPrintBi (vty, bi); - printed = 1; - } - } - - if (!printed) - { - vty_out (vty, " --?--%s", HVTYNL); - return; - } - + afi_t afi; /* of the VN address */ + struct bgp_node *bn; + struct bgp_info *bi; + uint8_t type = ZEBRA_ROUTE_BGP; + struct bgp *bgp; + int printed = 0; + struct prefix_rd prd0; + struct prefix_rd *prd; + + /* + * Find the bgp_info in the RIB corresponding to this + * prefix and rfd + */ + + afi = family2afi(p->family); + assert(afi == AFI_IP || afi == AFI_IP6); + + bgp = bgp_get_default(); /* assume 1 instance for now */ + assert(bgp); + + if (safi == SAFI_ENCAP) { + memset(&prd0, 0, sizeof(prd0)); + prd0.family = AF_UNSPEC; + prd0.prefixlen = 64; + prd = &prd0; + } else { + prd = &rfd->rd; + } + bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); + + vty_out(vty, " bn=%p%s", bn, HVTYNL); + + for (bi = bn->info; bi; bi = bi->next) { + if (bi->peer == rfd->peer && bi->type == type + && bi->sub_type == BGP_ROUTE_RFP && bi->extra + && bi->extra->vnc.export.rfapi_handle == (void *)rfd) { + + rfapiPrintBi(vty, bi); + printed = 1; + } + } + + if (!printed) { + vty_out(vty, " --?--%s", HVTYNL); + return; + } } -void -rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd) +void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd) { - /* pHD un-addr vn-addr pCB cookie rd lifetime */ - /* RT export list */ - /* RT import list */ - /* list of advertised prefixes */ - /* dump import table */ - - char *s; - void *cursor; - int rc; - afi_t afi; - struct rfapi_adb *adb; - char buf[BUFSIZ]; - - vty_out (vty, "%-10p ", rfd); - rfapiPrintRfapiIpAddr (vty, &rfd->un_addr); - vty_out (vty, " "); - rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr); - vty_out (vty, " %p %p ", rfd->response_cb, rfd->cookie); - rfapiPrintRd (vty, &rfd->rd); - vty_out (vty, " %d", rfd->response_lifetime); - vty_out (vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>")); - vty_out (vty, "%s", HVTYNL); - - vty_out (vty, " Peer %p #%d%s", rfd->peer, rfd->peer->lock, HVTYNL); - - /* export RT list */ - if (rfd->rt_export_list) - { - s = - ecommunity_ecom2str (rfd->rt_export_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out (vty, " Export %s%s", s, HVTYNL); - XFREE (MTYPE_ECOMMUNITY_STR, s); - } - else - { - vty_out (vty, " Export (nil)%s", HVTYNL); - } - - /* import RT list */ - if (rfd->import_table) - { - s = ecommunity_ecom2str (rfd->import_table->rt_import_list, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - vty_out (vty, " Import %s%s", s, HVTYNL); - XFREE (MTYPE_ECOMMUNITY_STR, s); - } - else - { - vty_out (vty, " Import (nil)%s", HVTYNL); - } - - for (afi = AFI_IP; afi < AFI_MAX; ++afi) - { - u_char family; - - family = afi2family (afi); - if (!family) - continue; - - cursor = NULL; - for (rc = - skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb, - &cursor); rc == 0; - rc = - skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb, - &cursor)) - { - - /* group like family prefixes together in output */ - if (family != adb->u.s.prefix_ip.family) - continue; - - prefix2str (&adb->u.s.prefix_ip, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ - - vty_out (vty, " Adv Pfx: %s%s", buf, HVTYNL); - rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip); - } - } - for (rc = - skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb, - &cursor); rc == 0; - rc = - skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb, - &cursor)) - { - - prefix2str (&adb->u.s.prefix_eth, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ - - vty_out (vty, " Adv Pfx: %s%s", buf, HVTYNL); - - /* TBD update the following function to print ethernet info */ - /* Also need to pass/use rd */ - rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip); - } - vty_out (vty, "%s", HVTYNL); + /* pHD un-addr vn-addr pCB cookie rd lifetime */ + /* RT export list */ + /* RT import list */ + /* list of advertised prefixes */ + /* dump import table */ + + char *s; + void *cursor; + int rc; + afi_t afi; + struct rfapi_adb *adb; + char buf[BUFSIZ]; + + vty_out(vty, "%-10p ", rfd); + rfapiPrintRfapiIpAddr(vty, &rfd->un_addr); + vty_out(vty, " "); + rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr); + vty_out(vty, " %p %p ", rfd->response_cb, rfd->cookie); + rfapiPrintRd(vty, &rfd->rd); + vty_out(vty, " %d", rfd->response_lifetime); + vty_out(vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>")); + vty_out(vty, "%s", HVTYNL); + + vty_out(vty, " Peer %p #%d%s", rfd->peer, rfd->peer->lock, HVTYNL); + + /* export RT list */ + if (rfd->rt_export_list) { + s = ecommunity_ecom2str(rfd->rt_export_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vty_out(vty, " Export %s%s", s, HVTYNL); + XFREE(MTYPE_ECOMMUNITY_STR, s); + } else { + vty_out(vty, " Export (nil)%s", HVTYNL); + } + + /* import RT list */ + if (rfd->import_table) { + s = ecommunity_ecom2str(rfd->import_table->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + vty_out(vty, " Import %s%s", s, HVTYNL); + XFREE(MTYPE_ECOMMUNITY_STR, s); + } else { + vty_out(vty, " Import (nil)%s", HVTYNL); + } + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + u_char family; + + family = afi2family(afi); + if (!family) + continue; + + cursor = NULL; + for (rc = skiplist_next(rfd->advertised.ipN_by_prefix, NULL, + (void **)&adb, &cursor); + rc == 0; + rc = skiplist_next(rfd->advertised.ipN_by_prefix, NULL, + (void **)&adb, &cursor)) { + + /* group like family prefixes together in output */ + if (family != adb->u.s.prefix_ip.family) + continue; + + prefix2str(&adb->u.s.prefix_ip, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + + vty_out(vty, " Adv Pfx: %s%s", buf, HVTYNL); + rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN, + &adb->u.s.prefix_ip); + } + } + for (rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL, + (void **)&adb, &cursor); + rc == 0; rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL, + (void **)&adb, &cursor)) { + + prefix2str(&adb->u.s.prefix_eth, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + + vty_out(vty, " Adv Pfx: %s%s", buf, HVTYNL); + + /* TBD update the following function to print ethernet info */ + /* Also need to pass/use rd */ + rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN, + &adb->u.s.prefix_ip); + } + vty_out(vty, "%s", HVTYNL); } /* * test scripts rely on first line for each nve starting in 1st column, * leading whitespace for additional detail of that nve */ -void -rfapiPrintMatchingDescriptors (struct vty *vty, - struct prefix *vn_prefix, - struct prefix *un_prefix) +void rfapiPrintMatchingDescriptors(struct vty *vty, struct prefix *vn_prefix, + struct prefix *un_prefix) { - struct bgp *bgp; - struct rfapi *h; - struct listnode *ln; - struct rfapi_descriptor *rfd; - int printed = 0; - - bgp = bgp_get_default (); /* assume 1 instance for now */ - if (!bgp) - return; - - h = bgp->rfapi; - assert (h); - - for (ln = listhead (&h->descriptors); ln; ln = listnextnode (ln)) - { - rfd = listgetdata (ln); - - struct prefix pfx; - - if (vn_prefix) - { - assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx)); - if (!prefix_match (vn_prefix, &pfx)) - continue; - } - - if (un_prefix) - { - assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx)); - if (!prefix_match (un_prefix, &pfx)) - continue; - } - - if (!printed) - { - /* print column header */ - vty_out (vty, - "%s %s %s %s %s %s %s %s%s", - "descriptor", "un-addr", "vn-addr", "callback", "cookie", - "RD", "lifetime", "group", HVTYNL); - } - rfapiPrintDescriptor (vty, rfd); - printed = 1; - } + struct bgp *bgp; + struct rfapi *h; + struct listnode *ln; + struct rfapi_descriptor *rfd; + int printed = 0; + + bgp = bgp_get_default(); /* assume 1 instance for now */ + if (!bgp) + return; + + h = bgp->rfapi; + assert(h); + + for (ln = listhead(&h->descriptors); ln; ln = listnextnode(ln)) { + rfd = listgetdata(ln); + + struct prefix pfx; + + if (vn_prefix) { + assert(!rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx)); + if (!prefix_match(vn_prefix, &pfx)) + continue; + } + + if (un_prefix) { + assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx)); + if (!prefix_match(un_prefix, &pfx)) + continue; + } + + if (!printed) { + /* print column header */ + vty_out(vty, "%s %s %s %s %s %s %s %s%s", "descriptor", + "un-addr", "vn-addr", "callback", "cookie", + "RD", "lifetime", "group", HVTYNL); + } + rfapiPrintDescriptor(vty, rfd); + printed = 1; + } } /* * Parse an address and put into a struct prefix */ -int -rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p) +int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, struct prefix *p) { - if (!str2prefix (str, p)) - { - vty_out (vty, "Malformed address \"%s\"%s", str, HVTYNL); - return CMD_WARNING; - } - switch (p->family) - { - case AF_INET: - if (p->prefixlen != 32) - { - vty_out (vty, "Not a host address: \"%s\"%s", str, HVTYNL); - return CMD_WARNING; - } - break; - case AF_INET6: - if (p->prefixlen != 128) - { - vty_out (vty, "Not a host address: \"%s\"%s", str, HVTYNL); - return CMD_WARNING; - } - break; - default: - vty_out (vty, "Invalid address \"%s\"%s", str, HVTYNL); - return CMD_WARNING; - } - return 0; + if (!str2prefix(str, p)) { + vty_out(vty, "Malformed address \"%s\"%s", str, HVTYNL); + return CMD_WARNING; + } + switch (p->family) { + case AF_INET: + if (p->prefixlen != 32) { + vty_out(vty, "Not a host address: \"%s\"%s", str, + HVTYNL); + return CMD_WARNING; + } + break; + case AF_INET6: + if (p->prefixlen != 128) { + vty_out(vty, "Not a host address: \"%s\"%s", str, + HVTYNL); + return CMD_WARNING; + } + break; + default: + vty_out(vty, "Invalid address \"%s\"%s", str, HVTYNL); + return CMD_WARNING; + } + return 0; } -int -rfapiCliGetRfapiIpAddr ( - struct vty *vty, - const char *str, - struct rfapi_ip_addr *hai) +int rfapiCliGetRfapiIpAddr(struct vty *vty, const char *str, + struct rfapi_ip_addr *hai) { - struct prefix pfx; - int rc; + struct prefix pfx; + int rc; - rc = rfapiCliGetPrefixAddr (vty, str, &pfx); - if (rc) - return rc; + rc = rfapiCliGetPrefixAddr(vty, str, &pfx); + if (rc) + return rc; - hai->addr_family = pfx.family; - if (pfx.family == AF_INET) - hai->addr.v4 = pfx.u.prefix4; - else - hai->addr.v6 = pfx.u.prefix6; + hai->addr_family = pfx.family; + if (pfx.family == AF_INET) + hai->addr.v4 = pfx.u.prefix4; + else + hai->addr.v6 = pfx.u.prefix6; - return 0; + return 0; } /* @@ -1989,137 +1781,125 @@ rfapiCliGetRfapiIpAddr ( * with a stream pointing to a vty, the user will have to type something * before the callback output shows up */ -void -rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops) +void rfapiPrintNhl(void *stream, struct rfapi_next_hop_entry *next_hops) { - struct rfapi_next_hop_entry *nh; - int count; + struct rfapi_next_hop_entry *nh; + int count; - int (*fp) (void *, const char *, ...); - struct vty *vty; - void *out; - const char *vty_newline; + int (*fp)(void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; #define REMAIN (BUFSIZ - (p-line)) #define INCP {p += (r > REMAIN)? REMAIN: r;} - - if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) - return; - - for (nh = next_hops, count = 1; nh; nh = nh->next, ++count) - { - - char line[BUFSIZ]; - char *p = line; - int r; - - r = snprintf (p, REMAIN, "%3d pfx=", count); - INCP; - - if (rfapiRfapiIpPrefix2Str (&nh->prefix, p, REMAIN)) - { - /* it fit, so count length */ - r = strlen (p); - } - else - { - /* didn't fit */ - goto truncate; - } - INCP; - - r = snprintf (p, REMAIN, ", un="); - INCP; - - if (rfapiRfapiIpAddr2Str (&nh->un_address, p, REMAIN)) - { - /* it fit, so count length */ - r = strlen (p); - } - else - { - /* didn't fit */ - goto truncate; - } - INCP; - - r = snprintf (p, REMAIN, ", vn="); - INCP; - - if (rfapiRfapiIpAddr2Str (&nh->vn_address, p, REMAIN)) - { - /* it fit, so count length */ - r = strlen (p); - } - else - { - /* didn't fit */ - goto truncate; - } - INCP; - - truncate: - line[BUFSIZ - 1] = 0; - fp (out, "%s%s", line, HVTYNL); - - /* - * options - */ - if (nh->vn_options) - { - struct rfapi_vn_option *vo; - char offset[] = " "; - - for (vo = nh->vn_options; vo; vo = vo->next) - { - char pbuf[100]; - - switch (vo->type) - { - case RFAPI_VN_OPTION_TYPE_L2ADDR: - rfapiEthAddr2Str (&vo->v.l2addr.macaddr, pbuf, - sizeof (pbuf)); - fp (out, "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s", - offset, pbuf, (vo->v.l2addr.label & 0x00ffffff), - (vo->v.l2addr.logical_net_id & 0x00ffffff), - vo->v.l2addr.local_nve_id, HVTYNL); - break; - - case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP: - prefix2str (&vo->v.local_nexthop.addr, pbuf, sizeof (pbuf)); - fp (out, "%sLNH %s cost=%d%s", - offset, pbuf, vo->v.local_nexthop.cost, HVTYNL); - break; - - default: - fp (out, "%svn option type %d (unknown)%s", - offset, vo->type, HVTYNL); - break; - } - } - } - if (nh->un_options) - { - struct rfapi_un_option *uo; - char offset[] = " "; - - for (uo = nh->un_options; uo; uo = uo->next) - { - switch (uo->type) - { - case RFAPI_UN_OPTION_TYPE_TUNNELTYPE: - rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel); - break; - default: - fp (out, "%sUN Option type %d%s", - offset, uo->type, vty_newline); - break; - } - - } - } - } + if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + for (nh = next_hops, count = 1; nh; nh = nh->next, ++count) { + + char line[BUFSIZ]; + char *p = line; + int r; + + r = snprintf(p, REMAIN, "%3d pfx=", count); + INCP; + + if (rfapiRfapiIpPrefix2Str(&nh->prefix, p, REMAIN)) { + /* it fit, so count length */ + r = strlen(p); + } else { + /* didn't fit */ + goto truncate; + } + INCP; + + r = snprintf(p, REMAIN, ", un="); + INCP; + + if (rfapiRfapiIpAddr2Str(&nh->un_address, p, REMAIN)) { + /* it fit, so count length */ + r = strlen(p); + } else { + /* didn't fit */ + goto truncate; + } + INCP; + + r = snprintf(p, REMAIN, ", vn="); + INCP; + + if (rfapiRfapiIpAddr2Str(&nh->vn_address, p, REMAIN)) { + /* it fit, so count length */ + r = strlen(p); + } else { + /* didn't fit */ + goto truncate; + } + INCP; + + truncate: + line[BUFSIZ - 1] = 0; + fp(out, "%s%s", line, HVTYNL); + + /* + * options + */ + if (nh->vn_options) { + struct rfapi_vn_option *vo; + char offset[] = " "; + + for (vo = nh->vn_options; vo; vo = vo->next) { + char pbuf[100]; + + switch (vo->type) { + case RFAPI_VN_OPTION_TYPE_L2ADDR: + rfapiEthAddr2Str(&vo->v.l2addr.macaddr, + pbuf, sizeof(pbuf)); + fp(out, + "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s", + offset, pbuf, + (vo->v.l2addr.label & 0x00ffffff), + (vo->v.l2addr.logical_net_id + & 0x00ffffff), + vo->v.l2addr.local_nve_id, HVTYNL); + break; + + case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP: + prefix2str(&vo->v.local_nexthop.addr, + pbuf, sizeof(pbuf)); + fp(out, "%sLNH %s cost=%d%s", offset, + pbuf, vo->v.local_nexthop.cost, + HVTYNL); + break; + + default: + fp(out, + "%svn option type %d (unknown)%s", + offset, vo->type, HVTYNL); + break; + } + } + } + if (nh->un_options) { + struct rfapi_un_option *uo; + char offset[] = " "; + + for (uo = nh->un_options; uo; uo = uo->next) { + switch (uo->type) { + case RFAPI_UN_OPTION_TYPE_TUNNELTYPE: + rfapi_print_tunneltype_option( + stream, 8, &uo->v.tunnel); + break; + default: + fp(out, "%sUN Option type %d%s", offset, + uo->type, vty_newline); + break; + } + } + } + } } /*********************************************************************** @@ -2129,397 +1909,350 @@ rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops) /* * Add another nexthop to the NHL */ -static void -rfapiAddDeleteLocalRfpPrefix ( - struct rfapi_ip_addr *un_addr, - struct rfapi_ip_addr *vn_addr, - struct rfapi_ip_prefix *rprefix, - int is_add, - uint32_t lifetime, /* add only */ - struct rfapi_vn_option *vn_options, - struct rfapi_next_hop_entry **head, - struct rfapi_next_hop_entry **tail) +static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr *un_addr, + struct rfapi_ip_addr *vn_addr, + struct rfapi_ip_prefix *rprefix, + int is_add, + uint32_t lifetime, /* add only */ + struct rfapi_vn_option *vn_options, + struct rfapi_next_hop_entry **head, + struct rfapi_next_hop_entry **tail) { - struct rfapi_next_hop_entry *new; - - /* - * construct NHL - */ - - new = XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_next_hop_entry)); - new->prefix = *rprefix; - new->un_address = *un_addr; - new->vn_address = *vn_addr; - - new->vn_options = vn_options; - if (is_add) - { - new->lifetime = lifetime; - } - else - { - new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; - } - - if (*tail) - (*tail)->next = new; - *tail = new; - if (!*head) - { - *head = new; - } + struct rfapi_next_hop_entry *new; + + /* + * construct NHL + */ + + new = XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_next_hop_entry)); + new->prefix = *rprefix; + new->un_address = *un_addr; + new->vn_address = *vn_addr; + + new->vn_options = vn_options; + if (is_add) { + new->lifetime = lifetime; + } else { + new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; + } + + if (*tail) + (*tail)->next = new; + *tail = new; + if (!*head) { + *head = new; + } } static int -register_add ( - struct vty *vty, - struct cmd_token *carg_prefix, - struct cmd_token *carg_vn, - struct cmd_token *carg_un, - struct cmd_token *carg_cost, /* optional */ - struct cmd_token *carg_lifetime, /* optional */ - struct cmd_token *carg_macaddr, /* optional */ - struct cmd_token *carg_vni, /* mac present=>mandatory Virtual Network ID */ - int argc, - struct cmd_token **argv) +register_add(struct vty *vty, struct cmd_token *carg_prefix, + struct cmd_token *carg_vn, struct cmd_token *carg_un, + struct cmd_token *carg_cost, /* optional */ + struct cmd_token *carg_lifetime, /* optional */ + struct cmd_token *carg_macaddr, /* optional */ + struct cmd_token + *carg_vni, /* mac present=>mandatory Virtual Network ID */ + int argc, struct cmd_token **argv) { - const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL; - const char *arg_vn = carg_vn ? carg_vn->arg : NULL; - const char *arg_un = carg_un ? carg_un->arg : NULL; - const char *arg_cost = carg_cost ? carg_cost->arg : NULL; - const char *arg_lifetime = carg_lifetime ? carg_lifetime->arg : NULL; - const char *arg_macaddr = carg_macaddr ? carg_macaddr->arg : NULL; - const char *arg_vni = carg_vni ? carg_vni->arg : NULL; - struct rfapi_ip_addr vn_address; - struct rfapi_ip_addr un_address; - struct prefix pfx; - struct rfapi_ip_prefix rpfx; - uint32_t cost; - uint32_t lnh_cost; - uint32_t lifetime; - rfapi_handle rfd; - struct rfapi_vn_option optary[10]; /* XXX must be big enough */ - struct rfapi_vn_option *opt = NULL; - int opt_next = 0; - - int rc = CMD_WARNING_CONFIG_FAILED; - char *endptr; - struct bgp *bgp; - struct rfapi *h; - struct rfapi_cfg *rfapi_cfg; - - const char *arg_lnh = NULL; - const char *arg_lnh_cost = NULL; - - bgp = bgp_get_default (); /* assume 1 instance for now */ - if (!bgp) - { - if (vty) - vty_out (vty, "BGP not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - h = bgp->rfapi; - rfapi_cfg = bgp->rfapi_cfg; - if (!h || !rfapi_cfg) - { - if (vty) - vty_out (vty, "RFAPI not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - for (; argc; --argc, ++argv) - { - if (strmatch(argv[0]->text, "local-next-hop")) - { - if (arg_lnh) - { - vty_out (vty,"local-next-hop specified more than once\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (argc <= 1) - { - vty_out (vty,"Missing parameter for local-next-hop\n"); - return CMD_WARNING_CONFIG_FAILED; - } - ++argv, --argc; - arg_lnh = argv[0]->arg; - } - if (strmatch(argv[0]->text, "local-cost")) - { - if (arg_lnh_cost) - { - vty_out (vty,"local-cost specified more than once\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (argc <= 1) - { - vty_out (vty,"Missing parameter for local-cost\n"); - return CMD_WARNING_CONFIG_FAILED; - } - ++argv, --argc; - arg_lnh_cost = argv[0]->arg; - } - } - - if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &vn_address))) - goto fail; - if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &un_address))) - goto fail; - - /* arg_prefix is optional if mac address is given */ - if (arg_macaddr && !arg_prefix) - { - /* - * fake up a 0/32 or 0/128 prefix - */ - switch (vn_address.addr_family) - { - case AF_INET: - arg_prefix = "0.0.0.0/32"; - break; - case AF_INET6: - arg_prefix = "0::0/128"; - break; - default: - vty_out (vty,"Internal error, unknown VN address family\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - } - - if (!str2prefix (arg_prefix, &pfx)) - { - vty_out (vty, "Malformed prefix \"%s\"\n",arg_prefix); - goto fail; - } - if (pfx.family != AF_INET - && pfx.family != AF_INET6) - { - vty_out (vty, "prefix \"%s\" has invalid address family\n", - arg_prefix); - goto fail; - } - - - memset (optary, 0, sizeof (optary)); - - if (arg_cost) - { - endptr = NULL; - cost = strtoul (arg_cost, &endptr, 10); - if (*endptr != '\0' || cost > 255) - { - vty_out (vty, "%% Invalid %s value\n", "cost"); - goto fail; - } - } - else - { - cost = 255; - } - - if (arg_lifetime) - { - if (!strcmp (arg_lifetime, "infinite")) - { - lifetime = RFAPI_INFINITE_LIFETIME; - } - else - { - endptr = NULL; - lifetime = strtoul (arg_lifetime, &endptr, 10); - if (*endptr != '\0') - { - vty_out (vty, "%% Invalid %s value\n","lifetime"); - goto fail; - } - } - } - else - { - lifetime = RFAPI_INFINITE_LIFETIME; /* default infinite */ - } - - if (arg_lnh_cost) - { - if (!arg_lnh) - { - vty_out (vty, - "%% %s may only be specified with local-next-hop\n", - "local-cost"); - goto fail; - } - endptr = NULL; - lnh_cost = strtoul (arg_lnh_cost, &endptr, 10); - if (*endptr != '\0' || lnh_cost > 255) - { - vty_out (vty, "%% Invalid %s value\n","local-cost"); - goto fail; - } - } - else - { - lnh_cost = 255; - } - - if (arg_lnh) - { - if (!arg_prefix) - { - vty_out (vty, "%% %s may only be specified with prefix\n", - "local-next-hop"); - goto fail; - } - if ((rc = rfapiCliGetPrefixAddr (vty, arg_lnh, - &optary[opt_next].v. - local_nexthop.addr))) - { - - goto fail; - } - - optary[opt_next].v.local_nexthop.cost = lnh_cost; - optary[opt_next].type = RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP; - - if (opt_next) - { - optary[opt_next - 1].next = optary + opt_next; - } - else - { - opt = optary; - } - ++opt_next; - } - - if (arg_vni && !arg_macaddr) - { - vty_out (vty, "%% %s may only be specified with mac address\n", - "virtual-network-identifier"); - goto fail; - } - - if (arg_macaddr) - { - if (!arg_vni) - { - vty_out (vty, - "Missing \"vni\" parameter (mandatory with mac)\n"); - return CMD_WARNING_CONFIG_FAILED; - } - optary[opt_next].v.l2addr.logical_net_id = strtoul(arg_vni, NULL, - 10); - - if ((rc = rfapiStr2EthAddr (arg_macaddr, - &optary[opt_next].v.l2addr.macaddr))) - { - vty_out (vty, "Invalid %s value\n","mac address"); - goto fail; - } - /* TBD label, NVE ID */ - - optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; - - if (opt_next) - { - optary[opt_next - 1].next = optary + opt_next; - } - else - { - opt = optary; - } - ++opt_next; - } - - vnc_zlog_debug_verbose - ("%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s", - __func__, arg_vn, arg_un, arg_prefix, - (arg_cost ? arg_cost : "NULL"), - (arg_lifetime ? arg_lifetime : "NULL"), - (arg_lnh ? arg_lnh : "NULL")); - - rfapiQprefix2Rprefix (&pfx, &rpfx); - - rpfx.cost = cost & 255; - - /* look up rf descriptor, call open if it doesn't exist */ - rc = - rfapi_find_rfd (bgp, &vn_address, &un_address, - (struct rfapi_descriptor **) &rfd); - if (rc) - { - if (ENOENT == rc) - { - struct rfapi_un_option uo; - - /* - * flag descriptor as provisionally opened for static route - * registration so that we can fix up the other parameters - * when the real open comes along - */ - memset (&uo, 0, sizeof (uo)); - uo.type = RFAPI_UN_OPTION_TYPE_PROVISIONAL; - - rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp), &vn_address, &un_address, &uo, /* flags */ - NULL, NULL, /* no userdata */ - &rfd); - if (rc) - { - vty_out (vty, "Can't open session for this NVE: %s\n", - rfapi_error_str(rc)); - rc = CMD_WARNING_CONFIG_FAILED; - goto fail; - } - } - else - { - vty_out (vty, "Can't find session for this NVE: %s\n", - rfapi_error_str(rc)); - goto fail; - } - } - - rc = - rfapi_register (rfd, &rpfx, lifetime, NULL, opt, RFAPI_REGISTER_ADD); - if (!rc) - { - struct rfapi_next_hop_entry *head = NULL; - struct rfapi_next_hop_entry *tail = NULL; - struct rfapi_vn_option *vn_opt_new; - - vnc_zlog_debug_verbose ("%s: rfapi_register succeeded, returning 0", __func__); - - if (h->rfp_methods.local_cb) - { - struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfd; - vn_opt_new = rfapi_vn_options_dup (opt); - - rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx, - 1, lifetime, vn_opt_new, &head, - &tail); - if (head) - { - h->flags |= RFAPI_INCALLBACK; - (*h->rfp_methods.local_cb) (head, r->cookie); - h->flags &= ~RFAPI_INCALLBACK; - } - head = tail = NULL; - } - return 0; - } - - vnc_zlog_debug_verbose ("%s: rfapi_register failed", __func__); - vty_out (vty, "\n"); - vty_out (vty, "Registration failed.\n"); - vty_out (vty, - "Confirm that either the VN or UN address matches a configured NVE group.\n"); - return CMD_WARNING_CONFIG_FAILED; - - fail: - vnc_zlog_debug_verbose ("%s: fail, rc=%d", __func__, rc); - return rc; + const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL; + const char *arg_vn = carg_vn ? carg_vn->arg : NULL; + const char *arg_un = carg_un ? carg_un->arg : NULL; + const char *arg_cost = carg_cost ? carg_cost->arg : NULL; + const char *arg_lifetime = carg_lifetime ? carg_lifetime->arg : NULL; + const char *arg_macaddr = carg_macaddr ? carg_macaddr->arg : NULL; + const char *arg_vni = carg_vni ? carg_vni->arg : NULL; + struct rfapi_ip_addr vn_address; + struct rfapi_ip_addr un_address; + struct prefix pfx; + struct rfapi_ip_prefix rpfx; + uint32_t cost; + uint32_t lnh_cost; + uint32_t lifetime; + rfapi_handle rfd; + struct rfapi_vn_option optary[10]; /* XXX must be big enough */ + struct rfapi_vn_option *opt = NULL; + int opt_next = 0; + + int rc = CMD_WARNING_CONFIG_FAILED; + char *endptr; + struct bgp *bgp; + struct rfapi *h; + struct rfapi_cfg *rfapi_cfg; + + const char *arg_lnh = NULL; + const char *arg_lnh_cost = NULL; + + bgp = bgp_get_default(); /* assume 1 instance for now */ + if (!bgp) { + if (vty) + vty_out(vty, "BGP not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + h = bgp->rfapi; + rfapi_cfg = bgp->rfapi_cfg; + if (!h || !rfapi_cfg) { + if (vty) + vty_out(vty, "RFAPI not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + for (; argc; --argc, ++argv) { + if (strmatch(argv[0]->text, "local-next-hop")) { + if (arg_lnh) { + vty_out(vty, + "local-next-hop specified more than once\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (argc <= 1) { + vty_out(vty, + "Missing parameter for local-next-hop\n"); + return CMD_WARNING_CONFIG_FAILED; + } + ++argv, --argc; + arg_lnh = argv[0]->arg; + } + if (strmatch(argv[0]->text, "local-cost")) { + if (arg_lnh_cost) { + vty_out(vty, + "local-cost specified more than once\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (argc <= 1) { + vty_out(vty, + "Missing parameter for local-cost\n"); + return CMD_WARNING_CONFIG_FAILED; + } + ++argv, --argc; + arg_lnh_cost = argv[0]->arg; + } + } + + if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_vn, &vn_address))) + goto fail; + if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_un, &un_address))) + goto fail; + + /* arg_prefix is optional if mac address is given */ + if (arg_macaddr && !arg_prefix) { + /* + * fake up a 0/32 or 0/128 prefix + */ + switch (vn_address.addr_family) { + case AF_INET: + arg_prefix = "0.0.0.0/32"; + break; + case AF_INET6: + arg_prefix = "0::0/128"; + break; + default: + vty_out(vty, + "Internal error, unknown VN address family\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + if (!str2prefix(arg_prefix, &pfx)) { + vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix); + goto fail; + } + if (pfx.family != AF_INET && pfx.family != AF_INET6) { + vty_out(vty, "prefix \"%s\" has invalid address family\n", + arg_prefix); + goto fail; + } + + + memset(optary, 0, sizeof(optary)); + + if (arg_cost) { + endptr = NULL; + cost = strtoul(arg_cost, &endptr, 10); + if (*endptr != '\0' || cost > 255) { + vty_out(vty, "%% Invalid %s value\n", "cost"); + goto fail; + } + } else { + cost = 255; + } + + if (arg_lifetime) { + if (!strcmp(arg_lifetime, "infinite")) { + lifetime = RFAPI_INFINITE_LIFETIME; + } else { + endptr = NULL; + lifetime = strtoul(arg_lifetime, &endptr, 10); + if (*endptr != '\0') { + vty_out(vty, "%% Invalid %s value\n", + "lifetime"); + goto fail; + } + } + } else { + lifetime = RFAPI_INFINITE_LIFETIME; /* default infinite */ + } + + if (arg_lnh_cost) { + if (!arg_lnh) { + vty_out(vty, + "%% %s may only be specified with local-next-hop\n", + "local-cost"); + goto fail; + } + endptr = NULL; + lnh_cost = strtoul(arg_lnh_cost, &endptr, 10); + if (*endptr != '\0' || lnh_cost > 255) { + vty_out(vty, "%% Invalid %s value\n", "local-cost"); + goto fail; + } + } else { + lnh_cost = 255; + } + + if (arg_lnh) { + if (!arg_prefix) { + vty_out(vty, + "%% %s may only be specified with prefix\n", + "local-next-hop"); + goto fail; + } + if ((rc = rfapiCliGetPrefixAddr( + vty, arg_lnh, + &optary[opt_next].v.local_nexthop.addr))) { + + goto fail; + } + + optary[opt_next].v.local_nexthop.cost = lnh_cost; + optary[opt_next].type = RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP; + + if (opt_next) { + optary[opt_next - 1].next = optary + opt_next; + } else { + opt = optary; + } + ++opt_next; + } + + if (arg_vni && !arg_macaddr) { + vty_out(vty, "%% %s may only be specified with mac address\n", + "virtual-network-identifier"); + goto fail; + } + + if (arg_macaddr) { + if (!arg_vni) { + vty_out(vty, + "Missing \"vni\" parameter (mandatory with mac)\n"); + return CMD_WARNING_CONFIG_FAILED; + } + optary[opt_next].v.l2addr.logical_net_id = + strtoul(arg_vni, NULL, 10); + + if ((rc = rfapiStr2EthAddr( + arg_macaddr, + &optary[opt_next].v.l2addr.macaddr))) { + vty_out(vty, "Invalid %s value\n", "mac address"); + goto fail; + } + /* TBD label, NVE ID */ + + optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; + + if (opt_next) { + optary[opt_next - 1].next = optary + opt_next; + } else { + opt = optary; + } + ++opt_next; + } + + vnc_zlog_debug_verbose( + "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s", + __func__, arg_vn, arg_un, arg_prefix, + (arg_cost ? arg_cost : "NULL"), + (arg_lifetime ? arg_lifetime : "NULL"), + (arg_lnh ? arg_lnh : "NULL")); + + rfapiQprefix2Rprefix(&pfx, &rpfx); + + rpfx.cost = cost & 255; + + /* look up rf descriptor, call open if it doesn't exist */ + rc = rfapi_find_rfd(bgp, &vn_address, &un_address, + (struct rfapi_descriptor **)&rfd); + if (rc) { + if (ENOENT == rc) { + struct rfapi_un_option uo; + + /* + * flag descriptor as provisionally opened for static + * route + * registration so that we can fix up the other + * parameters + * when the real open comes along + */ + memset(&uo, 0, sizeof(uo)); + uo.type = RFAPI_UN_OPTION_TYPE_PROVISIONAL; + + rc = rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp), + &vn_address, &un_address, + &uo, /* flags */ + NULL, NULL, /* no userdata */ + &rfd); + if (rc) { + vty_out(vty, + "Can't open session for this NVE: %s\n", + rfapi_error_str(rc)); + rc = CMD_WARNING_CONFIG_FAILED; + goto fail; + } + } else { + vty_out(vty, "Can't find session for this NVE: %s\n", + rfapi_error_str(rc)); + goto fail; + } + } + + rc = rfapi_register(rfd, &rpfx, lifetime, NULL, opt, + RFAPI_REGISTER_ADD); + if (!rc) { + struct rfapi_next_hop_entry *head = NULL; + struct rfapi_next_hop_entry *tail = NULL; + struct rfapi_vn_option *vn_opt_new; + + vnc_zlog_debug_verbose( + "%s: rfapi_register succeeded, returning 0", __func__); + + if (h->rfp_methods.local_cb) { + struct rfapi_descriptor *r = + (struct rfapi_descriptor *)rfd; + vn_opt_new = rfapi_vn_options_dup(opt); + + rfapiAddDeleteLocalRfpPrefix(&r->un_addr, &r->vn_addr, + &rpfx, 1, lifetime, + vn_opt_new, &head, &tail); + if (head) { + h->flags |= RFAPI_INCALLBACK; + (*h->rfp_methods.local_cb)(head, r->cookie); + h->flags &= ~RFAPI_INCALLBACK; + } + head = tail = NULL; + } + return 0; + } + + vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__); + vty_out(vty, "\n"); + vty_out(vty, "Registration failed.\n"); + vty_out(vty, + "Confirm that either the VN or UN address matches a configured NVE group.\n"); + return CMD_WARNING_CONFIG_FAILED; + +fail: + vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__, rc); + return rc; } /************************************************************************ @@ -2545,10 +2278,10 @@ DEFUN (add_vnc_prefix_cost_life_lnh, "Lifetime value in seconds\n" "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11], - /* mac vni */ - NULL, NULL, argc - 12, argv + 12); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], argv[9], argv[11], + /* mac vni */ + NULL, NULL, argc - 12, argv + 12); } DEFUN (add_vnc_prefix_life_cost_lnh, @@ -2571,10 +2304,10 @@ DEFUN (add_vnc_prefix_life_cost_lnh, "Administrative cost\n" "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9], - /* mac vni */ - NULL, NULL, argc - 12, argv + 12); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], argv[11], argv[9], + /* mac vni */ + NULL, NULL, argc - 12, argv + 12); } DEFUN (add_vnc_prefix_cost_lnh, @@ -2595,10 +2328,10 @@ DEFUN (add_vnc_prefix_cost_lnh, "Administrative cost\n" "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL, - /* mac vni */ - NULL, NULL, argc - 10, argv + 10); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], argv[9], NULL, + /* mac vni */ + NULL, NULL, argc - 10, argv + 10); } DEFUN (add_vnc_prefix_life_lnh, @@ -2619,10 +2352,10 @@ DEFUN (add_vnc_prefix_life_lnh, "Lifetime value in seconds\n" "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9], - /* mac vni */ - NULL, NULL, argc - 10, argv + 10); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], NULL, argv[9], + /* mac vni */ + NULL, NULL, argc - 10, argv + 10); } DEFUN (add_vnc_prefix_lnh, @@ -2641,10 +2374,10 @@ DEFUN (add_vnc_prefix_lnh, "UN IPv6 interface address\n" "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL, - /* mac vni */ - NULL, NULL, argc - 8, argv + 8); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], NULL, NULL, + /* mac vni */ + NULL, NULL, argc - 8, argv + 8); } /************************************************************************ @@ -2669,10 +2402,10 @@ DEFUN (add_vnc_prefix_cost_life, "Registration lifetime [default: infinite]\n" "Lifetime value in seconds\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11], - /* mac vni */ - NULL, NULL, 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], argv[9], argv[11], + /* mac vni */ + NULL, NULL, 0, NULL); } DEFUN (add_vnc_prefix_life_cost, @@ -2694,10 +2427,10 @@ DEFUN (add_vnc_prefix_life_cost, "Administrative cost [default: 255]\n" "Administrative cost\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9], - /* mac vni */ - NULL, NULL, 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], argv[11], argv[9], + /* mac vni */ + NULL, NULL, 0, NULL); } DEFUN (add_vnc_prefix_cost, @@ -2717,10 +2450,10 @@ DEFUN (add_vnc_prefix_cost, "Administrative cost [default: 255]\n" "Administrative cost\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL, - /* mac vni */ - NULL, NULL, 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], argv[9], NULL, + /* mac vni */ + NULL, NULL, 0, NULL); } DEFUN (add_vnc_prefix_life, @@ -2740,10 +2473,10 @@ DEFUN (add_vnc_prefix_life, "Registration lifetime [default: infinite]\n" "Lifetime value in seconds\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9], - /* mac vni */ - NULL, NULL, 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], NULL, argv[9], + /* mac vni */ + NULL, NULL, 0, NULL); } DEFUN (add_vnc_prefix, @@ -2761,10 +2494,10 @@ DEFUN (add_vnc_prefix, "UN IPv4 interface address\n" "UN IPv6 interface address\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL, - /* mac vni */ - NULL, NULL, 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[3], argv[5], argv[7], NULL, NULL, + /* mac vni */ + NULL, NULL, 0, NULL); } /************************************************************************ @@ -2793,10 +2526,10 @@ DEFUN (add_vnc_mac_vni_prefix_cost_life, "Registration lifetime [default: infinite]\n" "Lifetime value in seconds\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[11], argv[7], argv[9], argv[13], argv[15], - /* mac vni */ - argv[3], argv[5], 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[11], argv[7], argv[9], argv[13], argv[15], + /* mac vni */ + argv[3], argv[5], 0, NULL); } @@ -2821,10 +2554,10 @@ DEFUN (add_vnc_mac_vni_prefix_life, "Registration lifetime [default: infinite]\n" "Lifetime value in seconds\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[11], argv[7], argv[9], NULL, argv[13], - /* mac vni */ - argv[3], argv[5], 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[11], argv[7], argv[9], NULL, argv[13], + /* mac vni */ + argv[3], argv[5], 0, NULL); } DEFUN (add_vnc_mac_vni_prefix_cost, @@ -2847,10 +2580,10 @@ DEFUN (add_vnc_mac_vni_prefix_cost, "IPv6 prefix\n" "Administrative cost [default: 255]\n" "Administrative cost\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[11], argv[7], argv[9], argv[13], NULL, - /* mac vni */ - argv[3], argv[5], 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[11], argv[7], argv[9], argv[13], NULL, + /* mac vni */ + argv[3], argv[5], 0, NULL); } DEFUN (add_vnc_mac_vni_prefix, @@ -2871,10 +2604,10 @@ DEFUN (add_vnc_mac_vni_prefix, "Add/modify prefix related information\n" "IPv4 prefix\n" "IPv6 prefix\n") { - /* pfx vn un cost life */ - return register_add (vty, argv[11], argv[7], argv[9], NULL, NULL, - /* mac vni */ - argv[3], argv[5], 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, argv[11], argv[7], argv[9], NULL, NULL, + /* mac vni */ + argv[3], argv[5], 0, NULL); } DEFUN (add_vnc_mac_vni_cost_life, @@ -2897,10 +2630,10 @@ DEFUN (add_vnc_mac_vni_cost_life, "Registration lifetime [default: infinite]\n" "Lifetime value in seconds\n") { - /* pfx vn un cost life */ - return register_add (vty, NULL, argv[7], argv[9], argv[11], argv[13], - /* mac vni */ - argv[3], argv[5], 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, NULL, argv[7], argv[9], argv[11], argv[13], + /* mac vni */ + argv[3], argv[5], 0, NULL); } @@ -2921,10 +2654,10 @@ DEFUN (add_vnc_mac_vni_cost, "UN IPv6 interface address\n" "Administrative cost [default: 255]\n" "Administrative cost\n") { - /* pfx vn un cost life */ - return register_add (vty, NULL, argv[7], argv[9], argv[11], NULL, - /* mac vni */ - argv[3], argv[5], 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, NULL, argv[7], argv[9], argv[11], NULL, + /* mac vni */ + argv[3], argv[5], 0, NULL); } @@ -2946,10 +2679,10 @@ DEFUN (add_vnc_mac_vni_life, "Registration lifetime [default: infinite]\n" "Lifetime value in seconds\n") { - /* pfx vn un cost life */ - return register_add (vty, NULL, argv[7], argv[9], NULL, argv[11], - /* mac vni */ - argv[3], argv[5], 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, NULL, argv[7], argv[9], NULL, argv[11], + /* mac vni */ + argv[3], argv[5], 0, NULL); } @@ -2968,674 +2701,643 @@ DEFUN (add_vnc_mac_vni, "UN address of NVE\n" "UN IPv4 interface address\n" "UN IPv6 interface address\n") { - /* pfx vn un cost life */ - return register_add (vty, NULL, argv[7], argv[9], NULL, NULL, - /* mac vni */ - argv[3], argv[5], 0, NULL); + /* pfx vn un cost life */ + return register_add(vty, NULL, argv[7], argv[9], NULL, NULL, + /* mac vni */ + argv[3], argv[5], 0, NULL); } /************************************************************************ * Delete prefix ************************************************************************/ -struct rfapi_local_reg_delete_arg -{ - /* - * match parameters - */ - struct bgp *bgp; - struct rfapi_ip_addr un_address; /* AF==0: wildcard */ - struct rfapi_ip_addr vn_address; /* AF==0: wildcard */ - struct prefix prefix; /* AF==0: wildcard */ - struct prefix_rd rd; /* plen!=64: wildcard */ - struct rfapi_nve_group_cfg *rfg; /* NULL: wildcard */ - - struct rfapi_l2address_option_match l2o; - - /* - * result parameters - */ - struct vty *vty; - uint32_t reg_count; - uint32_t pfx_count; - uint32_t query_count; - - uint32_t failed_pfx_count; - - uint32_t nve_count; - struct skiplist *nves; - - uint32_t remote_active_nve_count; - uint32_t remote_active_pfx_count; - uint32_t remote_holddown_nve_count; - uint32_t remote_holddown_pfx_count; +struct rfapi_local_reg_delete_arg { + /* + * match parameters + */ + struct bgp *bgp; + struct rfapi_ip_addr un_address; /* AF==0: wildcard */ + struct rfapi_ip_addr vn_address; /* AF==0: wildcard */ + struct prefix prefix; /* AF==0: wildcard */ + struct prefix_rd rd; /* plen!=64: wildcard */ + struct rfapi_nve_group_cfg *rfg; /* NULL: wildcard */ + + struct rfapi_l2address_option_match l2o; + + /* + * result parameters + */ + struct vty *vty; + uint32_t reg_count; + uint32_t pfx_count; + uint32_t query_count; + + uint32_t failed_pfx_count; + + uint32_t nve_count; + struct skiplist *nves; + + uint32_t remote_active_nve_count; + uint32_t remote_active_pfx_count; + uint32_t remote_holddown_nve_count; + uint32_t remote_holddown_pfx_count; }; -struct nve_addr -{ - struct rfapi_ip_addr vn; - struct rfapi_ip_addr un; - struct rfapi_descriptor *rfd; - struct rfapi_local_reg_delete_arg *cda; +struct nve_addr { + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + struct rfapi_descriptor *rfd; + struct rfapi_local_reg_delete_arg *cda; }; -static void -nve_addr_free (void *hap) +static void nve_addr_free(void *hap) { - ((struct nve_addr *) hap)->cda->nve_count += 1; - XFREE (MTYPE_RFAPI_NVE_ADDR, hap); + ((struct nve_addr *)hap)->cda->nve_count += 1; + XFREE(MTYPE_RFAPI_NVE_ADDR, hap); } -static int -nve_addr_cmp (void *k1, void *k2) +static int nve_addr_cmp(void *k1, void *k2) { - struct nve_addr *a = (struct nve_addr *) k1; - struct nve_addr *b = (struct nve_addr *) k2; - int ret = 0; - - if (!a || !b) - { - return (a - b); - } - if (a->un.addr_family != b->un.addr_family) - { - return (a->un.addr_family - b->un.addr_family); - } - if (a->vn.addr_family != b->vn.addr_family) - { - return (a->vn.addr_family - b->vn.addr_family); - } - if (a->un.addr_family == AF_INET) - { - ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4); - if (ret != 0) - { - return ret; - } - } - else if (a->un.addr_family == AF_INET6) - { - ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6); - if (ret != 0) - { - return ret; - } - } - else - { - assert (0); - } - if (a->vn.addr_family == AF_INET) - { - ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4); - if (ret != 0) - return ret; - } - else if (a->vn.addr_family == AF_INET6) - { - ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6); - if (ret == 0) - { - return ret; - } - } - else - { - assert (0); - } - return 0; + struct nve_addr *a = (struct nve_addr *)k1; + struct nve_addr *b = (struct nve_addr *)k2; + int ret = 0; + + if (!a || !b) { + return (a - b); + } + if (a->un.addr_family != b->un.addr_family) { + return (a->un.addr_family - b->un.addr_family); + } + if (a->vn.addr_family != b->vn.addr_family) { + return (a->vn.addr_family - b->vn.addr_family); + } + if (a->un.addr_family == AF_INET) { + ret = IPV4_ADDR_CMP(&a->un.addr.v4, &b->un.addr.v4); + if (ret != 0) { + return ret; + } + } else if (a->un.addr_family == AF_INET6) { + ret = IPV6_ADDR_CMP(&a->un.addr.v6, &b->un.addr.v6); + if (ret != 0) { + return ret; + } + } else { + assert(0); + } + if (a->vn.addr_family == AF_INET) { + ret = IPV4_ADDR_CMP(&a->vn.addr.v4, &b->vn.addr.v4); + if (ret != 0) + return ret; + } else if (a->vn.addr_family == AF_INET6) { + ret = IPV6_ADDR_CMP(&a->vn.addr.v6, &b->vn.addr.v6); + if (ret == 0) { + return ret; + } + } else { + assert(0); + } + return 0; } -static int -parse_deleter_args ( - struct vty *vty, - struct bgp *bgp, - const char *arg_prefix, - const char *arg_vn, - const char *arg_un, - const char *arg_l2addr, - const char *arg_vni, - const char *arg_rd, - struct rfapi_nve_group_cfg *arg_rfg, - struct rfapi_local_reg_delete_arg *rcdarg) +static int parse_deleter_args(struct vty *vty, struct bgp *bgp, + const char *arg_prefix, const char *arg_vn, + const char *arg_un, const char *arg_l2addr, + const char *arg_vni, const char *arg_rd, + struct rfapi_nve_group_cfg *arg_rfg, + struct rfapi_local_reg_delete_arg *rcdarg) { - int rc = CMD_WARNING; - - memset (rcdarg, 0, sizeof (struct rfapi_local_reg_delete_arg)); - - rcdarg->vty = vty; - if (bgp == NULL) - bgp = bgp_get_default(); - rcdarg->bgp = bgp; - rcdarg->rfg = arg_rfg; /* may be NULL */ - - if (arg_vn && strcmp (arg_vn, "*")) - { - if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &rcdarg->vn_address))) - return rc; - } - if (arg_un && strcmp (arg_un, "*")) - { - if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &rcdarg->un_address))) - return rc; - } - if (arg_prefix && strcmp (arg_prefix, "*")) - { - - if (!str2prefix (arg_prefix, &rcdarg->prefix)) - { - vty_out (vty, "Malformed prefix \"%s\"\n", arg_prefix); - return rc; - } - } - - if (arg_l2addr) - { - if (!arg_vni) - { - vty_out (vty, "Missing VNI\n"); - return rc; - } - if (strcmp (arg_l2addr, "*")) - { - if ((rc = rfapiStr2EthAddr (arg_l2addr, &rcdarg->l2o.o.macaddr))) - { - vty_out (vty, "Malformed L2 Address \"%s\"\n", - arg_l2addr); - return rc; - } - rcdarg->l2o.flags |= RFAPI_L2O_MACADDR; - } - if (strcmp (arg_vni, "*")) - { - rcdarg->l2o.o.logical_net_id = strtoul(arg_vni, NULL, 10); - rcdarg->l2o.flags |= RFAPI_L2O_LNI; - } - } - if (arg_rd) - { - if (!str2prefix_rd (arg_rd, &rcdarg->rd)) - { - vty_out (vty, "Malformed RD \"%s\"\n", - arg_rd); - return rc; - } - } - - return CMD_SUCCESS; + int rc = CMD_WARNING; + + memset(rcdarg, 0, sizeof(struct rfapi_local_reg_delete_arg)); + + rcdarg->vty = vty; + if (bgp == NULL) + bgp = bgp_get_default(); + rcdarg->bgp = bgp; + rcdarg->rfg = arg_rfg; /* may be NULL */ + + if (arg_vn && strcmp(arg_vn, "*")) { + if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_vn, + &rcdarg->vn_address))) + return rc; + } + if (arg_un && strcmp(arg_un, "*")) { + if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_un, + &rcdarg->un_address))) + return rc; + } + if (arg_prefix && strcmp(arg_prefix, "*")) { + + if (!str2prefix(arg_prefix, &rcdarg->prefix)) { + vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix); + return rc; + } + } + + if (arg_l2addr) { + if (!arg_vni) { + vty_out(vty, "Missing VNI\n"); + return rc; + } + if (strcmp(arg_l2addr, "*")) { + if ((rc = rfapiStr2EthAddr(arg_l2addr, + &rcdarg->l2o.o.macaddr))) { + vty_out(vty, "Malformed L2 Address \"%s\"\n", + arg_l2addr); + return rc; + } + rcdarg->l2o.flags |= RFAPI_L2O_MACADDR; + } + if (strcmp(arg_vni, "*")) { + rcdarg->l2o.o.logical_net_id = + strtoul(arg_vni, NULL, 10); + rcdarg->l2o.flags |= RFAPI_L2O_LNI; + } + } + if (arg_rd) { + if (!str2prefix_rd(arg_rd, &rcdarg->rd)) { + vty_out(vty, "Malformed RD \"%s\"\n", arg_rd); + return rc; + } + } + + return CMD_SUCCESS; } static int -parse_deleter_tokens ( - struct vty *vty, - struct bgp *bgp, - struct cmd_token *carg_prefix, - struct cmd_token *carg_vn, - struct cmd_token *carg_un, - struct cmd_token *carg_l2addr, - struct cmd_token *carg_vni, - struct cmd_token *carg_rd, - struct rfapi_nve_group_cfg *arg_rfg, - struct rfapi_local_reg_delete_arg *rcdarg) +parse_deleter_tokens(struct vty *vty, struct bgp *bgp, + struct cmd_token *carg_prefix, struct cmd_token *carg_vn, + struct cmd_token *carg_un, struct cmd_token *carg_l2addr, + struct cmd_token *carg_vni, struct cmd_token *carg_rd, + struct rfapi_nve_group_cfg *arg_rfg, + struct rfapi_local_reg_delete_arg *rcdarg) { - const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL; - const char *arg_vn = carg_vn ? carg_vn->arg : NULL; - const char *arg_un = carg_un ? carg_un->arg : NULL; - const char *arg_l2addr = carg_l2addr ? carg_l2addr->arg : NULL; - const char *arg_vni = carg_vni ? carg_vni->arg : NULL; - const char *arg_rd = carg_rd ? carg_rd->arg : NULL; - return parse_deleter_args (vty, bgp,arg_prefix, arg_vn, arg_un, - arg_l2addr, arg_vni, arg_rd, - arg_rfg, rcdarg); + const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL; + const char *arg_vn = carg_vn ? carg_vn->arg : NULL; + const char *arg_un = carg_un ? carg_un->arg : NULL; + const char *arg_l2addr = carg_l2addr ? carg_l2addr->arg : NULL; + const char *arg_vni = carg_vni ? carg_vni->arg : NULL; + const char *arg_rd = carg_rd ? carg_rd->arg : NULL; + return parse_deleter_args(vty, bgp, arg_prefix, arg_vn, arg_un, + arg_l2addr, arg_vni, arg_rd, arg_rfg, rcdarg); } -static void -record_nve_in_cda_list ( - struct rfapi_local_reg_delete_arg *cda, - struct rfapi_ip_addr *un_address, - struct rfapi_ip_addr *vn_address, - struct rfapi_descriptor *rfd) +static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg *cda, + struct rfapi_ip_addr *un_address, + struct rfapi_ip_addr *vn_address, + struct rfapi_descriptor *rfd) { - struct nve_addr ha; - struct nve_addr *hap; - - memset (&ha, 0, sizeof (ha)); - ha.un = *un_address; - ha.vn = *vn_address; - ha.rfd = rfd; - - if (!cda->nves) - cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free); - - if (skiplist_search (cda->nves, &ha, (void *) &hap)) - { - hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr)); - assert (hap); - ha.cda = cda; - * hap = ha; - skiplist_insert (cda->nves, hap, hap); - } + struct nve_addr ha; + struct nve_addr *hap; + + memset(&ha, 0, sizeof(ha)); + ha.un = *un_address; + ha.vn = *vn_address; + ha.rfd = rfd; + + if (!cda->nves) + cda->nves = skiplist_new(0, nve_addr_cmp, nve_addr_free); + + if (skiplist_search(cda->nves, &ha, (void *)&hap)) { + hap = XCALLOC(MTYPE_RFAPI_NVE_ADDR, sizeof(struct nve_addr)); + assert(hap); + ha.cda = cda; + *hap = ha; + skiplist_insert(cda->nves, hap, hap); + } } -static void -clear_vnc_responses (struct rfapi_local_reg_delete_arg *cda) +static void clear_vnc_responses(struct rfapi_local_reg_delete_arg *cda) { - struct rfapi *h; - struct rfapi_descriptor *rfd; - int query_count = 0; - struct listnode *node; - struct bgp *bgp_default = bgp_get_default (); - - if (cda->vn_address.addr_family && cda->un_address.addr_family) - { - /* - * Single nve case - */ - if (rfapi_find_rfd - (bgp_default, &cda->vn_address, &cda->un_address, &rfd)) - return; - - rfapiRibClear (rfd); - rfapi_query_done_all (rfd, &query_count); - cda->query_count += query_count; - - /* - * Track unique nves seen - */ - record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd); - return; - } - - /* - * wildcard case - */ - - if (!bgp_default) - return; /* ENXIO */ - - h = bgp_default->rfapi; - - if (!h) - return; /* ENXIO */ - - for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) - { - /* - * match un, vn addresses of NVEs - */ - if (cda->un_address.addr_family && - rfapi_ip_addr_cmp (&cda->un_address, &rfd->un_addr)) - { - continue; - } - if (cda->vn_address.addr_family && - rfapi_ip_addr_cmp (&cda->vn_address, &rfd->vn_addr)) - { - continue; - } - - rfapiRibClear (rfd); - - rfapi_query_done_all (rfd, &query_count); - cda->query_count += query_count; - - /* - * Track unique nves seen - */ - record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd); - } + struct rfapi *h; + struct rfapi_descriptor *rfd; + int query_count = 0; + struct listnode *node; + struct bgp *bgp_default = bgp_get_default(); + + if (cda->vn_address.addr_family && cda->un_address.addr_family) { + /* + * Single nve case + */ + if (rfapi_find_rfd(bgp_default, &cda->vn_address, + &cda->un_address, &rfd)) + return; + + rfapiRibClear(rfd); + rfapi_query_done_all(rfd, &query_count); + cda->query_count += query_count; + + /* + * Track unique nves seen + */ + record_nve_in_cda_list(cda, &rfd->un_addr, &rfd->vn_addr, rfd); + return; + } + + /* + * wildcard case + */ + + if (!bgp_default) + return; /* ENXIO */ + + h = bgp_default->rfapi; + + if (!h) + return; /* ENXIO */ + + for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { + /* + * match un, vn addresses of NVEs + */ + if (cda->un_address.addr_family + && rfapi_ip_addr_cmp(&cda->un_address, &rfd->un_addr)) { + continue; + } + if (cda->vn_address.addr_family + && rfapi_ip_addr_cmp(&cda->vn_address, &rfd->vn_addr)) { + continue; + } + + rfapiRibClear(rfd); + + rfapi_query_done_all(rfd, &query_count); + cda->query_count += query_count; + + /* + * Track unique nves seen + */ + record_nve_in_cda_list(cda, &rfd->un_addr, &rfd->vn_addr, rfd); + } } /* * TBD need to count deleted prefixes and nves? * * ENXIO BGP or VNC not configured - */ -static int -rfapiDeleteLocalPrefixesByRFD (struct rfapi_local_reg_delete_arg *cda, - struct rfapi_descriptor *rfd) + */ +static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg *cda, + struct rfapi_descriptor *rfd) { - struct rfapi_ip_addr *pUn; /* NULL = wildcard */ - struct rfapi_ip_addr *pVn; /* NULL = wildcard */ - struct prefix *pPrefix; /* NULL = wildcard */ - struct prefix_rd *pPrd; /* NULL = wildcard */ + struct rfapi_ip_addr *pUn; /* NULL = wildcard */ + struct rfapi_ip_addr *pVn; /* NULL = wildcard */ + struct prefix *pPrefix; /* NULL = wildcard */ + struct prefix_rd *pPrd; /* NULL = wildcard */ - struct rfapi_ip_prefix rprefix; - struct rfapi_next_hop_entry *head = NULL; - struct rfapi_next_hop_entry *tail = NULL; + struct rfapi_ip_prefix rprefix; + struct rfapi_next_hop_entry *head = NULL; + struct rfapi_next_hop_entry *tail = NULL; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: entry", __func__); + vnc_zlog_debug_verbose("%s: entry", __func__); #endif - pUn = (cda->un_address.addr_family ? &cda->un_address : NULL); - pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL); - pPrefix = (cda->prefix.family ? &cda->prefix : NULL); - pPrd = (cda->rd.prefixlen == 64 ? &cda->rd : NULL); - - if (pPrefix) - { - rfapiQprefix2Rprefix (pPrefix, &rprefix); - } - - do /* to preserve old code structure */ - { - struct rfapi *h=cda->bgp->rfapi;; - struct rfapi_adb *adb; - int rc; - int deleted_from_this_nve; - struct nve_addr ha; - struct nve_addr *hap; + pUn = (cda->un_address.addr_family ? &cda->un_address : NULL); + pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL); + pPrefix = (cda->prefix.family ? &cda->prefix : NULL); + pPrd = (cda->rd.prefixlen == 64 ? &cda->rd : NULL); + + if (pPrefix) { + rfapiQprefix2Rprefix(pPrefix, &rprefix); + } + + do /* to preserve old code structure */ + { + struct rfapi *h = cda->bgp->rfapi; + ; + struct rfapi_adb *adb; + int rc; + int deleted_from_this_nve; + struct nve_addr ha; + struct nve_addr *hap; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); + vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd); #endif - /* - * match un, vn addresses of NVEs - */ - if (pUn && (rfapi_ip_addr_cmp (pUn, &rfd->un_addr))) - continue; - if (pVn && (rfapi_ip_addr_cmp (pVn, &rfd->vn_addr))) - continue; + /* + * match un, vn addresses of NVEs + */ + if (pUn && (rfapi_ip_addr_cmp(pUn, &rfd->un_addr))) + continue; + if (pVn && (rfapi_ip_addr_cmp(pVn, &rfd->vn_addr))) + continue; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: un, vn match", __func__); + vnc_zlog_debug_verbose("%s: un, vn match", __func__); #endif - /* - * match prefix - */ - - deleted_from_this_nve = 0; - - { - struct skiplist *sl; - struct rfapi_ip_prefix rp; - void *cursor; - struct list *adb_delete_list; - - /* - * The advertisements are stored in a skiplist. Withdrawing - * the registration deletes the advertisement from the - * skiplist, which we can't do while iterating over that - * same skiplist using the current skiplist API. - * - * Strategy: iterate over the skiplist and build another - * list containing only the matching ADBs. Then delete - * _everything_ in that second list (which can be done - * using either skiplists or quagga linklists). - */ - adb_delete_list = list_new (); - - /* - * Advertised IP prefixes (not 0/32 or 0/128) - */ - sl = rfd->advertised.ipN_by_prefix; - - for (cursor = NULL, - rc = skiplist_next (sl, NULL, (void **) &adb, &cursor); - !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor)) - { - - if (pPrefix) - { - if (!prefix_same (pPrefix, &adb->u.s.prefix_ip)) - { + /* + * match prefix + */ + + deleted_from_this_nve = 0; + + { + struct skiplist *sl; + struct rfapi_ip_prefix rp; + void *cursor; + struct list *adb_delete_list; + + /* + * The advertisements are stored in a skiplist. + * Withdrawing + * the registration deletes the advertisement from the + * skiplist, which we can't do while iterating over that + * same skiplist using the current skiplist API. + * + * Strategy: iterate over the skiplist and build another + * list containing only the matching ADBs. Then delete + * _everything_ in that second list (which can be done + * using either skiplists or quagga linklists). + */ + adb_delete_list = list_new(); + + /* + * Advertised IP prefixes (not 0/32 or 0/128) + */ + sl = rfd->advertised.ipN_by_prefix; + + for (cursor = NULL, + rc = skiplist_next(sl, NULL, (void **)&adb, + &cursor); + !rc; rc = skiplist_next(sl, NULL, (void **)&adb, + &cursor)) { + + if (pPrefix) { + if (!prefix_same(pPrefix, + &adb->u.s.prefix_ip)) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: adb=%p, prefix doesn't match, skipping", - __func__, adb); + vnc_zlog_debug_verbose( + "%s: adb=%p, prefix doesn't match, skipping", + __func__, adb); #endif - continue; - } - } - if (pPrd) - { - if (memcmp(pPrd->val, adb->u.s.prd.val, 8) != 0) - { + continue; + } + } + if (pPrd) { + if (memcmp(pPrd->val, adb->u.s.prd.val, + 8) + != 0) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: adb=%p, RD doesn't match, skipping", - __func__, adb); + vnc_zlog_debug_verbose( + "%s: adb=%p, RD doesn't match, skipping", + __func__, adb); #endif - continue; - } - } - if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR)) - { - if (memcmp - (cda->l2o.o.macaddr.octet, - adb->u.s.prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN)) - { + continue; + } + } + if (CHECK_FLAG(cda->l2o.flags, + RFAPI_L2O_MACADDR)) { + if (memcmp(cda->l2o.o.macaddr.octet, + adb->u.s.prefix_eth.u + .prefix_eth.octet, + ETHER_ADDR_LEN)) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: adb=%p, macaddr doesn't match, skipping", - __func__, adb); + vnc_zlog_debug_verbose( + "%s: adb=%p, macaddr doesn't match, skipping", + __func__, adb); #endif - continue; - } - } - - if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI)) - { - if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id) - { + continue; + } + } + + if (CHECK_FLAG(cda->l2o.flags, RFAPI_L2O_LNI)) { + if (cda->l2o.o.logical_net_id + != adb->l2o.logical_net_id) { #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: adb=%p, LNI doesn't match, skipping", - __func__, adb); + vnc_zlog_debug_verbose( + "%s: adb=%p, LNI doesn't match, skipping", + __func__, adb); #endif - continue; - } - } + continue; + } + } #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: ipN adding adb %p to delete list", __func__, - adb); + vnc_zlog_debug_verbose( + "%s: ipN adding adb %p to delete list", + __func__, adb); #endif - listnode_add (adb_delete_list, adb); - } - - struct listnode *node; - - for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb)) - { - int this_advertisement_prefix_count; - struct rfapi_vn_option optary[3]; - struct rfapi_vn_option *opt = NULL; - int cur_opt = 0; - - this_advertisement_prefix_count = 1; - - rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp); - - memset (optary, 0, sizeof (optary)); - - /* if mac addr present in advert, make l2o vn option */ - if (adb->u.s.prefix_eth.family == AF_ETHERNET) - { - if (opt != NULL) - opt->next = &optary[cur_opt]; - opt = &optary[cur_opt++]; - opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR; - opt->v.l2addr.macaddr = adb->u.s.prefix_eth.u.prefix_eth; - ++this_advertisement_prefix_count; - } - /* - * use saved RD value instead of trying to invert - * complex RD computation in rfapi_register() - */ - if (opt != NULL) - opt->next = &optary[cur_opt]; - opt = &optary[cur_opt++]; - opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; - opt->v.internal_rd = adb->u.s.prd; + listnode_add(adb_delete_list, adb); + } + + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(adb_delete_list, node, adb)) { + int this_advertisement_prefix_count; + struct rfapi_vn_option optary[3]; + struct rfapi_vn_option *opt = NULL; + int cur_opt = 0; + + this_advertisement_prefix_count = 1; + + rfapiQprefix2Rprefix(&adb->u.s.prefix_ip, &rp); + + memset(optary, 0, sizeof(optary)); + + /* if mac addr present in advert, make l2o vn + * option */ + if (adb->u.s.prefix_eth.family == AF_ETHERNET) { + if (opt != NULL) + opt->next = &optary[cur_opt]; + opt = &optary[cur_opt++]; + opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR; + opt->v.l2addr.macaddr = + adb->u.s.prefix_eth.u + .prefix_eth; + ++this_advertisement_prefix_count; + } + /* + * use saved RD value instead of trying to + * invert + * complex RD computation in rfapi_register() + */ + if (opt != NULL) + opt->next = &optary[cur_opt]; + opt = &optary[cur_opt++]; + opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; + opt->v.internal_rd = adb->u.s.prd; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: ipN killing reg from adb %p ", __func__, adb); + vnc_zlog_debug_verbose( + "%s: ipN killing reg from adb %p ", + __func__, adb); #endif - rc = rfapi_register (rfd, &rp, 0, NULL, - (cur_opt ? optary : NULL), RFAPI_REGISTER_KILL); - if (!rc) - { - cda->pfx_count += this_advertisement_prefix_count; - cda->reg_count += 1; - deleted_from_this_nve = 1; - } - if (h->rfp_methods.local_cb) - { - rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, &rfd->vn_addr, - &rp, 0, 0, NULL, &head, &tail); - } - } - list_delete_all_node (adb_delete_list); - - if (!(pPrefix && !RFAPI_0_PREFIX (pPrefix))) - { - void *cursor; - - /* - * Caller didn't specify a prefix, or specified (0/32 or 0/128) - */ - - /* - * Advertised 0/32 and 0/128 (indexed by ethernet address) - */ - sl = rfd->advertised.ip0_by_ether; - - for (cursor = NULL, - rc = skiplist_next (sl, NULL, (void **) &adb, &cursor); - !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor)) - { - - if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR)) - { - if (memcmp (cda->l2o.o.macaddr.octet, - adb->u.s.prefix_eth.u.prefix_eth.octet, - ETHER_ADDR_LEN)) - { - - continue; - } - } - if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI)) - { - if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id) - { - continue; - } - } + rc = rfapi_register(rfd, &rp, 0, NULL, + (cur_opt ? optary : NULL), + RFAPI_REGISTER_KILL); + if (!rc) { + cda->pfx_count += + this_advertisement_prefix_count; + cda->reg_count += 1; + deleted_from_this_nve = 1; + } + if (h->rfp_methods.local_cb) { + rfapiAddDeleteLocalRfpPrefix( + &rfd->un_addr, &rfd->vn_addr, + &rp, 0, 0, NULL, &head, &tail); + } + } + list_delete_all_node(adb_delete_list); + + if (!(pPrefix && !RFAPI_0_PREFIX(pPrefix))) { + void *cursor; + + /* + * Caller didn't specify a prefix, or specified + * (0/32 or 0/128) + */ + + /* + * Advertised 0/32 and 0/128 (indexed by + * ethernet address) + */ + sl = rfd->advertised.ip0_by_ether; + + for (cursor = NULL, + rc = skiplist_next(sl, NULL, (void **)&adb, + &cursor); + !rc; + rc = skiplist_next(sl, NULL, (void **)&adb, + &cursor)) { + + if (CHECK_FLAG(cda->l2o.flags, + RFAPI_L2O_MACADDR)) { + if (memcmp(cda->l2o.o.macaddr + .octet, + adb->u.s.prefix_eth.u + .prefix_eth + .octet, + ETHER_ADDR_LEN)) { + + continue; + } + } + if (CHECK_FLAG(cda->l2o.flags, + RFAPI_L2O_LNI)) { + if (cda->l2o.o.logical_net_id + != adb->l2o.logical_net_id) { + continue; + } + } #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: ip0 adding adb %p to delete list", - __func__, adb); + vnc_zlog_debug_verbose( + "%s: ip0 adding adb %p to delete list", + __func__, adb); #endif - listnode_add (adb_delete_list, adb); - } + listnode_add(adb_delete_list, adb); + } - for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb)) - { + for (ALL_LIST_ELEMENTS_RO(adb_delete_list, node, + adb)) { - struct rfapi_vn_option vn; + struct rfapi_vn_option vn; - rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp); + rfapiQprefix2Rprefix( + &adb->u.s.prefix_ip, &rp); - memset (&vn, 0, sizeof (vn)); - vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR; - vn.v.l2addr = adb->l2o; + memset(&vn, 0, sizeof(vn)); + vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR; + vn.v.l2addr = adb->l2o; #if DEBUG_L2_EXTRA - vnc_zlog_debug_verbose ("%s: ip0 killing reg from adb %p ", - __func__, adb); + vnc_zlog_debug_verbose( + "%s: ip0 killing reg from adb %p ", + __func__, adb); #endif - rc = rfapi_register (rfd, &rp, 0, NULL, &vn, - RFAPI_REGISTER_KILL); - if (!rc) - { - cda->pfx_count += 1; - cda->reg_count += 1; - deleted_from_this_nve = 1; - } - if (h->rfp_methods.local_cb) - { - struct rfapi_vn_option *vn_opt_new; - - vn_opt_new = rfapi_vn_options_dup (&vn); - rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, - &rfd->vn_addr, &rp, 0, 0, - vn_opt_new, &head, &tail); - } - } - list_delete_all_node (adb_delete_list); - } - list_delete (adb_delete_list); - } - - - if (head) - { /* should not be set if (NULL == rfapi_cfg->local_cb) */ - h->flags |= RFAPI_INCALLBACK; - (*h->rfp_methods.local_cb) (head, rfd->cookie); - h->flags &= ~RFAPI_INCALLBACK; - head = tail = NULL; - } - - if (deleted_from_this_nve) - { - /* - * track unique NVEs seen - */ - memset (&ha, 0, sizeof (ha)); - ha.un = rfd->un_addr; - ha.vn = rfd->vn_addr; - - if (!cda->nves) - cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free); - if (skiplist_search (cda->nves, &ha, (void **) &hap)) - { - hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr)); - assert (hap); - ha.cda = cda; - *hap = ha; - skiplist_insert (cda->nves, hap, hap); - } - } - } while (0); /* to preserve old code structure */ - - return 0; + rc = rfapi_register( + rfd, &rp, 0, NULL, &vn, + RFAPI_REGISTER_KILL); + if (!rc) { + cda->pfx_count += 1; + cda->reg_count += 1; + deleted_from_this_nve = 1; + } + if (h->rfp_methods.local_cb) { + struct rfapi_vn_option + *vn_opt_new; + + vn_opt_new = + rfapi_vn_options_dup( + &vn); + rfapiAddDeleteLocalRfpPrefix( + &rfd->un_addr, + &rfd->vn_addr, &rp, 0, + 0, vn_opt_new, &head, + &tail); + } + } + list_delete_all_node(adb_delete_list); + } + list_delete(adb_delete_list); + } + + + if (head) { /* should not be set if (NULL == + rfapi_cfg->local_cb) */ + h->flags |= RFAPI_INCALLBACK; + (*h->rfp_methods.local_cb)(head, rfd->cookie); + h->flags &= ~RFAPI_INCALLBACK; + head = tail = NULL; + } + + if (deleted_from_this_nve) { + /* + * track unique NVEs seen + */ + memset(&ha, 0, sizeof(ha)); + ha.un = rfd->un_addr; + ha.vn = rfd->vn_addr; + + if (!cda->nves) + cda->nves = skiplist_new(0, nve_addr_cmp, + nve_addr_free); + if (skiplist_search(cda->nves, &ha, (void **)&hap)) { + hap = XCALLOC(MTYPE_RFAPI_NVE_ADDR, + sizeof(struct nve_addr)); + assert(hap); + ha.cda = cda; + *hap = ha; + skiplist_insert(cda->nves, hap, hap); + } + } + } while (0); /* to preserve old code structure */ + + return 0; } -static int -rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) +static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg *cda) { - int rc = 0; - - if (cda->rfg) - { - if (cda->rfg->rfd) /* if not open, nothing to delete */ - rc = rfapiDeleteLocalPrefixesByRFD (cda, cda->rfg->rfd); - } - else - { - struct bgp *bgp = cda->bgp; - struct rfapi *h; - struct rfapi_cfg *rfapi_cfg; - - struct listnode *node; - struct rfapi_descriptor *rfd; - if (!bgp) - return ENXIO; - h = bgp->rfapi; - rfapi_cfg = bgp->rfapi_cfg; - if (!h || !rfapi_cfg) - return ENXIO; - vnc_zlog_debug_verbose ("%s: starting descriptor loop", __func__); - for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) - { - rc = rfapiDeleteLocalPrefixesByRFD (cda, rfd); - } - } - return rc; + int rc = 0; + + if (cda->rfg) { + if (cda->rfg->rfd) /* if not open, nothing to delete */ + rc = rfapiDeleteLocalPrefixesByRFD(cda, cda->rfg->rfd); + } else { + struct bgp *bgp = cda->bgp; + struct rfapi *h; + struct rfapi_cfg *rfapi_cfg; + + struct listnode *node; + struct rfapi_descriptor *rfd; + if (!bgp) + return ENXIO; + h = bgp->rfapi; + rfapi_cfg = bgp->rfapi_cfg; + if (!h || !rfapi_cfg) + return ENXIO; + vnc_zlog_debug_verbose("%s: starting descriptor loop", + __func__); + for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { + rc = rfapiDeleteLocalPrefixesByRFD(cda, rfd); + } + } + return rc; } /* @@ -3643,108 +3345,98 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) * * Deletes local and remote prefixes that match */ -static void -clear_vnc_prefix (struct rfapi_local_reg_delete_arg *cda) +static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg *cda) { - struct prefix pfx_un; - struct prefix pfx_vn; - - struct prefix *pUN = NULL; - struct prefix *pVN = NULL; - struct prefix *pPrefix = NULL; - - struct rfapi_import_table *it = NULL; - - /* - * Delete matching remote prefixes in holddown - */ - if (cda->vn_address.addr_family) - { - if (!rfapiRaddr2Qprefix (&cda->vn_address, &pfx_vn)) - pVN = &pfx_vn; - } - if (cda->un_address.addr_family) - { - if (!rfapiRaddr2Qprefix (&cda->un_address, &pfx_un)) - pUN = &pfx_un; - } - if (cda->prefix.family) - { - pPrefix = &cda->prefix; - } - if (cda->rfg) - { - it = cda->rfg->rfapi_import_table; - } - rfapiDeleteRemotePrefixes (pUN, pVN, pPrefix, it, - 0, 1, &cda->remote_active_pfx_count, - &cda->remote_active_nve_count, - &cda->remote_holddown_pfx_count, - &cda->remote_holddown_nve_count); - - /* - * Now do local prefixes - */ - rfapiDeleteLocalPrefixes (cda); + struct prefix pfx_un; + struct prefix pfx_vn; + + struct prefix *pUN = NULL; + struct prefix *pVN = NULL; + struct prefix *pPrefix = NULL; + + struct rfapi_import_table *it = NULL; + + /* + * Delete matching remote prefixes in holddown + */ + if (cda->vn_address.addr_family) { + if (!rfapiRaddr2Qprefix(&cda->vn_address, &pfx_vn)) + pVN = &pfx_vn; + } + if (cda->un_address.addr_family) { + if (!rfapiRaddr2Qprefix(&cda->un_address, &pfx_un)) + pUN = &pfx_un; + } + if (cda->prefix.family) { + pPrefix = &cda->prefix; + } + if (cda->rfg) { + it = cda->rfg->rfapi_import_table; + } + rfapiDeleteRemotePrefixes( + pUN, pVN, pPrefix, it, 0, 1, &cda->remote_active_pfx_count, + &cda->remote_active_nve_count, &cda->remote_holddown_pfx_count, + &cda->remote_holddown_nve_count); + + /* + * Now do local prefixes + */ + rfapiDeleteLocalPrefixes(cda); } -static void -print_cleared_stats (struct rfapi_local_reg_delete_arg *cda) +static void print_cleared_stats(struct rfapi_local_reg_delete_arg *cda) { - struct vty *vty = cda->vty; /* for benefit of VTYNL */ - - /* Our special element-deleting function counts nves */ - if (cda->nves) - { - skiplist_free (cda->nves); - cda->nves = NULL; - } - if (cda->failed_pfx_count) - vty_out (vty, "Failed to delete %d prefixes\n", - cda->failed_pfx_count); - - /* left as "prefixes" even in single case for ease of machine parsing */ - vty_out (vty, - "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n", - cda->reg_count, cda->pfx_count, cda->query_count,cda->nve_count); - -/* - * We don't currently allow deletion of active remote prefixes from - * the command line - */ - - vty_out (vty, "[Holddown] Cleared %u prefixes from %u NVEs\n", - cda->remote_holddown_pfx_count,cda->remote_holddown_nve_count); + struct vty *vty = cda->vty; /* for benefit of VTYNL */ + + /* Our special element-deleting function counts nves */ + if (cda->nves) { + skiplist_free(cda->nves); + cda->nves = NULL; + } + if (cda->failed_pfx_count) + vty_out(vty, "Failed to delete %d prefixes\n", + cda->failed_pfx_count); + + /* left as "prefixes" even in single case for ease of machine parsing */ + vty_out(vty, + "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n", + cda->reg_count, cda->pfx_count, cda->query_count, + cda->nve_count); + + /* + * We don't currently allow deletion of active remote prefixes from + * the command line + */ + + vty_out(vty, "[Holddown] Cleared %u prefixes from %u NVEs\n", + cda->remote_holddown_pfx_count, cda->remote_holddown_nve_count); } -/* +/* * Caller has already deleted registrations and queries for this/these * NVEs. Now we just have to close their descriptors. */ -static void -clear_vnc_nve_closer (struct rfapi_local_reg_delete_arg *cda) +static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg *cda) { - struct skiplist *sl = cda->nves; /* contains affected NVEs */ - struct nve_addr *pKey; - struct nve_addr *pValue; - void *cursor = NULL; - int rc; - - if (!sl) - return; - - for (rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor); - !rc; - rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor)) - { - - if (pValue->rfd) - { - ((struct rfapi_descriptor *) pValue->rfd)->flags |= - RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY; - rfapi_close (pValue->rfd); - } - } + struct skiplist *sl = cda->nves; /* contains affected NVEs */ + struct nve_addr *pKey; + struct nve_addr *pValue; + void *cursor = NULL; + int rc; + + if (!sl) + return; + + for (rc = skiplist_next(sl, (void **)&pKey, (void **)&pValue, &cursor); + !rc; rc = skiplist_next(sl, (void **)&pKey, (void **)&pValue, + &cursor)) { + + if (pValue->rfd) { + ((struct rfapi_descriptor *)pValue->rfd)->flags |= + RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY; + rfapi_close(pValue->rfd); + } + } } DEFUN (clear_vnc_nve_all, @@ -3756,21 +3448,22 @@ DEFUN (clear_vnc_nve_all, "For all NVEs\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; + struct rfapi_local_reg_delete_arg cda; + int rc; - if ((rc = parse_deleter_args (vty, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cda))) - return rc; + if ((rc = parse_deleter_args(vty, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, &cda))) + return rc; - cda.vty = vty; + cda.vty = vty; - clear_vnc_responses (&cda); - clear_vnc_prefix (&cda); - clear_vnc_nve_closer (&cda); + clear_vnc_responses(&cda); + clear_vnc_prefix(&cda); + clear_vnc_nve_closer(&cda); - print_cleared_stats (&cda); + print_cleared_stats(&cda); - return 0; + return 0; } DEFUN (clear_vnc_nve_vn_un, @@ -3788,22 +3481,22 @@ DEFUN (clear_vnc_nve_vn_un, "UN IPv4 interface address\n" "UN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; + struct rfapi_local_reg_delete_arg cda; + int rc; - if ((rc = - parse_deleter_tokens (vty, NULL, NULL, argv[4], argv[6], NULL, NULL, NULL, NULL, &cda))) - return rc; + if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[4], argv[6], NULL, + NULL, NULL, NULL, &cda))) + return rc; - cda.vty = vty; + cda.vty = vty; - clear_vnc_responses (&cda); - clear_vnc_prefix (&cda); - clear_vnc_nve_closer (&cda); + clear_vnc_responses(&cda); + clear_vnc_prefix(&cda); + clear_vnc_nve_closer(&cda); - print_cleared_stats (&cda); + print_cleared_stats(&cda); - return 0; + return 0; } DEFUN (clear_vnc_nve_un_vn, @@ -3821,22 +3514,22 @@ DEFUN (clear_vnc_nve_un_vn, "VN IPv4 interface address\n" "VN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; + struct rfapi_local_reg_delete_arg cda; + int rc; - if ((rc = - parse_deleter_tokens (vty, NULL, NULL, argv[6], argv[4], NULL, NULL, NULL, NULL, &cda))) - return rc; + if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[6], argv[4], NULL, + NULL, NULL, NULL, &cda))) + return rc; - cda.vty = vty; + cda.vty = vty; - clear_vnc_responses (&cda); - clear_vnc_prefix (&cda); - clear_vnc_nve_closer (&cda); + clear_vnc_responses(&cda); + clear_vnc_prefix(&cda); + clear_vnc_nve_closer(&cda); - print_cleared_stats (&cda); + print_cleared_stats(&cda); - return 0; + return 0; } DEFUN (clear_vnc_nve_vn, @@ -3850,20 +3543,21 @@ DEFUN (clear_vnc_nve_vn, "VN IPv4 interface address\n" "VN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; + struct rfapi_local_reg_delete_arg cda; + int rc; - if ((rc = parse_deleter_tokens (vty, NULL, NULL, argv[4], NULL, NULL, NULL, NULL, NULL, &cda))) - return rc; + if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[4], NULL, NULL, + NULL, NULL, NULL, &cda))) + return rc; - cda.vty = vty; + cda.vty = vty; - clear_vnc_responses (&cda); - clear_vnc_prefix (&cda); - clear_vnc_nve_closer (&cda); + clear_vnc_responses(&cda); + clear_vnc_prefix(&cda); + clear_vnc_nve_closer(&cda); - print_cleared_stats (&cda); - return 0; + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_nve_un, @@ -3877,20 +3571,21 @@ DEFUN (clear_vnc_nve_un, "UN IPv4 interface address\n" "UN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; + struct rfapi_local_reg_delete_arg cda; + int rc; - if ((rc = parse_deleter_tokens (vty, NULL, NULL, NULL, argv[4], NULL, NULL, NULL, NULL, &cda))) - return rc; + if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, argv[4], NULL, + NULL, NULL, NULL, &cda))) + return rc; - cda.vty = vty; + cda.vty = vty; - clear_vnc_responses (&cda); - clear_vnc_prefix (&cda); - clear_vnc_nve_closer (&cda); + clear_vnc_responses(&cda); + clear_vnc_prefix(&cda); + clear_vnc_nve_closer(&cda); - print_cleared_stats (&cda); - return 0; + print_cleared_stats(&cda); + return 0; } /*------------------------------------------------- @@ -3919,16 +3614,16 @@ DEFUN (clear_vnc_prefix_vn_un, "UN IPv4 interface address\n" "UN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - if ((rc = - parse_deleter_tokens (vty, NULL, argv[3], argv[5], argv[7], NULL, NULL, NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[5], argv[7], + NULL, NULL, NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_prefix_un_vn, @@ -3949,16 +3644,16 @@ DEFUN (clear_vnc_prefix_un_vn, "VN IPv4 interface address\n" "VN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - if ((rc = - parse_deleter_tokens (vty, NULL, argv[3], argv[7], argv[5], NULL, NULL, NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[7], argv[5], + NULL, NULL, NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_prefix_un, @@ -3975,16 +3670,16 @@ DEFUN (clear_vnc_prefix_un, "UN IPv4 interface address\n" "UN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - if ((rc = - parse_deleter_tokens (vty, NULL, argv[3], NULL, argv[5], NULL, NULL, NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_tokens(vty, NULL, argv[3], NULL, argv[5], NULL, + NULL, NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_prefix_vn, @@ -4001,16 +3696,16 @@ DEFUN (clear_vnc_prefix_vn, "VN IPv4 interface address\n" "VN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - if ((rc = - parse_deleter_tokens (vty, NULL, argv[3], argv[5], NULL, NULL, NULL, NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[5], NULL, NULL, + NULL, NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_prefix_all, @@ -4024,15 +3719,16 @@ DEFUN (clear_vnc_prefix_all, "IPv6 prefix\n" "From any NVE\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - if ((rc = parse_deleter_tokens (vty, NULL, argv[3], NULL, NULL, NULL, NULL, NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_tokens(vty, NULL, argv[3], NULL, NULL, NULL, + NULL, NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } /*------------------------------------------------- @@ -4063,18 +3759,17 @@ DEFUN (clear_vnc_mac_vn_un, "UN IPv4 interface address\n" "UN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, NULL, argv[7], argv[9], argv[3], argv[5], - NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[7], argv[9], + argv[3], argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_mac_un_vn, @@ -4097,18 +3792,17 @@ DEFUN (clear_vnc_mac_un_vn, "VN IPv4 interface address\n" "VN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, NULL, argv[9], argv[7], argv[3], argv[5], - NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[9], argv[7], + argv[3], argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_mac_un, @@ -4127,17 +3821,17 @@ DEFUN (clear_vnc_mac_un, "UN IPv4 interface address\n" "UN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, NULL, NULL, argv[7], argv[3], argv[5], NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, argv[7], argv[3], + argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_mac_vn, @@ -4156,17 +3850,17 @@ DEFUN (clear_vnc_mac_vn, "VN IPv4 interface address\n" "VN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, NULL, argv[7], NULL, argv[3], argv[5], NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[7], NULL, argv[3], + argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_mac_all, @@ -4182,17 +3876,17 @@ DEFUN (clear_vnc_mac_all, "Virtual network identifier\n" "From any NVE\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, NULL, NULL, NULL, argv[3], argv[5], NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, NULL, argv[3], + argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } /*------------------------------------------------- @@ -4223,18 +3917,17 @@ DEFUN (clear_vnc_mac_vn_un_prefix, "IPv4 prefix\n" "IPv6 prefix\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, argv[11], argv[7], argv[9], argv[3], argv[5], - NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, argv[11], argv[7], argv[9], + argv[3], argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_mac_un_vn_prefix, @@ -4265,18 +3958,17 @@ DEFUN (clear_vnc_mac_un_vn_prefix, "IPv4 prefix\n" "IPv6 prefix\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, argv[11], argv[9], argv[7], argv[3], argv[5], - NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, argv[11], argv[9], argv[7], + argv[3], argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_mac_un_prefix, @@ -4299,18 +3991,17 @@ DEFUN (clear_vnc_mac_un_prefix, "IPv4 Prefix\n" "IPv6 Prefix\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, argv[9], NULL, argv[7], argv[3], argv[5], - NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, argv[9], NULL, argv[7], + argv[3], argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_mac_vn_prefix, @@ -4333,18 +4024,17 @@ DEFUN (clear_vnc_mac_vn_prefix, "IPv4 Prefix\n" "IPv6 Prefix\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, argv[9], argv[7], NULL, argv[3], argv[5], - NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, argv[9], argv[7], NULL, + argv[3], argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } DEFUN (clear_vnc_mac_all_prefix, @@ -4363,17 +4053,17 @@ DEFUN (clear_vnc_mac_all_prefix, "VN IPv4 interface address\n" "VN IPv6 interface address\n") { - struct rfapi_local_reg_delete_arg cda; - int rc; - - /* pfx vn un L2 VNI */ - if ((rc = - parse_deleter_tokens (vty, NULL, argv[7], NULL, NULL, argv[3], argv[5], NULL, NULL, &cda))) - return rc; - cda.vty = vty; - clear_vnc_prefix (&cda); - print_cleared_stats (&cda); - return 0; + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = parse_deleter_tokens(vty, NULL, argv[7], NULL, NULL, argv[3], + argv[5], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix(&cda); + print_cleared_stats(&cda); + return 0; } /************************************************************************ @@ -4382,222 +4072,216 @@ DEFUN (clear_vnc_mac_all_prefix, /* copied from rfp_vty.c */ -static int -check_and_display_is_vnc_running (struct vty *vty) +static int check_and_display_is_vnc_running(struct vty *vty) { - if (!bgp_rfapi_is_vnc_configured (NULL)) - return 1; /* is running */ - - if (vty) - { - vty_out (vty, - "VNC is not configured. (There are no configured BGP VPN SAFI peers.)\n"); - } - return 0; /* not running */ + if (!bgp_rfapi_is_vnc_configured(NULL)) + return 1; /* is running */ + + if (vty) { + vty_out(vty, + "VNC is not configured. (There are no configured BGP VPN SAFI peers.)\n"); + } + return 0; /* not running */ } -static int -rfapi_vty_show_nve_summary (struct vty *vty, show_nve_summary_t show_type) +static int rfapi_vty_show_nve_summary(struct vty *vty, + show_nve_summary_t show_type) { - struct bgp *bgp_default = bgp_get_default (); - struct rfapi *h; - int is_vnc_running = !bgp_rfapi_is_vnc_configured (bgp_default); - - int active_local_routes; - int active_remote_routes; - int holddown_remote_routes; - int imported_remote_routes; - - if (!bgp_default) - goto notcfg; - - h = bgp_default->rfapi; - - if (!h) - goto notcfg; - - /* don't show local info if not running RFP */ - if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED) - { - - switch (show_type) - { - - case SHOW_NVE_SUMMARY_ACTIVE_NVES: - vty_out (vty, "%-24s ", "NVEs:"); - vty_out (vty, "%-8s %-8u ", "Active:", h->descriptors.count); - vty_out (vty, "%-8s %-8u ", "Maximum:", h->stat.max_descriptors); - vty_out (vty, "%-8s %-8u", "Unknown:", h->stat.count_unknown_nves); - break; - - case SHOW_NVE_SUMMARY_REGISTERED: - /* - * NB: With the introduction of L2 route support, we no - * longer have a one-to-one correspondence between - * locally-originated route advertisements and routes in - * the import tables that have local origin. This - * discrepancy arises because a single advertisement - * may contain both an IP prefix and a MAC address. - * Such an advertisement results in two import table - * entries: one indexed by IP prefix, the other indexed - * by MAC address. - * - * TBD: update computation and display of registration - * statistics to reflect the underlying semantics. - */ - if (is_vnc_running) - { - vty_out (vty, "%-24s ", "Registrations:"); - vty_out (vty, "%-8s %-8u ", "Active:", - rfapiApCountAll (bgp_default)); - vty_out (vty, "%-8s %-8u ", "Failed:", - h->stat.count_registrations_failed); - vty_out (vty, "%-8s %-8u", "Total:", - h->stat.count_registrations); - vty_out (vty, "\n"); - } - vty_out (vty, "%-24s ", "Prefixes registered:"); - vty_out (vty, "\n"); - - rfapiCountAllItRoutes (&active_local_routes, - &active_remote_routes, - &holddown_remote_routes, - &imported_remote_routes); - - /* local */ - if (is_vnc_running) - { - vty_out (vty, " %-20s ", "Locally:"); - vty_out (vty, "%-8s %-8u ", "Active:", active_local_routes); - vty_out (vty, "\n"); - } - - - vty_out (vty, " %-20s ", "Remotely:"); - vty_out (vty, "%-8s %-8u", "Active:", active_remote_routes); - vty_out (vty, "\n"); - vty_out (vty, " %-20s ", "In Holddown:"); - vty_out (vty, "%-8s %-8u", "Active:", holddown_remote_routes); - vty_out (vty, "\n"); - vty_out (vty, " %-20s ", "Imported:"); - vty_out (vty, "%-8s %-8u", "Active:", imported_remote_routes); - break; - - case SHOW_NVE_SUMMARY_QUERIES: - vty_out (vty, "%-24s ", "Queries:"); - vty_out (vty, "%-8s %-8u ", "Active:", rfapi_monitor_count (NULL)); - vty_out (vty, "%-8s %-8u ", "Failed:", - h->stat.count_queries_failed); - vty_out (vty, "%-8s %-8u", "Total:", h->stat.count_queries); - break; - - case SHOW_NVE_SUMMARY_RESPONSES: - rfapiRibShowResponsesSummary (vty); - - default: - break; - } - vty_out (vty, "\n"); - } - return 0; + struct bgp *bgp_default = bgp_get_default(); + struct rfapi *h; + int is_vnc_running = !bgp_rfapi_is_vnc_configured(bgp_default); + + int active_local_routes; + int active_remote_routes; + int holddown_remote_routes; + int imported_remote_routes; + + if (!bgp_default) + goto notcfg; + + h = bgp_default->rfapi; + + if (!h) + goto notcfg; + + /* don't show local info if not running RFP */ + if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED) { + + switch (show_type) { + + case SHOW_NVE_SUMMARY_ACTIVE_NVES: + vty_out(vty, "%-24s ", "NVEs:"); + vty_out(vty, "%-8s %-8u ", + "Active:", h->descriptors.count); + vty_out(vty, "%-8s %-8u ", + "Maximum:", h->stat.max_descriptors); + vty_out(vty, "%-8s %-8u", + "Unknown:", h->stat.count_unknown_nves); + break; + + case SHOW_NVE_SUMMARY_REGISTERED: + /* + * NB: With the introduction of L2 route support, we no + * longer have a one-to-one correspondence between + * locally-originated route advertisements and routes in + * the import tables that have local origin. This + * discrepancy arises because a single advertisement + * may contain both an IP prefix and a MAC address. + * Such an advertisement results in two import table + * entries: one indexed by IP prefix, the other indexed + * by MAC address. + * + * TBD: update computation and display of registration + * statistics to reflect the underlying semantics. + */ + if (is_vnc_running) { + vty_out(vty, "%-24s ", "Registrations:"); + vty_out(vty, "%-8s %-8u ", "Active:", + rfapiApCountAll(bgp_default)); + vty_out(vty, "%-8s %-8u ", "Failed:", + h->stat.count_registrations_failed); + vty_out(vty, "%-8s %-8u", + "Total:", h->stat.count_registrations); + vty_out(vty, "\n"); + } + vty_out(vty, "%-24s ", "Prefixes registered:"); + vty_out(vty, "\n"); + + rfapiCountAllItRoutes(&active_local_routes, + &active_remote_routes, + &holddown_remote_routes, + &imported_remote_routes); + + /* local */ + if (is_vnc_running) { + vty_out(vty, " %-20s ", "Locally:"); + vty_out(vty, "%-8s %-8u ", + "Active:", active_local_routes); + vty_out(vty, "\n"); + } + + + vty_out(vty, " %-20s ", "Remotely:"); + vty_out(vty, "%-8s %-8u", + "Active:", active_remote_routes); + vty_out(vty, "\n"); + vty_out(vty, " %-20s ", "In Holddown:"); + vty_out(vty, "%-8s %-8u", + "Active:", holddown_remote_routes); + vty_out(vty, "\n"); + vty_out(vty, " %-20s ", "Imported:"); + vty_out(vty, "%-8s %-8u", + "Active:", imported_remote_routes); + break; + + case SHOW_NVE_SUMMARY_QUERIES: + vty_out(vty, "%-24s ", "Queries:"); + vty_out(vty, "%-8s %-8u ", + "Active:", rfapi_monitor_count(NULL)); + vty_out(vty, "%-8s %-8u ", + "Failed:", h->stat.count_queries_failed); + vty_out(vty, "%-8s %-8u", + "Total:", h->stat.count_queries); + break; + + case SHOW_NVE_SUMMARY_RESPONSES: + rfapiRibShowResponsesSummary(vty); + + default: + break; + } + vty_out(vty, "\n"); + } + return 0; notcfg: - vty_out (vty, "VNC is not configured.\n"); - return CMD_WARNING; + vty_out(vty, "VNC is not configured.\n"); + return CMD_WARNING; } -static int -rfapi_show_nves ( - struct vty *vty, - struct prefix *vn_prefix, - struct prefix *un_prefix) +static int rfapi_show_nves(struct vty *vty, struct prefix *vn_prefix, + struct prefix *un_prefix) { - //struct hash *rfds; - //struct rfp_rfapi_descriptor_param param; - - struct bgp *bgp_default = bgp_get_default (); - struct rfapi *h; - struct listnode *node; - struct rfapi_descriptor *rfd; - - int total = 0; - int printed = 0; - int rc; - - if (!bgp_default) - goto notcfg; - - h = bgp_default->rfapi; - - if (!h) - goto notcfg; - - rc = rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); - if (rc) - return rc; - - for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) - { - struct prefix pfx; - char vn_addr_buf[INET6_ADDRSTRLEN] = - { - 0,}; - char un_addr_buf[INET6_ADDRSTRLEN] = - { - 0,}; - char age[10]; - - ++total; - - if (vn_prefix) - { - assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx)); - if (!prefix_match (vn_prefix, &pfx)) - continue; - } - - if (un_prefix) - { - assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx)); - if (!prefix_match (un_prefix, &pfx)) - continue; - } - - rfapiRfapiIpAddr2Str (&rfd->vn_addr, vn_addr_buf, INET6_ADDRSTRLEN); - rfapiRfapiIpAddr2Str (&rfd->un_addr, un_addr_buf, INET6_ADDRSTRLEN); - - if (!printed) - { - /* print out a header */ - vty_out (vty, - " Active Next Hops\n"); - vty_out (vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n", - "VN Address", - "UN Address", - "Regis", "Resps", "Reach", "Remove", "Age"); - } - - ++printed; - - vty_out (vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n", - vn_addr_buf, - un_addr_buf, - rfapiApCount (rfd), - rfapi_monitor_count (rfd), - rfd->stat_count_nh_reachable, - rfd->stat_count_nh_removal, - rfapiFormatAge(rfd->open_time, age, 10)); - } - - if (printed > 0 || vn_prefix || un_prefix) - vty_out (vty, "Displayed %d out of %d active NVEs\n", - printed, total); - - return 0; + // struct hash *rfds; + // struct rfp_rfapi_descriptor_param param; + + struct bgp *bgp_default = bgp_get_default(); + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; + + int total = 0; + int printed = 0; + int rc; + + if (!bgp_default) + goto notcfg; + + h = bgp_default->rfapi; + + if (!h) + goto notcfg; + + rc = rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); + if (rc) + return rc; + + for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { + struct prefix pfx; + char vn_addr_buf[INET6_ADDRSTRLEN] = { + 0, + }; + char un_addr_buf[INET6_ADDRSTRLEN] = { + 0, + }; + char age[10]; + + ++total; + + if (vn_prefix) { + assert(!rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx)); + if (!prefix_match(vn_prefix, &pfx)) + continue; + } + + if (un_prefix) { + assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx)); + if (!prefix_match(un_prefix, &pfx)) + continue; + } + + rfapiRfapiIpAddr2Str(&rfd->vn_addr, vn_addr_buf, + INET6_ADDRSTRLEN); + rfapiRfapiIpAddr2Str(&rfd->un_addr, un_addr_buf, + INET6_ADDRSTRLEN); + + if (!printed) { + /* print out a header */ + vty_out(vty, + " Active Next Hops\n"); + vty_out(vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n", + "VN Address", "UN Address", "Regis", "Resps", + "Reach", "Remove", "Age"); + } + + ++printed; + + vty_out(vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n", + vn_addr_buf, un_addr_buf, rfapiApCount(rfd), + rfapi_monitor_count(rfd), rfd->stat_count_nh_reachable, + rfd->stat_count_nh_removal, + rfapiFormatAge(rfd->open_time, age, 10)); + } + + if (printed > 0 || vn_prefix || un_prefix) + vty_out(vty, "Displayed %d out of %d active NVEs\n", printed, + total); + + return 0; notcfg: - vty_out (vty, "VNC is not configured.\n"); - return CMD_WARNING; + vty_out(vty, "VNC is not configured.\n"); + return CMD_WARNING; } @@ -4608,15 +4292,15 @@ DEFUN (vnc_show_summary, VNC_SHOW_STR "Display VNC status summary\n") { - if (!check_and_display_is_vnc_running (vty)) - return CMD_SUCCESS; - bgp_rfapi_show_summary (bgp_get_default (), vty); - vty_out (vty, "\n"); - rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); - rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); - rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_RESPONSES); - rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED); - return CMD_SUCCESS; + if (!check_and_display_is_vnc_running(vty)) + return CMD_SUCCESS; + bgp_rfapi_show_summary(bgp_get_default(), vty); + vty_out(vty, "\n"); + rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); + rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES); + rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_RESPONSES); + rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_REGISTERED); + return CMD_SUCCESS; } DEFUN (vnc_show_nves, @@ -4626,8 +4310,8 @@ DEFUN (vnc_show_nves, VNC_SHOW_STR "List known NVEs\n") { - rfapi_show_nves (vty, NULL, NULL); - return CMD_SUCCESS; + rfapi_show_nves(vty, NULL, NULL); + return CMD_SUCCESS; } DEFUN (vnc_show_nves_ptct, @@ -4641,75 +4325,65 @@ DEFUN (vnc_show_nves_ptct, "IPv4 interface address\n" "IPv6 interface address\n") { - struct prefix pfx; - - if (!check_and_display_is_vnc_running (vty)) - return CMD_SUCCESS; - - if (!str2prefix (argv[4]->arg, &pfx)) - { - vty_out (vty, "Malformed address \"%s\"\n", argv[4]->arg); - return CMD_WARNING; - } - if (pfx.family != AF_INET && pfx.family != AF_INET6) - { - vty_out (vty, "Invalid address \"%s\"\n", argv[4]->arg); - return CMD_WARNING; - } - - if (argv[3]->arg[0] == 'u') - { - rfapi_show_nves (vty, NULL, &pfx); - } - else - { - rfapi_show_nves (vty, &pfx, NULL); - } - - return CMD_SUCCESS; + struct prefix pfx; + + if (!check_and_display_is_vnc_running(vty)) + return CMD_SUCCESS; + + if (!str2prefix(argv[4]->arg, &pfx)) { + vty_out(vty, "Malformed address \"%s\"\n", argv[4]->arg); + return CMD_WARNING; + } + if (pfx.family != AF_INET && pfx.family != AF_INET6) { + vty_out(vty, "Invalid address \"%s\"\n", argv[4]->arg); + return CMD_WARNING; + } + + if (argv[3]->arg[0] == 'u') { + rfapi_show_nves(vty, NULL, &pfx); + } else { + rfapi_show_nves(vty, &pfx, NULL); + } + + return CMD_SUCCESS; } /* adapted from rfp_registration_cache_log() */ -static void -rfapi_show_registrations ( - struct vty *vty, - struct prefix *restrict_to, - int show_local, - int show_remote, - int show_holddown, - int show_imported) +static void rfapi_show_registrations(struct vty *vty, + struct prefix *restrict_to, int show_local, + int show_remote, int show_holddown, + int show_imported) { - int printed = 0; - - if (!vty) - return; - - rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED); - - if (show_local) - { - /* non-expiring, local */ - printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 1, 0, 0); - } - if (show_remote) - { - /* non-expiring, non-local */ - printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 0); - } - if (show_holddown) - { - /* expiring, including local */ - printed += rfapiShowRemoteRegistrations (vty, restrict_to, 1, 1, 1, 0); - } - if (show_imported) - { - /* non-expiring, non-local */ - printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 1); - } - if (!printed) - { - vty_out (vty, "\n"); - } + int printed = 0; + + if (!vty) + return; + + rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_REGISTERED); + + if (show_local) { + /* non-expiring, local */ + printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 1, + 0, 0); + } + if (show_remote) { + /* non-expiring, non-local */ + printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 0, + 1, 0); + } + if (show_holddown) { + /* expiring, including local */ + printed += rfapiShowRemoteRegistrations(vty, restrict_to, 1, 1, + 1, 0); + } + if (show_imported) { + /* non-expiring, non-local */ + printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 0, + 1, 1); + } + if (!printed) { + vty_out(vty, "\n"); + } } DEFUN (vnc_show_registrations_pfx, @@ -4722,24 +4396,20 @@ DEFUN (vnc_show_registrations_pfx, "Limit output to a particular IPv6 prefix\n" "Limit output to a particular IPv6 address\n") { - struct prefix p; - struct prefix *p_addr = NULL; - - if (argc > 3) - { - if (!str2prefix (argv[3]->arg, &p)) - { - vty_out (vty, "Invalid prefix: %s\n", argv[3]->arg); - return CMD_SUCCESS; - } - else - { - p_addr = &p; - } - } - - rfapi_show_registrations (vty, p_addr, 1, 1, 1, 1); - return CMD_SUCCESS; + struct prefix p; + struct prefix *p_addr = NULL; + + if (argc > 3) { + if (!str2prefix(argv[3]->arg, &p)) { + vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg); + return CMD_SUCCESS; + } else { + p_addr = &p; + } + } + + rfapi_show_registrations(vty, p_addr, 1, 1, 1, 1); + return CMD_SUCCESS; } DEFUN (vnc_show_registrations_some_pfx, @@ -4757,56 +4427,50 @@ DEFUN (vnc_show_registrations_some_pfx, "Limit output to a particular prefix or address\n" "Limit output to a particular prefix or address\n") { - struct prefix p; - struct prefix *p_addr = NULL; - - int show_local = 0; - int show_remote = 0; - int show_holddown = 0; - int show_imported = 0; - - if (argc > 4) - { - if (!str2prefix (argv[4]->arg, &p)) - { - vty_out (vty, "Invalid prefix: %s\n", argv[4]->arg); - return CMD_SUCCESS; - } - else - { - p_addr = &p; - } - } - switch (argv[3]->arg[0]) - { - case 'a': - show_local = 1; - show_remote = 1; - show_holddown = 1; - show_imported = 1; - break; - - case 'h': - show_holddown = 1; - break; - - case 'i': - show_imported = 1; - break; - - case 'l': - show_local = 1; - break; - - case 'r': - show_remote = 1; - break; - } - - rfapi_show_registrations (vty, p_addr, - show_local, show_remote, show_holddown, - show_imported); - return CMD_SUCCESS; + struct prefix p; + struct prefix *p_addr = NULL; + + int show_local = 0; + int show_remote = 0; + int show_holddown = 0; + int show_imported = 0; + + if (argc > 4) { + if (!str2prefix(argv[4]->arg, &p)) { + vty_out(vty, "Invalid prefix: %s\n", argv[4]->arg); + return CMD_SUCCESS; + } else { + p_addr = &p; + } + } + switch (argv[3]->arg[0]) { + case 'a': + show_local = 1; + show_remote = 1; + show_holddown = 1; + show_imported = 1; + break; + + case 'h': + show_holddown = 1; + break; + + case 'i': + show_imported = 1; + break; + + case 'l': + show_local = 1; + break; + + case 'r': + show_remote = 1; + break; + } + + rfapi_show_registrations(vty, p_addr, show_local, show_remote, + show_holddown, show_imported); + return CMD_SUCCESS; } DEFUN (vnc_show_responses_pfx, @@ -4819,29 +4483,25 @@ DEFUN (vnc_show_responses_pfx, "Limit output to a particular IPv6 prefix\n" "Limit output to a particular IPv6 address\n" ) { - struct prefix p; - struct prefix *p_addr = NULL; - - if (argc > 3) - { - if (!str2prefix (argv[3]->arg, &p)) - { - vty_out (vty, "Invalid prefix: %s\n", argv[3]->arg); - return CMD_SUCCESS; - } - else - { - p_addr = &p; - } - } - rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); - - rfapiRibShowResponsesSummary (vty); - - rfapiRibShowResponses (vty, p_addr, 0); - rfapiRibShowResponses (vty, p_addr, 1); - - return CMD_SUCCESS; + struct prefix p; + struct prefix *p_addr = NULL; + + if (argc > 3) { + if (!str2prefix(argv[3]->arg, &p)) { + vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg); + return CMD_SUCCESS; + } else { + p_addr = &p; + } + } + rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES); + + rfapiRibShowResponsesSummary(vty); + + rfapiRibShowResponses(vty, p_addr, 0); + rfapiRibShowResponses(vty, p_addr, 1); + + return CMD_SUCCESS; } DEFUN (vnc_show_responses_some_pfx, @@ -4856,49 +4516,44 @@ DEFUN (vnc_show_responses_some_pfx, "Limit output to a particular IPv6 prefix\n" "Limit output to a particular IPV6 address\n") { - struct prefix p; - struct prefix *p_addr = NULL; - - int show_active = 0; - int show_removed = 0; - - if (!check_and_display_is_vnc_running (vty)) - return CMD_SUCCESS; - - if (argc > 4) - { - if (!str2prefix (argv[4]->arg, &p)) - { - vty_out (vty, "Invalid prefix: %s\n", argv[4]->arg); - return CMD_SUCCESS; - } - else - { - p_addr = &p; - } - } - - switch (argv[3]->arg[0]) - { - case 'a': - show_active = 1; - break; - - case 'r': - show_removed = 1; - break; - } - - rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); - - rfapiRibShowResponsesSummary (vty); - - if (show_active) - rfapiRibShowResponses (vty, p_addr, 0); - if (show_removed) - rfapiRibShowResponses (vty, p_addr, 1); - - return CMD_SUCCESS; + struct prefix p; + struct prefix *p_addr = NULL; + + int show_active = 0; + int show_removed = 0; + + if (!check_and_display_is_vnc_running(vty)) + return CMD_SUCCESS; + + if (argc > 4) { + if (!str2prefix(argv[4]->arg, &p)) { + vty_out(vty, "Invalid prefix: %s\n", argv[4]->arg); + return CMD_SUCCESS; + } else { + p_addr = &p; + } + } + + switch (argv[3]->arg[0]) { + case 'a': + show_active = 1; + break; + + case 'r': + show_removed = 1; + break; + } + + rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES); + + rfapiRibShowResponsesSummary(vty); + + if (show_active) + rfapiRibShowResponses(vty, p_addr, 0); + if (show_removed) + rfapiRibShowResponses(vty, p_addr, 1); + + return CMD_SUCCESS; } DEFUN (show_vnc_queries_pfx, @@ -4911,22 +4566,20 @@ DEFUN (show_vnc_queries_pfx, "Limit output to a particular IPv6 prefix\n" "Limit output to a particualr IPV6 address\n") { - struct prefix pfx; - struct prefix *p = NULL; - - if (argc > 3) - { - if (!str2prefix (argv[3]->arg, &pfx)) - { - vty_out (vty, "Invalid prefix: %s\n", argv[3]->arg); - return CMD_WARNING; - } - p = &pfx; - } - - rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); - - return rfapiShowVncQueries (vty, p); + struct prefix pfx; + struct prefix *p = NULL; + + if (argc > 3) { + if (!str2prefix(argv[3]->arg, &pfx)) { + vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg); + return CMD_WARNING; + } + p = &pfx; + } + + rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES); + + return rfapiShowVncQueries(vty, p); } DEFUN (vnc_clear_counters, @@ -4936,43 +4589,42 @@ DEFUN (vnc_clear_counters, VNC_SHOW_STR "Reset VNC counters\n") { - struct bgp *bgp_default = bgp_get_default (); - struct rfapi *h; - struct listnode *node; - struct rfapi_descriptor *rfd; + struct bgp *bgp_default = bgp_get_default(); + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; - if (!bgp_default) - goto notcfg; + if (!bgp_default) + goto notcfg; - h = bgp_default->rfapi; + h = bgp_default->rfapi; - if (!h) - goto notcfg; + if (!h) + goto notcfg; - /* per-rfd */ - for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) - { - rfd->stat_count_nh_reachable = 0; - rfd->stat_count_nh_removal = 0; - } + /* per-rfd */ + for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { + rfd->stat_count_nh_reachable = 0; + rfd->stat_count_nh_removal = 0; + } - /* global */ - memset (&h->stat, 0, sizeof (h->stat)); + /* global */ + memset(&h->stat, 0, sizeof(h->stat)); - /* - * 151122 per bug 103, set count_registrations = number active. - * Do same for queries - */ - h->stat.count_registrations = rfapiApCountAll (bgp_default); - h->stat.count_queries = rfapi_monitor_count (NULL); + /* + * 151122 per bug 103, set count_registrations = number active. + * Do same for queries + */ + h->stat.count_registrations = rfapiApCountAll(bgp_default); + h->stat.count_queries = rfapi_monitor_count(NULL); - rfapiRibShowResponsesSummaryClear (); + rfapiRibShowResponsesSummaryClear(); - return CMD_SUCCESS; + return CMD_SUCCESS; notcfg: - vty_out (vty, "VNC is not configured.\n"); - return CMD_WARNING; + vty_out(vty, "VNC is not configured.\n"); + return CMD_WARNING; } /************************************************************************ @@ -4981,172 +4633,160 @@ notcfg: * add [vrf <vrf-name>] prefix <prefix> * [rd <value>] [label <value>] [local-preference <0-4294967295>] ************************************************************************/ -static int -vnc_add_vrf_prefix (struct vty *vty, - const char *arg_vrf, - const char *arg_prefix, - const char *arg_rd, /* optional */ - const char *arg_label, /* optional */ - const char *arg_pref) /* optional */ +static int vnc_add_vrf_prefix(struct vty *vty, const char *arg_vrf, + const char *arg_prefix, + const char *arg_rd, /* optional */ + const char *arg_label, /* optional */ + const char *arg_pref) /* optional */ { - struct bgp *bgp; - struct rfapi_nve_group_cfg *rfg; - struct prefix pfx; - struct rfapi_ip_prefix rpfx; - uint32_t pref = 0; - struct rfapi_vn_option optary[3]; - struct rfapi_vn_option *opt = NULL; - int cur_opt = 0; - - bgp = bgp_get_default (); /* assume main instance for now */ - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - if (!bgp->rfapi || !bgp->rfapi_cfg) - { - vty_out (vty, "VRF support not configured\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - rfg = bgp_rfapi_cfg_match_byname (bgp, arg_vrf, RFAPI_GROUP_CFG_VRF); - /* arg checks */ - if (!rfg) - { - vty_out (vty, "VRF \"%s\" appears not to be configured.\n", - arg_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - if (!rfg->rt_export_list || !rfg->rfapi_import_table) - { - vty_out (vty, "VRF \"%s\" is missing RT import/export RT configuration.\n", - arg_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - if (!rfg->rd.family && !arg_rd) - { - vty_out (vty, "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n", - arg_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - if (rfg->label > MPLS_LABEL_MAX && !arg_label) - { - vty_out (vty, "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n", - arg_vrf); - return CMD_WARNING_CONFIG_FAILED; - } - if (!str2prefix (arg_prefix, &pfx)) - { - vty_out (vty, "Malformed prefix \"%s\"\n", - arg_prefix); - return CMD_WARNING_CONFIG_FAILED; - } - rfapiQprefix2Rprefix (&pfx, &rpfx); - memset (optary, 0, sizeof (optary)); - if (arg_rd) - { - if (opt != NULL) - opt->next = &optary[cur_opt]; - opt = &optary[cur_opt++]; - opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; - if (!str2prefix_rd (arg_rd, &opt->v.internal_rd)) - { - vty_out (vty, "Malformed RD \"%s\"\n", - arg_rd); - return CMD_WARNING_CONFIG_FAILED; - } - } - if (rfg->label <= MPLS_LABEL_MAX || arg_label) - { - struct rfapi_l2address_option *l2o; - if (opt != NULL) - opt->next = &optary[cur_opt]; - opt = &optary[cur_opt++]; - opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR; - l2o = &opt->v.l2addr; - if (arg_label) - { - int32_t label; - label = strtoul(arg_label, NULL, 10); - l2o->label = label; - } - else - l2o->label = rfg->label; - } - if (arg_pref) - { - char *endptr = NULL; - pref = strtoul (arg_pref, &endptr, 10); - if (*endptr != '\0') - { - vty_out (vty, "%% Invalid local-preference value \"%s\"\n", - arg_pref); - return CMD_WARNING_CONFIG_FAILED; - } - } - rpfx.cost = 255 - (pref & 255) ; - if (rfg->rfd == NULL) /* need new rfapi_handle */ - { - /* based on rfapi_open */ - struct rfapi_descriptor *rfd; - rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor)); - rfd->bgp = bgp; - rfg->rfd = rfd; - /* leave most fields empty as will get from (dynamic) config when needed */ - rfd->default_tunneltype_option.type = BGP_ENCAP_TYPE_MPLS; - rfd->cookie = rfg; - if (rfg->vn_prefix.family && - !CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) - { - rfapiQprefix2Raddr(&rfg->vn_prefix, &rfd->vn_addr); - } - else - { - memset(&rfd->vn_addr, 0, sizeof(struct rfapi_ip_addr)); - rfd->vn_addr.addr_family = AF_INET; - rfd->vn_addr.addr.v4 = bgp->router_id; - } - rfd->un_addr = rfd->vn_addr; /* sigh, need something in UN for lookups */ - vnc_zlog_debug_verbose ("%s: Opening RFD for VRF %s", - __func__, rfg->name); - rfapi_init_and_open(bgp, rfd, rfg); - } - - if (!rfapi_register (rfg->rfd, &rpfx, RFAPI_INFINITE_LIFETIME, NULL, - (cur_opt ? optary : NULL), RFAPI_REGISTER_ADD)) - { - struct rfapi_next_hop_entry *head = NULL; - struct rfapi_next_hop_entry *tail = NULL; - struct rfapi_vn_option *vn_opt_new; - - vnc_zlog_debug_verbose ("%s: rfapi_register succeeded", __func__); - - if (bgp->rfapi->rfp_methods.local_cb) - { - struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfg->rfd; - vn_opt_new = rfapi_vn_options_dup (opt); - - rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx, - 1, RFAPI_INFINITE_LIFETIME, - vn_opt_new, &head, &tail); - if (head) - { - bgp->rfapi->flags |= RFAPI_INCALLBACK; - (*bgp->rfapi->rfp_methods.local_cb) (head, r->cookie); - bgp->rfapi->flags &= ~RFAPI_INCALLBACK; - } - head = tail = NULL; - } - vnc_zlog_debug_verbose ("%s completed, count=%d/%d", __func__, - rfg->rfapi_import_table->local_count[AFI_IP], - rfg->rfapi_import_table->local_count[AFI_IP6]); - return CMD_SUCCESS; - } - - vnc_zlog_debug_verbose ("%s: rfapi_register failed", __func__); - vty_out (vty, "Add failed.\n"); - return CMD_WARNING_CONFIG_FAILED; + struct bgp *bgp; + struct rfapi_nve_group_cfg *rfg; + struct prefix pfx; + struct rfapi_ip_prefix rpfx; + uint32_t pref = 0; + struct rfapi_vn_option optary[3]; + struct rfapi_vn_option *opt = NULL; + int cur_opt = 0; + + bgp = bgp_get_default(); /* assume main instance for now */ + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (!bgp->rfapi || !bgp->rfapi_cfg) { + vty_out(vty, "VRF support not configured\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + rfg = bgp_rfapi_cfg_match_byname(bgp, arg_vrf, RFAPI_GROUP_CFG_VRF); + /* arg checks */ + if (!rfg) { + vty_out(vty, "VRF \"%s\" appears not to be configured.\n", + arg_vrf); + return CMD_WARNING_CONFIG_FAILED; + } + if (!rfg->rt_export_list || !rfg->rfapi_import_table) { + vty_out(vty, + "VRF \"%s\" is missing RT import/export RT configuration.\n", + arg_vrf); + return CMD_WARNING_CONFIG_FAILED; + } + if (!rfg->rd.family && !arg_rd) { + vty_out(vty, + "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n", + arg_vrf); + return CMD_WARNING_CONFIG_FAILED; + } + if (rfg->label > MPLS_LABEL_MAX && !arg_label) { + vty_out(vty, + "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n", + arg_vrf); + return CMD_WARNING_CONFIG_FAILED; + } + if (!str2prefix(arg_prefix, &pfx)) { + vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix); + return CMD_WARNING_CONFIG_FAILED; + } + rfapiQprefix2Rprefix(&pfx, &rpfx); + memset(optary, 0, sizeof(optary)); + if (arg_rd) { + if (opt != NULL) + opt->next = &optary[cur_opt]; + opt = &optary[cur_opt++]; + opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; + if (!str2prefix_rd(arg_rd, &opt->v.internal_rd)) { + vty_out(vty, "Malformed RD \"%s\"\n", arg_rd); + return CMD_WARNING_CONFIG_FAILED; + } + } + if (rfg->label <= MPLS_LABEL_MAX || arg_label) { + struct rfapi_l2address_option *l2o; + if (opt != NULL) + opt->next = &optary[cur_opt]; + opt = &optary[cur_opt++]; + opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR; + l2o = &opt->v.l2addr; + if (arg_label) { + int32_t label; + label = strtoul(arg_label, NULL, 10); + l2o->label = label; + } else + l2o->label = rfg->label; + } + if (arg_pref) { + char *endptr = NULL; + pref = strtoul(arg_pref, &endptr, 10); + if (*endptr != '\0') { + vty_out(vty, + "%% Invalid local-preference value \"%s\"\n", + arg_pref); + return CMD_WARNING_CONFIG_FAILED; + } + } + rpfx.cost = 255 - (pref & 255); + if (rfg->rfd == NULL) /* need new rfapi_handle */ + { + /* based on rfapi_open */ + struct rfapi_descriptor *rfd; + rfd = XCALLOC(MTYPE_RFAPI_DESC, + sizeof(struct rfapi_descriptor)); + rfd->bgp = bgp; + rfg->rfd = rfd; + /* leave most fields empty as will get from (dynamic) config + * when needed */ + rfd->default_tunneltype_option.type = BGP_ENCAP_TYPE_MPLS; + rfd->cookie = rfg; + if (rfg->vn_prefix.family + && !CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) { + rfapiQprefix2Raddr(&rfg->vn_prefix, &rfd->vn_addr); + } else { + memset(&rfd->vn_addr, 0, sizeof(struct rfapi_ip_addr)); + rfd->vn_addr.addr_family = AF_INET; + rfd->vn_addr.addr.v4 = bgp->router_id; + } + rfd->un_addr = rfd->vn_addr; /* sigh, need something in UN for + lookups */ + vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__, + rfg->name); + rfapi_init_and_open(bgp, rfd, rfg); + } + + if (!rfapi_register(rfg->rfd, &rpfx, RFAPI_INFINITE_LIFETIME, NULL, + (cur_opt ? optary : NULL), RFAPI_REGISTER_ADD)) { + struct rfapi_next_hop_entry *head = NULL; + struct rfapi_next_hop_entry *tail = NULL; + struct rfapi_vn_option *vn_opt_new; + + vnc_zlog_debug_verbose("%s: rfapi_register succeeded", + __func__); + + if (bgp->rfapi->rfp_methods.local_cb) { + struct rfapi_descriptor *r = + (struct rfapi_descriptor *)rfg->rfd; + vn_opt_new = rfapi_vn_options_dup(opt); + + rfapiAddDeleteLocalRfpPrefix(&r->un_addr, &r->vn_addr, + &rpfx, 1, + RFAPI_INFINITE_LIFETIME, + vn_opt_new, &head, &tail); + if (head) { + bgp->rfapi->flags |= RFAPI_INCALLBACK; + (*bgp->rfapi->rfp_methods.local_cb)(head, + r->cookie); + bgp->rfapi->flags &= ~RFAPI_INCALLBACK; + } + head = tail = NULL; + } + vnc_zlog_debug_verbose( + "%s completed, count=%d/%d", __func__, + rfg->rfapi_import_table->local_count[AFI_IP], + rfg->rfapi_import_table->local_count[AFI_IP6]); + return CMD_SUCCESS; + } + + vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__); + vty_out(vty, "Add failed.\n"); + return CMD_WARNING_CONFIG_FAILED; } DEFUN (add_vrf_prefix_rd_label_pref, @@ -5165,33 +4805,32 @@ DEFUN (add_vrf_prefix_rd_label_pref, "Set advertised local preference\n" "local preference (higher=more preferred)\n") { - char *arg_vrf = argv[2]->arg; - char *arg_prefix = argv[4]->arg; - char *arg_rd = NULL; /* optional */ - char *arg_label = NULL; /* optional */ - char *arg_pref = NULL; /* optional */ - int pargc = 5; - argc--; /* don't parse argument */ - while (pargc < argc) - { - switch (argv[pargc++]->arg[0]) - { - case 'r': - arg_rd = argv[pargc]->arg; - break; - case 'l': - arg_label = argv[pargc]->arg; - break; - case 'p': - arg_pref = argv[pargc]->arg; - break; - default: - break; - } - pargc ++; - } - - return vnc_add_vrf_prefix (vty, arg_vrf, arg_prefix, arg_rd, arg_label, arg_pref); + char *arg_vrf = argv[2]->arg; + char *arg_prefix = argv[4]->arg; + char *arg_rd = NULL; /* optional */ + char *arg_label = NULL; /* optional */ + char *arg_pref = NULL; /* optional */ + int pargc = 5; + argc--; /* don't parse argument */ + while (pargc < argc) { + switch (argv[pargc++]->arg[0]) { + case 'r': + arg_rd = argv[pargc]->arg; + break; + case 'l': + arg_label = argv[pargc]->arg; + break; + case 'p': + arg_pref = argv[pargc]->arg; + break; + default: + break; + } + pargc++; + } + + return vnc_add_vrf_prefix(vty, arg_vrf, arg_prefix, arg_rd, arg_label, + arg_pref); } /************************************************************************ @@ -5199,89 +4838,78 @@ DEFUN (add_vrf_prefix_rd_label_pref, * * clear [vrf <vrf-name>] prefix <prefix> [rd <value>] ************************************************************************/ -static int -rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg) +static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg) { - int count = 0; - afi_t afi = AFI_MAX; - while (afi-- > 0) - { - count += rfg->rfapi_import_table->local_count[afi]; - } - return count; + int count = 0; + afi_t afi = AFI_MAX; + while (afi-- > 0) { + count += rfg->rfapi_import_table->local_count[afi]; + } + return count; } -static void -clear_vnc_vrf_closer (struct rfapi_nve_group_cfg *rfg) +static void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg *rfg) { - struct rfapi_descriptor *rfd = rfg->rfd; - afi_t afi; - - if (rfd == NULL) - return; - /* check if IT is empty */ - for (afi = 0; - afi < AFI_MAX && rfg->rfapi_import_table->local_count[afi] == 0; - afi++); - - if (afi == AFI_MAX) - { - vnc_zlog_debug_verbose ("%s: closing RFD for VRF %s", - __func__, rfg->name); - rfg->rfd = NULL; - rfapi_close(rfd); - } - else - { - vnc_zlog_debug_verbose ("%s: VRF %s afi=%d count=%d", - __func__, rfg->name, afi, - rfg->rfapi_import_table->local_count[afi]); - } + struct rfapi_descriptor *rfd = rfg->rfd; + afi_t afi; + + if (rfd == NULL) + return; + /* check if IT is empty */ + for (afi = 0; + afi < AFI_MAX && rfg->rfapi_import_table->local_count[afi] == 0; + afi++) + ; + + if (afi == AFI_MAX) { + vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__, + rfg->name); + rfg->rfd = NULL; + rfapi_close(rfd); + } else { + vnc_zlog_debug_verbose( + "%s: VRF %s afi=%d count=%d", __func__, rfg->name, afi, + rfg->rfapi_import_table->local_count[afi]); + } } -static int -vnc_clear_vrf (struct vty *vty, - struct bgp *bgp, - const char *arg_vrf, - const char *arg_prefix, /* NULL = all */ - const char *arg_rd) /* optional */ +static int vnc_clear_vrf(struct vty *vty, struct bgp *bgp, const char *arg_vrf, + const char *arg_prefix, /* NULL = all */ + const char *arg_rd) /* optional */ { - struct rfapi_nve_group_cfg *rfg; - struct rfapi_local_reg_delete_arg cda; - int rc; - int start_count; - - if (bgp == NULL) - bgp = bgp_get_default (); /* assume main instance for now */ - if (!bgp) - { - vty_out (vty, "No BGP process is configured\n"); - return CMD_WARNING; - } - if (!bgp->rfapi || !bgp->rfapi_cfg) - { - vty_out (vty, "VRF support not configured\n"); - return CMD_WARNING; - } - rfg = bgp_rfapi_cfg_match_byname (bgp, arg_vrf, RFAPI_GROUP_CFG_VRF); - /* arg checks */ - if (!rfg) - { - vty_out (vty, "VRF \"%s\" appears not to be configured.\n", - arg_vrf); - return CMD_WARNING; - } - rc = parse_deleter_args (vty, bgp, arg_prefix, NULL, NULL, NULL, NULL, - arg_rd, rfg, &cda); - if (rc != CMD_SUCCESS) /* parse error */ - return rc; - - start_count = rfapi_cfg_group_it_count(rfg); - clear_vnc_prefix (&cda); - clear_vnc_vrf_closer (rfg); - vty_out (vty, "Cleared %u out of %d prefixes.\n", - cda.pfx_count, start_count); - return CMD_SUCCESS; + struct rfapi_nve_group_cfg *rfg; + struct rfapi_local_reg_delete_arg cda; + int rc; + int start_count; + + if (bgp == NULL) + bgp = bgp_get_default(); /* assume main instance for now */ + if (!bgp) { + vty_out(vty, "No BGP process is configured\n"); + return CMD_WARNING; + } + if (!bgp->rfapi || !bgp->rfapi_cfg) { + vty_out(vty, "VRF support not configured\n"); + return CMD_WARNING; + } + rfg = bgp_rfapi_cfg_match_byname(bgp, arg_vrf, RFAPI_GROUP_CFG_VRF); + /* arg checks */ + if (!rfg) { + vty_out(vty, "VRF \"%s\" appears not to be configured.\n", + arg_vrf); + return CMD_WARNING; + } + rc = parse_deleter_args(vty, bgp, arg_prefix, NULL, NULL, NULL, NULL, + arg_rd, rfg, &cda); + if (rc != CMD_SUCCESS) /* parse error */ + return rc; + + start_count = rfapi_cfg_group_it_count(rfg); + clear_vnc_prefix(&cda); + clear_vnc_vrf_closer(rfg); + vty_out(vty, "Cleared %u out of %d prefixes.\n", cda.pfx_count, + start_count); + return CMD_SUCCESS; } DEFUN (clear_vrf_prefix_rd, @@ -5296,27 +4924,25 @@ DEFUN (clear_vrf_prefix_rd, "Specific VRF Route Distinguisher\n" "<as-number>:<number> or <ip-address>:<number>\n") { - char *arg_vrf = argv[2]->arg; - char *arg_prefix = NULL; /* optional */ - char *arg_rd = NULL; /* optional */ - int pargc = 3; - argc--; /* don't check parameter */ - while (pargc < argc) - { - switch (argv[pargc++]->arg[0]) - { - case 'r': - arg_rd = argv[pargc]->arg; - break; - case 'p': - arg_prefix = argv[pargc]->arg; - break; - default: - break; - } - pargc ++; - } - return vnc_clear_vrf (vty, NULL, arg_vrf, arg_prefix, arg_rd); + char *arg_vrf = argv[2]->arg; + char *arg_prefix = NULL; /* optional */ + char *arg_rd = NULL; /* optional */ + int pargc = 3; + argc--; /* don't check parameter */ + while (pargc < argc) { + switch (argv[pargc++]->arg[0]) { + case 'r': + arg_rd = argv[pargc]->arg; + break; + case 'p': + arg_prefix = argv[pargc]->arg; + break; + default: + break; + } + pargc++; + } + return vnc_clear_vrf(vty, NULL, arg_vrf, arg_prefix, arg_rd); } DEFUN (clear_vrf_all, @@ -5327,71 +4953,71 @@ DEFUN (clear_vrf_all, "VRF name\n" "All prefixes\n") { - char *arg_vrf = argv[2]->arg; - return vnc_clear_vrf (vty, NULL, arg_vrf, NULL, NULL); + char *arg_vrf = argv[2]->arg; + return vnc_clear_vrf(vty, NULL, arg_vrf, NULL, NULL); } -void rfapi_vty_init () +void rfapi_vty_init() { - install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd); - install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd); - install_element (ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd); - install_element (ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd); - install_element (ENABLE_NODE, &add_vnc_prefix_lnh_cmd); - - install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_cmd); - install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_cmd); - install_element (ENABLE_NODE, &add_vnc_prefix_cost_cmd); - install_element (ENABLE_NODE, &add_vnc_prefix_life_cmd); - install_element (ENABLE_NODE, &add_vnc_prefix_cmd); - - install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd); - install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd); - install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd); - install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd); - install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd); - install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_cmd); - install_element (ENABLE_NODE, &add_vnc_mac_vni_life_cmd); - install_element (ENABLE_NODE, &add_vnc_mac_vni_cmd); - - install_element (ENABLE_NODE, &add_vrf_prefix_rd_label_pref_cmd); - - install_element (ENABLE_NODE, &clear_vnc_nve_all_cmd); - install_element (ENABLE_NODE, &clear_vnc_nve_vn_un_cmd); - install_element (ENABLE_NODE, &clear_vnc_nve_un_vn_cmd); - install_element (ENABLE_NODE, &clear_vnc_nve_vn_cmd); - install_element (ENABLE_NODE, &clear_vnc_nve_un_cmd); - - install_element (ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd); - install_element (ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd); - install_element (ENABLE_NODE, &clear_vnc_prefix_un_cmd); - install_element (ENABLE_NODE, &clear_vnc_prefix_vn_cmd); - install_element (ENABLE_NODE, &clear_vnc_prefix_all_cmd); - - install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_cmd); - install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_cmd); - install_element (ENABLE_NODE, &clear_vnc_mac_un_cmd); - install_element (ENABLE_NODE, &clear_vnc_mac_vn_cmd); - install_element (ENABLE_NODE, &clear_vnc_mac_all_cmd); - - install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd); - install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd); - install_element (ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd); - install_element (ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd); - install_element (ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd); - - install_element (ENABLE_NODE, &clear_vrf_prefix_rd_cmd); - install_element (ENABLE_NODE, &clear_vrf_all_cmd); - - install_element (ENABLE_NODE, &vnc_clear_counters_cmd); - - install_element (VIEW_NODE, &vnc_show_summary_cmd); - install_element (VIEW_NODE, &vnc_show_nves_cmd); - install_element (VIEW_NODE, &vnc_show_nves_ptct_cmd); - - install_element (VIEW_NODE, &vnc_show_registrations_pfx_cmd); - install_element (VIEW_NODE, &vnc_show_registrations_some_pfx_cmd); - install_element (VIEW_NODE, &vnc_show_responses_pfx_cmd); - install_element (VIEW_NODE, &vnc_show_responses_some_pfx_cmd); - install_element (VIEW_NODE, &show_vnc_queries_pfx_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_lnh_cmd); + + install_element(ENABLE_NODE, &add_vnc_prefix_cost_life_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_life_cost_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_cost_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_life_cmd); + install_element(ENABLE_NODE, &add_vnc_prefix_cmd); + + install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd); + install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd); + install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd); + install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd); + install_element(ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd); + install_element(ENABLE_NODE, &add_vnc_mac_vni_cost_cmd); + install_element(ENABLE_NODE, &add_vnc_mac_vni_life_cmd); + install_element(ENABLE_NODE, &add_vnc_mac_vni_cmd); + + install_element(ENABLE_NODE, &add_vrf_prefix_rd_label_pref_cmd); + + install_element(ENABLE_NODE, &clear_vnc_nve_all_cmd); + install_element(ENABLE_NODE, &clear_vnc_nve_vn_un_cmd); + install_element(ENABLE_NODE, &clear_vnc_nve_un_vn_cmd); + install_element(ENABLE_NODE, &clear_vnc_nve_vn_cmd); + install_element(ENABLE_NODE, &clear_vnc_nve_un_cmd); + + install_element(ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd); + install_element(ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd); + install_element(ENABLE_NODE, &clear_vnc_prefix_un_cmd); + install_element(ENABLE_NODE, &clear_vnc_prefix_vn_cmd); + install_element(ENABLE_NODE, &clear_vnc_prefix_all_cmd); + + install_element(ENABLE_NODE, &clear_vnc_mac_vn_un_cmd); + install_element(ENABLE_NODE, &clear_vnc_mac_un_vn_cmd); + install_element(ENABLE_NODE, &clear_vnc_mac_un_cmd); + install_element(ENABLE_NODE, &clear_vnc_mac_vn_cmd); + install_element(ENABLE_NODE, &clear_vnc_mac_all_cmd); + + install_element(ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd); + install_element(ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd); + install_element(ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd); + install_element(ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd); + install_element(ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd); + + install_element(ENABLE_NODE, &clear_vrf_prefix_rd_cmd); + install_element(ENABLE_NODE, &clear_vrf_all_cmd); + + install_element(ENABLE_NODE, &vnc_clear_counters_cmd); + + install_element(VIEW_NODE, &vnc_show_summary_cmd); + install_element(VIEW_NODE, &vnc_show_nves_cmd); + install_element(VIEW_NODE, &vnc_show_nves_ptct_cmd); + + install_element(VIEW_NODE, &vnc_show_registrations_pfx_cmd); + install_element(VIEW_NODE, &vnc_show_registrations_some_pfx_cmd); + install_element(VIEW_NODE, &vnc_show_responses_pfx_cmd); + install_element(VIEW_NODE, &vnc_show_responses_some_pfx_cmd); + install_element(VIEW_NODE, &show_vnc_queries_pfx_cmd); } diff --git a/bgpd/rfapi/rfapi_vty.h b/bgpd/rfapi/rfapi_vty.h index 46b77b55ed..a08183aa46 100644 --- a/bgpd/rfapi/rfapi_vty.h +++ b/bgpd/rfapi/rfapi_vty.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -23,74 +23,59 @@ #include "lib/vty.h" -typedef enum -{ - SHOW_NVE_SUMMARY_ACTIVE_NVES, - SHOW_NVE_SUMMARY_UNKNOWN_NVES, /* legacy */ - SHOW_NVE_SUMMARY_REGISTERED, - SHOW_NVE_SUMMARY_QUERIES, - SHOW_NVE_SUMMARY_RESPONSES, - SHOW_NVE_SUMMARY_MAX +typedef enum { + SHOW_NVE_SUMMARY_ACTIVE_NVES, + SHOW_NVE_SUMMARY_UNKNOWN_NVES, /* legacy */ + SHOW_NVE_SUMMARY_REGISTERED, + SHOW_NVE_SUMMARY_QUERIES, + SHOW_NVE_SUMMARY_RESPONSES, + SHOW_NVE_SUMMARY_MAX } show_nve_summary_t; #define VNC_SHOW_STR "VNC information\n" -extern char * -rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len); +extern char *rfapiFormatSeconds(uint32_t seconds, char *buf, size_t len); -extern char * -rfapiFormatAge (time_t age, char *buf, size_t len); +extern char *rfapiFormatAge(time_t age, char *buf, size_t len); -extern void -rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix); +extern void rfapiRprefixApplyMask(struct rfapi_ip_prefix *rprefix); -extern int -rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr); +extern int rfapiQprefix2Raddr(struct prefix *qprefix, + struct rfapi_ip_addr *raddr); -extern void -rfapiQprefix2Rprefix (struct prefix *qprefix, - struct rfapi_ip_prefix *rprefix); +extern void rfapiQprefix2Rprefix(struct prefix *qprefix, + struct rfapi_ip_prefix *rprefix); -extern int -rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, - struct prefix *qprefix); +extern int rfapiRprefix2Qprefix(struct rfapi_ip_prefix *rprefix, + struct prefix *qprefix); -extern int -rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx); +extern int rfapiRaddr2Qprefix(struct rfapi_ip_addr *hia, struct prefix *pfx); -extern int -rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2); +extern int rfapiRprefixSame(struct rfapi_ip_prefix *hp1, + struct rfapi_ip_prefix *hp2); -extern void -rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx); +extern void rfapiL2o2Qprefix(struct rfapi_l2address_option *l2o, + struct prefix *pfx); -extern int -rfapiStr2EthAddr (const char *str, struct ethaddr *ea); +extern int rfapiStr2EthAddr(const char *str, struct ethaddr *ea); -extern const char * -rfapi_ntop ( - int af, - const void *src, - char *buf, - socklen_t size); +extern const char *rfapi_ntop(int af, const void *src, char *buf, + socklen_t size); -extern int -rfapiDebugPrintf (void *dummy, const char *format, ...); +extern int rfapiDebugPrintf(void *dummy, const char *format, ...); -extern int -rfapiStream2Vty ( - void *stream, /* input */ - int (**fp) (void *, const char *, ...), /* output */ - struct vty **vty, /* output */ - void **outstream, /* output */ - const char **vty_newline); /* output */ +extern int rfapiStream2Vty(void *stream, /* input */ + int (**fp)(void *, const char *, ...), /* output */ + struct vty **vty, /* output */ + void **outstream, /* output */ + const char **vty_newline); /* output */ /*------------------------------------------ * rfapiRfapiIpAddr2Str * * UI helper: generate string from rfapi_ip_addr * - * input: + * input: * a IP v4/v6 address * * output @@ -101,75 +86,50 @@ rfapiStream2Vty ( * NULL conversion failed * non-NULL pointer to buf --------------------------------------------*/ -extern const char * -rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize); +extern const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr *a, char *buf, + int bufsize); -extern void -rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a); +extern void rfapiPrintRfapiIpAddr(void *stream, struct rfapi_ip_addr *a); -extern void -rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p); +extern void rfapiPrintRfapiIpPrefix(void *stream, struct rfapi_ip_prefix *p); -void -rfapiPrintRd (struct vty *vty, struct prefix_rd *prd); +void rfapiPrintRd(struct vty *vty, struct prefix_rd *prd); -extern void -rfapiPrintAdvertisedInfo ( - struct vty *vty, - struct rfapi_descriptor *rfd, - safi_t safi, - struct prefix *p); +extern void rfapiPrintAdvertisedInfo(struct vty *vty, + struct rfapi_descriptor *rfd, safi_t safi, + struct prefix *p); -extern void -rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd); +extern void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd); -extern void -rfapiPrintMatchingDescriptors (struct vty *vty, - struct prefix *vn_prefix, - struct prefix *un_prefix); +extern void rfapiPrintMatchingDescriptors(struct vty *vty, + struct prefix *vn_prefix, + struct prefix *un_prefix); -extern void -rfapiPrintAttrPtrs (void *stream, struct attr *attr); +extern void rfapiPrintAttrPtrs(void *stream, struct attr *attr); /* * Parse an address and put into a struct prefix */ -extern int -rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p); - -extern int -rfapiCliGetRfapiIpAddr ( - struct vty *vty, - const char *str, - struct rfapi_ip_addr *hai); - -extern void -rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops); - -extern char * -rfapiMonitorVpn2Str ( - struct rfapi_monitor_vpn *m, - char *buf, - int size); - -extern const char * -rfapiRfapiIpPrefix2Str ( - struct rfapi_ip_prefix *p, - char *buf, - int bufsize); - -extern void -rfapiShowItNode (void *stream, struct route_node *rn); - -extern char * -rfapiEthAddr2Str ( - const struct ethaddr *ea, - char *buf, - int bufsize); +extern int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, + struct prefix *p); + +extern int rfapiCliGetRfapiIpAddr(struct vty *vty, const char *str, + struct rfapi_ip_addr *hai); + +extern void rfapiPrintNhl(void *stream, struct rfapi_next_hop_entry *next_hops); + +extern char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn *m, char *buf, + int size); + +extern const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix *p, char *buf, + int bufsize); + +extern void rfapiShowItNode(void *stream, struct route_node *rn); + +extern char *rfapiEthAddr2Str(const struct ethaddr *ea, char *buf, int bufsize); /* install vty commands */ -extern void -rfapi_vty_init (void); +extern void rfapi_vty_init(void); /*------------------------------------------ * rfapiShowRemoteRegistrations @@ -177,7 +137,7 @@ rfapi_vty_init (void); * UI helper: produces the "remote" portion of the output * of "show vnc registrations". * - * input: + * input: * stream pointer to output stream * prefix_only pointer to prefix. If non-NULL, print only registrations * matching the specified prefix @@ -189,21 +149,17 @@ rfapi_vty_init (void); * 0 nothing printed * >0 something printed --------------------------------------------*/ -extern int -rfapiShowRemoteRegistrations ( - void *stream, - struct prefix *prefix_only, - int show_expiring, - int show_local, - int show_remote, - int show_imported); +extern int rfapiShowRemoteRegistrations(void *stream, + struct prefix *prefix_only, + int show_expiring, int show_local, + int show_remote, int show_imported); /*------------------------------------------ * rfapi_monitor_count * * UI helper: count number of active monitors * - * input: + * input: * handle rfapi handle (NULL to count across * all open handles) * @@ -212,11 +168,9 @@ rfapiShowRemoteRegistrations ( * return value: * count of monitors --------------------------------------------*/ -extern uint32_t -rfapi_monitor_count (rfapi_handle); +extern uint32_t rfapi_monitor_count(rfapi_handle); -extern int -rfapiShowVncQueries (void *stream, struct prefix *pfx_match); +extern int rfapiShowVncQueries(void *stream, struct prefix *pfx_match); #endif diff --git a/bgpd/rfapi/vnc_debug.c b/bgpd/rfapi/vnc_debug.c index 1f9e1b10fe..d4ff9451c3 100644 --- a/bgpd/rfapi/vnc_debug.c +++ b/bgpd/rfapi/vnc_debug.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2016, LabN Consulting, L.L.C. * @@ -34,19 +34,18 @@ unsigned long conf_vnc_debug; unsigned long term_vnc_debug; struct vnc_debug { - unsigned long bit; - const char *name; + unsigned long bit; + const char *name; }; -struct vnc_debug vncdebug[] = -{ - {VNC_DEBUG_RFAPI_QUERY, "rfapi-query"}, - {VNC_DEBUG_IMPORT_BI_ATTACH, "import-bi-attach"}, - {VNC_DEBUG_IMPORT_DEL_REMOTE, "import-del-remote"}, - {VNC_DEBUG_EXPORT_BGP_GETCE, "export-bgp-getce"}, - {VNC_DEBUG_EXPORT_BGP_DIRECT_ADD, "export-bgp-direct-add"}, - {VNC_DEBUG_IMPORT_BGP_ADD_ROUTE, "import-bgp-add-route"}, - {VNC_DEBUG_VERBOSE, "verbose"}, +struct vnc_debug vncdebug[] = { + {VNC_DEBUG_RFAPI_QUERY, "rfapi-query"}, + {VNC_DEBUG_IMPORT_BI_ATTACH, "import-bi-attach"}, + {VNC_DEBUG_IMPORT_DEL_REMOTE, "import-del-remote"}, + {VNC_DEBUG_EXPORT_BGP_GETCE, "export-bgp-getce"}, + {VNC_DEBUG_EXPORT_BGP_DIRECT_ADD, "export-bgp-direct-add"}, + {VNC_DEBUG_IMPORT_BGP_ADD_ROUTE, "import-bgp-add-route"}, + {VNC_DEBUG_VERBOSE, "verbose"}, }; #define VNC_STR "VNC information\n" @@ -65,28 +64,23 @@ DEFUN (debug_bgp_vnc, "import delete remote routes\n" "verbose logging\n") { - size_t i; - - for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) - { - if (strmatch(argv[3]->text, vncdebug[i].name)) - { - if (vty->node == CONFIG_NODE) - { - conf_vnc_debug |= vncdebug[i].bit; - term_vnc_debug |= vncdebug[i].bit; - } - else - { - term_vnc_debug |= vncdebug[i].bit; - vty_out (vty, "BGP vnc %s debugging is on\n", - vncdebug[i].name); - } - return CMD_SUCCESS; + size_t i; + + for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) { + if (strmatch(argv[3]->text, vncdebug[i].name)) { + if (vty->node == CONFIG_NODE) { + conf_vnc_debug |= vncdebug[i].bit; + term_vnc_debug |= vncdebug[i].bit; + } else { + term_vnc_debug |= vncdebug[i].bit; + vty_out(vty, "BGP vnc %s debugging is on\n", + vncdebug[i].name); + } + return CMD_SUCCESS; + } } - } - vty_out (vty, "Unknown debug flag: %s\n", argv[3]->arg); - return CMD_WARNING_CONFIG_FAILED; + vty_out(vty, "Unknown debug flag: %s\n", argv[3]->arg); + return CMD_WARNING_CONFIG_FAILED; } DEFUN (no_debug_bgp_vnc, @@ -102,30 +96,25 @@ DEFUN (no_debug_bgp_vnc, "import delete remote routes\n" "verbose logging\n") { - size_t i; - - if (strmatch(argv[0]->text, "no")) - argc--, argv++; - for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) - { - if (strmatch(argv[3]->text, vncdebug[i].name)) - { - if (vty->node == CONFIG_NODE) - { - conf_vnc_debug &= ~vncdebug[i].bit; - term_vnc_debug &= ~vncdebug[i].bit; - } - else - { - term_vnc_debug &= ~vncdebug[i].bit; - vty_out (vty, "BGP vnc %s debugging is off\n", - vncdebug[i].name); - } - return CMD_SUCCESS; + size_t i; + + if (strmatch(argv[0]->text, "no")) + argc--, argv++; + for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) { + if (strmatch(argv[3]->text, vncdebug[i].name)) { + if (vty->node == CONFIG_NODE) { + conf_vnc_debug &= ~vncdebug[i].bit; + term_vnc_debug &= ~vncdebug[i].bit; + } else { + term_vnc_debug &= ~vncdebug[i].bit; + vty_out(vty, "BGP vnc %s debugging is off\n", + vncdebug[i].name); + } + return CMD_SUCCESS; + } } - } - vty_out (vty, "Unknown debug flag: %s\n", argv[3]->arg); - return CMD_WARNING_CONFIG_FAILED; + vty_out(vty, "Unknown debug flag: %s\n", argv[3]->arg); + return CMD_WARNING_CONFIG_FAILED; } @@ -143,10 +132,10 @@ DEFUN (no_debug_bgp_vnc_all, BGP_STR VNC_STR) { - term_vnc_debug = 0; - vty_out (vty, "All possible VNC debugging has been turned off\n"); - - return CMD_SUCCESS; + term_vnc_debug = 0; + vty_out(vty, "All possible VNC debugging has been turned off\n"); + + return CMD_SUCCESS; } /*********************************************************************** @@ -161,55 +150,44 @@ DEFUN (show_debugging_bgp_vnc, BGP_STR VNC_STR) { - size_t i; + size_t i; - vty_out (vty, "BGP VNC debugging status:\n"); + vty_out(vty, "BGP VNC debugging status:\n"); - for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) - { - if (term_vnc_debug & vncdebug[i].bit) - { - vty_out (vty, " BGP VNC %s debugging is on\n", - vncdebug[i].name); + for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) { + if (term_vnc_debug & vncdebug[i].bit) { + vty_out(vty, " BGP VNC %s debugging is on\n", + vncdebug[i].name); + } } - } - vty_out (vty, "\n"); - return CMD_SUCCESS; + vty_out(vty, "\n"); + return CMD_SUCCESS; } -static int -bgp_vnc_config_write_debug (struct vty *vty) +static int bgp_vnc_config_write_debug(struct vty *vty) { - int write = 0; - size_t i; - - for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) - { - if (conf_vnc_debug & vncdebug[i].bit) - { - vty_out (vty, "debug bgp vnc %s\n", vncdebug[i].name); - write++; + int write = 0; + size_t i; + + for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) { + if (conf_vnc_debug & vncdebug[i].bit) { + vty_out(vty, "debug bgp vnc %s\n", vncdebug[i].name); + write++; + } } - } - return write; + return write; } -static struct cmd_node debug_node = -{ - DEBUG_VNC_NODE, - "", - 1 -}; +static struct cmd_node debug_node = {DEBUG_VNC_NODE, "", 1}; -void -vnc_debug_init (void) +void vnc_debug_init(void) { - install_node (&debug_node, bgp_vnc_config_write_debug); - install_element (ENABLE_NODE, &show_debugging_bgp_vnc_cmd); + install_node(&debug_node, bgp_vnc_config_write_debug); + install_element(ENABLE_NODE, &show_debugging_bgp_vnc_cmd); - install_element (ENABLE_NODE, &debug_bgp_vnc_cmd); - install_element (CONFIG_NODE, &debug_bgp_vnc_cmd); - install_element (ENABLE_NODE, &no_debug_bgp_vnc_cmd); + install_element(ENABLE_NODE, &debug_bgp_vnc_cmd); + install_element(CONFIG_NODE, &debug_bgp_vnc_cmd); + install_element(ENABLE_NODE, &no_debug_bgp_vnc_cmd); - install_element (ENABLE_NODE, &no_debug_bgp_vnc_all_cmd); + install_element(ENABLE_NODE, &no_debug_bgp_vnc_all_cmd); } diff --git a/bgpd/rfapi/vnc_debug.h b/bgpd/rfapi/vnc_debug.h index c1d81f5c15..dd49383072 100644 --- a/bgpd/rfapi/vnc_debug.h +++ b/bgpd/rfapi/vnc_debug.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2016, LabN Consulting, L.L.C. * @@ -44,8 +44,7 @@ extern unsigned long term_vnc_debug; #define vnc_zlog_debug_verbose if (VNC_DEBUG(VERBOSE)) zlog_debug #define vnc_zlog_debug_any if (VNC_DEBUG(ANY)) zlog_debug -extern void -vnc_debug_init (void); +extern void vnc_debug_init(void); #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index 342dc6a193..b699cec9e7 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -63,472 +63,441 @@ * - strip Tunnel Encap attr * - copy all ECs */ -static void -encap_attr_export_ce ( - struct attr *new, - struct attr *orig, - struct prefix *use_nexthop) +static void encap_attr_export_ce(struct attr *new, struct attr *orig, + struct prefix *use_nexthop) { - /* - * Make "new" a ghost attr copy of "orig" - */ - memset (new, 0, sizeof (struct attr)); - bgp_attr_dup (new, orig); - - /* - * Set nexthop - */ - switch (use_nexthop->family) - { - case AF_INET: - new->nexthop = use_nexthop->u.prefix4; - new->mp_nexthop_len = 4; /* bytes */ - new->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); - break; - - case AF_INET6: - new->mp_nexthop_global = use_nexthop->u.prefix6; - new->mp_nexthop_len = 16; /* bytes */ - break; - - default: - assert (0); - break; - } - - /* - * Set MED - * - * Note that it will be deleted when BGP sends to any eBGP - * peer unless PEER_FLAG_MED_UNCHANGED is set: - * - * neighbor NEIGHBOR attribute-unchanged med - */ - if (!CHECK_FLAG (new->flag, BGP_ATTR_MULTI_EXIT_DISC)) - { - if (CHECK_FLAG (new->flag, BGP_ATTR_LOCAL_PREF)) - { - if (new->local_pref > 255) - new->med = 0; - else - new->med = 255 - new->local_pref; - } - else - { - new->med = 255; /* shouldn't happen */ - } - new->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); - } - - /* - * "new" is now a ghost attr: - * - it owns an "extra" struct - * - it owns any non-interned parts - * - any references to interned parts are not counted - * - * Caller should, after using the attr, call: - * - bgp_attr_flush() to free non-interned parts - */ + /* + * Make "new" a ghost attr copy of "orig" + */ + memset(new, 0, sizeof(struct attr)); + bgp_attr_dup(new, orig); + + /* + * Set nexthop + */ + switch (use_nexthop->family) { + case AF_INET: + new->nexthop = use_nexthop->u.prefix4; + new->mp_nexthop_len = 4; /* bytes */ + new->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); + break; + + case AF_INET6: + new->mp_nexthop_global = use_nexthop->u.prefix6; + new->mp_nexthop_len = 16; /* bytes */ + break; + + default: + assert(0); + break; + } + + /* + * Set MED + * + * Note that it will be deleted when BGP sends to any eBGP + * peer unless PEER_FLAG_MED_UNCHANGED is set: + * + * neighbor NEIGHBOR attribute-unchanged med + */ + if (!CHECK_FLAG(new->flag, BGP_ATTR_MULTI_EXIT_DISC)) { + if (CHECK_FLAG(new->flag, BGP_ATTR_LOCAL_PREF)) { + if (new->local_pref > 255) + new->med = 0; + else + new->med = 255 - new->local_pref; + } else { + new->med = 255; /* shouldn't happen */ + } + new->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); + } + + /* + * "new" is now a ghost attr: + * - it owns an "extra" struct + * - it owns any non-interned parts + * - any references to interned parts are not counted + * + * Caller should, after using the attr, call: + * - bgp_attr_flush() to free non-interned parts + */ } -static int -getce (struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce) +static int getce(struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce) { - uint8_t *ecp; - int i; - uint16_t localadmin = bgp->rfapi_cfg->resolve_nve_roo_local_admin; - - for (ecp = attr->ecommunity->val, i = 0; - i < attr->ecommunity->size; ++i, ecp += ECOMMUNITY_SIZE) - { - - if (VNC_DEBUG(EXPORT_BGP_GETCE)) - { - vnc_zlog_debug_any ("%s: %02x %02x %02x %02x %02x %02x %02x %02x", - __func__, - ecp[0], ecp[1], ecp[2], ecp[3], ecp[4], ecp[5], ecp[6], - ecp[7]); - } - - /* - * is it ROO? - */ - if (ecp[0] != 1 || ecp[1] != 3) - { - continue; - } - - /* - * Match local admin value? - */ - if (ecp[6] != ((localadmin & 0xff00) >> 8) || - ecp[7] != (localadmin & 0xff)) - continue; - - memset ((uint8_t *) pfx_ce, 0, sizeof (*pfx_ce)); - memcpy (&pfx_ce->u.prefix4, ecp + 2, 4); - pfx_ce->family = AF_INET; - pfx_ce->prefixlen = 32; - - return 0; - } - return -1; + uint8_t *ecp; + int i; + uint16_t localadmin = bgp->rfapi_cfg->resolve_nve_roo_local_admin; + + for (ecp = attr->ecommunity->val, i = 0; i < attr->ecommunity->size; + ++i, ecp += ECOMMUNITY_SIZE) { + + if (VNC_DEBUG(EXPORT_BGP_GETCE)) { + vnc_zlog_debug_any( + "%s: %02x %02x %02x %02x %02x %02x %02x %02x", + __func__, ecp[0], ecp[1], ecp[2], ecp[3], + ecp[4], ecp[5], ecp[6], ecp[7]); + } + + /* + * is it ROO? + */ + if (ecp[0] != 1 || ecp[1] != 3) { + continue; + } + + /* + * Match local admin value? + */ + if (ecp[6] != ((localadmin & 0xff00) >> 8) + || ecp[7] != (localadmin & 0xff)) + continue; + + memset((uint8_t *)pfx_ce, 0, sizeof(*pfx_ce)); + memcpy(&pfx_ce->u.prefix4, ecp + 2, 4); + pfx_ce->family = AF_INET; + pfx_ce->prefixlen = 32; + + return 0; + } + return -1; } -void -vnc_direct_bgp_add_route_ce ( - struct bgp *bgp, - struct route_node *rn, - struct bgp_info *bi) +void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn, + struct bgp_info *bi) { - struct attr *attr = bi->attr; - struct peer *peer = bi->peer; - struct prefix *prefix = &rn->p; - afi_t afi = family2afi (prefix->family); - struct bgp_node *urn; - struct bgp_info *ubi; - struct attr hattr; - struct attr *iattr; - struct prefix ce_nexthop; - struct prefix post_routemap_nexthop; - - - if (!afi) - { - zlog_err ("%s: can't get afi of route node", __func__); - return; - } - - if ((bi->type != ZEBRA_ROUTE_BGP) || - (bi->sub_type != BGP_ROUTE_NORMAL && - bi->sub_type != BGP_ROUTE_RFP && bi->sub_type != BGP_ROUTE_STATIC)) - { - - vnc_zlog_debug_verbose ("%s: wrong route type/sub_type for export, skipping", - __func__); - return; - } - - /* check bgp redist flag for vnc direct ("vpn") routes */ - if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", - __func__); - return; - } - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - if (!VNC_EXPORT_BGP_CE_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp ce mode not enabled, skipping", - __func__); - return; - } - - /* - * prefix list check - */ - if (bgp->rfapi_cfg->plist_export_bgp[afi]) - { - if (prefix_list_apply (bgp->rfapi_cfg->plist_export_bgp[afi], prefix) == - PREFIX_DENY) - { - vnc_zlog_debug_verbose ("%s: prefix list denied, skipping", __func__); - return; - } - } - - - /* - * Extract CE - * This works only for IPv4 because IPv6 addresses are too big - * to fit in an extended community - */ - if (getce (bgp, attr, &ce_nexthop)) - { - vnc_zlog_debug_verbose ("%s: EC has no encoded CE, skipping", __func__); - return; - } - - /* - * Is this route already represented in the unicast RIB? - * (look up prefix; compare route type, sub_type, peer, nexthop) - */ - urn = - bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, prefix, - NULL); - for (ubi = urn->info; ubi; ubi = ubi->next) - { - struct prefix unicast_nexthop; - - if (CHECK_FLAG (ubi->flags, BGP_INFO_REMOVED)) - continue; - - rfapiUnicastNexthop2Prefix (afi, ubi->attr, &unicast_nexthop); - - if (ubi->type == ZEBRA_ROUTE_VNC_DIRECT && - ubi->sub_type == BGP_ROUTE_REDISTRIBUTE && - ubi->peer == peer && prefix_same (&unicast_nexthop, &ce_nexthop)) - { - - vnc_zlog_debug_verbose - ("%s: already have matching exported unicast route, skipping", - __func__); - return; - } - } - - /* - * Construct new attribute set with CE addr as - * nexthop and without Tunnel Encap attr - */ - encap_attr_export_ce (&hattr, attr, &ce_nexthop); - if (bgp->rfapi_cfg->routemap_export_bgp) - { - struct bgp_info info; - route_map_result_t ret; - - memset (&info, 0, sizeof (info)); - info.peer = peer; - info.attr = &hattr; - ret = - route_map_apply (bgp->rfapi_cfg->routemap_export_bgp, prefix, - RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - return; - } - } - - iattr = bgp_attr_intern (&hattr); - bgp_attr_flush (&hattr); - - /* - * Rule: disallow route-map alteration of next-hop, because it - * would make it too difficult to keep track of the correspondence - * between VPN routes and unicast routes. - */ - rfapiUnicastNexthop2Prefix (afi, iattr, &post_routemap_nexthop); - - if (!prefix_same (&ce_nexthop, &post_routemap_nexthop)) - { - vnc_zlog_debug_verbose - ("%s: route-map modification of nexthop not allowed, skipping", - __func__); - bgp_attr_unintern (&iattr); - return; - } - - bgp_update (peer, prefix, - 0, /* addpath_id */ - iattr, /* bgp_update copies this attr */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, /* tag not used for unicast */ - 0, NULL); /* EVPN not used */ - bgp_attr_unintern (&iattr); + struct attr *attr = bi->attr; + struct peer *peer = bi->peer; + struct prefix *prefix = &rn->p; + afi_t afi = family2afi(prefix->family); + struct bgp_node *urn; + struct bgp_info *ubi; + struct attr hattr; + struct attr *iattr; + struct prefix ce_nexthop; + struct prefix post_routemap_nexthop; + + + if (!afi) { + zlog_err("%s: can't get afi of route node", __func__); + return; + } + + if ((bi->type != ZEBRA_ROUTE_BGP) + || (bi->sub_type != BGP_ROUTE_NORMAL + && bi->sub_type != BGP_ROUTE_RFP + && bi->sub_type != BGP_ROUTE_STATIC)) { + + vnc_zlog_debug_verbose( + "%s: wrong route type/sub_type for export, skipping", + __func__); + return; + } + + /* check bgp redist flag for vnc direct ("vpn") routes */ + if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of VNC direct routes is off", + __func__); + return; + } + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + if (!VNC_EXPORT_BGP_CE_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp ce mode not enabled, skipping", + __func__); + return; + } + + /* + * prefix list check + */ + if (bgp->rfapi_cfg->plist_export_bgp[afi]) { + if (prefix_list_apply(bgp->rfapi_cfg->plist_export_bgp[afi], + prefix) + == PREFIX_DENY) { + vnc_zlog_debug_verbose( + "%s: prefix list denied, skipping", __func__); + return; + } + } + + + /* + * Extract CE + * This works only for IPv4 because IPv6 addresses are too big + * to fit in an extended community + */ + if (getce(bgp, attr, &ce_nexthop)) { + vnc_zlog_debug_verbose("%s: EC has no encoded CE, skipping", + __func__); + return; + } + + /* + * Is this route already represented in the unicast RIB? + * (look up prefix; compare route type, sub_type, peer, nexthop) + */ + urn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, + prefix, NULL); + for (ubi = urn->info; ubi; ubi = ubi->next) { + struct prefix unicast_nexthop; + + if (CHECK_FLAG(ubi->flags, BGP_INFO_REMOVED)) + continue; + + rfapiUnicastNexthop2Prefix(afi, ubi->attr, &unicast_nexthop); + + if (ubi->type == ZEBRA_ROUTE_VNC_DIRECT + && ubi->sub_type == BGP_ROUTE_REDISTRIBUTE + && ubi->peer == peer + && prefix_same(&unicast_nexthop, &ce_nexthop)) { + + vnc_zlog_debug_verbose( + "%s: already have matching exported unicast route, skipping", + __func__); + return; + } + } + + /* + * Construct new attribute set with CE addr as + * nexthop and without Tunnel Encap attr + */ + encap_attr_export_ce(&hattr, attr, &ce_nexthop); + if (bgp->rfapi_cfg->routemap_export_bgp) { + struct bgp_info info; + route_map_result_t ret; + + memset(&info, 0, sizeof(info)); + info.peer = peer; + info.attr = &hattr; + ret = route_map_apply(bgp->rfapi_cfg->routemap_export_bgp, + prefix, RMAP_BGP, &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + return; + } + } + + iattr = bgp_attr_intern(&hattr); + bgp_attr_flush(&hattr); + + /* + * Rule: disallow route-map alteration of next-hop, because it + * would make it too difficult to keep track of the correspondence + * between VPN routes and unicast routes. + */ + rfapiUnicastNexthop2Prefix(afi, iattr, &post_routemap_nexthop); + + if (!prefix_same(&ce_nexthop, &post_routemap_nexthop)) { + vnc_zlog_debug_verbose( + "%s: route-map modification of nexthop not allowed, skipping", + __func__); + bgp_attr_unintern(&iattr); + return; + } + + bgp_update(peer, prefix, 0, /* addpath_id */ + iattr, /* bgp_update copies this attr */ + afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ + NULL, /* tag not used for unicast */ + 0, NULL); /* EVPN not used */ + bgp_attr_unintern(&iattr); } /* * "Withdrawing a Route" export process */ -void -vnc_direct_bgp_del_route_ce ( - struct bgp *bgp, - struct route_node *rn, - struct bgp_info *bi) +void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, + struct bgp_info *bi) { - afi_t afi = family2afi (rn->p.family); - struct bgp_info *vbi; - struct prefix ce_nexthop; - - if (!afi) - { - zlog_err ("%s: bad afi", __func__); - return; - } - - /* check bgp redist flag for vnc direct ("vpn") routes */ - if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", - __func__); - return; - } - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - if (!VNC_EXPORT_BGP_CE_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp ce mode not enabled, skipping", - __func__); - return; - } - - /* - * Extract CE - * This works only for IPv4 because IPv6 addresses are too big - * to fit in an extended community - */ - if (getce (bgp, bi->attr, &ce_nexthop)) - { - vnc_zlog_debug_verbose ("%s: EC has no encoded CE, skipping", __func__); - return; - } - - /* - * Look for other VPN routes with same prefix, same 5226 CE, - * same peer. If at least one is present, don't remove the - * route from the unicast RIB - */ - - for (vbi = rn->info; vbi; vbi = vbi->next) - { - struct prefix ce; - if (bi == vbi) - continue; - if (bi->peer != vbi->peer) - continue; - if (getce (bgp, vbi->attr, &ce)) - continue; - if (prefix_same (&ce, &ce_nexthop)) - { - vnc_zlog_debug_verbose ("%s: still have a route via CE, not deleting unicast", - __func__); - return; - } - } - - /* - * withdraw the route - */ - bgp_withdraw (bi->peer, &rn->p, - 0, /* addpath_id */ - NULL, /* attr, ignored */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, NULL); /* tag not used for unicast */ + afi_t afi = family2afi(rn->p.family); + struct bgp_info *vbi; + struct prefix ce_nexthop; + + if (!afi) { + zlog_err("%s: bad afi", __func__); + return; + } + + /* check bgp redist flag for vnc direct ("vpn") routes */ + if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of VNC direct routes is off", + __func__); + return; + } + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + if (!VNC_EXPORT_BGP_CE_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp ce mode not enabled, skipping", + __func__); + return; + } + + /* + * Extract CE + * This works only for IPv4 because IPv6 addresses are too big + * to fit in an extended community + */ + if (getce(bgp, bi->attr, &ce_nexthop)) { + vnc_zlog_debug_verbose("%s: EC has no encoded CE, skipping", + __func__); + return; + } + + /* + * Look for other VPN routes with same prefix, same 5226 CE, + * same peer. If at least one is present, don't remove the + * route from the unicast RIB + */ + + for (vbi = rn->info; vbi; vbi = vbi->next) { + struct prefix ce; + if (bi == vbi) + continue; + if (bi->peer != vbi->peer) + continue; + if (getce(bgp, vbi->attr, &ce)) + continue; + if (prefix_same(&ce, &ce_nexthop)) { + vnc_zlog_debug_verbose( + "%s: still have a route via CE, not deleting unicast", + __func__); + return; + } + } + /* + * withdraw the route + */ + bgp_withdraw(bi->peer, &rn->p, 0, /* addpath_id */ + NULL, /* attr, ignored */ + afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ + NULL, NULL); /* tag not used for unicast */ } -static void -vnc_direct_bgp_vpn_enable_ce (struct bgp *bgp, afi_t afi) +static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi) { - struct rfapi_cfg *hc; - struct route_node *rn; - struct bgp_info *ri; + struct rfapi_cfg *hc; + struct route_node *rn; + struct bgp_info *ri; - vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); + vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); - if (!bgp) - return; + if (!bgp) + return; - if (!(hc = bgp->rfapi_cfg)) - return; + if (!(hc = bgp->rfapi_cfg)) + return; - if (!VNC_EXPORT_BGP_CE_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export of CE routes not enabled, skipping", __func__); - return; - } - - if (afi != AFI_IP - && afi != AFI_IP6) - { - vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); - return; - } + if (!VNC_EXPORT_BGP_CE_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export of CE routes not enabled, skipping", + __func__); + return; + } - /* - * Go through entire ce import table and export to BGP unicast. - */ - for (rn = route_top (bgp->rfapi->it_ce->imported_vpn[afi]); rn; - rn = route_next (rn)) - { + if (afi != AFI_IP && afi != AFI_IP6) { + vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); + return; + } - if (!rn->info) - continue; + /* + * Go through entire ce import table and export to BGP unicast. + */ + for (rn = route_top(bgp->rfapi->it_ce->imported_vpn[afi]); rn; + rn = route_next(rn)) { - { - char prefixstr[BUFSIZ]; + if (!rn->info) + continue; - prefixstr[0] = 0; - inet_ntop (rn->p.family, &rn->p.u.prefix, prefixstr, BUFSIZ); - vnc_zlog_debug_verbose ("%s: checking prefix %s/%d", __func__, prefixstr, - rn->p.prefixlen); - } + { + char prefixstr[BUFSIZ]; - for (ri = rn->info; ri; ri = ri->next) - { + prefixstr[0] = 0; + inet_ntop(rn->p.family, &rn->p.u.prefix, prefixstr, + BUFSIZ); + vnc_zlog_debug_verbose("%s: checking prefix %s/%d", + __func__, prefixstr, + rn->p.prefixlen); + } - vnc_zlog_debug_verbose ("%s: ri->sub_type: %d", __func__, ri->sub_type); + for (ri = rn->info; ri; ri = ri->next) { - if (ri->sub_type == BGP_ROUTE_NORMAL || - ri->sub_type == BGP_ROUTE_RFP || - ri->sub_type == BGP_ROUTE_STATIC) - { + vnc_zlog_debug_verbose("%s: ri->sub_type: %d", __func__, + ri->sub_type); - vnc_direct_bgp_add_route_ce (bgp, rn, ri); - } + if (ri->sub_type == BGP_ROUTE_NORMAL + || ri->sub_type == BGP_ROUTE_RFP + || ri->sub_type == BGP_ROUTE_STATIC) { - } - } + vnc_direct_bgp_add_route_ce(bgp, rn, ri); + } + } + } } -static void -vnc_direct_bgp_vpn_disable_ce (struct bgp *bgp, afi_t afi) +static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi) { - struct bgp_node *rn; - - vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); - - if (!bgp) - return; - - if (afi != AFI_IP - && afi != AFI_IP6) - { - vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); - return; - } - - /* - * Go through the entire BGP unicast table and remove routes that - * originated from us - */ - for (rn = bgp_table_top (bgp->rib[afi][SAFI_UNICAST]); rn; - rn = bgp_route_next (rn)) - { - - struct bgp_info *ri; - struct bgp_info *next; - - for (ri = rn->info, next = NULL; ri; ri = next) - { - - next = ri->next; - - if (ri->type == ZEBRA_ROUTE_VNC_DIRECT && - ri->sub_type == BGP_ROUTE_REDISTRIBUTE) - { - - bgp_withdraw (ri->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - NULL, /* ignored */ - AFI_IP, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, NULL); /* tag not used for unicast */ - } - } - } + struct bgp_node *rn; + + vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); + + if (!bgp) + return; + + if (afi != AFI_IP && afi != AFI_IP6) { + vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); + return; + } + + /* + * Go through the entire BGP unicast table and remove routes that + * originated from us + */ + for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; + rn = bgp_route_next(rn)) { + + struct bgp_info *ri; + struct bgp_info *next; + + for (ri = rn->info, next = NULL; ri; ri = next) { + + next = ri->next; + + if (ri->type == ZEBRA_ROUTE_VNC_DIRECT + && ri->sub_type == BGP_ROUTE_REDISTRIBUTE) { + + bgp_withdraw( + ri->peer, &rn->p, /* prefix */ + 0, /* addpath_id */ + NULL, /* ignored */ + AFI_IP, SAFI_UNICAST, + ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for unicast */ + NULL, + NULL); /* tag not used for unicast */ + } + } + } } /*********************************************************************** @@ -539,73 +508,68 @@ vnc_direct_bgp_vpn_disable_ce (struct bgp *bgp, afi_t afi) * Export methods that proxy nexthop BEGIN ***********************************************************************/ -static struct ecommunity * -vnc_route_origin_ecom (struct route_node *rn) +static struct ecommunity *vnc_route_origin_ecom(struct route_node *rn) { - struct ecommunity *new; - struct bgp_info *bi; - - if (!rn->info) - return NULL; - - new = ecommunity_new (); - - for (bi = rn->info; bi; bi = bi->next) - { - - struct ecommunity_val roec; - - switch (BGP_MP_NEXTHOP_FAMILY (bi->attr->mp_nexthop_len)) - { - case AF_INET: - memset (&roec, 0, sizeof (roec)); - roec.val[0] = 0x01; - roec.val[1] = 0x03; - memcpy (roec.val + 2, - &bi->attr->mp_nexthop_global_in.s_addr, 4); - roec.val[6] = 0; - roec.val[7] = 0; - ecommunity_add_val (new, &roec); - break; - case AF_INET6: - /* No support for IPv6 addresses in extended communities */ - break; - } - } - - if (!new->size) - { - ecommunity_free (&new); - new = NULL; - } - - return new; + struct ecommunity *new; + struct bgp_info *bi; + + if (!rn->info) + return NULL; + + new = ecommunity_new(); + + for (bi = rn->info; bi; bi = bi->next) { + + struct ecommunity_val roec; + + switch (BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len)) { + case AF_INET: + memset(&roec, 0, sizeof(roec)); + roec.val[0] = 0x01; + roec.val[1] = 0x03; + memcpy(roec.val + 2, + &bi->attr->mp_nexthop_global_in.s_addr, 4); + roec.val[6] = 0; + roec.val[7] = 0; + ecommunity_add_val(new, &roec); + break; + case AF_INET6: + /* No support for IPv6 addresses in extended communities + */ + break; + } + } + + if (!new->size) { + ecommunity_free(&new); + new = NULL; + } + + return new; } -static struct ecommunity * -vnc_route_origin_ecom_single (struct in_addr *origin) +static struct ecommunity *vnc_route_origin_ecom_single(struct in_addr *origin) { - struct ecommunity *new; - struct ecommunity_val roec; - - memset (&roec, 0, sizeof (roec)); - roec.val[0] = 0x01; - roec.val[1] = 0x03; - memcpy (roec.val + 2, &origin->s_addr, 4); - roec.val[6] = 0; - roec.val[7] = 0; - - new = ecommunity_new (); - assert (new); - ecommunity_add_val (new, &roec); - - if (!new->size) - { - ecommunity_free (&new); - new = NULL; - } - - return new; + struct ecommunity *new; + struct ecommunity_val roec; + + memset(&roec, 0, sizeof(roec)); + roec.val[0] = 0x01; + roec.val[1] = 0x03; + memcpy(roec.val + 2, &origin->s_addr, 4); + roec.val[6] = 0; + roec.val[7] = 0; + + new = ecommunity_new(); + assert(new); + ecommunity_add_val(new, &roec); + + if (!new->size) { + ecommunity_free(&new); + new = NULL; + } + + return new; } @@ -615,750 +579,722 @@ vnc_route_origin_ecom_single (struct in_addr *origin) * memory is allocated by caller. */ static int -encap_attr_export ( - struct attr *new, - struct attr *orig, - struct prefix *new_nexthop, - struct route_node *rn) /* for VN addrs for ecom list */ - /* if rn is 0, use route's nexthop */ +encap_attr_export(struct attr *new, struct attr *orig, + struct prefix *new_nexthop, + struct route_node *rn) /* for VN addrs for ecom list */ + /* if rn is 0, use route's nexthop */ { - struct prefix orig_nexthop; - struct prefix *use_nexthop; - static struct ecommunity *ecom_ro; - - if (new_nexthop) - { - use_nexthop = new_nexthop; - } - else - { - use_nexthop = &orig_nexthop; - orig_nexthop.family = - BGP_MP_NEXTHOP_FAMILY (orig->mp_nexthop_len); - if (orig_nexthop.family == AF_INET) - { - orig_nexthop.prefixlen = 32; - orig_nexthop.u.prefix4 = orig->mp_nexthop_global_in; - } - else if (orig_nexthop.family == AF_INET6) - { - orig_nexthop.prefixlen = 128; - orig_nexthop.u.prefix6 = orig->mp_nexthop_global; - } - else - { - return -1; /* FAIL - can't compute nexthop */ - } - } - - - /* - * Make "new" a ghost attr copy of "orig" - */ - memset (new, 0, sizeof (struct attr)); - bgp_attr_dup (new, orig); - - /* - * Set nexthop - */ - switch (use_nexthop->family) - { - case AF_INET: - new->nexthop = use_nexthop->u.prefix4; - new->mp_nexthop_len = 4; /* bytes */ - new->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); - break; - - case AF_INET6: - new->mp_nexthop_global = use_nexthop->u.prefix6; - new->mp_nexthop_len = 16; /* bytes */ - break; - - default: - assert (0); - break; - } - - if (rn) - { - ecom_ro = vnc_route_origin_ecom (rn); - } - else - { - /* TBD test/assert for IPv6 */ - ecom_ro = vnc_route_origin_ecom_single (&use_nexthop->u.prefix4); - } - if (new->ecommunity) - { - if (ecom_ro) - new->ecommunity = ecommunity_merge (ecom_ro, new->ecommunity); - } - else - { - new->ecommunity = ecom_ro; - } - if (ecom_ro) - { - new->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES); - } - - /* - * Set MED - * - * Note that it will be deleted when BGP sends to any eBGP - * peer unless PEER_FLAG_MED_UNCHANGED is set: - * - * neighbor NEIGHBOR attribute-unchanged med - */ - if (!CHECK_FLAG (new->flag, BGP_ATTR_MULTI_EXIT_DISC)) - { - if (CHECK_FLAG (new->flag, BGP_ATTR_LOCAL_PREF)) - { - if (new->local_pref > 255) - new->med = 0; - else - new->med = 255 - new->local_pref; - } - else - { - new->med = 255; /* shouldn't happen */ - } - new->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); - } - - /* - * "new" is now a ghost attr: - * - it owns an "extra" struct - * - it owns any non-interned parts - * - any references to interned parts are not counted - * - * Caller should, after using the attr, call: - * - bgp_attr_flush() to free non-interned parts - */ - - return 0; + struct prefix orig_nexthop; + struct prefix *use_nexthop; + static struct ecommunity *ecom_ro; + + if (new_nexthop) { + use_nexthop = new_nexthop; + } else { + use_nexthop = &orig_nexthop; + orig_nexthop.family = + BGP_MP_NEXTHOP_FAMILY(orig->mp_nexthop_len); + if (orig_nexthop.family == AF_INET) { + orig_nexthop.prefixlen = 32; + orig_nexthop.u.prefix4 = orig->mp_nexthop_global_in; + } else if (orig_nexthop.family == AF_INET6) { + orig_nexthop.prefixlen = 128; + orig_nexthop.u.prefix6 = orig->mp_nexthop_global; + } else { + return -1; /* FAIL - can't compute nexthop */ + } + } + + + /* + * Make "new" a ghost attr copy of "orig" + */ + memset(new, 0, sizeof(struct attr)); + bgp_attr_dup(new, orig); + + /* + * Set nexthop + */ + switch (use_nexthop->family) { + case AF_INET: + new->nexthop = use_nexthop->u.prefix4; + new->mp_nexthop_len = 4; /* bytes */ + new->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); + break; + + case AF_INET6: + new->mp_nexthop_global = use_nexthop->u.prefix6; + new->mp_nexthop_len = 16; /* bytes */ + break; + + default: + assert(0); + break; + } + + if (rn) { + ecom_ro = vnc_route_origin_ecom(rn); + } else { + /* TBD test/assert for IPv6 */ + ecom_ro = vnc_route_origin_ecom_single(&use_nexthop->u.prefix4); + } + if (new->ecommunity) { + if (ecom_ro) + new->ecommunity = + ecommunity_merge(ecom_ro, new->ecommunity); + } else { + new->ecommunity = ecom_ro; + } + if (ecom_ro) { + new->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); + } + + /* + * Set MED + * + * Note that it will be deleted when BGP sends to any eBGP + * peer unless PEER_FLAG_MED_UNCHANGED is set: + * + * neighbor NEIGHBOR attribute-unchanged med + */ + if (!CHECK_FLAG(new->flag, BGP_ATTR_MULTI_EXIT_DISC)) { + if (CHECK_FLAG(new->flag, BGP_ATTR_LOCAL_PREF)) { + if (new->local_pref > 255) + new->med = 0; + else + new->med = 255 - new->local_pref; + } else { + new->med = 255; /* shouldn't happen */ + } + new->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); + } + + /* + * "new" is now a ghost attr: + * - it owns an "extra" struct + * - it owns any non-interned parts + * - any references to interned parts are not counted + * + * Caller should, after using the attr, call: + * - bgp_attr_flush() to free non-interned parts + */ + + return 0; } /* * "Adding a Route" export process */ -void -vnc_direct_bgp_add_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn) +void vnc_direct_bgp_add_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn) { - struct attr attr = { 0 }; - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - afi_t afi = family2afi (rn->p.family); - - if (!afi) - { - zlog_err ("%s: can't get afi of route node", __func__); - return; - } - - /* check bgp redist flag for vnc direct ("vpn") routes */ - if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", - __func__); - return; - } - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", - __func__); - return; - } - - if (!listcount (bgp->rfapi_cfg->rfg_export_direct_bgp_l)) - { - vnc_zlog_debug_verbose ("%s: no bgp-direct export nve group, skipping", __func__); - return; - } - - bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE); - /* TBD set some configured med, see add_vnc_route() */ - - vnc_zlog_debug_verbose ("%s: looping over nve-groups in direct-bgp export list", - __func__); - - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, nnode, rfgn)) - { - - struct listnode *ln; - - /* - * If nve group is not defined yet, skip it - */ - if (!rfgn->rfg) - continue; - - /* - * If the nve group uses a different import table, skip it - */ - if (import_table != rfgn->rfg->rfapi_import_table) - continue; - - /* - * if no NVEs currently associated with this group, skip it - */ - if (!rfgn->rfg->nves) - continue; - - /* - * per-nve-group prefix list check - */ - if (rfgn->rfg->plist_export_bgp[afi]) - { - if (prefix_list_apply (rfgn->rfg->plist_export_bgp[afi], &rn->p) == - PREFIX_DENY) - - continue; - } - - /* - * For each NVE that is assigned to the export nve group, generate - * a route with that NVE as its next hop - */ - for (ln = listhead (rfgn->rfg->nves); ln; ln = listnextnode (ln)) - { - - struct prefix nhp; - struct rfapi_descriptor *irfd; - struct bgp_info info; - struct attr hattr; - struct attr *iattr; - - irfd = listgetdata (ln); - - if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) - continue; - - /* - * Construct new attribute set with NVE's VN addr as - * nexthop and without Tunnel Encap attr - */ - if (encap_attr_export (&hattr, &attr, &nhp, rn)) - continue; - - if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) - { - vnc_zlog_debug_any ("%s: attr follows", __func__); - rfapiPrintAttrPtrs (NULL, &attr); - vnc_zlog_debug_any ("%s: hattr follows", __func__); - rfapiPrintAttrPtrs (NULL, &hattr); - } - - if (rfgn->rfg->routemap_export_bgp) - { - route_map_result_t ret; - info.peer = irfd->peer; - info.attr = &hattr; - ret = route_map_apply (rfgn->rfg->routemap_export_bgp, &rn->p, - RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - vnc_zlog_debug_verbose - ("%s: route map says DENY, so not calling bgp_update", - __func__); - continue; - } - } - - if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) - { - vnc_zlog_debug_any ("%s: hattr after route_map_apply:", __func__); - rfapiPrintAttrPtrs (NULL, &hattr); - } - - iattr = bgp_attr_intern (&hattr); - bgp_attr_flush (&hattr); - - bgp_update (irfd->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - iattr, /* bgp_update copies it */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, /* tag not used for unicast */ - 0, NULL); /* EVPN not used */ - - bgp_attr_unintern (&iattr); - } - } - - aspath_unintern (&attr.aspath); + struct attr attr = {0}; + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + afi_t afi = family2afi(rn->p.family); + + if (!afi) { + zlog_err("%s: can't get afi of route node", __func__); + return; + } + + /* check bgp redist flag for vnc direct ("vpn") routes */ + if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of VNC direct routes is off", + __func__); + return; + } + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp group mode not enabled, skipping", + __func__); + return; + } + + if (!listcount(bgp->rfapi_cfg->rfg_export_direct_bgp_l)) { + vnc_zlog_debug_verbose( + "%s: no bgp-direct export nve group, skipping", + __func__); + return; + } + + bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); + /* TBD set some configured med, see add_vnc_route() */ + + vnc_zlog_debug_verbose( + "%s: looping over nve-groups in direct-bgp export list", + __func__); + + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + nnode, rfgn)) { + + struct listnode *ln; + + /* + * If nve group is not defined yet, skip it + */ + if (!rfgn->rfg) + continue; + + /* + * If the nve group uses a different import table, skip it + */ + if (import_table != rfgn->rfg->rfapi_import_table) + continue; + + /* + * if no NVEs currently associated with this group, skip it + */ + if (!rfgn->rfg->nves) + continue; + + /* + * per-nve-group prefix list check + */ + if (rfgn->rfg->plist_export_bgp[afi]) { + if (prefix_list_apply(rfgn->rfg->plist_export_bgp[afi], + &rn->p) + == PREFIX_DENY) + + continue; + } + + /* + * For each NVE that is assigned to the export nve group, + * generate + * a route with that NVE as its next hop + */ + for (ln = listhead(rfgn->rfg->nves); ln; + ln = listnextnode(ln)) { + + struct prefix nhp; + struct rfapi_descriptor *irfd; + struct bgp_info info; + struct attr hattr; + struct attr *iattr; + + irfd = listgetdata(ln); + + if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) + continue; + + /* + * Construct new attribute set with NVE's VN addr as + * nexthop and without Tunnel Encap attr + */ + if (encap_attr_export(&hattr, &attr, &nhp, rn)) + continue; + + if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) { + vnc_zlog_debug_any("%s: attr follows", + __func__); + rfapiPrintAttrPtrs(NULL, &attr); + vnc_zlog_debug_any("%s: hattr follows", + __func__); + rfapiPrintAttrPtrs(NULL, &hattr); + } + + if (rfgn->rfg->routemap_export_bgp) { + route_map_result_t ret; + info.peer = irfd->peer; + info.attr = &hattr; + ret = route_map_apply( + rfgn->rfg->routemap_export_bgp, &rn->p, + RMAP_BGP, &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + vnc_zlog_debug_verbose( + "%s: route map says DENY, so not calling bgp_update", + __func__); + continue; + } + } + + if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) { + vnc_zlog_debug_any( + "%s: hattr after route_map_apply:", + __func__); + rfapiPrintAttrPtrs(NULL, &hattr); + } + + iattr = bgp_attr_intern(&hattr); + bgp_attr_flush(&hattr); + + bgp_update(irfd->peer, &rn->p, /* prefix */ + 0, /* addpath_id */ + iattr, /* bgp_update copies it */ + afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for unicast */ + NULL, /* tag not used for unicast */ + 0, NULL); /* EVPN not used */ + + bgp_attr_unintern(&iattr); + } + } + + aspath_unintern(&attr.aspath); } /* * "Withdrawing a Route" export process */ -void -vnc_direct_bgp_del_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn) +void vnc_direct_bgp_del_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn) { - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - afi_t afi = family2afi (rn->p.family); - - if (!afi) - { - zlog_err ("%s: can't get afi route node", __func__); - return; - } - - /* check bgp redist flag for vnc direct ("vpn") routes */ - if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", - __func__); - return; - } - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", - __func__); - return; - } - - if (!listcount (bgp->rfapi_cfg->rfg_export_direct_bgp_l)) - { - vnc_zlog_debug_verbose ("%s: no bgp-direct export nve group, skipping", __func__); - return; - } - - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, nnode, rfgn)) - { - - struct listnode *ln; - - /* - * If nve group is not defined yet, skip it - */ - if (!rfgn->rfg) - continue; - - /* - * if no NVEs currently associated with this group, skip it - */ - if (!rfgn->rfg->nves) - continue; - - /* - * If the nve group uses a different import table, - * skip it - */ - if (import_table != rfgn->rfg->rfapi_import_table) - continue; - - /* - * For each NVE that is assigned to the export nve group, generate - * a route with that NVE as its next hop - */ - for (ln = listhead (rfgn->rfg->nves); ln; ln = listnextnode (ln)) - { - - struct prefix nhp; - struct rfapi_descriptor *irfd; - - irfd = listgetdata (ln); - - if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) - continue; - - bgp_withdraw (irfd->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - NULL, /* attr, ignored */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, NULL); /* tag not used for unicast */ - } - } + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + afi_t afi = family2afi(rn->p.family); + + if (!afi) { + zlog_err("%s: can't get afi route node", __func__); + return; + } + + /* check bgp redist flag for vnc direct ("vpn") routes */ + if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of VNC direct routes is off", + __func__); + return; + } + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp group mode not enabled, skipping", + __func__); + return; + } + + if (!listcount(bgp->rfapi_cfg->rfg_export_direct_bgp_l)) { + vnc_zlog_debug_verbose( + "%s: no bgp-direct export nve group, skipping", + __func__); + return; + } + + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + nnode, rfgn)) { + + struct listnode *ln; + + /* + * If nve group is not defined yet, skip it + */ + if (!rfgn->rfg) + continue; + + /* + * if no NVEs currently associated with this group, skip it + */ + if (!rfgn->rfg->nves) + continue; + + /* + * If the nve group uses a different import table, + * skip it + */ + if (import_table != rfgn->rfg->rfapi_import_table) + continue; + + /* + * For each NVE that is assigned to the export nve group, + * generate + * a route with that NVE as its next hop + */ + for (ln = listhead(rfgn->rfg->nves); ln; + ln = listnextnode(ln)) { + + struct prefix nhp; + struct rfapi_descriptor *irfd; + + irfd = listgetdata(ln); + + if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) + continue; + + bgp_withdraw(irfd->peer, &rn->p, /* prefix */ + 0, /* addpath_id */ + NULL, /* attr, ignored */ + afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for unicast */ + NULL, NULL); /* tag not used for unicast */ + } + } } -void -vnc_direct_bgp_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd) +void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) { - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - struct rfapi_nve_group_cfg *rfg = rfd->rfg; - afi_t afi = family2afi (rfd->vn_addr.addr_family); - - if (!afi) - { - zlog_err ("%s: can't get afi of nve vn addr", __func__); - return; - } - - if (!bgp) - return; - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", - __func__); - return; - } - - if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", - __func__); - return; - } - - /* - * Loop over the list of NVE-Groups configured for - * exporting to direct-bgp and see if this new NVE's - * group is among them. - */ - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, nnode, rfgn)) - { - - /* - * Yes, this NVE's group is configured for export to direct-bgp - */ - if (rfgn->rfg == rfg) - { - - struct route_table *rt = NULL; - struct route_node *rn; - struct attr attr = { 0 }; - struct rfapi_import_table *import_table; - - - import_table = rfg->rfapi_import_table; - - bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE); - /* TBD set some configured med, see add_vnc_route() */ - - if (afi == AFI_IP - || afi == AFI_IP6) - { - rt = import_table->imported_vpn[afi]; - } - else - { - zlog_err ("%s: bad afi %d", __func__, afi); - return; - } - - /* - * Walk the NVE-Group's VNC Import table - */ - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - - if (rn->info) - { - - struct prefix nhp; - struct rfapi_descriptor *irfd = rfd; - struct attr hattr; - struct attr *iattr; - struct bgp_info info; - - if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) - continue; - - /* - * per-nve-group prefix list check - */ - if (rfgn->rfg->plist_export_bgp[afi]) - { - if (prefix_list_apply (rfgn->rfg->plist_export_bgp[afi], - &rn->p) == PREFIX_DENY) - - continue; - } - - - /* - * Construct new attribute set with NVE's VN addr as - * nexthop and without Tunnel Encap attr - */ - if (encap_attr_export (&hattr, &attr, &nhp, rn)) - continue; - - if (rfgn->rfg->routemap_export_bgp) - { - route_map_result_t ret; - info.peer = irfd->peer; - info.attr = &hattr; - ret = route_map_apply (rfgn->rfg->routemap_export_bgp, - &rn->p, RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - continue; - } - - } - - iattr = bgp_attr_intern (&hattr); - bgp_attr_flush (&hattr); - - bgp_update (irfd->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - iattr, /* bgp_update copies it */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, /* tag not used for unicast */ - 0, NULL); /* EVPN not used */ - - bgp_attr_unintern (&iattr); - - } - } - - aspath_unintern (&attr.aspath); - } - } + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + struct rfapi_nve_group_cfg *rfg = rfd->rfg; + afi_t afi = family2afi(rfd->vn_addr.addr_family); + + if (!afi) { + zlog_err("%s: can't get afi of nve vn addr", __func__); + return; + } + + if (!bgp) + return; + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp group mode not enabled, skipping", + __func__); + return; + } + + if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of VNC direct routes is off", + __func__); + return; + } + + /* + * Loop over the list of NVE-Groups configured for + * exporting to direct-bgp and see if this new NVE's + * group is among them. + */ + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + nnode, rfgn)) { + + /* + * Yes, this NVE's group is configured for export to direct-bgp + */ + if (rfgn->rfg == rfg) { + + struct route_table *rt = NULL; + struct route_node *rn; + struct attr attr = {0}; + struct rfapi_import_table *import_table; + + + import_table = rfg->rfapi_import_table; + + bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); + /* TBD set some configured med, see add_vnc_route() */ + + if (afi == AFI_IP || afi == AFI_IP6) { + rt = import_table->imported_vpn[afi]; + } else { + zlog_err("%s: bad afi %d", __func__, afi); + return; + } + + /* + * Walk the NVE-Group's VNC Import table + */ + for (rn = route_top(rt); rn; rn = route_next(rn)) { + + if (rn->info) { + + struct prefix nhp; + struct rfapi_descriptor *irfd = rfd; + struct attr hattr; + struct attr *iattr; + struct bgp_info info; + + if (rfapiRaddr2Qprefix(&irfd->vn_addr, + &nhp)) + continue; + + /* + * per-nve-group prefix list check + */ + if (rfgn->rfg->plist_export_bgp[afi]) { + if (prefix_list_apply( + rfgn->rfg->plist_export_bgp + [afi], + &rn->p) + == PREFIX_DENY) + + continue; + } + + + /* + * Construct new attribute set with + * NVE's VN addr as + * nexthop and without Tunnel Encap attr + */ + if (encap_attr_export(&hattr, &attr, + &nhp, rn)) + continue; + + if (rfgn->rfg->routemap_export_bgp) { + route_map_result_t ret; + info.peer = irfd->peer; + info.attr = &hattr; + ret = route_map_apply( + rfgn->rfg + ->routemap_export_bgp, + &rn->p, RMAP_BGP, + &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + continue; + } + } + + iattr = bgp_attr_intern(&hattr); + bgp_attr_flush(&hattr); + + bgp_update(irfd->peer, + &rn->p, /* prefix */ + 0, /* addpath_id */ + iattr, /* bgp_update copies + it */ + afi, SAFI_UNICAST, + ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for + unicast */ + NULL, /* tag not used for + unicast */ + 0, NULL); /* EVPN not used */ + + bgp_attr_unintern(&iattr); + } + } + + aspath_unintern(&attr.aspath); + } + } } -void -vnc_direct_bgp_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd) +void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) { - struct listnode *node, *nnode; - struct rfapi_rfg_name *rfgn; - struct rfapi_nve_group_cfg *rfg = rfd->rfg; - afi_t afi = family2afi (rfd->vn_addr.addr_family); - - if (!afi) - { - zlog_err ("%s: can't get afi of nve vn addr", __func__); - return; - } - - if (!bgp) - return; - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", - __func__); - return; - } - - if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", - __func__); - return; - } - - /* - * Loop over the list of NVE-Groups configured for - * exporting to direct-bgp and see if this new NVE's - * group is among them. - */ - for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, nnode, rfgn)) - { - - /* - * Yes, this NVE's group is configured for export to direct-bgp - */ - if (rfg && rfgn->rfg == rfg) - { - - struct route_table *rt = NULL; - struct route_node *rn; - struct rfapi_import_table *import_table; - - import_table = rfg->rfapi_import_table; - - if (afi == AFI_IP - || afi == AFI_IP6) - { - rt = import_table->imported_vpn[afi]; - } - else - { - zlog_err ("%s: bad afi %d", __func__, afi); - return; - } - - /* - * Walk the NVE-Group's VNC Import table - */ - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - - if (rn->info) - { - - struct prefix nhp; - struct rfapi_descriptor *irfd = rfd; - - if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) - continue; - - bgp_withdraw (irfd->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - NULL, /* attr, ignored */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, NULL); /* tag not used for unicast */ - - } - } - } - } -} + struct listnode *node, *nnode; + struct rfapi_rfg_name *rfgn; + struct rfapi_nve_group_cfg *rfg = rfd->rfg; + afi_t afi = family2afi(rfd->vn_addr.addr_family); + + if (!afi) { + zlog_err("%s: can't get afi of nve vn addr", __func__); + return; + } + + if (!bgp) + return; + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp group mode not enabled, skipping", + __func__); + return; + } + + if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of VNC direct routes is off", + __func__); + return; + } + /* + * Loop over the list of NVE-Groups configured for + * exporting to direct-bgp and see if this new NVE's + * group is among them. + */ + for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + nnode, rfgn)) { + + /* + * Yes, this NVE's group is configured for export to direct-bgp + */ + if (rfg && rfgn->rfg == rfg) { + + struct route_table *rt = NULL; + struct route_node *rn; + struct rfapi_import_table *import_table; + + import_table = rfg->rfapi_import_table; + + if (afi == AFI_IP || afi == AFI_IP6) { + rt = import_table->imported_vpn[afi]; + } else { + zlog_err("%s: bad afi %d", __func__, afi); + return; + } + + /* + * Walk the NVE-Group's VNC Import table + */ + for (rn = route_top(rt); rn; rn = route_next(rn)) { + + if (rn->info) { + + struct prefix nhp; + struct rfapi_descriptor *irfd = rfd; + + if (rfapiRaddr2Qprefix(&irfd->vn_addr, + &nhp)) + continue; + + bgp_withdraw(irfd->peer, + &rn->p, /* prefix */ + 0, /* addpath_id */ + NULL, /* attr, ignored */ + afi, SAFI_UNICAST, + ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for + unicast */ + NULL, NULL); /* tag not + used for + unicast */ + } + } + } + } +} /* * Caller is responsible for ensuring that the specified nve-group * is actually part of the list of exported nve groups. */ -static void -vnc_direct_bgp_add_group_afi ( - struct bgp *bgp, - struct rfapi_nve_group_cfg *rfg, - afi_t afi) +static void vnc_direct_bgp_add_group_afi(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg, + afi_t afi) { - struct route_table *rt = NULL; - struct route_node *rn; - struct attr attr = { 0 }; - struct rfapi_import_table *import_table; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - - import_table = rfg->rfapi_import_table; - if (!import_table) - { - vnc_zlog_debug_verbose ("%s: import table not defined, returning", __func__); - return; - } - - if (afi == AFI_IP - || afi == AFI_IP6) - { - rt = import_table->imported_vpn[afi]; - } - else - { - zlog_err ("%s: bad afi %d", __func__, afi); - return; - } - - if (!rfg->nves) - { - /* avoid segfault below if list doesn't exist */ - vnc_zlog_debug_verbose ("%s: no NVEs in this group", __func__); - return; - } - - bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE); - /* TBD set some configured med, see add_vnc_route() */ - - /* - * Walk the NVE-Group's VNC Import table - */ - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - - if (rn->info) - { - - struct listnode *ln; - - /* - * per-nve-group prefix list check - */ - if (rfg->plist_export_bgp[afi]) - { - if (prefix_list_apply (rfg->plist_export_bgp[afi], &rn->p) == - PREFIX_DENY) - - continue; - } - - /* - * For each NVE that is assigned to the export nve group, generate - * a route with that NVE as its next hop - */ - for (ln = listhead (rfg->nves); ln; ln = listnextnode (ln)) - { - - struct prefix nhp; - struct rfapi_descriptor *irfd; - struct bgp_info info; - struct attr hattr; - struct attr *iattr; - - irfd = listgetdata (ln); - - if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) - continue; - - /* - * Construct new attribute set with NVE's VN addr as - * nexthop and without Tunnel Encap attr - */ - if (encap_attr_export (&hattr, &attr, &nhp, rn)) - continue; - - if (rfg->routemap_export_bgp) - { - route_map_result_t ret; - info.peer = irfd->peer; - info.attr = &hattr; - ret = route_map_apply (rfg->routemap_export_bgp, - &rn->p, RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - continue; - } - - } - - iattr = bgp_attr_intern (&hattr); - bgp_attr_flush (&hattr); - - bgp_update (irfd->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - iattr, /* bgp_update copies it */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, /* tag not used for unicast */ - 0, NULL); /* EVPN not used */ - - bgp_attr_unintern (&iattr); - } - } - } - - aspath_unintern (&attr.aspath); + struct route_table *rt = NULL; + struct route_node *rn; + struct attr attr = {0}; + struct rfapi_import_table *import_table; + + vnc_zlog_debug_verbose("%s: entry", __func__); + + import_table = rfg->rfapi_import_table; + if (!import_table) { + vnc_zlog_debug_verbose( + "%s: import table not defined, returning", __func__); + return; + } + + if (afi == AFI_IP || afi == AFI_IP6) { + rt = import_table->imported_vpn[afi]; + } else { + zlog_err("%s: bad afi %d", __func__, afi); + return; + } + + if (!rfg->nves) { + /* avoid segfault below if list doesn't exist */ + vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__); + return; + } + + bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); + /* TBD set some configured med, see add_vnc_route() */ + + /* + * Walk the NVE-Group's VNC Import table + */ + for (rn = route_top(rt); rn; rn = route_next(rn)) { + + if (rn->info) { + + struct listnode *ln; + + /* + * per-nve-group prefix list check + */ + if (rfg->plist_export_bgp[afi]) { + if (prefix_list_apply( + rfg->plist_export_bgp[afi], &rn->p) + == PREFIX_DENY) + + continue; + } + + /* + * For each NVE that is assigned to the export nve + * group, generate + * a route with that NVE as its next hop + */ + for (ln = listhead(rfg->nves); ln; + ln = listnextnode(ln)) { + + struct prefix nhp; + struct rfapi_descriptor *irfd; + struct bgp_info info; + struct attr hattr; + struct attr *iattr; + + irfd = listgetdata(ln); + + if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) + continue; + + /* + * Construct new attribute set with NVE's VN + * addr as + * nexthop and without Tunnel Encap attr + */ + if (encap_attr_export(&hattr, &attr, &nhp, rn)) + continue; + + if (rfg->routemap_export_bgp) { + route_map_result_t ret; + info.peer = irfd->peer; + info.attr = &hattr; + ret = route_map_apply( + rfg->routemap_export_bgp, + &rn->p, RMAP_BGP, &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + continue; + } + } + + iattr = bgp_attr_intern(&hattr); + bgp_attr_flush(&hattr); + + bgp_update(irfd->peer, &rn->p, /* prefix */ + 0, /* addpath_id */ + iattr, /* bgp_update copies it */ + afi, SAFI_UNICAST, + ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for unicast */ + NULL, /* tag not used for unicast */ + 0, NULL); /* EVPN not used */ + + bgp_attr_unintern(&iattr); + } + } + } + + aspath_unintern(&attr.aspath); } @@ -1366,80 +1302,77 @@ vnc_direct_bgp_add_group_afi ( * Caller is responsible for ensuring that the specified nve-group * is actually part of the list of exported nve groups. */ -void -vnc_direct_bgp_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) +void vnc_direct_bgp_add_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) { - vnc_direct_bgp_add_group_afi (bgp, rfg, AFI_IP); - vnc_direct_bgp_add_group_afi (bgp, rfg, AFI_IP6); + vnc_direct_bgp_add_group_afi(bgp, rfg, AFI_IP); + vnc_direct_bgp_add_group_afi(bgp, rfg, AFI_IP6); } - /* * Caller is responsible for ensuring that the specified nve-group * was actually part of the list of exported nve groups. */ -static void -vnc_direct_bgp_del_group_afi ( - struct bgp *bgp, - struct rfapi_nve_group_cfg *rfg, - afi_t afi) +static void vnc_direct_bgp_del_group_afi(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg, + afi_t afi) { - struct route_table *rt = NULL; - struct route_node *rn; - struct rfapi_import_table *import_table; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - - import_table = rfg->rfapi_import_table; - if (!import_table) - { - vnc_zlog_debug_verbose ("%s: import table not defined, returning", __func__); - return; - } - - assert (afi == AFI_IP - || afi == AFI_IP6); - rt = import_table->imported_vpn[afi]; - - if (!rfg->nves) - { - /* avoid segfault below if list does not exist */ - vnc_zlog_debug_verbose ("%s: no NVEs in this group", __func__); - return; - } - - /* - * Walk the NVE-Group's VNC Import table - */ - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - - if (rn->info) - { - - struct listnode *ln; - - /* - * For each NVE that is assigned to the export nve group, generate - * a route with that NVE as its next hop - */ - for (ln = listhead (rfg->nves); ln; ln = listnextnode (ln)) - { - - struct rfapi_descriptor *irfd; - - irfd = listgetdata (ln); - - bgp_withdraw (irfd->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - NULL, /* attr, ignored */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, NULL); /* tag not used for unicast */ - - } - } - } + struct route_table *rt = NULL; + struct route_node *rn; + struct rfapi_import_table *import_table; + + vnc_zlog_debug_verbose("%s: entry", __func__); + + import_table = rfg->rfapi_import_table; + if (!import_table) { + vnc_zlog_debug_verbose( + "%s: import table not defined, returning", __func__); + return; + } + + assert(afi == AFI_IP || afi == AFI_IP6); + rt = import_table->imported_vpn[afi]; + + if (!rfg->nves) { + /* avoid segfault below if list does not exist */ + vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__); + return; + } + + /* + * Walk the NVE-Group's VNC Import table + */ + for (rn = route_top(rt); rn; rn = route_next(rn)) { + + if (rn->info) { + + struct listnode *ln; + + /* + * For each NVE that is assigned to the export nve + * group, generate + * a route with that NVE as its next hop + */ + for (ln = listhead(rfg->nves); ln; + ln = listnextnode(ln)) { + + struct rfapi_descriptor *irfd; + + irfd = listgetdata(ln); + + bgp_withdraw( + irfd->peer, &rn->p, /* prefix */ + 0, /* addpath_id */ + NULL, /* attr, ignored */ + afi, SAFI_UNICAST, + ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for unicast */ + NULL, + NULL); /* tag not used for unicast */ + } + } + } } @@ -1447,189 +1380,173 @@ vnc_direct_bgp_del_group_afi ( * Caller is responsible for ensuring that the specified nve-group * was actually part of the list of exported nve groups. */ -void -vnc_direct_bgp_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) +void vnc_direct_bgp_del_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) { - vnc_direct_bgp_del_group_afi (bgp, rfg, AFI_IP); - vnc_direct_bgp_del_group_afi (bgp, rfg, AFI_IP6); + vnc_direct_bgp_del_group_afi(bgp, rfg, AFI_IP); + vnc_direct_bgp_del_group_afi(bgp, rfg, AFI_IP6); } -void -vnc_direct_bgp_reexport_group_afi ( - struct bgp *bgp, - struct rfapi_nve_group_cfg *rfg, - afi_t afi) +void vnc_direct_bgp_reexport_group_afi(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg, + afi_t afi) { - struct listnode *node; - struct rfapi_rfg_name *rfgn; - - if (VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) - { - /* - * look in the list of currently-exported groups - */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - /* - * If it matches, reexport it - */ - vnc_direct_bgp_del_group_afi (bgp, rfg, afi); - vnc_direct_bgp_add_group_afi (bgp, rfg, afi); - break; - } - } - } + struct listnode *node; + struct rfapi_rfg_name *rfgn; + + if (VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { + /* + * look in the list of currently-exported groups + */ + for (ALL_LIST_ELEMENTS_RO( + bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + /* + * If it matches, reexport it + */ + vnc_direct_bgp_del_group_afi(bgp, rfg, afi); + vnc_direct_bgp_add_group_afi(bgp, rfg, afi); + break; + } + } + } } -static void -vnc_direct_bgp_unexport_table ( - afi_t afi, - struct route_table *rt, - struct list *nve_list) +static void vnc_direct_bgp_unexport_table(afi_t afi, struct route_table *rt, + struct list *nve_list) { - if (nve_list) - { - - struct route_node *rn; - - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - - if (rn->info) - { - - struct listnode *hln; - struct rfapi_descriptor *irfd; - - for (ALL_LIST_ELEMENTS_RO (nve_list, hln, irfd)) - { - - bgp_withdraw (irfd->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - NULL, /* attr, ignored */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, NULL); /* tag not used for unicast, EVPN neither */ - - } - } - } - } + if (nve_list) { + + struct route_node *rn; + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + + if (rn->info) { + + struct listnode *hln; + struct rfapi_descriptor *irfd; + + for (ALL_LIST_ELEMENTS_RO(nve_list, hln, + irfd)) { + + bgp_withdraw(irfd->peer, + &rn->p, /* prefix */ + 0, /* addpath_id */ + NULL, /* attr, ignored */ + afi, SAFI_UNICAST, + ZEBRA_ROUTE_VNC_DIRECT, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for + unicast */ + NULL, NULL); /* tag not + used for + unicast, + EVPN + neither */ + } + } + } + } } -static void -import_table_to_nve_list_direct_bgp ( - struct bgp *bgp, - struct rfapi_import_table *it, - struct list **nves, - uint8_t family) +static void import_table_to_nve_list_direct_bgp(struct bgp *bgp, + struct rfapi_import_table *it, + struct list **nves, + uint8_t family) { - struct listnode *node; - struct rfapi_rfg_name *rfgn; - - /* - * Loop over the list of NVE-Groups configured for - * exporting to direct-bgp. - * - * Build a list of NVEs that use this import table - */ - *nves = NULL; - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, - node, rfgn)) - { - - /* - * If this NVE-Group's import table matches the current one - */ - if (rfgn->rfg && rfgn->rfg->nves && rfgn->rfg->rfapi_import_table == it) - { - - nve_group_to_nve_list (rfgn->rfg, nves, family); - } - } + struct listnode *node; + struct rfapi_rfg_name *rfgn; + + /* + * Loop over the list of NVE-Groups configured for + * exporting to direct-bgp. + * + * Build a list of NVEs that use this import table + */ + *nves = NULL; + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, + rfgn)) { + + /* + * If this NVE-Group's import table matches the current one + */ + if (rfgn->rfg && rfgn->rfg->nves + && rfgn->rfg->rfapi_import_table == it) { + + nve_group_to_nve_list(rfgn->rfg, nves, family); + } + } } -void -vnc_direct_bgp_vpn_enable (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi) { - struct listnode *rfgn; - struct rfapi_nve_group_cfg *rfg; - - if (!bgp) - return; - - if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", - __func__); - return; - } - - if (afi != AFI_IP - && afi != AFI_IP6) - { - vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); - return; - } - - /* - * Policy is applied per-nve-group, so we need to iterate - * over the groups to add everything. - */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->nve_groups_sequential, - rfgn, rfg)) - { - - /* - * contains policy management - */ - vnc_direct_bgp_add_group_afi (bgp, rfg, afi); - } + struct listnode *rfgn; + struct rfapi_nve_group_cfg *rfg; + + if (!bgp) + return; + + if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp group mode not enabled, skipping", + __func__); + return; + } + + if (afi != AFI_IP && afi != AFI_IP6) { + vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); + return; + } + + /* + * Policy is applied per-nve-group, so we need to iterate + * over the groups to add everything. + */ + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, rfgn, + rfg)) { + + /* + * contains policy management + */ + vnc_direct_bgp_add_group_afi(bgp, rfg, afi); + } } -void -vnc_direct_bgp_vpn_disable (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi) { - struct rfapi_import_table *it; - uint8_t family = afi2family (afi); + struct rfapi_import_table *it; + uint8_t family = afi2family(afi); - vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); + vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); - if (!bgp) - return; + if (!bgp) + return; - if (!bgp->rfapi) - { - vnc_zlog_debug_verbose ("%s: rfapi not initialized", __func__); - return; - } + if (!bgp->rfapi) { + vnc_zlog_debug_verbose("%s: rfapi not initialized", __func__); + return; + } - if (!family || (afi != AFI_IP - && afi != AFI_IP6)) - { - vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); - return; - } + if (!family || (afi != AFI_IP && afi != AFI_IP6)) { + vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); + return; + } - for (it = bgp->rfapi->imports; it; it = it->next) - { + for (it = bgp->rfapi->imports; it; it = it->next) { - struct list *nve_list = NULL; + struct list *nve_list = NULL; - import_table_to_nve_list_direct_bgp (bgp, it, &nve_list, family); + import_table_to_nve_list_direct_bgp(bgp, it, &nve_list, family); - if (nve_list) - { - vnc_direct_bgp_unexport_table (afi, it->imported_vpn[afi], - nve_list); - list_free (nve_list); - } - } + if (nve_list) { + vnc_direct_bgp_unexport_table( + afi, it->imported_vpn[afi], nve_list); + list_free(nve_list); + } + } } @@ -1649,137 +1566,121 @@ vnc_direct_bgp_vpn_disable (struct bgp *bgp, afi_t afi) * TBD do we need to check bi->type and bi->sub_type here, or does * caller do it? */ -void -vnc_direct_bgp_rh_add_route ( - struct bgp *bgp, - afi_t afi, - struct prefix *prefix, - struct peer *peer, - struct attr *attr) +void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi, + struct prefix *prefix, struct peer *peer, + struct attr *attr) { - struct vnc_export_info *eti; - struct attr hattr; - struct rfapi_cfg *hc; - struct attr *iattr; - - if (!afi) - { - zlog_err ("%s: can't get afi of route node", __func__); - return; - } - - /* check bgp redist flag for vnc direct ("vpn") routes */ - if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", - __func__); - return; - } - - if (!(hc = bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - if (!VNC_EXPORT_BGP_RH_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp RH mode not enabled, skipping", - __func__); - return; - } - - /* - * prefix list check - */ - if (hc->plist_export_bgp[afi]) - { - if (prefix_list_apply (hc->plist_export_bgp[afi], prefix) == - PREFIX_DENY) - return; - } - - /* - * Construct new attribute set with NVE's VN addr as - * nexthop and without Tunnel Encap attr - */ - if (encap_attr_export (&hattr, attr, NULL, NULL)) - return; - if (hc->routemap_export_bgp) - { - struct bgp_info info; - route_map_result_t ret; - - memset (&info, 0, sizeof (info)); - info.peer = peer; - info.attr = &hattr; - ret = - route_map_apply (hc->routemap_export_bgp, prefix, RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - return; - } - } - - iattr = bgp_attr_intern (&hattr); - bgp_attr_flush (&hattr); - - /* - * record route information that we will need to expire - * this route - */ - eti = vnc_eti_get (bgp, EXPORT_TYPE_BGP, prefix, peer, - ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); - rfapiGetVncLifetime (attr, &eti->lifetime); - eti->lifetime = rfapiGetHolddownFromLifetime (eti->lifetime); - - if (eti->timer) - { - /* - * export expiration timer is already running on - * this route: cancel it - */ - thread_cancel (eti->timer); - eti->timer = NULL; - } - - bgp_update (peer, prefix, /* prefix */ - 0, /* addpath_id */ - iattr, /* bgp_update copies this attr */ - afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, /* tag not used for unicast, EVPN neither */ - 0, NULL); /* EVPN not used */ - bgp_attr_unintern (&iattr); + struct vnc_export_info *eti; + struct attr hattr; + struct rfapi_cfg *hc; + struct attr *iattr; + + if (!afi) { + zlog_err("%s: can't get afi of route node", __func__); + return; + } + + /* check bgp redist flag for vnc direct ("vpn") routes */ + if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of VNC direct routes is off", + __func__); + return; + } + + if (!(hc = bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + if (!VNC_EXPORT_BGP_RH_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp RH mode not enabled, skipping", + __func__); + return; + } + + /* + * prefix list check + */ + if (hc->plist_export_bgp[afi]) { + if (prefix_list_apply(hc->plist_export_bgp[afi], prefix) + == PREFIX_DENY) + return; + } + + /* + * Construct new attribute set with NVE's VN addr as + * nexthop and without Tunnel Encap attr + */ + if (encap_attr_export(&hattr, attr, NULL, NULL)) + return; + if (hc->routemap_export_bgp) { + struct bgp_info info; + route_map_result_t ret; + + memset(&info, 0, sizeof(info)); + info.peer = peer; + info.attr = &hattr; + ret = route_map_apply(hc->routemap_export_bgp, prefix, RMAP_BGP, + &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + return; + } + } + + iattr = bgp_attr_intern(&hattr); + bgp_attr_flush(&hattr); + + /* + * record route information that we will need to expire + * this route + */ + eti = vnc_eti_get(bgp, EXPORT_TYPE_BGP, prefix, peer, + ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); + rfapiGetVncLifetime(attr, &eti->lifetime); + eti->lifetime = rfapiGetHolddownFromLifetime(eti->lifetime); + + if (eti->timer) { + /* + * export expiration timer is already running on + * this route: cancel it + */ + thread_cancel(eti->timer); + eti->timer = NULL; + } + bgp_update(peer, prefix, /* prefix */ + 0, /* addpath_id */ + iattr, /* bgp_update copies this attr */ + afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, + BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ + NULL, /* tag not used for unicast, EVPN neither */ + 0, NULL); /* EVPN not used */ + bgp_attr_unintern(&iattr); } -static int -vncExportWithdrawTimer (struct thread *t) +static int vncExportWithdrawTimer(struct thread *t) { - struct vnc_export_info *eti = t->arg; - - /* - * withdraw the route - */ - bgp_withdraw ( - eti->peer, - &eti->node->p, - 0, /* addpath_id */ - NULL, /* attr, ignored */ - family2afi (eti->node->p.family), - SAFI_UNICAST, - eti->type, - eti->subtype, - NULL, /* RD not used for unicast */ - NULL, NULL); /* tag not used for unicast, EVPN neither */ - - /* - * Free the eti - */ - vnc_eti_delete (eti); - - return 0; + struct vnc_export_info *eti = t->arg; + + /* + * withdraw the route + */ + bgp_withdraw(eti->peer, &eti->node->p, 0, /* addpath_id */ + NULL, /* attr, ignored */ + family2afi(eti->node->p.family), SAFI_UNICAST, eti->type, + eti->subtype, NULL, /* RD not used for unicast */ + NULL, NULL); /* tag not used for unicast, EVPN neither */ + + /* + * Free the eti + */ + vnc_eti_delete(eti); + + return 0; } /* @@ -1787,287 +1688,295 @@ vncExportWithdrawTimer (struct thread *t) * TBD do we need to check bi->type and bi->sub_type here, or does * caller do it? */ -void -vnc_direct_bgp_rh_del_route ( - struct bgp *bgp, - afi_t afi, - struct prefix *prefix, - struct peer *peer) +void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi, + struct prefix *prefix, struct peer *peer) { - struct vnc_export_info *eti; - - if (!afi) - { - zlog_err ("%s: can't get afi route node", __func__); - return; - } - - /* check bgp redist flag for vnc direct ("vpn") routes */ - if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", - __func__); - return; - } - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - if (!VNC_EXPORT_BGP_RH_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", - __func__); - return; - } - - eti = vnc_eti_get (bgp, EXPORT_TYPE_BGP, prefix, peer, - ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); - - if (!eti->timer && eti->lifetime <= INT32_MAX) - { - eti->timer = NULL; - thread_add_timer(bm->master, vncExportWithdrawTimer, eti, eti->lifetime, - &eti->timer); - vnc_zlog_debug_verbose ("%s: set expiration timer for %u seconds", - __func__, eti->lifetime); - } + struct vnc_export_info *eti; + + if (!afi) { + zlog_err("%s: can't get afi route node", __func__); + return; + } + + /* check bgp redist flag for vnc direct ("vpn") routes */ + if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of VNC direct routes is off", + __func__); + return; + } + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + if (!VNC_EXPORT_BGP_RH_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export-to-bgp group mode not enabled, skipping", + __func__); + return; + } + + eti = vnc_eti_get(bgp, EXPORT_TYPE_BGP, prefix, peer, + ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); + + if (!eti->timer && eti->lifetime <= INT32_MAX) { + eti->timer = NULL; + thread_add_timer(bm->master, vncExportWithdrawTimer, eti, + eti->lifetime, &eti->timer); + vnc_zlog_debug_verbose( + "%s: set expiration timer for %u seconds", __func__, + eti->lifetime); + } } -void -vnc_direct_bgp_rh_vpn_enable (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi) { - struct prefix_rd prd; - struct bgp_node *prn; - struct rfapi_cfg *hc; - - vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); - - if (!bgp) - return; - - if (!(hc = bgp->rfapi_cfg)) - return; - - if (!VNC_EXPORT_BGP_RH_ENABLED (bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: export of RH routes not enabled, skipping", __func__); - return; - } - - if (afi != AFI_IP - && afi != AFI_IP6) - { - vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); - return; - } - - /* - * Go through the entire BGP VPN table and export to BGP unicast. - */ - - vnc_zlog_debug_verbose ("%s: starting RD loop", __func__); - - /* Loop over all the RDs */ - for (prn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); prn; - prn = bgp_route_next (prn)) - { - - struct bgp_table *table; - struct bgp_node *rn; - struct bgp_info *ri; - - memset (&prd, 0, sizeof (prd)); - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - memcpy (prd.val, prn->p.u.val, 8); - - /* This is the per-RD table of prefixes */ - table = prn->info; - - for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) - { - - /* - * skip prefix list check if no routes here - */ - if (!rn->info) - continue; - - { - char prefixstr[BUFSIZ]; - - prefixstr[0] = 0; - inet_ntop (rn->p.family, &rn->p.u.prefix, prefixstr, BUFSIZ); - vnc_zlog_debug_verbose ("%s: checking prefix %s/%d", __func__, prefixstr, - rn->p.prefixlen); - } - - /* - * prefix list check - */ - if (hc->plist_export_bgp[afi]) - { - if (prefix_list_apply (hc->plist_export_bgp[afi], &rn->p) == - PREFIX_DENY) - { - - vnc_zlog_debug_verbose ("%s: prefix list says DENY", __func__); - continue; - } - } - - for (ri = rn->info; ri; ri = ri->next) - { - - vnc_zlog_debug_verbose ("%s: ri->sub_type: %d", __func__, ri->sub_type); - - if (ri->sub_type == BGP_ROUTE_NORMAL || - ri->sub_type == BGP_ROUTE_RFP) - { - - struct vnc_export_info *eti; - struct attr hattr; - struct attr *iattr; - - /* - * Construct new attribute set with NVE's VN addr as - * nexthop and without Tunnel Encap attr - */ - if (encap_attr_export (&hattr, ri->attr, NULL, NULL)) - { - vnc_zlog_debug_verbose ("%s: encap_attr_export failed", __func__); - continue; - } - - if (hc->routemap_export_bgp) - { - struct bgp_info info; - route_map_result_t ret; - - memset (&info, 0, sizeof (info)); - info.peer = ri->peer; - info.attr = &hattr; - ret = route_map_apply (hc->routemap_export_bgp, - &rn->p, RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - vnc_zlog_debug_verbose ("%s: route map says DENY", __func__); - continue; - } - } - - iattr = bgp_attr_intern (&hattr); - bgp_attr_flush (&hattr); - - /* - * record route information that we will need to expire - * this route - */ - eti = vnc_eti_get (bgp, EXPORT_TYPE_BGP, &rn->p, ri->peer, - ZEBRA_ROUTE_VNC_DIRECT_RH, - BGP_ROUTE_REDISTRIBUTE); - rfapiGetVncLifetime (ri->attr, &eti->lifetime); - - if (eti->timer) - { - /* - * export expiration timer is already running on - * this route: cancel it - */ - thread_cancel (eti->timer); - eti->timer = NULL; - } - - vnc_zlog_debug_verbose ("%s: calling bgp_update", __func__); - - bgp_update (ri->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - iattr, /* bgp_update copies it */ - AFI_IP, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, /* tag not used for unicast, EVPN neither */ - 0, NULL); /* EVPN not used */ - bgp_attr_unintern (&iattr); - } - } - } - } + struct prefix_rd prd; + struct bgp_node *prn; + struct rfapi_cfg *hc; + + vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); + + if (!bgp) + return; + + if (!(hc = bgp->rfapi_cfg)) + return; + + if (!VNC_EXPORT_BGP_RH_ENABLED(bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose( + "%s: export of RH routes not enabled, skipping", + __func__); + return; + } + + if (afi != AFI_IP && afi != AFI_IP6) { + vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); + return; + } + + /* + * Go through the entire BGP VPN table and export to BGP unicast. + */ + + vnc_zlog_debug_verbose("%s: starting RD loop", __func__); + + /* Loop over all the RDs */ + for (prn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); prn; + prn = bgp_route_next(prn)) { + + struct bgp_table *table; + struct bgp_node *rn; + struct bgp_info *ri; + + memset(&prd, 0, sizeof(prd)); + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + memcpy(prd.val, prn->p.u.val, 8); + + /* This is the per-RD table of prefixes */ + table = prn->info; + + for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { + + /* + * skip prefix list check if no routes here + */ + if (!rn->info) + continue; + + { + char prefixstr[BUFSIZ]; + + prefixstr[0] = 0; + inet_ntop(rn->p.family, &rn->p.u.prefix, + prefixstr, BUFSIZ); + vnc_zlog_debug_verbose( + "%s: checking prefix %s/%d", __func__, + prefixstr, rn->p.prefixlen); + } + + /* + * prefix list check + */ + if (hc->plist_export_bgp[afi]) { + if (prefix_list_apply(hc->plist_export_bgp[afi], + &rn->p) + == PREFIX_DENY) { + + vnc_zlog_debug_verbose( + "%s: prefix list says DENY", + __func__); + continue; + } + } + + for (ri = rn->info; ri; ri = ri->next) { + + vnc_zlog_debug_verbose("%s: ri->sub_type: %d", + __func__, ri->sub_type); + + if (ri->sub_type == BGP_ROUTE_NORMAL + || ri->sub_type == BGP_ROUTE_RFP) { + + struct vnc_export_info *eti; + struct attr hattr; + struct attr *iattr; + + /* + * Construct new attribute set with + * NVE's VN addr as + * nexthop and without Tunnel Encap attr + */ + if (encap_attr_export(&hattr, ri->attr, + NULL, NULL)) { + vnc_zlog_debug_verbose( + "%s: encap_attr_export failed", + __func__); + continue; + } + + if (hc->routemap_export_bgp) { + struct bgp_info info; + route_map_result_t ret; + + memset(&info, 0, sizeof(info)); + info.peer = ri->peer; + info.attr = &hattr; + ret = route_map_apply( + hc->routemap_export_bgp, + &rn->p, RMAP_BGP, + &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + vnc_zlog_debug_verbose( + "%s: route map says DENY", + __func__); + continue; + } + } + + iattr = bgp_attr_intern(&hattr); + bgp_attr_flush(&hattr); + + /* + * record route information that we will + * need to expire + * this route + */ + eti = vnc_eti_get( + bgp, EXPORT_TYPE_BGP, &rn->p, + ri->peer, + ZEBRA_ROUTE_VNC_DIRECT_RH, + BGP_ROUTE_REDISTRIBUTE); + rfapiGetVncLifetime(ri->attr, + &eti->lifetime); + + if (eti->timer) { + /* + * export expiration timer is + * already running on + * this route: cancel it + */ + thread_cancel(eti->timer); + eti->timer = NULL; + } + + vnc_zlog_debug_verbose( + "%s: calling bgp_update", + __func__); + + bgp_update(ri->peer, + &rn->p, /* prefix */ + 0, /* addpath_id */ + iattr, /* bgp_update copies + it */ + AFI_IP, SAFI_UNICAST, + ZEBRA_ROUTE_VNC_DIRECT_RH, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for + unicast */ + NULL, /* tag not used for + unicast, EVPN + neither */ + 0, NULL); /* EVPN not used */ + bgp_attr_unintern(&iattr); + } + } + } + } } -void -vnc_direct_bgp_rh_vpn_disable (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi) { - struct bgp_node *rn; - - vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); - - if (!bgp) - return; - - if (afi != AFI_IP - && afi != AFI_IP6) - { - vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); - return; - } - - /* - * Go through the entire BGP unicast table and remove routes that - * originated from us - */ - for (rn = bgp_table_top (bgp->rib[afi][SAFI_UNICAST]); rn; - rn = bgp_route_next (rn)) - { - - struct bgp_info *ri; - struct bgp_info *next; - - for (ri = rn->info, next = NULL; ri; ri = next) - { - - next = ri->next; - - if (ri->type == ZEBRA_ROUTE_VNC_DIRECT_RH && - ri->sub_type == BGP_ROUTE_REDISTRIBUTE) - { - - struct vnc_export_info *eti; - - /* - * Delete routes immediately (no timer) - */ - eti = - vnc_eti_checktimer (bgp, EXPORT_TYPE_BGP, &rn->p, ri->peer, - ZEBRA_ROUTE_VNC_DIRECT_RH, - BGP_ROUTE_REDISTRIBUTE); - if (eti) - { - if (eti->timer) - thread_cancel (eti->timer); - vnc_eti_delete (eti); - } - - bgp_withdraw (ri->peer, &rn->p, /* prefix */ - 0, /* addpath_id */ - NULL, /* ignored */ - AFI_IP, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ - NULL, NULL); /* tag not used for unicast, EVPN neither */ - } - } - } + struct bgp_node *rn; + + vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); + + if (!bgp) + return; + + if (afi != AFI_IP && afi != AFI_IP6) { + vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); + return; + } + + /* + * Go through the entire BGP unicast table and remove routes that + * originated from us + */ + for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; + rn = bgp_route_next(rn)) { + + struct bgp_info *ri; + struct bgp_info *next; + + for (ri = rn->info, next = NULL; ri; ri = next) { + + next = ri->next; + + if (ri->type == ZEBRA_ROUTE_VNC_DIRECT_RH + && ri->sub_type == BGP_ROUTE_REDISTRIBUTE) { + + struct vnc_export_info *eti; + + /* + * Delete routes immediately (no timer) + */ + eti = vnc_eti_checktimer( + bgp, EXPORT_TYPE_BGP, &rn->p, ri->peer, + ZEBRA_ROUTE_VNC_DIRECT_RH, + BGP_ROUTE_REDISTRIBUTE); + if (eti) { + if (eti->timer) + thread_cancel(eti->timer); + vnc_eti_delete(eti); + } + + bgp_withdraw(ri->peer, &rn->p, /* prefix */ + 0, /* addpath_id */ + NULL, /* ignored */ + AFI_IP, SAFI_UNICAST, + ZEBRA_ROUTE_VNC_DIRECT_RH, + BGP_ROUTE_REDISTRIBUTE, + NULL, /* RD not used for unicast */ + NULL, NULL); /* tag not used for + unicast, EVPN + neither */ + } + } + } } -void -vnc_direct_bgp_rh_reexport (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_rh_reexport(struct bgp *bgp, afi_t afi) { - if (VNC_EXPORT_BGP_RH_ENABLED (bgp->rfapi_cfg)) - { - vnc_direct_bgp_rh_vpn_disable (bgp, afi); - vnc_direct_bgp_rh_vpn_enable (bgp, afi); - } + if (VNC_EXPORT_BGP_RH_ENABLED(bgp->rfapi_cfg)) { + vnc_direct_bgp_rh_vpn_disable(bgp, afi); + vnc_direct_bgp_rh_vpn_enable(bgp, afi); + } } /*********************************************************************** @@ -2079,67 +1988,60 @@ vnc_direct_bgp_rh_reexport (struct bgp *bgp, afi_t afi) * is OK to call this function from, e.g., bgp_redistribute_set() * without caring if export is enabled or not */ -void -vnc_export_bgp_enable (struct bgp *bgp, afi_t afi) +void vnc_export_bgp_enable(struct bgp *bgp, afi_t afi) { - switch (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) - { - case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE: - break; - - case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP: - vnc_direct_bgp_vpn_enable (bgp, afi); - break; - - case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH: - vnc_direct_bgp_rh_vpn_enable (bgp, afi); - break; - - case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE: - vnc_direct_bgp_vpn_enable_ce (bgp, afi); - break; - } + switch (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) { + case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE: + break; + + case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP: + vnc_direct_bgp_vpn_enable(bgp, afi); + break; + + case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH: + vnc_direct_bgp_rh_vpn_enable(bgp, afi); + break; + + case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE: + vnc_direct_bgp_vpn_enable_ce(bgp, afi); + break; + } } -void -vnc_export_bgp_disable (struct bgp *bgp, afi_t afi) +void vnc_export_bgp_disable(struct bgp *bgp, afi_t afi) { - switch (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) - { - case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE: - break; - - case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP: - vnc_direct_bgp_vpn_disable (bgp, afi); - break; - - case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH: - vnc_direct_bgp_rh_vpn_disable (bgp, afi); - break; - - case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE: - vnc_direct_bgp_vpn_disable_ce (bgp, afi); - break; - } + switch (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) { + case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE: + break; + + case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP: + vnc_direct_bgp_vpn_disable(bgp, afi); + break; + + case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH: + vnc_direct_bgp_rh_vpn_disable(bgp, afi); + break; + + case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE: + vnc_direct_bgp_vpn_disable_ce(bgp, afi); + break; + } } -void -vnc_export_bgp_prechange (struct bgp *bgp) +void vnc_export_bgp_prechange(struct bgp *bgp) { - vnc_export_bgp_disable (bgp, AFI_IP); - vnc_export_bgp_disable (bgp, AFI_IP6); + vnc_export_bgp_disable(bgp, AFI_IP); + vnc_export_bgp_disable(bgp, AFI_IP6); } -void -vnc_export_bgp_postchange (struct bgp *bgp) +void vnc_export_bgp_postchange(struct bgp *bgp) { - vnc_export_bgp_enable (bgp, AFI_IP); - vnc_export_bgp_enable (bgp, AFI_IP6); + vnc_export_bgp_enable(bgp, AFI_IP); + vnc_export_bgp_enable(bgp, AFI_IP6); } -void -vnc_direct_bgp_reexport (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_reexport(struct bgp *bgp, afi_t afi) { - vnc_export_bgp_disable (bgp, afi); - vnc_export_bgp_enable (bgp, afi); + vnc_export_bgp_disable(bgp, afi); + vnc_export_bgp_enable(bgp, afi); } diff --git a/bgpd/rfapi/vnc_export_bgp.h b/bgpd/rfapi/vnc_export_bgp.h index 7dbbb40e0a..a6f8c82c0d 100644 --- a/bgpd/rfapi/vnc_export_bgp.h +++ b/bgpd/rfapi/vnc_export_bgp.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -28,14 +28,14 @@ #include "bgpd/bgp_route.h" -extern void vnc_direct_bgp_rh_reexport (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_rh_reexport(struct bgp *bgp, afi_t afi); -extern void vnc_export_bgp_prechange (struct bgp *bgp); +extern void vnc_export_bgp_prechange(struct bgp *bgp); -extern void vnc_export_bgp_postchange (struct bgp *bgp); +extern void vnc_export_bgp_postchange(struct bgp *bgp); -extern void vnc_export_bgp_enable (struct bgp *bgp, afi_t afi); +extern void vnc_export_bgp_enable(struct bgp *bgp, afi_t afi); -extern void vnc_export_bgp_disable (struct bgp *bgp, afi_t afi); +extern void vnc_export_bgp_disable(struct bgp *bgp, afi_t afi); #endif /* _QUAGGA_RFAPI_VNC_EXPORT_BGP_H_ */ diff --git a/bgpd/rfapi/vnc_export_bgp_p.h b/bgpd/rfapi/vnc_export_bgp_p.h index 31830a3c13..c164a35432 100644 --- a/bgpd/rfapi/vnc_export_bgp_p.h +++ b/bgpd/rfapi/vnc_export_bgp_p.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -29,66 +29,46 @@ #include "rfapi_private.h" -extern void -vnc_direct_bgp_add_route_ce ( - struct bgp *bgp, - struct route_node *rn, - struct bgp_info *bi); - -extern void -vnc_direct_bgp_del_route_ce ( - struct bgp *bgp, - struct route_node *rn, - struct bgp_info *bi); - -extern void -vnc_direct_bgp_add_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn); - -extern void -vnc_direct_bgp_del_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn); - -extern void -vnc_direct_bgp_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd); - -extern void -vnc_direct_bgp_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd); - -extern void -vnc_direct_bgp_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); - -extern void -vnc_direct_bgp_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); - -extern void -vnc_direct_bgp_reexport_group_afi ( - struct bgp *bgp, - struct rfapi_nve_group_cfg *rfg, - afi_t afi); - - -extern void -vnc_direct_bgp_rh_add_route ( - struct bgp *bgp, - afi_t afi, - struct prefix *prefix, - struct peer *peer, - struct attr *attr); - - -extern void -vnc_direct_bgp_rh_del_route ( - struct bgp *bgp, - afi_t afi, - struct prefix *prefix, - struct peer *peer); - -extern void -vnc_direct_bgp_reexport (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn, + struct bgp_info *bi); + +extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, + struct bgp_info *bi); + +extern void vnc_direct_bgp_add_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn); + +extern void vnc_direct_bgp_del_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn); + +extern void vnc_direct_bgp_add_nve(struct bgp *bgp, + struct rfapi_descriptor *rfd); + +extern void vnc_direct_bgp_del_nve(struct bgp *bgp, + struct rfapi_descriptor *rfd); + +extern void vnc_direct_bgp_add_group(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg); + +extern void vnc_direct_bgp_del_group(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg); + +extern void vnc_direct_bgp_reexport_group_afi(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg, + afi_t afi); + + +extern void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi, + struct prefix *prefix, + struct peer *peer, struct attr *attr); + + +extern void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi, + struct prefix *prefix, + struct peer *peer); + +extern void vnc_direct_bgp_reexport(struct bgp *bgp, afi_t afi); #endif /* _QUAGGA_RFAPI_VNC_EXPORT_BGP_P_H_ */ diff --git a/bgpd/rfapi/vnc_export_table.c b/bgpd/rfapi/vnc_export_table.c index 5c7a64d3bb..bbdb59c125 100644 --- a/bgpd/rfapi/vnc_export_table.c +++ b/bgpd/rfapi/vnc_export_table.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -33,182 +33,160 @@ #include "bgpd/rfapi/rfapi_import.h" #include "bgpd/rfapi/vnc_debug.h" -struct route_node * -vnc_etn_get (struct bgp *bgp, vnc_export_type_t type, struct prefix *p) +struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, + struct prefix *p) { - struct route_table *t = NULL; - struct route_node *rn = NULL; - afi_t afi; - - if (!bgp || !bgp->rfapi) - return NULL; - - afi = family2afi (p->family); - assert (afi == AFI_IP || afi == AFI_IP6); - - switch (type) - { - case EXPORT_TYPE_BGP: - if (!bgp->rfapi->rt_export_bgp[afi]) - bgp->rfapi->rt_export_bgp[afi] = route_table_init (); - t = bgp->rfapi->rt_export_bgp[afi]; - break; - - case EXPORT_TYPE_ZEBRA: - if (!bgp->rfapi->rt_export_zebra[afi]) - bgp->rfapi->rt_export_zebra[afi] = route_table_init (); - t = bgp->rfapi->rt_export_zebra[afi]; - break; - } - - if (t) - rn = route_node_get (t, p); - return rn; + struct route_table *t = NULL; + struct route_node *rn = NULL; + afi_t afi; + + if (!bgp || !bgp->rfapi) + return NULL; + + afi = family2afi(p->family); + assert(afi == AFI_IP || afi == AFI_IP6); + + switch (type) { + case EXPORT_TYPE_BGP: + if (!bgp->rfapi->rt_export_bgp[afi]) + bgp->rfapi->rt_export_bgp[afi] = route_table_init(); + t = bgp->rfapi->rt_export_bgp[afi]; + break; + + case EXPORT_TYPE_ZEBRA: + if (!bgp->rfapi->rt_export_zebra[afi]) + bgp->rfapi->rt_export_zebra[afi] = route_table_init(); + t = bgp->rfapi->rt_export_zebra[afi]; + break; + } + + if (t) + rn = route_node_get(t, p); + return rn; } -struct route_node * -vnc_etn_lookup (struct bgp *bgp, vnc_export_type_t type, struct prefix *p) +struct route_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, + struct prefix *p) { - struct route_table *t = NULL; - struct route_node *rn = NULL; - afi_t afi; - - if (!bgp || !bgp->rfapi) - return NULL; - - afi = family2afi (p->family); - assert (afi == AFI_IP || afi == AFI_IP6); - - switch (type) - { - case EXPORT_TYPE_BGP: - if (!bgp->rfapi->rt_export_bgp[afi]) - bgp->rfapi->rt_export_bgp[afi] = route_table_init (); - t = bgp->rfapi->rt_export_bgp[afi]; - break; - - case EXPORT_TYPE_ZEBRA: - if (!bgp->rfapi->rt_export_zebra[afi]) - bgp->rfapi->rt_export_zebra[afi] = route_table_init (); - t = bgp->rfapi->rt_export_zebra[afi]; - break; - } - - if (t) - rn = route_node_lookup (t, p); - return rn; + struct route_table *t = NULL; + struct route_node *rn = NULL; + afi_t afi; + + if (!bgp || !bgp->rfapi) + return NULL; + + afi = family2afi(p->family); + assert(afi == AFI_IP || afi == AFI_IP6); + + switch (type) { + case EXPORT_TYPE_BGP: + if (!bgp->rfapi->rt_export_bgp[afi]) + bgp->rfapi->rt_export_bgp[afi] = route_table_init(); + t = bgp->rfapi->rt_export_bgp[afi]; + break; + + case EXPORT_TYPE_ZEBRA: + if (!bgp->rfapi->rt_export_zebra[afi]) + bgp->rfapi->rt_export_zebra[afi] = route_table_init(); + t = bgp->rfapi->rt_export_zebra[afi]; + break; + } + + if (t) + rn = route_node_lookup(t, p); + return rn; } -struct vnc_export_info * -vnc_eti_get ( - struct bgp *bgp, - vnc_export_type_t etype, - struct prefix *p, - struct peer *peer, - uint8_t type, - uint8_t subtype) +struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype, + struct prefix *p, struct peer *peer, + uint8_t type, uint8_t subtype) { - struct route_node *etn; - struct vnc_export_info *eti; - - etn = vnc_etn_get (bgp, etype, p); - assert (etn); - - for (eti = etn->info; eti; eti = eti->next) - { - if (peer == eti->peer && type == eti->type && subtype == eti->subtype) - { - - break; - } - } - - if (eti) - { - route_unlock_node (etn); - } - else - { - eti = XCALLOC (MTYPE_RFAPI_ETI, sizeof (struct vnc_export_info)); - assert (eti); - eti->node = etn; - eti->peer = peer; - peer_lock (peer); - eti->type = type; - eti->subtype = subtype; - eti->next = etn->info; - etn->info = eti; - } - - return eti; + struct route_node *etn; + struct vnc_export_info *eti; + + etn = vnc_etn_get(bgp, etype, p); + assert(etn); + + for (eti = etn->info; eti; eti = eti->next) { + if (peer == eti->peer && type == eti->type + && subtype == eti->subtype) { + + break; + } + } + + if (eti) { + route_unlock_node(etn); + } else { + eti = XCALLOC(MTYPE_RFAPI_ETI, sizeof(struct vnc_export_info)); + assert(eti); + eti->node = etn; + eti->peer = peer; + peer_lock(peer); + eti->type = type; + eti->subtype = subtype; + eti->next = etn->info; + etn->info = eti; + } + + return eti; } -void -vnc_eti_delete (struct vnc_export_info *goner) +void vnc_eti_delete(struct vnc_export_info *goner) { - struct route_node *etn; - struct vnc_export_info *eti; - struct vnc_export_info *eti_prev = NULL; - - etn = goner->node; - - for (eti = etn->info; eti; eti_prev = eti, eti = eti->next) - { - if (eti == goner) - break; - } - - if (!eti) - { - vnc_zlog_debug_verbose ("%s: COULDN'T FIND ETI", __func__); - return; - } - - if (eti_prev) - { - eti_prev->next = goner->next; - } - else - { - etn->info = goner->next; - } - - peer_unlock (eti->peer); - goner->node = NULL; - XFREE (MTYPE_RFAPI_ETI, goner); - - route_unlock_node (etn); + struct route_node *etn; + struct vnc_export_info *eti; + struct vnc_export_info *eti_prev = NULL; + + etn = goner->node; + + for (eti = etn->info; eti; eti_prev = eti, eti = eti->next) { + if (eti == goner) + break; + } + + if (!eti) { + vnc_zlog_debug_verbose("%s: COULDN'T FIND ETI", __func__); + return; + } + + if (eti_prev) { + eti_prev->next = goner->next; + } else { + etn->info = goner->next; + } + + peer_unlock(eti->peer); + goner->node = NULL; + XFREE(MTYPE_RFAPI_ETI, goner); + + route_unlock_node(etn); } -struct vnc_export_info * -vnc_eti_checktimer ( - struct bgp *bgp, - vnc_export_type_t etype, - struct prefix *p, - struct peer *peer, - uint8_t type, - uint8_t subtype) +struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp, + vnc_export_type_t etype, + struct prefix *p, struct peer *peer, + uint8_t type, uint8_t subtype) { - struct route_node *etn; - struct vnc_export_info *eti; + struct route_node *etn; + struct vnc_export_info *eti; - etn = vnc_etn_lookup (bgp, etype, p); - if (!etn) - return NULL; + etn = vnc_etn_lookup(bgp, etype, p); + if (!etn) + return NULL; - for (eti = etn->info; eti; eti = eti->next) - { - if (peer == eti->peer && type == eti->type && subtype == eti->subtype) - { + for (eti = etn->info; eti; eti = eti->next) { + if (peer == eti->peer && type == eti->type + && subtype == eti->subtype) { - break; - } - } + break; + } + } - route_unlock_node (etn); + route_unlock_node(etn); - if (eti && eti->timer) - return eti; + if (eti && eti->timer) + return eti; - return NULL; + return NULL; } diff --git a/bgpd/rfapi/vnc_export_table.h b/bgpd/rfapi/vnc_export_table.h index 234520670d..aa38233e8f 100644 --- a/bgpd/rfapi/vnc_export_table.h +++ b/bgpd/rfapi/vnc_export_table.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -30,55 +30,37 @@ #define VNC_EXPORT_TYPE_BGP 1 #define VNC_EXPORT_TYPE_ZEBRA 2 -typedef enum vnc_export_type -{ - EXPORT_TYPE_BGP, - EXPORT_TYPE_ZEBRA +typedef enum vnc_export_type { + EXPORT_TYPE_BGP, + EXPORT_TYPE_ZEBRA } vnc_export_type_t; -struct vnc_export_info -{ - struct vnc_export_info *next; - struct route_node *node; - struct peer *peer; - u_char type; - u_char subtype; - uint32_t lifetime; - struct thread *timer; +struct vnc_export_info { + struct vnc_export_info *next; + struct route_node *node; + struct peer *peer; + u_char type; + u_char subtype; + uint32_t lifetime; + struct thread *timer; }; -extern struct route_node * -vnc_etn_get ( - struct bgp *bgp, - vnc_export_type_t type, - struct prefix *p); +extern struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, + struct prefix *p); extern struct route_node * -vnc_etn_lookup ( - struct bgp *bgp, - vnc_export_type_t type, - struct prefix *p); +vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, struct prefix *p); -extern struct vnc_export_info * -vnc_eti_get ( - struct bgp *bgp, - vnc_export_type_t etype, - struct prefix *p, - struct peer *peer, - uint8_t type, - uint8_t subtype); +extern struct vnc_export_info *vnc_eti_get(struct bgp *bgp, + vnc_export_type_t etype, + struct prefix *p, struct peer *peer, + uint8_t type, uint8_t subtype); -extern void -vnc_eti_delete (struct vnc_export_info *goner); +extern void vnc_eti_delete(struct vnc_export_info *goner); extern struct vnc_export_info * -vnc_eti_checktimer ( - struct bgp *bgp, - vnc_export_type_t etype, - struct prefix *p, - struct peer *peer, - uint8_t type, - uint8_t subtype); +vnc_eti_checktimer(struct bgp *bgp, vnc_export_type_t etype, struct prefix *p, + struct peer *peer, uint8_t type, uint8_t subtype); #endif /* _QUAGGA_VNC_VNC_EXPORT_TABLE_H_ */ diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 1daf02a6bf..117d4fbfd4 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -37,7 +37,7 @@ #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_route.h" -#include "bgpd/bgp_mplsvpn.h" /* for RD_TYPE_IP */ +#include "bgpd/bgp_mplsvpn.h" /* for RD_TYPE_IP */ #include "bgpd/rfapi/vnc_export_bgp.h" #include "bgpd/rfapi/bgp_rfapi_cfg.h" @@ -69,237 +69,212 @@ static struct rfapi_descriptor vncHDResolveNve; /* dummy nve descriptor */ * * LOCAL_PREF unchanged */ -uint32_t -calc_local_pref (struct attr *attr, struct peer *peer) +uint32_t calc_local_pref(struct attr *attr, struct peer *peer) { - uint32_t local_pref = 0; - - if (!attr) - { - if (peer) - { - return peer->bgp->default_local_pref; - } - return bgp_get_default ()->default_local_pref; - } - - if (peer && (peer->as != peer->bgp->as)) - { - if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) - { - if (attr->med > 255) - { - local_pref = 0; - } - else - { - local_pref = 255 - attr->med; - } - } - else - { - local_pref = peer->bgp->default_local_pref; - } - } - else - { - if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) - { - local_pref = attr->local_pref; - } - else - { - if (peer && peer->bgp) - { - local_pref = peer->bgp->default_local_pref; - } - } - } - - return local_pref; + uint32_t local_pref = 0; + + if (!attr) { + if (peer) { + return peer->bgp->default_local_pref; + } + return bgp_get_default()->default_local_pref; + } + + if (peer && (peer->as != peer->bgp->as)) { + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) { + if (attr->med > 255) { + local_pref = 0; + } else { + local_pref = 255 - attr->med; + } + } else { + local_pref = peer->bgp->default_local_pref; + } + } else { + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { + local_pref = attr->local_pref; + } else { + if (peer && peer->bgp) { + local_pref = peer->bgp->default_local_pref; + } + } + } + + return local_pref; } -static int -is_host_prefix (struct prefix *p) +static int is_host_prefix(struct prefix *p) { - switch (p->family) - { - case AF_INET: - return (p->prefixlen == 32); - case AF_INET6: - return (p->prefixlen == 128); - } - return 0; + switch (p->family) { + case AF_INET: + return (p->prefixlen == 32); + case AF_INET6: + return (p->prefixlen == 128); + } + return 0; } /*********************************************************************** * RHN list ***********************************************************************/ -struct prefix_bag -{ - struct prefix hpfx; /* ce address = unicast nexthop */ - struct prefix upfx; /* unicast prefix */ - struct bgp_info *ubi; /* unicast route */ +struct prefix_bag { + struct prefix hpfx; /* ce address = unicast nexthop */ + struct prefix upfx; /* unicast prefix */ + struct bgp_info *ubi; /* unicast route */ }; -static const u_char maskbit[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, - 0xf8, 0xfc, 0xfe, 0xff -}; +static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff}; -int -vnc_prefix_cmp (void *pfx1, void *pfx2) +int vnc_prefix_cmp(void *pfx1, void *pfx2) { - int offset; - int shift; - u_char mask; - - struct prefix *p1 = pfx1; - struct prefix *p2 = pfx2; - - if (p1->family < p2->family) - return -1; - if (p1->family > p2->family) - return 1; - - if (p1->prefixlen < p2->prefixlen) - return -1; - if (p1->prefixlen > p2->prefixlen) - return 1; - - offset = p1->prefixlen / 8; - shift = p1->prefixlen % 8; - if (shift == 0 && offset) - { /* catch aligned case */ - offset--; - shift = 8; - } - - /* Set both prefix's head pointer. */ - const u_char *pp1 = (const u_char *) &p1->u.prefix; - const u_char *pp2 = (const u_char *) &p2->u.prefix; - - while (offset--) - { - if (*pp1 < *pp2) - return -1; - if (*pp1 > *pp2) - return 1; - ++pp1; - ++pp2; - } - - mask = maskbit[shift]; - if ((*pp1 & mask) < (*pp2 & mask)) - return -1; - if ((*pp1 & mask) > (*pp2 & mask)) - return 1; - - return 0; + int offset; + int shift; + u_char mask; + + struct prefix *p1 = pfx1; + struct prefix *p2 = pfx2; + + if (p1->family < p2->family) + return -1; + if (p1->family > p2->family) + return 1; + + if (p1->prefixlen < p2->prefixlen) + return -1; + if (p1->prefixlen > p2->prefixlen) + return 1; + + offset = p1->prefixlen / 8; + shift = p1->prefixlen % 8; + if (shift == 0 && offset) { /* catch aligned case */ + offset--; + shift = 8; + } + + /* Set both prefix's head pointer. */ + const u_char *pp1 = (const u_char *)&p1->u.prefix; + const u_char *pp2 = (const u_char *)&p2->u.prefix; + + while (offset--) { + if (*pp1 < *pp2) + return -1; + if (*pp1 > *pp2) + return 1; + ++pp1; + ++pp2; + } + + mask = maskbit[shift]; + if ((*pp1 & mask) < (*pp2 & mask)) + return -1; + if ((*pp1 & mask) > (*pp2 & mask)) + return 1; + + return 0; } -static void -prefix_bag_free (void *pb) +static void prefix_bag_free(void *pb) { - XFREE (MTYPE_RFAPI_PREFIX_BAG, pb); + XFREE(MTYPE_RFAPI_PREFIX_BAG, pb); } #if DEBUG_RHN_LIST -static void -print_rhn_list (const char *tag1, const char *tag2) +static void print_rhn_list(const char *tag1, const char *tag2) { - struct bgp *bgp; - struct skiplist *sl; - struct skiplistnode *p; - struct prefix_bag *pb; - int count = 0; - - bgp = bgp_get_default (); - if (!bgp) - return; - - sl = bgp->frapi->resolve_nve_nexthop; - if (!sl) - { - vnc_zlog_debug_verbose ("%s: %s: RHN List is empty", (tag1 ? tag1 : ""), - (tag2 ? tag2 : "")); - return; - } - - vnc_zlog_debug_verbose ("%s: %s: RHN list:", (tag1 ? tag1 : ""), (tag2 ? tag2 : "")); - - /* XXX uses secret knowledge of skiplist structure */ - for (p = sl->header->forward[0]; p; p = p->forward[0]) - { - char kbuf[BUFSIZ]; - char hbuf[BUFSIZ]; - char ubuf[BUFSIZ]; - - pb = p->value; - - prefix2str (p->key, kbuf, BUFSIZ); - prefix2str (&pb->hpfx, hbuf, BUFSIZ); - prefix2str (&pb->upfx, ubuf, BUFSIZ); - - vnc_zlog_debug_verbose ("RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p", - ++count, p, kbuf, ubuf, hbuf, pb->ubi); - } + struct bgp *bgp; + struct skiplist *sl; + struct skiplistnode *p; + struct prefix_bag *pb; + int count = 0; + + bgp = bgp_get_default(); + if (!bgp) + return; + + sl = bgp->frapi->resolve_nve_nexthop; + if (!sl) { + vnc_zlog_debug_verbose("%s: %s: RHN List is empty", + (tag1 ? tag1 : ""), (tag2 ? tag2 : "")); + return; + } + + vnc_zlog_debug_verbose("%s: %s: RHN list:", (tag1 ? tag1 : ""), + (tag2 ? tag2 : "")); + + /* XXX uses secret knowledge of skiplist structure */ + for (p = sl->header->forward[0]; p; p = p->forward[0]) { + char kbuf[BUFSIZ]; + char hbuf[BUFSIZ]; + char ubuf[BUFSIZ]; + + pb = p->value; + + prefix2str(p->key, kbuf, BUFSIZ); + prefix2str(&pb->hpfx, hbuf, BUFSIZ); + prefix2str(&pb->upfx, ubuf, BUFSIZ); + + vnc_zlog_debug_verbose( + "RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p", + ++count, p, kbuf, ubuf, hbuf, pb->ubi); + } } #endif #ifdef ENABLE_VNC_RHNCK -static void -vnc_rhnck (char *tag) +static void vnc_rhnck(char *tag) { - struct bgp *bgp; - struct skiplist *sl; - struct skiplistnode *p; - - bgp = bgp_get_default (); - if (!bgp) - return; - sl = bgp->rfapi->resolve_nve_nexthop; - - if (!sl) - return; - - /* XXX uses secret knowledge of skiplist structure */ - for (p = sl->header->forward[0]; p; p = p->forward[0]) - { - struct prefix_bag *pb; - struct prefix *pkey; - afi_t afi; - struct prefix pfx_orig_nexthop; - - memset (&pfx_orig_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */ - - pkey = p->key; - pb = p->value; - - afi = family2afi (pb->upfx.family); - - rfapiUnicastNexthop2Prefix (afi, pb->ubi->attr, &pfx_orig_nexthop); - - /* pb->hpfx, pb->ubi nexthop, pkey should all reflect the same pfx */ - assert (!vnc_prefix_cmp (&pb->hpfx, pkey)); - if (vnc_prefix_cmp (&pb->hpfx, &pfx_orig_nexthop)) - { - char str_onh[BUFSIZ]; - char str_nve_pfx[BUFSIZ]; - - prefix2str (&pfx_orig_nexthop, str_onh, BUFSIZ); - str_onh[BUFSIZ - 1] = 0; - - prefix2str (&pb->hpfx, str_nve_pfx, BUFSIZ); - str_nve_pfx[BUFSIZ - 1] = 0; - - vnc_zlog_debug_verbose - ("%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", - __func__, tag, str_onh, str_nve_pfx); - assert (0); - } - } - vnc_zlog_debug_verbose ("%s: vnc_rhnck OK", tag); + struct bgp *bgp; + struct skiplist *sl; + struct skiplistnode *p; + + bgp = bgp_get_default(); + if (!bgp) + return; + sl = bgp->rfapi->resolve_nve_nexthop; + + if (!sl) + return; + + /* XXX uses secret knowledge of skiplist structure */ + for (p = sl->header->forward[0]; p; p = p->forward[0]) { + struct prefix_bag *pb; + struct prefix *pkey; + afi_t afi; + struct prefix pfx_orig_nexthop; + + memset(&pfx_orig_nexthop, 0, + sizeof(struct prefix)); /* keep valgrind happy */ + + pkey = p->key; + pb = p->value; + + afi = family2afi(pb->upfx.family); + + rfapiUnicastNexthop2Prefix(afi, pb->ubi->attr, + &pfx_orig_nexthop); + + /* pb->hpfx, pb->ubi nexthop, pkey should all reflect the same + * pfx */ + assert(!vnc_prefix_cmp(&pb->hpfx, pkey)); + if (vnc_prefix_cmp(&pb->hpfx, &pfx_orig_nexthop)) { + char str_onh[BUFSIZ]; + char str_nve_pfx[BUFSIZ]; + + prefix2str(&pfx_orig_nexthop, str_onh, BUFSIZ); + str_onh[BUFSIZ - 1] = 0; + + prefix2str(&pb->hpfx, str_nve_pfx, BUFSIZ); + str_nve_pfx[BUFSIZ - 1] = 0; + + vnc_zlog_debug_verbose( + "%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", + __func__, tag, str_onh, str_nve_pfx); + assert(0); + } + } + vnc_zlog_debug_verbose("%s: vnc_rhnck OK", tag); } #define VNC_RHNCK(n) do {char buf[BUFSIZ];sprintf(buf,"%s: %s", __func__, #n);vnc_rhnck(buf);} while (0) @@ -324,1181 +299,1106 @@ vnc_rhnck (char *tag) * * If return code is 0, caller MUST release ecom */ -static int -process_unicast_route ( - struct bgp *bgp, /* in */ - afi_t afi, /* in */ - struct prefix *prefix, /* in */ - struct bgp_info *info, /* in */ - struct ecommunity **ecom, /* OUT */ - struct prefix *unicast_nexthop) /* OUT */ +static int process_unicast_route(struct bgp *bgp, /* in */ + afi_t afi, /* in */ + struct prefix *prefix, /* in */ + struct bgp_info *info, /* in */ + struct ecommunity **ecom, /* OUT */ + struct prefix *unicast_nexthop) /* OUT */ { - struct rfapi_cfg *hc = bgp->rfapi_cfg; - struct peer *peer = info->peer; - struct attr *attr = info->attr; - struct attr hattr; - struct route_map *rmap = NULL; - struct prefix pfx_orig_nexthop; - - memset (&pfx_orig_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */ - - /* - * prefix list check - */ - if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) - { - vnc_zlog_debug_verbose ("%s: HC prefix list is set, checking", __func__); - if (prefix_list_apply - (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi], - prefix) == PREFIX_DENY) - { - vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route", - __func__); - return -1; - } - vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__); - } - - /* apply routemap, if any, later */ - rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; - - /* - * Extract original nexthop, which we expect to be a NVE connected router - * Note that this is the nexthop before any possible application of policy - */ - /* - * Incoming prefix is unicast. If v6, it is in multiprotocol area, - * but if v4 it is in attr->nexthop - */ - rfapiUnicastNexthop2Prefix (afi, attr, &pfx_orig_nexthop); - - /* - * route map handling - * This code is here because it allocates an interned attr which - * must be freed before we return. It's easier to put it after - * all of the possible returns above. - */ - memset (&hattr, 0, sizeof (struct attr)); - bgp_attr_dup (&hattr, attr); /* hattr becomes a ghost attr */ - - if (rmap) - { - struct bgp_info info; - route_map_result_t ret; - - memset (&info, 0, sizeof (info)); - info.peer = peer; - info.attr = &hattr; - ret = route_map_apply (rmap, prefix, RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__, - rmap->name); - return -1; - } - } - - /* - * Get the (possibly altered by policy) unicast nexthop - * for later lookup in the Import Table by caller - */ - rfapiUnicastNexthop2Prefix (afi, &hattr, unicast_nexthop); - - if (hattr.ecommunity) - *ecom = ecommunity_dup (hattr.ecommunity); - else - *ecom = ecommunity_new (); - - /* - * Done with hattr, clean up - */ - bgp_attr_flush (&hattr); - - /* - * Add EC that carries original NH of iBGP route (2 bytes = magic - * value indicating it came from an VNC gateway; default 5226, but - * must be user configurable). Note that this is the nexthop before - * any application of policy. - */ - { - struct ecommunity_val vnc_gateway_magic; - uint16_t localadmin; - - /* Using route origin extended community type */ - memset (&vnc_gateway_magic, 0, sizeof (vnc_gateway_magic)); - vnc_gateway_magic.val[0] = 0x01; - vnc_gateway_magic.val[1] = 0x03; - - /* Only works for IPv4 nexthops */ - if (prefix->family == AF_INET) - { - memcpy (vnc_gateway_magic.val + 2, &unicast_nexthop->u.prefix4, 4); - } - localadmin = htons (hc->resolve_nve_roo_local_admin); - memcpy (vnc_gateway_magic.val + 6, (char *) &localadmin, 2); - - ecommunity_add_val (*ecom, &vnc_gateway_magic); - } - - return 0; + struct rfapi_cfg *hc = bgp->rfapi_cfg; + struct peer *peer = info->peer; + struct attr *attr = info->attr; + struct attr hattr; + struct route_map *rmap = NULL; + struct prefix pfx_orig_nexthop; + + memset(&pfx_orig_nexthop, 0, + sizeof(struct prefix)); /* keep valgrind happy */ + + /* + * prefix list check + */ + if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) { + vnc_zlog_debug_verbose("%s: HC prefix list is set, checking", + __func__); + if (prefix_list_apply( + hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi], + prefix) + == PREFIX_DENY) { + vnc_zlog_debug_verbose( + "%s: prefix list returns DENY, blocking route", + __func__); + return -1; + } + vnc_zlog_debug_verbose( + "%s: prefix list returns PASS, allowing route", + __func__); + } + + /* apply routemap, if any, later */ + rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; + + /* + * Extract original nexthop, which we expect to be a NVE connected + * router + * Note that this is the nexthop before any possible application of + * policy + */ + /* + * Incoming prefix is unicast. If v6, it is in multiprotocol area, + * but if v4 it is in attr->nexthop + */ + rfapiUnicastNexthop2Prefix(afi, attr, &pfx_orig_nexthop); + + /* + * route map handling + * This code is here because it allocates an interned attr which + * must be freed before we return. It's easier to put it after + * all of the possible returns above. + */ + memset(&hattr, 0, sizeof(struct attr)); + bgp_attr_dup(&hattr, attr); /* hattr becomes a ghost attr */ + + if (rmap) { + struct bgp_info info; + route_map_result_t ret; + + memset(&info, 0, sizeof(info)); + info.peer = peer; + info.attr = &hattr; + ret = route_map_apply(rmap, prefix, RMAP_BGP, &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + vnc_zlog_debug_verbose( + "%s: route map \"%s\" says DENY, returning", + __func__, rmap->name); + return -1; + } + } + + /* + * Get the (possibly altered by policy) unicast nexthop + * for later lookup in the Import Table by caller + */ + rfapiUnicastNexthop2Prefix(afi, &hattr, unicast_nexthop); + + if (hattr.ecommunity) + *ecom = ecommunity_dup(hattr.ecommunity); + else + *ecom = ecommunity_new(); + + /* + * Done with hattr, clean up + */ + bgp_attr_flush(&hattr); + + /* + * Add EC that carries original NH of iBGP route (2 bytes = magic + * value indicating it came from an VNC gateway; default 5226, but + * must be user configurable). Note that this is the nexthop before + * any application of policy. + */ + { + struct ecommunity_val vnc_gateway_magic; + uint16_t localadmin; + + /* Using route origin extended community type */ + memset(&vnc_gateway_magic, 0, sizeof(vnc_gateway_magic)); + vnc_gateway_magic.val[0] = 0x01; + vnc_gateway_magic.val[1] = 0x03; + + /* Only works for IPv4 nexthops */ + if (prefix->family == AF_INET) { + memcpy(vnc_gateway_magic.val + 2, + &unicast_nexthop->u.prefix4, 4); + } + localadmin = htons(hc->resolve_nve_roo_local_admin); + memcpy(vnc_gateway_magic.val + 6, (char *)&localadmin, 2); + + ecommunity_add_val(*ecom, &vnc_gateway_magic); + } + + return 0; } -static void -vnc_import_bgp_add_route_mode_resolve_nve_one_bi ( - struct bgp *bgp, - afi_t afi, - struct bgp_info *bi, /* VPN bi */ - struct prefix_rd *prd, /* RD */ - struct prefix *prefix, /* unicast route prefix */ - uint32_t *local_pref,/* NULL = no local_pref */ - uint32_t *med, /* NULL = no med */ - struct ecommunity *ecom) /* generated ecoms */ +static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( + struct bgp *bgp, afi_t afi, struct bgp_info *bi, /* VPN bi */ + struct prefix_rd *prd, /* RD */ + struct prefix *prefix, /* unicast route prefix */ + uint32_t *local_pref, /* NULL = no local_pref */ + uint32_t *med, /* NULL = no med */ + struct ecommunity *ecom) /* generated ecoms */ { - struct prefix un; - struct prefix nexthop; - struct rfapi_ip_addr nexthop_h; - uint32_t lifetime; - uint32_t *plifetime; - struct bgp_attr_encap_subtlv *encaptlvs; - uint32_t label = 0; - - struct rfapi_un_option optary[3]; - struct rfapi_un_option *opt = NULL; - int cur_opt = 0; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - - if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT) - { - - return; - } - if (bi->sub_type != BGP_ROUTE_NORMAL && - bi->sub_type != BGP_ROUTE_STATIC && bi->sub_type != BGP_ROUTE_RFP) - { - - return; - } - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - return; - - vncHDResolveNve.peer = bi->peer; - if (!rfapiGetVncTunnelUnAddr (bi->attr, &un)) - { - if (rfapiQprefix2Raddr (&un, &vncHDResolveNve.un_addr)) - return; - } - else - { - memset (&vncHDResolveNve.un_addr, 0, sizeof (vncHDResolveNve.un_addr)); - } - - /* Use nexthop of VPN route as nexthop of constructed route */ - rfapiNexthop2Prefix (bi->attr, &nexthop); - rfapiQprefix2Raddr (&nexthop, &nexthop_h); - - if (rfapiGetVncLifetime (bi->attr, &lifetime)) - { - plifetime = NULL; - } - else - { - plifetime = &lifetime; - } - - if (bi->attr) - { - encaptlvs = bi->attr->vnc_subtlvs; - if (bi->attr->encap_tunneltype != BGP_ENCAP_TYPE_RESERVED && - bi->attr->encap_tunneltype != BGP_ENCAP_TYPE_MPLS) - { - if (opt != NULL) - opt->next = &optary[cur_opt]; - opt = &optary[cur_opt++]; - memset (opt, 0, sizeof (struct rfapi_un_option)); - opt->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; - opt->v.tunnel.type = bi->attr->encap_tunneltype; - /* TBD parse bi->attr->extra->encap_subtlvs */ - } - } - else - { - encaptlvs = NULL; - } - - struct ecommunity *new_ecom = ecommunity_dup (ecom); - - if (bi->attr && bi->attr->ecommunity) - ecommunity_merge (new_ecom, bi->attr->ecommunity); - - if (bi->extra) - label = decode_label (&bi->extra->label); - - add_vnc_route ( - &vncHDResolveNve, - bgp, - SAFI_MPLS_VPN, - prefix, /* unicast route prefix */ - prd, - &nexthop_h, /* new nexthop */ - local_pref, - plifetime, - (struct bgp_tea_options *) encaptlvs, /* RFP options */ - opt, - NULL, - new_ecom, - med, /* NULL => don't set med */ - (label?&label:NULL), /* NULL= default */ - ZEBRA_ROUTE_BGP_DIRECT, - BGP_ROUTE_REDISTRIBUTE, - RFAPI_AHR_RFPOPT_IS_VNCTLV); /* flags */ - - ecommunity_free (&new_ecom); + struct prefix un; + struct prefix nexthop; + struct rfapi_ip_addr nexthop_h; + uint32_t lifetime; + uint32_t *plifetime; + struct bgp_attr_encap_subtlv *encaptlvs; + uint32_t label = 0; + + struct rfapi_un_option optary[3]; + struct rfapi_un_option *opt = NULL; + int cur_opt = 0; + vnc_zlog_debug_verbose("%s: entry", __func__); + + if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT) { + + return; + } + if (bi->sub_type != BGP_ROUTE_NORMAL && bi->sub_type != BGP_ROUTE_STATIC + && bi->sub_type != BGP_ROUTE_RFP) { + + return; + } + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + return; + + vncHDResolveNve.peer = bi->peer; + if (!rfapiGetVncTunnelUnAddr(bi->attr, &un)) { + if (rfapiQprefix2Raddr(&un, &vncHDResolveNve.un_addr)) + return; + } else { + memset(&vncHDResolveNve.un_addr, 0, + sizeof(vncHDResolveNve.un_addr)); + } + + /* Use nexthop of VPN route as nexthop of constructed route */ + rfapiNexthop2Prefix(bi->attr, &nexthop); + rfapiQprefix2Raddr(&nexthop, &nexthop_h); + + if (rfapiGetVncLifetime(bi->attr, &lifetime)) { + plifetime = NULL; + } else { + plifetime = &lifetime; + } + + if (bi->attr) { + encaptlvs = bi->attr->vnc_subtlvs; + if (bi->attr->encap_tunneltype != BGP_ENCAP_TYPE_RESERVED + && bi->attr->encap_tunneltype != BGP_ENCAP_TYPE_MPLS) { + if (opt != NULL) + opt->next = &optary[cur_opt]; + opt = &optary[cur_opt++]; + memset(opt, 0, sizeof(struct rfapi_un_option)); + opt->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; + opt->v.tunnel.type = bi->attr->encap_tunneltype; + /* TBD parse bi->attr->extra->encap_subtlvs */ + } + } else { + encaptlvs = NULL; + } + + struct ecommunity *new_ecom = ecommunity_dup(ecom); + + if (bi->attr && bi->attr->ecommunity) + ecommunity_merge(new_ecom, bi->attr->ecommunity); + + if (bi->extra) + label = decode_label(&bi->extra->label); + + add_vnc_route(&vncHDResolveNve, bgp, SAFI_MPLS_VPN, + prefix, /* unicast route prefix */ + prd, &nexthop_h, /* new nexthop */ + local_pref, plifetime, + (struct bgp_tea_options *)encaptlvs, /* RFP options */ + opt, NULL, new_ecom, med, /* NULL => don't set med */ + (label ? &label : NULL), /* NULL= default */ + ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, + RFAPI_AHR_RFPOPT_IS_VNCTLV); /* flags */ + + ecommunity_free(&new_ecom); } -static void -vnc_import_bgp_add_route_mode_resolve_nve_one_rd ( - struct prefix_rd *prd, /* RD */ - struct bgp_table *table_rd, /* per-rd VPN route table */ - afi_t afi, - struct bgp *bgp, - struct prefix *prefix, /* unicast prefix */ - struct ecommunity *ecom, /* generated ecoms */ - uint32_t *local_pref, /* NULL = no local_pref */ - uint32_t *med, /* NULL = no med */ - struct prefix *ubi_nexthop) /* unicast nexthop */ +static void vnc_import_bgp_add_route_mode_resolve_nve_one_rd( + struct prefix_rd *prd, /* RD */ + struct bgp_table *table_rd, /* per-rd VPN route table */ + afi_t afi, struct bgp *bgp, struct prefix *prefix, /* unicast prefix */ + struct ecommunity *ecom, /* generated ecoms */ + uint32_t *local_pref, /* NULL = no local_pref */ + uint32_t *med, /* NULL = no med */ + struct prefix *ubi_nexthop) /* unicast nexthop */ { - struct bgp_node *bn; - struct bgp_info *bi; + struct bgp_node *bn; + struct bgp_info *bi; - if (!table_rd) - return; + if (!table_rd) + return; - { - char str_nh[BUFSIZ]; + { + char str_nh[BUFSIZ]; - prefix2str (ubi_nexthop, str_nh, BUFSIZ); - str_nh[BUFSIZ - 1] = 0; + prefix2str(ubi_nexthop, str_nh, BUFSIZ); + str_nh[BUFSIZ - 1] = 0; - vnc_zlog_debug_verbose ("%s: ubi_nexthop=%s", __func__, str_nh); - } + vnc_zlog_debug_verbose("%s: ubi_nexthop=%s", __func__, str_nh); + } - /* exact match */ - bn = bgp_node_lookup (table_rd, ubi_nexthop); - if (!bn) - { - vnc_zlog_debug_verbose ("%s: no match in RD's table for ubi_nexthop", __func__); - return; - } + /* exact match */ + bn = bgp_node_lookup(table_rd, ubi_nexthop); + if (!bn) { + vnc_zlog_debug_verbose( + "%s: no match in RD's table for ubi_nexthop", __func__); + return; + } - /* Iterate over bgp_info items at this node */ - for (bi = bn->info; bi; bi = bi->next) - { + /* Iterate over bgp_info items at this node */ + for (bi = bn->info; bi; bi = bi->next) { - vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp, afi, bi, /* VPN bi */ - prd, - prefix, - local_pref, - med, ecom); - } + vnc_import_bgp_add_route_mode_resolve_nve_one_bi( + bgp, afi, bi, /* VPN bi */ + prd, prefix, local_pref, med, ecom); + } - bgp_unlock_node (bn); + bgp_unlock_node(bn); } -static void -vnc_import_bgp_add_route_mode_resolve_nve ( - struct bgp *bgp, - struct prefix *prefix,/* unicast prefix */ - struct bgp_info *info) /* unicast info */ +static void vnc_import_bgp_add_route_mode_resolve_nve( + struct bgp *bgp, struct prefix *prefix, /* unicast prefix */ + struct bgp_info *info) /* unicast info */ { - afi_t afi = family2afi (prefix->family); - struct rfapi_cfg *hc = NULL; - - struct prefix pfx_unicast_nexthop = { 0 }; /* happy valgrind */ - - struct ecommunity *ecom = NULL; - uint32_t local_pref; - uint32_t *med = NULL; - - struct prefix_bag *pb; - struct bgp_node *bnp; /* prd table node */ - - /*debugging */ - { - char str_pfx[BUFSIZ]; - char str_nh[BUFSIZ]; - struct prefix nh; - - prefix2str (prefix, str_pfx, BUFSIZ); - str_pfx[BUFSIZ - 1] = 0; - - nh.prefixlen = 0; - rfapiUnicastNexthop2Prefix (afi, info->attr, &nh); - if (nh.prefixlen) - { - prefix2str (&nh, str_nh, BUFSIZ); - str_nh[BUFSIZ - 1] = 0; - } - else - { - str_nh[0] = '?'; - str_nh[1] = 0; - } - - vnc_zlog_debug_verbose ("%s(bgp=%p, unicast prefix=%s, unicast nh=%s)", - __func__, bgp, str_pfx, str_nh); - } - - if (info->type != ZEBRA_ROUTE_BGP) - { - vnc_zlog_debug_verbose ("%s: unicast type %d=\"%s\" is not %d=%s, skipping", - __func__, info->type, zebra_route_string (info->type), - ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP"); - return; - } - - /* - * Preliminary checks - */ - - if (!afi) - { - zlog_err ("%s: can't get afi of prefix", __func__); - return; - } - - if (!(hc = bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - /* check vnc redist flag for bgp direct routes */ - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose - ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", - __func__, afi); - return; - } - - - if (process_unicast_route (bgp, afi, prefix, info, - &ecom, &pfx_unicast_nexthop)) - { - - vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__); - return; - } - - local_pref = calc_local_pref (info->attr, info->peer); - if (info->attr && - (info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))) - { - - med = &info->attr->med; - } - - - /* - * At this point, we have allocated: - * - * ecom ecommunity ptr, union of unicast and ROO parts (no NVE part) - * - * And we have set: - * - * pfx_unicast_nexthop nexthop of uncast route - */ - - if (!bgp->rfapi->resolve_nve_nexthop) - { - bgp->rfapi->resolve_nve_nexthop = - skiplist_new (SKIPLIST_FLAG_ALLOW_DUPLICATES, vnc_prefix_cmp, - prefix_bag_free); - } - - pb = XCALLOC (MTYPE_RFAPI_PREFIX_BAG, sizeof (struct prefix_bag)); - pb->hpfx = pfx_unicast_nexthop; - pb->ubi = info; - pb->upfx = *prefix; - - bgp_info_lock (info); /* skiplist refers to it */ - skiplist_insert (bgp->rfapi->resolve_nve_nexthop, &pb->hpfx, pb); - - /* - * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop - * (exact match, /32). If an exact match is found, call add_vnc_route. - */ - - for (bnp = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); bnp; - bnp = bgp_route_next (bnp)) - { - - struct bgp_table *table; - - table = (struct bgp_table *) (bnp->info); - - if (!table) - continue; - - vnc_import_bgp_add_route_mode_resolve_nve_one_rd ((struct prefix_rd *) - &bnp->p, table, afi, - bgp, prefix, ecom, - &local_pref, med, - &pfx_unicast_nexthop); - - } - - - if (ecom) - ecommunity_free (&ecom); - - vnc_zlog_debug_verbose ("%s: done", __func__); + afi_t afi = family2afi(prefix->family); + struct rfapi_cfg *hc = NULL; + + struct prefix pfx_unicast_nexthop = {0}; /* happy valgrind */ + + struct ecommunity *ecom = NULL; + uint32_t local_pref; + uint32_t *med = NULL; + + struct prefix_bag *pb; + struct bgp_node *bnp; /* prd table node */ + + /*debugging */ + { + char str_pfx[BUFSIZ]; + char str_nh[BUFSIZ]; + struct prefix nh; + + prefix2str(prefix, str_pfx, BUFSIZ); + str_pfx[BUFSIZ - 1] = 0; + + nh.prefixlen = 0; + rfapiUnicastNexthop2Prefix(afi, info->attr, &nh); + if (nh.prefixlen) { + prefix2str(&nh, str_nh, BUFSIZ); + str_nh[BUFSIZ - 1] = 0; + } else { + str_nh[0] = '?'; + str_nh[1] = 0; + } + + vnc_zlog_debug_verbose( + "%s(bgp=%p, unicast prefix=%s, unicast nh=%s)", + __func__, bgp, str_pfx, str_nh); + } + + if (info->type != ZEBRA_ROUTE_BGP) { + vnc_zlog_debug_verbose( + "%s: unicast type %d=\"%s\" is not %d=%s, skipping", + __func__, info->type, zebra_route_string(info->type), + ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP"); + return; + } + + /* + * Preliminary checks + */ + + if (!afi) { + zlog_err("%s: can't get afi of prefix", __func__); + return; + } + + if (!(hc = bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + /* check vnc redist flag for bgp direct routes */ + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", + __func__, afi); + return; + } + + + if (process_unicast_route(bgp, afi, prefix, info, &ecom, + &pfx_unicast_nexthop)) { + + vnc_zlog_debug_verbose( + "%s: process_unicast_route error, skipping", __func__); + return; + } + + local_pref = calc_local_pref(info->attr, info->peer); + if (info->attr + && (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { + + med = &info->attr->med; + } + + + /* + * At this point, we have allocated: + * + * ecom ecommunity ptr, union of unicast and ROO parts (no NVE part) + * + * And we have set: + * + * pfx_unicast_nexthop nexthop of uncast route + */ + + if (!bgp->rfapi->resolve_nve_nexthop) { + bgp->rfapi->resolve_nve_nexthop = + skiplist_new(SKIPLIST_FLAG_ALLOW_DUPLICATES, + vnc_prefix_cmp, prefix_bag_free); + } + + pb = XCALLOC(MTYPE_RFAPI_PREFIX_BAG, sizeof(struct prefix_bag)); + pb->hpfx = pfx_unicast_nexthop; + pb->ubi = info; + pb->upfx = *prefix; + + bgp_info_lock(info); /* skiplist refers to it */ + skiplist_insert(bgp->rfapi->resolve_nve_nexthop, &pb->hpfx, pb); + + /* + * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop + * (exact match, /32). If an exact match is found, call add_vnc_route. + */ + + for (bnp = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); bnp; + bnp = bgp_route_next(bnp)) { + + struct bgp_table *table; + + table = (struct bgp_table *)(bnp->info); + + if (!table) + continue; + + vnc_import_bgp_add_route_mode_resolve_nve_one_rd( + (struct prefix_rd *)&bnp->p, table, afi, bgp, prefix, + ecom, &local_pref, med, &pfx_unicast_nexthop); + } + + + if (ecom) + ecommunity_free(&ecom); + + vnc_zlog_debug_verbose("%s: done", __func__); } -static void -vnc_import_bgp_add_route_mode_plain (struct bgp *bgp, - struct prefix *prefix, - struct bgp_info *info) +static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, + struct prefix *prefix, + struct bgp_info *info) { - afi_t afi = family2afi (prefix->family); - struct peer *peer = info->peer; - struct attr *attr = info->attr; - struct attr hattr; - struct rfapi_cfg *hc = NULL; - struct attr *iattr = NULL; - - struct rfapi_ip_addr vnaddr; - struct prefix vn_pfx_space; - struct prefix *vn_pfx = NULL; - int ahr_flags = 0; - struct ecommunity *ecom = NULL; - struct prefix_rd prd; - struct route_map *rmap = NULL; - uint32_t local_pref; - uint32_t *med = NULL; - - { - char buf[BUFSIZ]; - - buf[0] = 0; - prefix2str (prefix, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_verbose ("%s(prefix=%s) entry", __func__, buf); - } - - if (!afi) - { - zlog_err ("%s: can't get afi of prefix", __func__); - return; - } - - if (!(hc = bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - /* check vnc redist flag for bgp direct routes */ - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose - ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", - __func__, afi); - return; - } - - /* - * mode "plain" specific code - */ - { - vnc_zlog_debug_verbose ("%s: NOT using redist RFG", __func__); - - /* - * prefix list check - */ - if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) - { - vnc_zlog_debug_verbose ("%s: HC prefix list is set, checking", __func__); - if (prefix_list_apply - (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi], - prefix) == PREFIX_DENY) - { - vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route", - __func__); - return; - } - vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__); - } - - /* apply routemap, if any, later */ - rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; - - /* - * Incoming prefix is unicast. If v6, it is in multiprotocol area, - * but if v4 it is in attr->nexthop - */ - rfapiUnicastNexthop2Prefix (afi, attr, &vn_pfx_space); - vn_pfx = &vn_pfx_space; - - /* UN address */ - ahr_flags |= RFAPI_AHR_NO_TUNNEL_SUBTLV; - } - - if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) - { - char buf[BUFSIZ]; - - buf[0] = 0; - prefix2str (vn_pfx, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_any ("%s vn_pfx=%s", __func__, buf); - } - - /* - * Compute VN address - */ - if (rfapiQprefix2Raddr (vn_pfx, &vnaddr)) - { - vnc_zlog_debug_verbose ("%s: redist VN invalid, skipping", __func__); - return; - } - - /* - * route map handling - * This code is here because it allocates an interned attr which - * must be freed before we return. It's easier to put it after - * all of the possible returns above. - */ - memset (&hattr, 0, sizeof (struct attr)); - bgp_attr_dup (&hattr, attr); /* hattr becomes a ghost attr */ - - if (rmap) - { - struct bgp_info info; - route_map_result_t ret; - - memset (&info, 0, sizeof (info)); - info.peer = peer; - info.attr = &hattr; - ret = route_map_apply (rmap, prefix, RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__, - rmap->name); - return; - } - } - - iattr = bgp_attr_intern (&hattr); - bgp_attr_flush (&hattr); - - /* Now iattr is an allocated interned attr */ - - /* - * Mode "plain" specific code - * - * Sets RD in dummy HD - * Allocates ecom - */ - { - if (vnaddr.addr_family != AF_INET) - { - vnc_zlog_debug_verbose - ("%s: can't auto-assign RD, VN AF (%d) is not IPv4, skipping", - __func__, vnaddr.addr_family); - if (iattr) - { - bgp_attr_unintern (&iattr); - } - return; - } - memset (&prd, 0, sizeof (prd)); - rfapi_set_autord_from_vn (&prd, &vnaddr); - - if (iattr && iattr->ecommunity) - ecom = ecommunity_dup (iattr->ecommunity); - - } - - local_pref = calc_local_pref (iattr, peer); - - if (iattr && (iattr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))) - { - med = &iattr->med; - } - - if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) - { - char buf[BUFSIZ]; - - buf[0] = 0; - rfapiRfapiIpAddr2Str (&vnaddr, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_any ("%s: setting vnaddr to %s", __func__, buf); - } - - vncHDBgpDirect.peer = peer; - add_vnc_route (&vncHDBgpDirect, bgp, SAFI_MPLS_VPN, prefix, &prd, &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), NULL, /* RFP options */ - NULL, NULL, ecom, med, /* med */ - NULL, /* label: default */ - ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, ahr_flags); - vncHDBgpDirect.peer = NULL; - - if (ecom) - ecommunity_free (&ecom); + afi_t afi = family2afi(prefix->family); + struct peer *peer = info->peer; + struct attr *attr = info->attr; + struct attr hattr; + struct rfapi_cfg *hc = NULL; + struct attr *iattr = NULL; + + struct rfapi_ip_addr vnaddr; + struct prefix vn_pfx_space; + struct prefix *vn_pfx = NULL; + int ahr_flags = 0; + struct ecommunity *ecom = NULL; + struct prefix_rd prd; + struct route_map *rmap = NULL; + uint32_t local_pref; + uint32_t *med = NULL; + + { + char buf[BUFSIZ]; + + buf[0] = 0; + prefix2str(prefix, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf); + } + + if (!afi) { + zlog_err("%s: can't get afi of prefix", __func__); + return; + } + + if (!(hc = bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + /* check vnc redist flag for bgp direct routes */ + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", + __func__, afi); + return; + } + + /* + * mode "plain" specific code + */ + { + vnc_zlog_debug_verbose("%s: NOT using redist RFG", __func__); + + /* + * prefix list check + */ + if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) { + vnc_zlog_debug_verbose( + "%s: HC prefix list is set, checking", + __func__); + if (prefix_list_apply( + hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT] + [afi], + prefix) + == PREFIX_DENY) { + vnc_zlog_debug_verbose( + "%s: prefix list returns DENY, blocking route", + __func__); + return; + } + vnc_zlog_debug_verbose( + "%s: prefix list returns PASS, allowing route", + __func__); + } + + /* apply routemap, if any, later */ + rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; + + /* + * Incoming prefix is unicast. If v6, it is in multiprotocol + * area, + * but if v4 it is in attr->nexthop + */ + rfapiUnicastNexthop2Prefix(afi, attr, &vn_pfx_space); + vn_pfx = &vn_pfx_space; + + /* UN address */ + ahr_flags |= RFAPI_AHR_NO_TUNNEL_SUBTLV; + } + + if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { + char buf[BUFSIZ]; + + buf[0] = 0; + prefix2str(vn_pfx, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf); + } + + /* + * Compute VN address + */ + if (rfapiQprefix2Raddr(vn_pfx, &vnaddr)) { + vnc_zlog_debug_verbose("%s: redist VN invalid, skipping", + __func__); + return; + } + + /* + * route map handling + * This code is here because it allocates an interned attr which + * must be freed before we return. It's easier to put it after + * all of the possible returns above. + */ + memset(&hattr, 0, sizeof(struct attr)); + bgp_attr_dup(&hattr, attr); /* hattr becomes a ghost attr */ + + if (rmap) { + struct bgp_info info; + route_map_result_t ret; + + memset(&info, 0, sizeof(info)); + info.peer = peer; + info.attr = &hattr; + ret = route_map_apply(rmap, prefix, RMAP_BGP, &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + vnc_zlog_debug_verbose( + "%s: route map \"%s\" says DENY, returning", + __func__, rmap->name); + return; + } + } + + iattr = bgp_attr_intern(&hattr); + bgp_attr_flush(&hattr); + + /* Now iattr is an allocated interned attr */ + + /* + * Mode "plain" specific code + * + * Sets RD in dummy HD + * Allocates ecom + */ + { + if (vnaddr.addr_family != AF_INET) { + vnc_zlog_debug_verbose( + "%s: can't auto-assign RD, VN AF (%d) is not IPv4, skipping", + __func__, vnaddr.addr_family); + if (iattr) { + bgp_attr_unintern(&iattr); + } + return; + } + memset(&prd, 0, sizeof(prd)); + rfapi_set_autord_from_vn(&prd, &vnaddr); + + if (iattr && iattr->ecommunity) + ecom = ecommunity_dup(iattr->ecommunity); + } + + local_pref = calc_local_pref(iattr, peer); + + if (iattr && (iattr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { + med = &iattr->med; + } + + if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { + char buf[BUFSIZ]; + + buf[0] = 0; + rfapiRfapiIpAddr2Str(&vnaddr, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_any("%s: setting vnaddr to %s", __func__, buf); + } + + vncHDBgpDirect.peer = peer; + add_vnc_route(&vncHDBgpDirect, bgp, SAFI_MPLS_VPN, prefix, &prd, + &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), + NULL, /* RFP options */ + NULL, NULL, ecom, med, /* med */ + NULL, /* label: default */ + ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, + ahr_flags); + vncHDBgpDirect.peer = NULL; + + if (ecom) + ecommunity_free(&ecom); } static void -vnc_import_bgp_add_route_mode_nvegroup (struct bgp *bgp, - struct prefix *prefix, - struct bgp_info *info, - struct rfapi_nve_group_cfg *rfg) +vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix, + struct bgp_info *info, + struct rfapi_nve_group_cfg *rfg) { - afi_t afi = family2afi (prefix->family); - struct peer *peer = info->peer; - struct attr *attr = info->attr; - struct attr hattr; - struct rfapi_cfg *hc = NULL; - struct attr *iattr = NULL; - - struct rfapi_ip_addr vnaddr; - struct prefix *vn_pfx = NULL; - int ahr_flags = 0; - struct ecommunity *ecom = NULL; - struct prefix_rd prd; - struct route_map *rmap = NULL; - uint32_t local_pref; - - { - char buf[BUFSIZ]; - - buf[0] = 0; - prefix2str (prefix, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_verbose ("%s(prefix=%s) entry", __func__, buf); - } - - assert (rfg); - - if (!afi) - { - zlog_err ("%s: can't get afi of prefix", __func__); - return; - } - - if (!(hc = bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - /* check vnc redist flag for bgp direct routes */ - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose - ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", - __func__, afi); - return; - } - - - /* - * RFG-specific code - */ - { - - struct rfapi_ip_prefix pfx_un; - - vnc_zlog_debug_verbose ("%s: using redist RFG", __func__); - - /* - * RFG prefix list check - */ - if (rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) - { - vnc_zlog_debug_verbose ("%s: RFG prefix list is set, checking", __func__); - if (prefix_list_apply - (rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi], - prefix) == PREFIX_DENY) - { - vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route", - __func__); - return; - } - vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__); - } - - /* apply routemap, if any, later */ - rmap = rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; - - /* - * export nve group's VN addr prefix must be a /32 which - * will yield the VN addr to use - */ - vn_pfx = &rfg->vn_prefix; - - /* - * UN Address - */ - if (!is_host_prefix (&rfg->un_prefix)) - { - /* NB prefixlen==0 means it has not been configured */ - vnc_zlog_debug_verbose ("%s: redist RFG UN pfx not host pfx (plen=%d), skipping", - __func__, rfg->un_prefix.prefixlen); - return; - } - - rfapiQprefix2Rprefix (&rfg->un_prefix, &pfx_un); - - vncHDBgpDirect.un_addr = pfx_un.prefix; - } - - if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) - { - char buf[BUFSIZ]; - - buf[0] = 0; - prefix2str (vn_pfx, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_any ("%s vn_pfx=%s", __func__, buf); - } - - /* - * Compute VN address - */ - if (rfapiQprefix2Raddr (vn_pfx, &vnaddr)) - { - vnc_zlog_debug_verbose ("%s: redist VN invalid, skipping", __func__); - return; - } - - /* - * route map handling - * This code is here because it allocates an interned attr which - * must be freed before we return. It's easier to put it after - * all of the possible returns above. - */ - memset (&hattr, 0, sizeof (struct attr)); - bgp_attr_dup (&hattr, attr); /* hattr becomes a ghost attr */ - - if (rmap) - { - struct bgp_info info; - route_map_result_t ret; - - memset (&info, 0, sizeof (info)); - info.peer = peer; - info.attr = &hattr; - ret = route_map_apply (rmap, prefix, RMAP_BGP, &info); - if (ret == RMAP_DENYMATCH) - { - bgp_attr_flush (&hattr); - vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__, - rmap->name); - return; - } - } - - iattr = bgp_attr_intern (&hattr); - bgp_attr_flush (&hattr); - - /* Now iattr is an allocated interned attr */ - - /* - * RFG-specific code - * - * Sets RD in dummy HD - * Allocates ecom - */ - { - - memset (&prd, 0, sizeof (prd)); - prd = rfg->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - if (rfg->rd.family == AF_UNIX) - { - rfapi_set_autord_from_vn (&prd, &vnaddr); - } - - if (rfg->rt_export_list) - ecom = ecommunity_dup (bgp->rfapi_cfg->rfg_redist->rt_export_list); - else - ecom = ecommunity_new (); - - if (iattr && iattr->ecommunity) - ecom = ecommunity_merge (ecom, iattr->ecommunity); - } - - local_pref = calc_local_pref (iattr, peer); - - if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) - { - char buf[BUFSIZ]; - - buf[0] = 0; - rfapiRfapiIpAddr2Str (&vnaddr, buf, BUFSIZ); - buf[BUFSIZ - 1] = 0; - vnc_zlog_debug_any ("%s: setting vnaddr to %s", __func__, buf); - } - - vncHDBgpDirect.peer = peer; - add_vnc_route ( - &vncHDBgpDirect, - bgp, - SAFI_MPLS_VPN, - prefix, - &prd, - &vnaddr, - &local_pref, - &(bgp->rfapi_cfg->redist_lifetime), - NULL, /* RFP options */ - NULL, - NULL, - ecom, - NULL, /* med */ - NULL, /* label: default */ - ZEBRA_ROUTE_BGP_DIRECT, - BGP_ROUTE_REDISTRIBUTE, - ahr_flags); - vncHDBgpDirect.peer = NULL; - - if (ecom) - ecommunity_free (&ecom); + afi_t afi = family2afi(prefix->family); + struct peer *peer = info->peer; + struct attr *attr = info->attr; + struct attr hattr; + struct rfapi_cfg *hc = NULL; + struct attr *iattr = NULL; + + struct rfapi_ip_addr vnaddr; + struct prefix *vn_pfx = NULL; + int ahr_flags = 0; + struct ecommunity *ecom = NULL; + struct prefix_rd prd; + struct route_map *rmap = NULL; + uint32_t local_pref; + + { + char buf[BUFSIZ]; + + buf[0] = 0; + prefix2str(prefix, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf); + } + + assert(rfg); + + if (!afi) { + zlog_err("%s: can't get afi of prefix", __func__); + return; + } + + if (!(hc = bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + /* check vnc redist flag for bgp direct routes */ + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", + __func__, afi); + return; + } + + + /* + * RFG-specific code + */ + { + + struct rfapi_ip_prefix pfx_un; + + vnc_zlog_debug_verbose("%s: using redist RFG", __func__); + + /* + * RFG prefix list check + */ + if (rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) { + vnc_zlog_debug_verbose( + "%s: RFG prefix list is set, checking", + __func__); + if (prefix_list_apply( + rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT] + [afi], + prefix) + == PREFIX_DENY) { + vnc_zlog_debug_verbose( + "%s: prefix list returns DENY, blocking route", + __func__); + return; + } + vnc_zlog_debug_verbose( + "%s: prefix list returns PASS, allowing route", + __func__); + } + + /* apply routemap, if any, later */ + rmap = rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; + + /* + * export nve group's VN addr prefix must be a /32 which + * will yield the VN addr to use + */ + vn_pfx = &rfg->vn_prefix; + + /* + * UN Address + */ + if (!is_host_prefix(&rfg->un_prefix)) { + /* NB prefixlen==0 means it has not been configured */ + vnc_zlog_debug_verbose( + "%s: redist RFG UN pfx not host pfx (plen=%d), skipping", + __func__, rfg->un_prefix.prefixlen); + return; + } + + rfapiQprefix2Rprefix(&rfg->un_prefix, &pfx_un); + + vncHDBgpDirect.un_addr = pfx_un.prefix; + } + + if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { + char buf[BUFSIZ]; + + buf[0] = 0; + prefix2str(vn_pfx, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf); + } + + /* + * Compute VN address + */ + if (rfapiQprefix2Raddr(vn_pfx, &vnaddr)) { + vnc_zlog_debug_verbose("%s: redist VN invalid, skipping", + __func__); + return; + } + + /* + * route map handling + * This code is here because it allocates an interned attr which + * must be freed before we return. It's easier to put it after + * all of the possible returns above. + */ + memset(&hattr, 0, sizeof(struct attr)); + bgp_attr_dup(&hattr, attr); /* hattr becomes a ghost attr */ + + if (rmap) { + struct bgp_info info; + route_map_result_t ret; + + memset(&info, 0, sizeof(info)); + info.peer = peer; + info.attr = &hattr; + ret = route_map_apply(rmap, prefix, RMAP_BGP, &info); + if (ret == RMAP_DENYMATCH) { + bgp_attr_flush(&hattr); + vnc_zlog_debug_verbose( + "%s: route map \"%s\" says DENY, returning", + __func__, rmap->name); + return; + } + } + + iattr = bgp_attr_intern(&hattr); + bgp_attr_flush(&hattr); + + /* Now iattr is an allocated interned attr */ + + /* + * RFG-specific code + * + * Sets RD in dummy HD + * Allocates ecom + */ + { + + memset(&prd, 0, sizeof(prd)); + prd = rfg->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + if (rfg->rd.family == AF_UNIX) { + rfapi_set_autord_from_vn(&prd, &vnaddr); + } + + if (rfg->rt_export_list) + ecom = ecommunity_dup( + bgp->rfapi_cfg->rfg_redist->rt_export_list); + else + ecom = ecommunity_new(); + + if (iattr && iattr->ecommunity) + ecom = ecommunity_merge(ecom, iattr->ecommunity); + } + + local_pref = calc_local_pref(iattr, peer); + + if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { + char buf[BUFSIZ]; + + buf[0] = 0; + rfapiRfapiIpAddr2Str(&vnaddr, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vnc_zlog_debug_any("%s: setting vnaddr to %s", __func__, buf); + } + + vncHDBgpDirect.peer = peer; + add_vnc_route(&vncHDBgpDirect, bgp, SAFI_MPLS_VPN, prefix, &prd, + &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), + NULL, /* RFP options */ + NULL, NULL, ecom, NULL, /* med */ + NULL, /* label: default */ + ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, + ahr_flags); + vncHDBgpDirect.peer = NULL; + + if (ecom) + ecommunity_free(&ecom); } -static void -vnc_import_bgp_del_route_mode_plain (struct bgp *bgp, - struct prefix *prefix, - struct bgp_info *info) +static void vnc_import_bgp_del_route_mode_plain(struct bgp *bgp, + struct prefix *prefix, + struct bgp_info *info) { - struct prefix_rd prd; - afi_t afi = family2afi (prefix->family); - struct prefix *vn_pfx = NULL; - struct rfapi_ip_addr vnaddr; - struct prefix vn_pfx_space; - - - assert (afi); - - /* - * Compute VN address - */ - - if (info && info->attr) - { - rfapiUnicastNexthop2Prefix (afi, info->attr, &vn_pfx_space); - } - else - { - vnc_zlog_debug_verbose ("%s: no attr, can't delete route", __func__); - return; - } - vn_pfx = &vn_pfx_space; - - vnaddr.addr_family = vn_pfx->family; - switch (vn_pfx->family) - { - case AF_INET: - if (vn_pfx->prefixlen != 32) - { - vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 32, skipping", - __func__, vn_pfx->prefixlen); - return; - } - vnaddr.addr.v4 = vn_pfx->u.prefix4; - break; - - case AF_INET6: - if (vn_pfx->prefixlen != 128) - { - vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 128, skipping", - __func__, vn_pfx->prefixlen); - return; - } - vnaddr.addr.v6 = vn_pfx->u.prefix6; - break; - - default: - vnc_zlog_debug_verbose ("%s: no redist RFG VN host pfx configured, skipping", - __func__); - return; - } - - - memset (&prd, 0, sizeof (prd)); - if (rfapi_set_autord_from_vn (&prd, &vnaddr)) - { - vnc_zlog_debug_verbose ("%s: can't auto-assign RD, skipping", __func__); - return; - } - - vncHDBgpDirect.peer = info->peer; - vnc_zlog_debug_verbose ("%s: setting peer to %p", __func__, vncHDBgpDirect.peer); - del_vnc_route (&vncHDBgpDirect, - info->peer, - bgp, - SAFI_MPLS_VPN, - prefix, - &prd, - ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 1); - - vncHDBgpDirect.peer = NULL; + struct prefix_rd prd; + afi_t afi = family2afi(prefix->family); + struct prefix *vn_pfx = NULL; + struct rfapi_ip_addr vnaddr; + struct prefix vn_pfx_space; + + + assert(afi); + + /* + * Compute VN address + */ + + if (info && info->attr) { + rfapiUnicastNexthop2Prefix(afi, info->attr, &vn_pfx_space); + } else { + vnc_zlog_debug_verbose("%s: no attr, can't delete route", + __func__); + return; + } + vn_pfx = &vn_pfx_space; + + vnaddr.addr_family = vn_pfx->family; + switch (vn_pfx->family) { + case AF_INET: + if (vn_pfx->prefixlen != 32) { + vnc_zlog_debug_verbose( + "%s: redist VN plen (%d) != 32, skipping", + __func__, vn_pfx->prefixlen); + return; + } + vnaddr.addr.v4 = vn_pfx->u.prefix4; + break; + + case AF_INET6: + if (vn_pfx->prefixlen != 128) { + vnc_zlog_debug_verbose( + "%s: redist VN plen (%d) != 128, skipping", + __func__, vn_pfx->prefixlen); + return; + } + vnaddr.addr.v6 = vn_pfx->u.prefix6; + break; + + default: + vnc_zlog_debug_verbose( + "%s: no redist RFG VN host pfx configured, skipping", + __func__); + return; + } + + + memset(&prd, 0, sizeof(prd)); + if (rfapi_set_autord_from_vn(&prd, &vnaddr)) { + vnc_zlog_debug_verbose("%s: can't auto-assign RD, skipping", + __func__); + return; + } + + vncHDBgpDirect.peer = info->peer; + vnc_zlog_debug_verbose("%s: setting peer to %p", __func__, + vncHDBgpDirect.peer); + del_vnc_route(&vncHDBgpDirect, info->peer, bgp, SAFI_MPLS_VPN, prefix, + &prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, + NULL, 1); + + vncHDBgpDirect.peer = NULL; } -static void -vnc_import_bgp_del_route_mode_nvegroup (struct bgp *bgp, - struct prefix *prefix, - struct bgp_info *info) +static void vnc_import_bgp_del_route_mode_nvegroup(struct bgp *bgp, + struct prefix *prefix, + struct bgp_info *info) { - struct prefix_rd prd; - afi_t afi = family2afi (prefix->family); - struct rfapi_nve_group_cfg *rfg = NULL; - struct prefix *vn_pfx = NULL; - struct rfapi_ip_addr vnaddr; - - - assert (afi); - - assert ((rfg = bgp->rfapi_cfg->rfg_redist)); - - /* - * Compute VN address - */ - - /* - * export nve group's VN addr prefix must be a /32 which - * will yield the VN addr to use - */ - vn_pfx = &rfg->vn_prefix; - - - vnaddr.addr_family = vn_pfx->family; - switch (vn_pfx->family) - { - case AF_INET: - if (vn_pfx->prefixlen != 32) - { - vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 32, skipping", - __func__, vn_pfx->prefixlen); - return; - } - vnaddr.addr.v4 = vn_pfx->u.prefix4; - break; - - case AF_INET6: - if (vn_pfx->prefixlen != 128) - { - vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 128, skipping", - __func__, vn_pfx->prefixlen); - return; - } - vnaddr.addr.v6 = vn_pfx->u.prefix6; - break; - - default: - vnc_zlog_debug_verbose ("%s: no redist RFG VN host pfx configured, skipping", - __func__); - return; - } - - memset (&prd, 0, sizeof (prd)); - prd = rfg->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - if (rfg->rd.family == AF_UNIX) - { - /* means "auto" with VN addr */ - if (rfapi_set_autord_from_vn (&prd, &vnaddr)) - { - vnc_zlog_debug_verbose ("%s: can't auto-assign RD, skipping", __func__); - return; - } - } - - - vncHDBgpDirect.peer = info->peer; - vnc_zlog_debug_verbose ("%s: setting peer to %p", __func__, vncHDBgpDirect.peer); - del_vnc_route (&vncHDBgpDirect, - info->peer, - bgp, - SAFI_MPLS_VPN, - prefix, - &prd, - ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 1); - - vncHDBgpDirect.peer = NULL; + struct prefix_rd prd; + afi_t afi = family2afi(prefix->family); + struct rfapi_nve_group_cfg *rfg = NULL; + struct prefix *vn_pfx = NULL; + struct rfapi_ip_addr vnaddr; + + + assert(afi); + + assert((rfg = bgp->rfapi_cfg->rfg_redist)); + + /* + * Compute VN address + */ + + /* + * export nve group's VN addr prefix must be a /32 which + * will yield the VN addr to use + */ + vn_pfx = &rfg->vn_prefix; + + + vnaddr.addr_family = vn_pfx->family; + switch (vn_pfx->family) { + case AF_INET: + if (vn_pfx->prefixlen != 32) { + vnc_zlog_debug_verbose( + "%s: redist VN plen (%d) != 32, skipping", + __func__, vn_pfx->prefixlen); + return; + } + vnaddr.addr.v4 = vn_pfx->u.prefix4; + break; + + case AF_INET6: + if (vn_pfx->prefixlen != 128) { + vnc_zlog_debug_verbose( + "%s: redist VN plen (%d) != 128, skipping", + __func__, vn_pfx->prefixlen); + return; + } + vnaddr.addr.v6 = vn_pfx->u.prefix6; + break; + + default: + vnc_zlog_debug_verbose( + "%s: no redist RFG VN host pfx configured, skipping", + __func__); + return; + } + + memset(&prd, 0, sizeof(prd)); + prd = rfg->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + if (rfg->rd.family == AF_UNIX) { + /* means "auto" with VN addr */ + if (rfapi_set_autord_from_vn(&prd, &vnaddr)) { + vnc_zlog_debug_verbose( + "%s: can't auto-assign RD, skipping", __func__); + return; + } + } + + + vncHDBgpDirect.peer = info->peer; + vnc_zlog_debug_verbose("%s: setting peer to %p", __func__, + vncHDBgpDirect.peer); + del_vnc_route(&vncHDBgpDirect, info->peer, bgp, SAFI_MPLS_VPN, prefix, + &prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, + NULL, 1); + + vncHDBgpDirect.peer = NULL; } -static void -vnc_import_bgp_del_route_mode_resolve_nve_one_bi ( - struct bgp *bgp, - afi_t afi, - struct bgp_info *bi, /* VPN bi */ - struct prefix_rd *prd, /* RD */ - struct prefix *prefix)/* unicast route prefix */ +static void vnc_import_bgp_del_route_mode_resolve_nve_one_bi( + struct bgp *bgp, afi_t afi, struct bgp_info *bi, /* VPN bi */ + struct prefix_rd *prd, /* RD */ + struct prefix *prefix) /* unicast route prefix */ { - struct prefix un; - - if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT) - { - - return; - } - if (bi->sub_type != BGP_ROUTE_NORMAL && - bi->sub_type != BGP_ROUTE_STATIC && bi->sub_type != BGP_ROUTE_RFP) - { - - return; - } - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - return; - - vncHDResolveNve.peer = bi->peer; - if (!rfapiGetVncTunnelUnAddr (bi->attr, &un)) - { - if (rfapiQprefix2Raddr (&un, &vncHDResolveNve.un_addr)) - return; - } - else - { - memset (&vncHDResolveNve.un_addr, 0, sizeof (vncHDResolveNve.un_addr)); - } - - del_vnc_route (&vncHDResolveNve, vncHDResolveNve.peer, bgp, SAFI_MPLS_VPN, prefix, /* unicast route prefix */ - prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 0); /* flags */ + struct prefix un; + + if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT) { + return; + } + if (bi->sub_type != BGP_ROUTE_NORMAL && bi->sub_type != BGP_ROUTE_STATIC + && bi->sub_type != BGP_ROUTE_RFP) { + + return; + } + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + return; + + vncHDResolveNve.peer = bi->peer; + if (!rfapiGetVncTunnelUnAddr(bi->attr, &un)) { + if (rfapiQprefix2Raddr(&un, &vncHDResolveNve.un_addr)) + return; + } else { + memset(&vncHDResolveNve.un_addr, 0, + sizeof(vncHDResolveNve.un_addr)); + } + + del_vnc_route(&vncHDResolveNve, vncHDResolveNve.peer, bgp, + SAFI_MPLS_VPN, prefix, /* unicast route prefix */ + prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, + 0); /* flags */ } -static void -vnc_import_bgp_del_route_mode_resolve_nve_one_rd ( - struct prefix_rd *prd, - struct bgp_table *table_rd, /* per-rd VPN route table */ - afi_t afi, - struct bgp *bgp, - struct prefix *prefix, /* unicast prefix */ - struct prefix *ubi_nexthop) /* unicast bi's nexthop */ +static void vnc_import_bgp_del_route_mode_resolve_nve_one_rd( + struct prefix_rd *prd, + struct bgp_table *table_rd, /* per-rd VPN route table */ + afi_t afi, struct bgp *bgp, struct prefix *prefix, /* unicast prefix */ + struct prefix *ubi_nexthop) /* unicast bi's nexthop */ { - struct bgp_node *bn; - struct bgp_info *bi; + struct bgp_node *bn; + struct bgp_info *bi; - if (!table_rd) - return; + if (!table_rd) + return; - { - char str_nh[BUFSIZ]; + { + char str_nh[BUFSIZ]; - prefix2str (ubi_nexthop, str_nh, BUFSIZ); - str_nh[BUFSIZ - 1] = 0; + prefix2str(ubi_nexthop, str_nh, BUFSIZ); + str_nh[BUFSIZ - 1] = 0; - vnc_zlog_debug_verbose ("%s: ubi_nexthop=%s", __func__, str_nh); - } + vnc_zlog_debug_verbose("%s: ubi_nexthop=%s", __func__, str_nh); + } - /* exact match */ - bn = bgp_node_lookup (table_rd, ubi_nexthop); - if (!bn) - { - vnc_zlog_debug_verbose ("%s: no match in RD's table for ubi_nexthop", __func__); - return; - } + /* exact match */ + bn = bgp_node_lookup(table_rd, ubi_nexthop); + if (!bn) { + vnc_zlog_debug_verbose( + "%s: no match in RD's table for ubi_nexthop", __func__); + return; + } - /* Iterate over bgp_info items at this node */ - for (bi = bn->info; bi; bi = bi->next) - { + /* Iterate over bgp_info items at this node */ + for (bi = bn->info; bi; bi = bi->next) { - vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp, afi, bi, /* VPN bi */ - prd, /* VPN RD */ - prefix); /* unicast route prefix */ - } + vnc_import_bgp_del_route_mode_resolve_nve_one_bi( + bgp, afi, bi, /* VPN bi */ + prd, /* VPN RD */ + prefix); /* unicast route prefix */ + } - bgp_unlock_node (bn); + bgp_unlock_node(bn); } -static void -vnc_import_bgp_del_route_mode_resolve_nve (struct bgp *bgp, - afi_t afi, - struct prefix *prefix, - struct bgp_info *info) +static void vnc_import_bgp_del_route_mode_resolve_nve(struct bgp *bgp, + afi_t afi, + struct prefix *prefix, + struct bgp_info *info) { - struct ecommunity *ecom = NULL; - struct prefix pfx_unicast_nexthop = { 0 }; /* happy valgrind */ - - //struct listnode *hnode; - //struct rfapi_descriptor *rfd; - struct prefix_bag *pb; - void *cursor; - struct skiplist *sl = bgp->rfapi->resolve_nve_nexthop; - int rc; - struct bgp_node *bnp; /* prd table node */ - - if (!sl) - { - vnc_zlog_debug_verbose ("%s: no RHN entries, skipping", __func__); - return; - } - - if (info->type != ZEBRA_ROUTE_BGP) - { - vnc_zlog_debug_verbose ("%s: unicast type %d=\"%s\" is not %d=%s, skipping", - __func__, info->type, zebra_route_string (info->type), - ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP"); - return; - } - - if (process_unicast_route (bgp, afi, prefix, info, - &ecom, &pfx_unicast_nexthop)) - { - - vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__); - return; - } - - rc = skiplist_first_value (sl, &pfx_unicast_nexthop, (void *) &pb, &cursor); - while (!rc) - { - if (pb->ubi == info) - { - skiplist_delete (sl, &pfx_unicast_nexthop, pb); - bgp_info_unlock (info); - break; - } - rc = - skiplist_next_value (sl, &pfx_unicast_nexthop, (void *) &pb, &cursor); - } - - /* - * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop - * (exact match, /32). If an exact match is found, call add_vnc_route. - */ - - for (bnp = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); bnp; - bnp = bgp_route_next (bnp)) - { - - struct bgp_table *table; - - table = (struct bgp_table *) (bnp->info); - - if (!table) - continue; - - vnc_import_bgp_del_route_mode_resolve_nve_one_rd ((struct prefix_rd *) &bnp->p, table, afi, bgp, prefix, &pfx_unicast_nexthop); /* TBD how is this set? */ - } - - if (ecom) - ecommunity_free (&ecom); -} + struct ecommunity *ecom = NULL; + struct prefix pfx_unicast_nexthop = {0}; /* happy valgrind */ + + // struct listnode *hnode; + // struct rfapi_descriptor *rfd; + struct prefix_bag *pb; + void *cursor; + struct skiplist *sl = bgp->rfapi->resolve_nve_nexthop; + int rc; + struct bgp_node *bnp; /* prd table node */ + + if (!sl) { + vnc_zlog_debug_verbose("%s: no RHN entries, skipping", + __func__); + return; + } + if (info->type != ZEBRA_ROUTE_BGP) { + vnc_zlog_debug_verbose( + "%s: unicast type %d=\"%s\" is not %d=%s, skipping", + __func__, info->type, zebra_route_string(info->type), + ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP"); + return; + } + if (process_unicast_route(bgp, afi, prefix, info, &ecom, + &pfx_unicast_nexthop)) { + + vnc_zlog_debug_verbose( + "%s: process_unicast_route error, skipping", __func__); + return; + } + + rc = skiplist_first_value(sl, &pfx_unicast_nexthop, (void *)&pb, + &cursor); + while (!rc) { + if (pb->ubi == info) { + skiplist_delete(sl, &pfx_unicast_nexthop, pb); + bgp_info_unlock(info); + break; + } + rc = skiplist_next_value(sl, &pfx_unicast_nexthop, (void *)&pb, + &cursor); + } + + /* + * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop + * (exact match, /32). If an exact match is found, call add_vnc_route. + */ + + for (bnp = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); bnp; + bnp = bgp_route_next(bnp)) { + + struct bgp_table *table; + + table = (struct bgp_table *)(bnp->info); + + if (!table) + continue; + + vnc_import_bgp_del_route_mode_resolve_nve_one_rd( + (struct prefix_rd *)&bnp->p, table, afi, bgp, prefix, + &pfx_unicast_nexthop); /* TBD how is this set? */ + } + + if (ecom) + ecommunity_free(&ecom); +} /*********************************************************************** @@ -1509,262 +1409,256 @@ vnc_import_bgp_del_route_mode_resolve_nve (struct bgp *bgp, * Should be called whan a bi is added to VPN RIB. This function * will check if it is a host route and return immediately if not. */ -void -vnc_import_bgp_add_vnc_host_route_mode_resolve_nve ( - struct bgp *bgp, - struct prefix_rd *prd, /* RD */ - struct bgp_table *table_rd, /* per-rd VPN route table */ - struct prefix *prefix, /* VPN prefix */ - struct bgp_info *bi) /* new VPN host route */ +void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( + struct bgp *bgp, struct prefix_rd *prd, /* RD */ + struct bgp_table *table_rd, /* per-rd VPN route table */ + struct prefix *prefix, /* VPN prefix */ + struct bgp_info *bi) /* new VPN host route */ { - afi_t afi = family2afi (prefix->family); - struct skiplist *sl = NULL; - int rc; - struct prefix_bag *pb; - void *cursor; - struct rfapi_cfg *hc = NULL; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - - if (afi != AFI_IP && afi != AFI_IP6) - { - vnc_zlog_debug_verbose ("%s: bad afi %d, skipping", __func__, afi); - return; - } - - if (!(hc = bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - /* check vnc redist flag for bgp direct routes */ - if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose - ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", - __func__, afi); - return; - } - - if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE) - { - vnc_zlog_debug_verbose ("%s: not in resolve-nve mode, skipping", __func__); - return; - } - - if (bgp && bgp->rfapi) - sl = bgp->rfapi->resolve_nve_nexthop; - - if (!sl) - { - vnc_zlog_debug_verbose ("%s: no resolve_nve_nexthop skiplist, skipping", __func__); - return; - } - - if (!is_host_prefix (prefix)) - { - vnc_zlog_debug_verbose ("%s: not host prefix, skipping", __func__); - return; - } - - rc = skiplist_first_value (sl, prefix, (void *) &pb, &cursor); - while (!rc) - { - struct ecommunity *ecom; - struct prefix pfx_unicast_nexthop; - uint32_t *med = NULL; - uint32_t local_pref; - - memset (&pfx_unicast_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */ - - if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) - { - char hbuf[BUFSIZ]; - char ubuf[BUFSIZ]; + afi_t afi = family2afi(prefix->family); + struct skiplist *sl = NULL; + int rc; + struct prefix_bag *pb; + void *cursor; + struct rfapi_cfg *hc = NULL; + + vnc_zlog_debug_verbose("%s: entry", __func__); + + if (afi != AFI_IP && afi != AFI_IP6) { + vnc_zlog_debug_verbose("%s: bad afi %d, skipping", __func__, + afi); + return; + } + + if (!(hc = bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } - prefix2str (&pb->hpfx, hbuf, BUFSIZ); - prefix2str (&pb->upfx, ubuf, BUFSIZ); + /* check vnc redist flag for bgp direct routes */ + if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", + __func__, afi); + return; + } - vnc_zlog_debug_any - ("%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p", - __func__, cursor, ubuf, hbuf, pb->ubi); + if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE) { + vnc_zlog_debug_verbose("%s: not in resolve-nve mode, skipping", + __func__); + return; } - if (process_unicast_route (bgp, afi, &pb->upfx, pb->ubi, - &ecom, &pfx_unicast_nexthop)) - { + if (bgp && bgp->rfapi) + sl = bgp->rfapi->resolve_nve_nexthop; + + if (!sl) { + vnc_zlog_debug_verbose( + "%s: no resolve_nve_nexthop skiplist, skipping", + __func__); + return; + } + + if (!is_host_prefix(prefix)) { + vnc_zlog_debug_verbose("%s: not host prefix, skipping", + __func__); + return; + } + + rc = skiplist_first_value(sl, prefix, (void *)&pb, &cursor); + while (!rc) { + struct ecommunity *ecom; + struct prefix pfx_unicast_nexthop; + uint32_t *med = NULL; + uint32_t local_pref; + + memset(&pfx_unicast_nexthop, 0, + sizeof(struct prefix)); /* keep valgrind happy */ + + if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { + char hbuf[BUFSIZ]; + char ubuf[BUFSIZ]; - vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__); - continue; - } - local_pref = calc_local_pref (pb->ubi->attr, pb->ubi->peer); + prefix2str(&pb->hpfx, hbuf, BUFSIZ); + prefix2str(&pb->upfx, ubuf, BUFSIZ); - if (pb->ubi->attr && - (pb->ubi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))) - { + vnc_zlog_debug_any( + "%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p", + __func__, cursor, ubuf, hbuf, pb->ubi); + } - med = &pb->ubi->attr->med; - } + if (process_unicast_route(bgp, afi, &pb->upfx, pb->ubi, &ecom, + &pfx_unicast_nexthop)) { - /* - * Sanity check - */ - if (vnc_prefix_cmp (&pfx_unicast_nexthop, prefix)) - { - char str_unh[BUFSIZ]; - char str_nve_pfx[BUFSIZ]; + vnc_zlog_debug_verbose( + "%s: process_unicast_route error, skipping", + __func__); + continue; + } + local_pref = calc_local_pref(pb->ubi->attr, pb->ubi->peer); - prefix2str (&pfx_unicast_nexthop, str_unh, BUFSIZ); - str_unh[BUFSIZ - 1] = 0; + if (pb->ubi->attr + && (pb->ubi->attr->flag + & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { - prefix2str (prefix, str_nve_pfx, BUFSIZ); - str_nve_pfx[BUFSIZ - 1] = 0; + med = &pb->ubi->attr->med; + } - vnc_zlog_debug_verbose - ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", - __func__, str_unh, str_nve_pfx); - assert (0); - } + /* + * Sanity check + */ + if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) { + char str_unh[BUFSIZ]; + char str_nve_pfx[BUFSIZ]; - vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp, afi, bi, /* VPN bi */ - prd, &pb->upfx, /* unicast prefix */ - &local_pref, - med, ecom); + prefix2str(&pfx_unicast_nexthop, str_unh, BUFSIZ); + str_unh[BUFSIZ - 1] = 0; - if (ecom) - ecommunity_free (&ecom); + prefix2str(prefix, str_nve_pfx, BUFSIZ); + str_nve_pfx[BUFSIZ - 1] = 0; + + vnc_zlog_debug_verbose( + "%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", + __func__, str_unh, str_nve_pfx); + assert(0); + } + + vnc_import_bgp_add_route_mode_resolve_nve_one_bi( + bgp, afi, bi, /* VPN bi */ + prd, &pb->upfx, /* unicast prefix */ + &local_pref, med, ecom); + + if (ecom) + ecommunity_free(&ecom); #if DEBUG_RHN_LIST - /* debug */ - { - char pbuf[BUFSIZ]; + /* debug */ + { + char pbuf[BUFSIZ]; - prefix2str (prefix, pbuf, BUFSIZ); + prefix2str(prefix, pbuf, BUFSIZ); - vnc_zlog_debug_verbose ("%s: advancing past RHN Entry (q=%p): with prefix %s", - __func__, cursor, pbuf); - print_rhn_list (__func__, NULL); /* debug */ - } + vnc_zlog_debug_verbose( + "%s: advancing past RHN Entry (q=%p): with prefix %s", + __func__, cursor, pbuf); + print_rhn_list(__func__, NULL); /* debug */ + } #endif - rc = skiplist_next_value (sl, prefix, (void *) &pb, &cursor); - } - vnc_zlog_debug_verbose ("%s: done", __func__); + rc = skiplist_next_value(sl, prefix, (void *)&pb, &cursor); + } + vnc_zlog_debug_verbose("%s: done", __func__); } -void -vnc_import_bgp_del_vnc_host_route_mode_resolve_nve ( - struct bgp *bgp, - struct prefix_rd *prd, /* RD */ - struct bgp_table *table_rd, /* per-rd VPN route table */ - struct prefix *prefix, /* VPN prefix */ - struct bgp_info *bi) /* old VPN host route */ +void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( + struct bgp *bgp, struct prefix_rd *prd, /* RD */ + struct bgp_table *table_rd, /* per-rd VPN route table */ + struct prefix *prefix, /* VPN prefix */ + struct bgp_info *bi) /* old VPN host route */ { - afi_t afi = family2afi (prefix->family); - struct skiplist *sl = NULL; - struct prefix_bag *pb; - void *cursor; - struct rfapi_cfg *hc = NULL; - int rc; - - { - char str_pfx[BUFSIZ]; - - prefix2str (prefix, str_pfx, BUFSIZ); - str_pfx[BUFSIZ - 1] = 0; - - vnc_zlog_debug_verbose ("%s(bgp=%p, nve prefix=%s)", __func__, bgp, str_pfx); - } - - if (afi != AFI_IP && afi != AFI_IP6) - return; - - if (!(hc = bgp->rfapi_cfg)) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - /* check vnc redist flag for bgp direct routes */ - if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose - ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", - __func__, afi); - return; - } - - if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE) - { - vnc_zlog_debug_verbose ("%s: not in resolve-nve mode, skipping", __func__); - return; - } - - if (bgp && bgp->rfapi) - sl = bgp->rfapi->resolve_nve_nexthop; - - if (!sl) - { - vnc_zlog_debug_verbose ("%s: no RHN entries, skipping", __func__); - return; - } - - if (!is_host_prefix (prefix)) - { - vnc_zlog_debug_verbose ("%s: not host route, skip", __func__); - return; - } - - /* - * Find all entries with key == CE in the RHN list - */ - rc = skiplist_first_value (sl, prefix, (void *) &pb, &cursor); - while (!rc) - { - - struct ecommunity *ecom; - struct prefix pfx_unicast_nexthop; - - memset (&pfx_unicast_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */ - - if (process_unicast_route (bgp, afi, &pb->upfx, pb->ubi, - &ecom, &pfx_unicast_nexthop)) - { - - vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__); - continue; - } - - /* - * Sanity check - */ - if (vnc_prefix_cmp (&pfx_unicast_nexthop, prefix)) - { - char str_unh[BUFSIZ]; - char str_nve_pfx[BUFSIZ]; - - prefix2str (&pfx_unicast_nexthop, str_unh, BUFSIZ); - str_unh[BUFSIZ - 1] = 0; - - prefix2str (prefix, str_nve_pfx, BUFSIZ); - str_nve_pfx[BUFSIZ - 1] = 0; - - vnc_zlog_debug_verbose - ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", - __func__, str_unh, str_nve_pfx); - assert (0); - } - - vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp, - afi, - bi, prd, &pb->upfx); - - if (ecom) - ecommunity_free (&ecom); - - rc = skiplist_next_value (sl, prefix, (void *) &pb, &cursor); - } + afi_t afi = family2afi(prefix->family); + struct skiplist *sl = NULL; + struct prefix_bag *pb; + void *cursor; + struct rfapi_cfg *hc = NULL; + int rc; + + { + char str_pfx[BUFSIZ]; + + prefix2str(prefix, str_pfx, BUFSIZ); + str_pfx[BUFSIZ - 1] = 0; + + vnc_zlog_debug_verbose("%s(bgp=%p, nve prefix=%s)", __func__, + bgp, str_pfx); + } + + if (afi != AFI_IP && afi != AFI_IP6) + return; + + if (!(hc = bgp->rfapi_cfg)) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + /* check vnc redist flag for bgp direct routes */ + if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", + __func__, afi); + return; + } + + if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE) { + vnc_zlog_debug_verbose("%s: not in resolve-nve mode, skipping", + __func__); + return; + } + + if (bgp && bgp->rfapi) + sl = bgp->rfapi->resolve_nve_nexthop; + + if (!sl) { + vnc_zlog_debug_verbose("%s: no RHN entries, skipping", + __func__); + return; + } + + if (!is_host_prefix(prefix)) { + vnc_zlog_debug_verbose("%s: not host route, skip", __func__); + return; + } + + /* + * Find all entries with key == CE in the RHN list + */ + rc = skiplist_first_value(sl, prefix, (void *)&pb, &cursor); + while (!rc) { + + struct ecommunity *ecom; + struct prefix pfx_unicast_nexthop; + + memset(&pfx_unicast_nexthop, 0, + sizeof(struct prefix)); /* keep valgrind happy */ + + if (process_unicast_route(bgp, afi, &pb->upfx, pb->ubi, &ecom, + &pfx_unicast_nexthop)) { + + vnc_zlog_debug_verbose( + "%s: process_unicast_route error, skipping", + __func__); + continue; + } + + /* + * Sanity check + */ + if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) { + char str_unh[BUFSIZ]; + char str_nve_pfx[BUFSIZ]; + + prefix2str(&pfx_unicast_nexthop, str_unh, BUFSIZ); + str_unh[BUFSIZ - 1] = 0; + + prefix2str(prefix, str_nve_pfx, BUFSIZ); + str_nve_pfx[BUFSIZ - 1] = 0; + + vnc_zlog_debug_verbose( + "%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", + __func__, str_unh, str_nve_pfx); + assert(0); + } + + vnc_import_bgp_del_route_mode_resolve_nve_one_bi( + bgp, afi, bi, prd, &pb->upfx); + + if (ecom) + ecommunity_free(&ecom); + + rc = skiplist_next_value(sl, prefix, (void *)&pb, &cursor); + } } @@ -1774,25 +1668,24 @@ vnc_import_bgp_del_vnc_host_route_mode_resolve_nve ( #define DEBUG_IS_USABLE_INTERIOR 1 -static int -is_usable_interior_route (struct bgp_info *bi_interior) +static int is_usable_interior_route(struct bgp_info *bi_interior) { - if (!VALID_INTERIOR_TYPE (bi_interior->type)) - { + if (!VALID_INTERIOR_TYPE(bi_interior->type)) { #if DEBUG_IS_USABLE_INTERIOR - vnc_zlog_debug_verbose ("%s: NO: type %d is not valid interior type", - __func__, bi_interior->type); + vnc_zlog_debug_verbose( + "%s: NO: type %d is not valid interior type", __func__, + bi_interior->type); #endif - return 0; - } - if (!CHECK_FLAG (bi_interior->flags, BGP_INFO_VALID)) - { + return 0; + } + if (!CHECK_FLAG(bi_interior->flags, BGP_INFO_VALID)) { #if DEBUG_IS_USABLE_INTERIOR - vnc_zlog_debug_verbose ("%s: NO: BGP_INFO_VALID not set", __func__); + vnc_zlog_debug_verbose("%s: NO: BGP_INFO_VALID not set", + __func__); #endif - return 0; - } - return 1; + return 0; + } + return 1; } /* @@ -1804,192 +1697,188 @@ is_usable_interior_route (struct bgp_info *bi_interior) * We filter here on the instance name to make sure we get only the * right routes. */ -static void -vnc_import_bgp_exterior_add_route_it ( - struct bgp *bgp, /* exterior instance, we hope */ - struct prefix *prefix,/* unicast prefix */ - struct bgp_info *info, /* unicast info */ - struct rfapi_import_table *it_only)/* NULL, or limit to this IT */ +static void vnc_import_bgp_exterior_add_route_it( + struct bgp *bgp, /* exterior instance, we hope */ + struct prefix *prefix, /* unicast prefix */ + struct bgp_info *info, /* unicast info */ + struct rfapi_import_table *it_only) /* NULL, or limit to this IT */ { - struct rfapi *h; - struct rfapi_cfg *hc; - struct prefix pfx_orig_nexthop; - struct rfapi_import_table *it; - struct bgp *bgp_default = bgp_get_default (); - afi_t afi = family2afi (prefix->family); - - if (!bgp_default) - return; - - h = bgp_default->rfapi; - hc = bgp_default->rfapi_cfg; - - vnc_zlog_debug_verbose ("%s: entry with it=%p", __func__, it_only); - - if (!h || !hc) - { - vnc_zlog_debug_verbose ("%s: rfapi or rfapi_cfg not instantiated, skipping", - __func__); - return; - } - if (!hc->redist_bgp_exterior_view) - { - vnc_zlog_debug_verbose ("%s: exterior view not set, skipping", __func__); - return; - } - if (bgp != hc->redist_bgp_exterior_view) - { - vnc_zlog_debug_verbose ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping", - __func__, bgp, hc->redist_bgp_exterior_view); - return; - } - - if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vnc_zlog_debug_verbose ("%s: redist of exterior routes not enabled, skipping", - __func__); - return; - } - - if (!info->attr) - { - vnc_zlog_debug_verbose ("%s: no info, skipping", __func__); - return; - } - - /* - * Extract nexthop from exterior route - * - * Incoming prefix is unicast. If v6, it is in multiprotocol area, - * but if v4 it is in attr->nexthop - */ - rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_orig_nexthop); - - for (it = h->imports; it; it = it->next) - { - struct route_table *table; - struct route_node *rn; - struct route_node *par; - struct bgp_info *bi_interior; - int have_usable_route; - - vnc_zlog_debug_verbose ("%s: doing it %p", __func__, it); - - if (it_only && (it_only != it)) - { - vnc_zlog_debug_verbose ("%s: doesn't match it_only %p", __func__, it_only); - continue; - } - - table = it->imported_vpn[afi]; - - for (rn = route_node_match (table, &pfx_orig_nexthop), - have_usable_route = 0; (!have_usable_route) && rn;) - { - - vnc_zlog_debug_verbose ("%s: it %p trying rn %p", __func__, it, rn); - - for (bi_interior = rn->info; bi_interior; - bi_interior = bi_interior->next) - { - struct prefix_rd *prd; - struct attr new_attr; - u_int32_t label = 0; - - if (!is_usable_interior_route (bi_interior)) - continue; - - vnc_zlog_debug_verbose ("%s: usable: bi_interior %p", __func__, - bi_interior); - - /* - * have a legitimate route to exterior's nexthop - * via NVE. - * - * Import unicast route to the import table - */ - have_usable_route = 1; - - if (bi_interior->extra) - { - prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (&bi_interior->extra->label); - } - else - prd = NULL; - - /* use local_pref from unicast route */ - memset (&new_attr, 0, sizeof (struct attr)); - bgp_attr_dup (&new_attr, bi_interior->attr); - if (info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) - { - new_attr.local_pref = info->attr->local_pref; - new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); - } - - rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL, /* rfd */ - prefix, - NULL, - afi, - prd, - &new_attr, - ZEBRA_ROUTE_BGP_DIRECT_EXT, - BGP_ROUTE_REDISTRIBUTE, &label); - - } - - if (have_usable_route) - { - /* - * Make monitor - * - * TBD factor this out into its own function - */ - struct prefix *pfx_mon = prefix_new (); - if (!RFAPI_MONITOR_EXTERIOR (rn)->source) - { - RFAPI_MONITOR_EXTERIOR (rn)->source = - skiplist_new (0, NULL, (void (*)(void *)) prefix_free); - route_lock_node (rn); /* for skiplist */ - } - route_lock_node (rn); /* for skiplist entry */ - prefix_copy (pfx_mon, prefix); - if (!skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn)->source, - info, pfx_mon)) - { - - bgp_info_lock (info); - } - } - par = rn->parent; - if (par) - route_lock_node (par); - route_unlock_node (rn); - rn = par; - } - if (rn) - route_unlock_node (rn); - - if (!have_usable_route) - { - struct prefix *pfx_mon = prefix_new (); - prefix_copy (pfx_mon, prefix); - if (!skiplist_insert (it->monitor_exterior_orphans, info, pfx_mon)) - { - - bgp_info_lock (info); - } - } - } + struct rfapi *h; + struct rfapi_cfg *hc; + struct prefix pfx_orig_nexthop; + struct rfapi_import_table *it; + struct bgp *bgp_default = bgp_get_default(); + afi_t afi = family2afi(prefix->family); + + if (!bgp_default) + return; + + h = bgp_default->rfapi; + hc = bgp_default->rfapi_cfg; + + vnc_zlog_debug_verbose("%s: entry with it=%p", __func__, it_only); + + if (!h || !hc) { + vnc_zlog_debug_verbose( + "%s: rfapi or rfapi_cfg not instantiated, skipping", + __func__); + return; + } + if (!hc->redist_bgp_exterior_view) { + vnc_zlog_debug_verbose("%s: exterior view not set, skipping", + __func__); + return; + } + if (bgp != hc->redist_bgp_exterior_view) { + vnc_zlog_debug_verbose( + "%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping", + __func__, bgp, hc->redist_bgp_exterior_view); + return; + } + + if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vnc_zlog_debug_verbose( + "%s: redist of exterior routes not enabled, skipping", + __func__); + return; + } + + if (!info->attr) { + vnc_zlog_debug_verbose("%s: no info, skipping", __func__); + return; + } + + /* + * Extract nexthop from exterior route + * + * Incoming prefix is unicast. If v6, it is in multiprotocol area, + * but if v4 it is in attr->nexthop + */ + rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_orig_nexthop); + + for (it = h->imports; it; it = it->next) { + struct route_table *table; + struct route_node *rn; + struct route_node *par; + struct bgp_info *bi_interior; + int have_usable_route; + + vnc_zlog_debug_verbose("%s: doing it %p", __func__, it); + + if (it_only && (it_only != it)) { + vnc_zlog_debug_verbose("%s: doesn't match it_only %p", + __func__, it_only); + continue; + } + + table = it->imported_vpn[afi]; + + for (rn = route_node_match(table, &pfx_orig_nexthop), + have_usable_route = 0; + (!have_usable_route) && rn;) { + + vnc_zlog_debug_verbose("%s: it %p trying rn %p", + __func__, it, rn); + + for (bi_interior = rn->info; bi_interior; + bi_interior = bi_interior->next) { + struct prefix_rd *prd; + struct attr new_attr; + u_int32_t label = 0; + + if (!is_usable_interior_route(bi_interior)) + continue; + + vnc_zlog_debug_verbose( + "%s: usable: bi_interior %p", __func__, + bi_interior); + + /* + * have a legitimate route to exterior's nexthop + * via NVE. + * + * Import unicast route to the import table + */ + have_usable_route = 1; + + if (bi_interior->extra) { + prd = &bi_interior->extra->vnc.import + .rd; + label = decode_label( + &bi_interior->extra->label); + } else + prd = NULL; + + /* use local_pref from unicast route */ + memset(&new_attr, 0, sizeof(struct attr)); + bgp_attr_dup(&new_attr, bi_interior->attr); + if (info->attr->flag + & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { + new_attr.local_pref = + info->attr->local_pref; + new_attr.flag |= ATTR_FLAG_BIT( + BGP_ATTR_LOCAL_PREF); + } + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_UPDATE, + bi_interior->peer, NULL, /* rfd */ + prefix, NULL, afi, prd, &new_attr, + ZEBRA_ROUTE_BGP_DIRECT_EXT, + BGP_ROUTE_REDISTRIBUTE, &label); + } + + if (have_usable_route) { + /* + * Make monitor + * + * TBD factor this out into its own function + */ + struct prefix *pfx_mon = prefix_new(); + if (!RFAPI_MONITOR_EXTERIOR(rn)->source) { + RFAPI_MONITOR_EXTERIOR(rn)->source = + skiplist_new( + 0, NULL, + (void (*)(void *)) + prefix_free); + route_lock_node(rn); /* for skiplist */ + } + route_lock_node(rn); /* for skiplist entry */ + prefix_copy(pfx_mon, prefix); + if (!skiplist_insert( + RFAPI_MONITOR_EXTERIOR(rn)->source, + info, pfx_mon)) { + + bgp_info_lock(info); + } + } + par = rn->parent; + if (par) + route_lock_node(par); + route_unlock_node(rn); + rn = par; + } + if (rn) + route_unlock_node(rn); + + if (!have_usable_route) { + struct prefix *pfx_mon = prefix_new(); + prefix_copy(pfx_mon, prefix); + if (!skiplist_insert(it->monitor_exterior_orphans, info, + pfx_mon)) { + + bgp_info_lock(info); + } + } + } } -void -vnc_import_bgp_exterior_add_route ( - struct bgp *bgp, /* exterior instance, we hope */ - struct prefix *prefix,/* unicast prefix */ - struct bgp_info *info) /* unicast info */ +void vnc_import_bgp_exterior_add_route( + struct bgp *bgp, /* exterior instance, we hope */ + struct prefix *prefix, /* unicast prefix */ + struct bgp_info *info) /* unicast info */ { - vnc_import_bgp_exterior_add_route_it (bgp, prefix, info, NULL); + vnc_import_bgp_exterior_add_route_it(bgp, prefix, info, NULL); } /* @@ -2001,155 +1890,163 @@ vnc_import_bgp_exterior_add_route ( * We filter here on the instance name to make sure we get only the * right routes. */ -void -vnc_import_bgp_exterior_del_route ( - struct bgp *bgp, - struct prefix *prefix, /* unicast prefix */ - struct bgp_info *info) /* unicast info */ +void vnc_import_bgp_exterior_del_route( + struct bgp *bgp, struct prefix *prefix, /* unicast prefix */ + struct bgp_info *info) /* unicast info */ { - struct rfapi *h; - struct rfapi_cfg *hc; - struct rfapi_import_table *it; - struct prefix pfx_orig_nexthop; - afi_t afi = family2afi (prefix->family); - struct bgp *bgp_default = bgp_get_default (); - - if (!bgp_default) - return; - - memset (&pfx_orig_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */ - - h = bgp_default->rfapi; - hc = bgp_default->rfapi_cfg; - - if (!h || !hc) - { - vnc_zlog_debug_verbose ("%s: rfapi or rfapi_cfg not instantiated, skipping", - __func__); - return; - } - if (!hc->redist_bgp_exterior_view) - { - vnc_zlog_debug_verbose ("%s: exterior view not set, skipping", __func__); - return; - } - if (bgp != hc->redist_bgp_exterior_view) - { - vnc_zlog_debug_verbose ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping", - __func__, bgp, hc->redist_bgp_exterior_view); - return; - } - if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping", - __func__); - return; - } - - if (!info->attr) - { - vnc_zlog_debug_verbose ("%s: no info, skipping", __func__); - return; - } - - /* - * Extract nexthop from exterior route - * - * Incoming prefix is unicast. If v6, it is in multiprotocol area, - * but if v4 it is in attr->nexthop - */ - rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_orig_nexthop); - - for (it = h->imports; it; it = it->next) - { - struct route_table *table; - struct route_node *rn; - struct route_node *par; - struct bgp_info *bi_interior; - int have_usable_route; - - table = it->imported_vpn[afi]; - - for (rn = route_node_match (table, &pfx_orig_nexthop), - have_usable_route = 0; (!have_usable_route) && rn;) - { - - for (bi_interior = rn->info; bi_interior; - bi_interior = bi_interior->next) - { - struct prefix_rd *prd; - u_int32_t label = 0; - - if (!is_usable_interior_route (bi_interior)) - continue; - - /* - * have a legitimate route to exterior's nexthop - * via NVE. - * - * Import unicast route to the import table - */ - have_usable_route = 1; - - if (bi_interior->extra) - { - prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (&bi_interior->extra->label); - } - else - prd = NULL; - - rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi_interior->peer, NULL, /* rfd */ - prefix, - NULL, - afi, - prd, - bi_interior->attr, - ZEBRA_ROUTE_BGP_DIRECT_EXT, - BGP_ROUTE_REDISTRIBUTE, &label); - - /* - * Delete monitor - * - * TBD factor this out into its own function - */ - { - if (RFAPI_MONITOR_EXTERIOR (rn)->source) - { - if (!skiplist_delete (RFAPI_MONITOR_EXTERIOR (rn)->source, - info, NULL)) - { - - bgp_info_unlock (info); - route_unlock_node (rn); /* sl entry */ - } - if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn)->source)) - { - skiplist_free (RFAPI_MONITOR_EXTERIOR (rn)->source); - RFAPI_MONITOR_EXTERIOR (rn)->source = NULL; - route_unlock_node (rn); /* skiplist itself */ - } - } - } - } - par = rn->parent; - if (par) - route_lock_node (par); - route_unlock_node (rn); - rn = par; - } - if (rn) - route_unlock_node (rn); - - if (!have_usable_route) - { - if (!skiplist_delete (it->monitor_exterior_orphans, info, NULL)) - { - - bgp_info_unlock (info); - } - } - } + struct rfapi *h; + struct rfapi_cfg *hc; + struct rfapi_import_table *it; + struct prefix pfx_orig_nexthop; + afi_t afi = family2afi(prefix->family); + struct bgp *bgp_default = bgp_get_default(); + + if (!bgp_default) + return; + + memset(&pfx_orig_nexthop, 0, + sizeof(struct prefix)); /* keep valgrind happy */ + + h = bgp_default->rfapi; + hc = bgp_default->rfapi_cfg; + + if (!h || !hc) { + vnc_zlog_debug_verbose( + "%s: rfapi or rfapi_cfg not instantiated, skipping", + __func__); + return; + } + if (!hc->redist_bgp_exterior_view) { + vnc_zlog_debug_verbose("%s: exterior view not set, skipping", + __func__); + return; + } + if (bgp != hc->redist_bgp_exterior_view) { + vnc_zlog_debug_verbose( + "%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping", + __func__, bgp, hc->redist_bgp_exterior_view); + return; + } + if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vnc_zlog_debug_verbose( + "%s: redist of exterior routes no enabled, skipping", + __func__); + return; + } + + if (!info->attr) { + vnc_zlog_debug_verbose("%s: no info, skipping", __func__); + return; + } + + /* + * Extract nexthop from exterior route + * + * Incoming prefix is unicast. If v6, it is in multiprotocol area, + * but if v4 it is in attr->nexthop + */ + rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_orig_nexthop); + + for (it = h->imports; it; it = it->next) { + struct route_table *table; + struct route_node *rn; + struct route_node *par; + struct bgp_info *bi_interior; + int have_usable_route; + + table = it->imported_vpn[afi]; + + for (rn = route_node_match(table, &pfx_orig_nexthop), + have_usable_route = 0; + (!have_usable_route) && rn;) { + + for (bi_interior = rn->info; bi_interior; + bi_interior = bi_interior->next) { + struct prefix_rd *prd; + u_int32_t label = 0; + + if (!is_usable_interior_route(bi_interior)) + continue; + + /* + * have a legitimate route to exterior's nexthop + * via NVE. + * + * Import unicast route to the import table + */ + have_usable_route = 1; + + if (bi_interior->extra) { + prd = &bi_interior->extra->vnc.import + .rd; + label = decode_label( + &bi_interior->extra->label); + } else + prd = NULL; + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_KILL, bi_interior->peer, + NULL, /* rfd */ + prefix, NULL, afi, prd, + bi_interior->attr, + ZEBRA_ROUTE_BGP_DIRECT_EXT, + BGP_ROUTE_REDISTRIBUTE, &label); + + /* + * Delete monitor + * + * TBD factor this out into its own function + */ + { + if (RFAPI_MONITOR_EXTERIOR(rn) + ->source) { + if (!skiplist_delete( + RFAPI_MONITOR_EXTERIOR( + rn) + ->source, + info, NULL)) { + + bgp_info_unlock(info); + route_unlock_node( + rn); /* sl entry + */ + } + if (skiplist_empty( + RFAPI_MONITOR_EXTERIOR( + rn) + ->source)) { + skiplist_free( + RFAPI_MONITOR_EXTERIOR( + rn) + ->source); + RFAPI_MONITOR_EXTERIOR( + rn) + ->source = NULL; + route_unlock_node( + rn); /* skiplist + itself + */ + } + } + } + } + par = rn->parent; + if (par) + route_lock_node(par); + route_unlock_node(rn); + rn = par; + } + if (rn) + route_unlock_node(rn); + + if (!have_usable_route) { + if (!skiplist_delete(it->monitor_exterior_orphans, info, + NULL)) { + + bgp_info_unlock(info); + } + } + } } /* @@ -2159,387 +2056,378 @@ vnc_import_bgp_exterior_del_route ( * NB should also be called whenever an existing vpn interior route * becomes valid (e.g., valid_interior_count is inremented) */ -void -vnc_import_bgp_exterior_add_route_interior ( - struct bgp *bgp, - struct rfapi_import_table *it, - struct route_node *rn_interior, /* VPN IT node */ - struct bgp_info *bi_interior) /* VPN IT route */ +void vnc_import_bgp_exterior_add_route_interior( + struct bgp *bgp, struct rfapi_import_table *it, + struct route_node *rn_interior, /* VPN IT node */ + struct bgp_info *bi_interior) /* VPN IT route */ { - afi_t afi = family2afi (rn_interior->p.family); - struct route_node *par; - struct bgp_info *bi_exterior; - struct prefix *pfx_exterior; /* exterior pfx */ - void *cursor; - int rc; - struct list *list_adopted; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - - if (!is_usable_interior_route (bi_interior)) - { - vnc_zlog_debug_verbose ("%s: not usable interior route, skipping", __func__); - return; - } - - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping", - __func__); - return; - } - - if (it == bgp->rfapi->it_ce) - { - vnc_zlog_debug_verbose ("%s: import table is it_ce, skipping", __func__); - return; - } - - /*debugging */ - { - char str_pfx[BUFSIZ]; - - prefix2str (&rn_interior->p, str_pfx, BUFSIZ); - str_pfx[BUFSIZ - 1] = 0; - - vnc_zlog_debug_verbose ("%s: interior prefix=%s, bi type=%d", - __func__, str_pfx, bi_interior->type); - } - - if (RFAPI_HAS_MONITOR_EXTERIOR (rn_interior)) - { - - int count = 0; /* debugging */ - - vnc_zlog_debug_verbose ("%s: has exterior monitor; ext src: %p", __func__, - RFAPI_MONITOR_EXTERIOR (rn_interior)->source); - - /* - * There is a monitor here already. Therefore, we do not need - * to do any pulldown. Just construct exterior routes based - * on the new interior route. - */ - cursor = NULL; - for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - (void **) &bi_exterior, - (void **) &pfx_exterior, &cursor); !rc; - rc = - skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - (void **) &bi_exterior, (void **) &pfx_exterior, - &cursor)) - { - - struct prefix_rd *prd; - struct attr new_attr; - u_int32_t label = 0; - - - ++count; /* debugging */ - - assert (bi_exterior); - assert (pfx_exterior); - - if (bi_interior->extra) - { - prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (&bi_interior->extra->label); - } - else - prd = NULL; - - /* use local_pref from unicast route */ - memset (&new_attr, 0, sizeof (struct attr)); - bgp_attr_dup (&new_attr, bi_interior->attr); - if (bi_exterior && - (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) - { - new_attr.local_pref = bi_exterior->attr->local_pref; - new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); - } - - rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL, /* rfd */ - pfx_exterior, - NULL, - afi, - prd, - &new_attr, - ZEBRA_ROUTE_BGP_DIRECT_EXT, - BGP_ROUTE_REDISTRIBUTE, &label); - - } - vnc_zlog_debug_verbose - ("%s: finished constructing exteriors based on existing monitors", - __func__); - return; - } - - vnc_zlog_debug_verbose ("%s: no exterior monitor", __func__); - - /* - * No monitor at this node. Is this the first valid interior - * route at this node? - */ - if (RFAPI_MONITOR_EXTERIOR (rn_interior)->valid_interior_count > 1) - { - vnc_zlog_debug_verbose - ("%s: new interior route not first valid one, skipping pulldown", - __func__); - return; - } - - /* - * Look up the tree for possible pulldown candidates. - * Find nearest parent with an exterior route monitor - */ - for (par = rn_interior->parent; par; par = par->parent) - { - if (RFAPI_HAS_MONITOR_EXTERIOR (par)) - break; - } - - if (par) - { - - vnc_zlog_debug_verbose ("%s: checking parent %p for possible pulldowns", - __func__, par); - - /* check monitors at par for possible pulldown */ - cursor = NULL; - for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (par)->source, - (void **) &bi_exterior, - (void **) &pfx_exterior, &cursor); !rc; - rc = - skiplist_next (RFAPI_MONITOR_EXTERIOR (par)->source, - (void **) &bi_exterior, (void **) &pfx_exterior, - &cursor)) - { - - struct prefix pfx_nexthop; - - memset (&pfx_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */ - - /* check original nexthop for prefix match */ - rfapiUnicastNexthop2Prefix (afi, bi_exterior->attr, &pfx_nexthop); - - if (prefix_match (&rn_interior->p, &pfx_nexthop)) - { - - struct bgp_info *bi; - struct prefix_rd *prd; - struct attr new_attr; - u_int32_t label = 0; - - /* do pull-down */ - - /* - * add monitor to longer prefix - */ - struct prefix *pfx_mon = prefix_new (); - prefix_copy (pfx_mon, pfx_exterior); - if (!RFAPI_MONITOR_EXTERIOR (rn_interior)->source) - { - RFAPI_MONITOR_EXTERIOR (rn_interior)->source = - skiplist_new (0, NULL, (void (*)(void *)) prefix_free); - route_lock_node (rn_interior); - } - skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - bi_exterior, pfx_mon); - route_lock_node (rn_interior); - - /* - * Delete constructed exterior routes based on - * parent routes. - */ - for (bi = par->info; bi; bi = bi->next) - { - - if (bi->extra) - { - prd = &bi->extra->vnc.import.rd; - label = decode_label (&bi->extra->label); - } - else - prd = NULL; - - rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi->peer, NULL, /* rfd */ - pfx_exterior, - NULL, - afi, - prd, - bi->attr, - ZEBRA_ROUTE_BGP_DIRECT_EXT, - BGP_ROUTE_REDISTRIBUTE, - &label); - } - - - /* - * Add constructed exterior routes based on - * the new interior route at longer prefix. - */ - if (bi_interior->extra) - { - prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (&bi_interior->extra->label); - } - else - prd = NULL; - - /* use local_pref from unicast route */ - memset (&new_attr, 0, sizeof (struct attr)); - bgp_attr_dup (&new_attr, bi_interior->attr); - if (bi_exterior && - (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) - { - new_attr.local_pref = bi_exterior->attr->local_pref; - new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); - } - - rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL, /* rfd */ - pfx_exterior, - NULL, - afi, - prd, - &new_attr, - ZEBRA_ROUTE_BGP_DIRECT_EXT, - BGP_ROUTE_REDISTRIBUTE, &label); - - } - } - - /* - * The only monitors at rn_interior are the ones we added just - * above, so we can use the rn_interior list to identify which - * monitors to delete from the parent. - */ - cursor = NULL; - for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - (void **) &bi_exterior, NULL, &cursor); - !rc; - rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - (void **) &bi_exterior, NULL, &cursor)) - { - - - skiplist_delete (RFAPI_MONITOR_EXTERIOR (par)->source, - bi_exterior, NULL); - route_unlock_node (par); /* sl entry */ - } - if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (par)->source)) - { - skiplist_free (RFAPI_MONITOR_EXTERIOR (par)->source); - RFAPI_MONITOR_EXTERIOR (par)->source = NULL; - route_unlock_node (par); /* sl itself */ - } - } - - vnc_zlog_debug_verbose ("%s: checking orphans", __func__); - - /* - * See if any orphans can be pulled down to the current node - */ - cursor = NULL; - list_adopted = NULL; - for (rc = skiplist_next (it->monitor_exterior_orphans, - (void **) &bi_exterior, (void **) &pfx_exterior, - &cursor); !rc; - rc = - skiplist_next (it->monitor_exterior_orphans, (void **) &bi_exterior, - (void **) &pfx_exterior, &cursor)) - { - - struct prefix pfx_nexthop; - char buf[BUFSIZ]; - afi_t afi_exterior = family2afi (pfx_exterior->family); - - prefix2str (pfx_exterior, buf, sizeof (buf)); - buf[sizeof (buf) - 1] = 0; - vnc_zlog_debug_verbose ("%s: checking exterior orphan at prefix %s", __func__, buf); - - if (afi_exterior != afi) - { - vnc_zlog_debug_verbose ("%s: exterior orphan afi %d != interior afi %d, skip", - __func__, afi_exterior, afi); - continue; - } - - /* check original nexthop for prefix match */ - rfapiUnicastNexthop2Prefix (afi, bi_exterior->attr, &pfx_nexthop); - - if (prefix_match (&rn_interior->p, &pfx_nexthop)) - { - - struct prefix_rd *prd; - struct attr new_attr; - u_int32_t label = 0; - - /* do pull-down */ - - /* - * add monitor to longer prefix - */ - - struct prefix *pfx_mon = prefix_new (); - prefix_copy (pfx_mon, pfx_exterior); - if (!RFAPI_MONITOR_EXTERIOR (rn_interior)->source) - { - RFAPI_MONITOR_EXTERIOR (rn_interior)->source = - skiplist_new (0, NULL, (void (*)(void *)) prefix_free); - route_lock_node (rn_interior); /* sl */ - } - skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - bi_exterior, pfx_mon); - route_lock_node (rn_interior); /* sl entry */ - if (!list_adopted) - { - list_adopted = list_new (); - } - listnode_add (list_adopted, bi_exterior); - - /* - * Add constructed exterior routes based on the - * new interior route at the longer prefix. - */ - if (bi_interior->extra) - { - prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (&bi_interior->extra->label); - } - else - prd = NULL; - - /* use local_pref from unicast route */ - memset (&new_attr, 0, sizeof (struct attr)); - bgp_attr_dup (&new_attr, bi_interior->attr); - if (bi_exterior && - (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) - { - new_attr.local_pref = bi_exterior->attr->local_pref; - new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); - } - - rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL, /* rfd */ - pfx_exterior, - NULL, - afi, - prd, - &new_attr, - ZEBRA_ROUTE_BGP_DIRECT_EXT, - BGP_ROUTE_REDISTRIBUTE, &label); - - } - } - if (list_adopted) - { - struct listnode *node; - struct route_node *bi_exterior; - - for (ALL_LIST_ELEMENTS_RO (list_adopted, node, bi_exterior)) - { - skiplist_delete (it->monitor_exterior_orphans, bi_exterior, NULL); - } - list_delete (list_adopted); - } + afi_t afi = family2afi(rn_interior->p.family); + struct route_node *par; + struct bgp_info *bi_exterior; + struct prefix *pfx_exterior; /* exterior pfx */ + void *cursor; + int rc; + struct list *list_adopted; + + vnc_zlog_debug_verbose("%s: entry", __func__); + + if (!is_usable_interior_route(bi_interior)) { + vnc_zlog_debug_verbose( + "%s: not usable interior route, skipping", __func__); + return; + } + + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vnc_zlog_debug_verbose( + "%s: redist of exterior routes no enabled, skipping", + __func__); + return; + } + + if (it == bgp->rfapi->it_ce) { + vnc_zlog_debug_verbose("%s: import table is it_ce, skipping", + __func__); + return; + } + + /*debugging */ + { + char str_pfx[BUFSIZ]; + + prefix2str(&rn_interior->p, str_pfx, BUFSIZ); + str_pfx[BUFSIZ - 1] = 0; + + vnc_zlog_debug_verbose("%s: interior prefix=%s, bi type=%d", + __func__, str_pfx, bi_interior->type); + } + + if (RFAPI_HAS_MONITOR_EXTERIOR(rn_interior)) { + + int count = 0; /* debugging */ + + vnc_zlog_debug_verbose( + "%s: has exterior monitor; ext src: %p", __func__, + RFAPI_MONITOR_EXTERIOR(rn_interior)->source); + + /* + * There is a monitor here already. Therefore, we do not need + * to do any pulldown. Just construct exterior routes based + * on the new interior route. + */ + cursor = NULL; + for (rc = skiplist_next( + RFAPI_MONITOR_EXTERIOR(rn_interior)->source, + (void **)&bi_exterior, (void **)&pfx_exterior, + &cursor); + !rc; rc = skiplist_next( + RFAPI_MONITOR_EXTERIOR(rn_interior)->source, + (void **)&bi_exterior, (void **)&pfx_exterior, + &cursor)) { + + struct prefix_rd *prd; + struct attr new_attr; + u_int32_t label = 0; + + + ++count; /* debugging */ + + assert(bi_exterior); + assert(pfx_exterior); + + if (bi_interior->extra) { + prd = &bi_interior->extra->vnc.import.rd; + label = decode_label( + &bi_interior->extra->label); + } else + prd = NULL; + + /* use local_pref from unicast route */ + memset(&new_attr, 0, sizeof(struct attr)); + bgp_attr_dup(&new_attr, bi_interior->attr); + if (bi_exterior + && (bi_exterior->attr->flag + & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { + new_attr.local_pref = + bi_exterior->attr->local_pref; + new_attr.flag |= + ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); + } + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_UPDATE, bi_interior->peer, + NULL, /* rfd */ + pfx_exterior, NULL, afi, prd, &new_attr, + ZEBRA_ROUTE_BGP_DIRECT_EXT, + BGP_ROUTE_REDISTRIBUTE, &label); + } + vnc_zlog_debug_verbose( + "%s: finished constructing exteriors based on existing monitors", + __func__); + return; + } + + vnc_zlog_debug_verbose("%s: no exterior monitor", __func__); + + /* + * No monitor at this node. Is this the first valid interior + * route at this node? + */ + if (RFAPI_MONITOR_EXTERIOR(rn_interior)->valid_interior_count > 1) { + vnc_zlog_debug_verbose( + "%s: new interior route not first valid one, skipping pulldown", + __func__); + return; + } + + /* + * Look up the tree for possible pulldown candidates. + * Find nearest parent with an exterior route monitor + */ + for (par = rn_interior->parent; par; par = par->parent) { + if (RFAPI_HAS_MONITOR_EXTERIOR(par)) + break; + } + + if (par) { + + vnc_zlog_debug_verbose( + "%s: checking parent %p for possible pulldowns", + __func__, par); + + /* check monitors at par for possible pulldown */ + cursor = NULL; + for (rc = skiplist_next(RFAPI_MONITOR_EXTERIOR(par)->source, + (void **)&bi_exterior, + (void **)&pfx_exterior, &cursor); + !rc; + rc = skiplist_next(RFAPI_MONITOR_EXTERIOR(par)->source, + (void **)&bi_exterior, + (void **)&pfx_exterior, &cursor)) { + + struct prefix pfx_nexthop; + + memset(&pfx_nexthop, 0, + sizeof(struct prefix)); /* keep valgrind happy */ + + /* check original nexthop for prefix match */ + rfapiUnicastNexthop2Prefix(afi, bi_exterior->attr, + &pfx_nexthop); + + if (prefix_match(&rn_interior->p, &pfx_nexthop)) { + + struct bgp_info *bi; + struct prefix_rd *prd; + struct attr new_attr; + u_int32_t label = 0; + + /* do pull-down */ + + /* + * add monitor to longer prefix + */ + struct prefix *pfx_mon = prefix_new(); + prefix_copy(pfx_mon, pfx_exterior); + if (!RFAPI_MONITOR_EXTERIOR(rn_interior) + ->source) { + RFAPI_MONITOR_EXTERIOR(rn_interior) + ->source = skiplist_new( + 0, NULL, + (void (*)(void *))prefix_free); + route_lock_node(rn_interior); + } + skiplist_insert( + RFAPI_MONITOR_EXTERIOR(rn_interior) + ->source, + bi_exterior, pfx_mon); + route_lock_node(rn_interior); + + /* + * Delete constructed exterior routes based on + * parent routes. + */ + for (bi = par->info; bi; bi = bi->next) { + + if (bi->extra) { + prd = &bi->extra->vnc.import.rd; + label = decode_label( + &bi->extra->label); + } else + prd = NULL; + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_KILL, bi->peer, + NULL, /* rfd */ + pfx_exterior, NULL, afi, prd, + bi->attr, + ZEBRA_ROUTE_BGP_DIRECT_EXT, + BGP_ROUTE_REDISTRIBUTE, &label); + } + + + /* + * Add constructed exterior routes based on + * the new interior route at longer prefix. + */ + if (bi_interior->extra) { + prd = &bi_interior->extra->vnc.import + .rd; + label = decode_label( + &bi_interior->extra->label); + } else + prd = NULL; + + /* use local_pref from unicast route */ + memset(&new_attr, 0, sizeof(struct attr)); + bgp_attr_dup(&new_attr, bi_interior->attr); + if (bi_exterior + && (bi_exterior->attr->flag + & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { + new_attr.local_pref = + bi_exterior->attr->local_pref; + new_attr.flag |= ATTR_FLAG_BIT( + BGP_ATTR_LOCAL_PREF); + } + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_UPDATE, + bi_interior->peer, NULL, /* rfd */ + pfx_exterior, NULL, afi, prd, &new_attr, + ZEBRA_ROUTE_BGP_DIRECT_EXT, + BGP_ROUTE_REDISTRIBUTE, &label); + } + } + + /* + * The only monitors at rn_interior are the ones we added just + * above, so we can use the rn_interior list to identify which + * monitors to delete from the parent. + */ + cursor = NULL; + for (rc = skiplist_next( + RFAPI_MONITOR_EXTERIOR(rn_interior)->source, + (void **)&bi_exterior, NULL, &cursor); + !rc; rc = skiplist_next( + RFAPI_MONITOR_EXTERIOR(rn_interior)->source, + (void **)&bi_exterior, NULL, &cursor)) { + + + skiplist_delete(RFAPI_MONITOR_EXTERIOR(par)->source, + bi_exterior, NULL); + route_unlock_node(par); /* sl entry */ + } + if (skiplist_empty(RFAPI_MONITOR_EXTERIOR(par)->source)) { + skiplist_free(RFAPI_MONITOR_EXTERIOR(par)->source); + RFAPI_MONITOR_EXTERIOR(par)->source = NULL; + route_unlock_node(par); /* sl itself */ + } + } + + vnc_zlog_debug_verbose("%s: checking orphans", __func__); + + /* + * See if any orphans can be pulled down to the current node + */ + cursor = NULL; + list_adopted = NULL; + for (rc = skiplist_next(it->monitor_exterior_orphans, + (void **)&bi_exterior, (void **)&pfx_exterior, + &cursor); + !rc; rc = skiplist_next(it->monitor_exterior_orphans, + (void **)&bi_exterior, + (void **)&pfx_exterior, &cursor)) { + + struct prefix pfx_nexthop; + char buf[BUFSIZ]; + afi_t afi_exterior = family2afi(pfx_exterior->family); + + prefix2str(pfx_exterior, buf, sizeof(buf)); + buf[sizeof(buf) - 1] = 0; + vnc_zlog_debug_verbose( + "%s: checking exterior orphan at prefix %s", __func__, + buf); + + if (afi_exterior != afi) { + vnc_zlog_debug_verbose( + "%s: exterior orphan afi %d != interior afi %d, skip", + __func__, afi_exterior, afi); + continue; + } + + /* check original nexthop for prefix match */ + rfapiUnicastNexthop2Prefix(afi, bi_exterior->attr, + &pfx_nexthop); + + if (prefix_match(&rn_interior->p, &pfx_nexthop)) { + + struct prefix_rd *prd; + struct attr new_attr; + u_int32_t label = 0; + + /* do pull-down */ + + /* + * add monitor to longer prefix + */ + + struct prefix *pfx_mon = prefix_new(); + prefix_copy(pfx_mon, pfx_exterior); + if (!RFAPI_MONITOR_EXTERIOR(rn_interior)->source) { + RFAPI_MONITOR_EXTERIOR(rn_interior)->source = + skiplist_new( + 0, NULL, + (void (*)(void *))prefix_free); + route_lock_node(rn_interior); /* sl */ + } + skiplist_insert( + RFAPI_MONITOR_EXTERIOR(rn_interior)->source, + bi_exterior, pfx_mon); + route_lock_node(rn_interior); /* sl entry */ + if (!list_adopted) { + list_adopted = list_new(); + } + listnode_add(list_adopted, bi_exterior); + + /* + * Add constructed exterior routes based on the + * new interior route at the longer prefix. + */ + if (bi_interior->extra) { + prd = &bi_interior->extra->vnc.import.rd; + label = decode_label( + &bi_interior->extra->label); + } else + prd = NULL; + + /* use local_pref from unicast route */ + memset(&new_attr, 0, sizeof(struct attr)); + bgp_attr_dup(&new_attr, bi_interior->attr); + if (bi_exterior + && (bi_exterior->attr->flag + & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { + new_attr.local_pref = + bi_exterior->attr->local_pref; + new_attr.flag |= + ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); + } + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_UPDATE, bi_interior->peer, + NULL, /* rfd */ + pfx_exterior, NULL, afi, prd, &new_attr, + ZEBRA_ROUTE_BGP_DIRECT_EXT, + BGP_ROUTE_REDISTRIBUTE, &label); + } + } + if (list_adopted) { + struct listnode *node; + struct route_node *bi_exterior; + + for (ALL_LIST_ELEMENTS_RO(list_adopted, node, bi_exterior)) { + skiplist_delete(it->monitor_exterior_orphans, + bi_exterior, NULL); + } + list_delete(list_adopted); + } } /* @@ -2552,348 +2440,327 @@ vnc_import_bgp_exterior_add_route_interior ( * NB should also be called whenever an existing vpn interior route * becomes invalid (e.g., valid_interior_count is decremented) */ -void -vnc_import_bgp_exterior_del_route_interior ( - struct bgp *bgp, - struct rfapi_import_table *it, - struct route_node *rn_interior, /* VPN IT node */ - struct bgp_info *bi_interior) /* VPN IT route */ +void vnc_import_bgp_exterior_del_route_interior( + struct bgp *bgp, struct rfapi_import_table *it, + struct route_node *rn_interior, /* VPN IT node */ + struct bgp_info *bi_interior) /* VPN IT route */ { - afi_t afi = family2afi (rn_interior->p.family); - struct route_node *par; - struct bgp_info *bi_exterior; - struct prefix *pfx_exterior; /* exterior pfx */ - void *cursor; - int rc; - - if (!VALID_INTERIOR_TYPE (bi_interior->type)) - { - vnc_zlog_debug_verbose ("%s: type %d not valid interior type, skipping", - __func__, bi_interior->type); - return; - } - - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping", - __func__); - return; - } - - if (it == bgp->rfapi->it_ce) - { - vnc_zlog_debug_verbose ("%s: it is it_ce, skipping", __func__); - return; - } - - /* If no exterior routes depend on this prefix, nothing to do */ - if (!RFAPI_HAS_MONITOR_EXTERIOR (rn_interior)) - { - vnc_zlog_debug_verbose ("%s: no exterior monitor, skipping", __func__); - return; - } - - /*debugging */ - { - char str_pfx[BUFSIZ]; - - prefix2str (&rn_interior->p, str_pfx, BUFSIZ); - str_pfx[BUFSIZ - 1] = 0; - - vnc_zlog_debug_verbose ("%s: interior prefix=%s, bi type=%d", - __func__, str_pfx, bi_interior->type); - } - - /* - * Remove constructed routes based on the deleted interior route - */ - cursor = NULL; - for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - (void **) &bi_exterior, (void **) &pfx_exterior, - &cursor); !rc; - rc = - skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - (void **) &bi_exterior, (void **) &pfx_exterior, - &cursor)) - { - - struct prefix_rd *prd; - u_int32_t label = 0; - - if (bi_interior->extra) - { - prd = &bi_interior->extra->vnc.import.rd; - label = decode_label (&bi_interior->extra->label); - } - else - prd = NULL; - - rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi_interior->peer, NULL, /* rfd */ - pfx_exterior, - NULL, - afi, - prd, - bi_interior->attr, - ZEBRA_ROUTE_BGP_DIRECT_EXT, - BGP_ROUTE_REDISTRIBUTE, &label); - } - - /* - * If there are no remaining valid interior routes at this prefix, - * we need to look up the tree for a possible node to move monitors to - */ - if (RFAPI_MONITOR_EXTERIOR (rn_interior)->valid_interior_count) - { - vnc_zlog_debug_verbose ("%s: interior routes still present, skipping", __func__); - return; - } - - /* - * Find nearest parent with at least one valid interior route - * If none is found, par will end up NULL, and we will move - * the monitors to the orphan list for this import table - */ - for (par = rn_interior->parent; par; par = par->parent) - { - if (RFAPI_MONITOR_EXTERIOR (par)->valid_interior_count) - break; - } - - vnc_zlog_debug_verbose ("%s: par=%p, ext src: %p", __func__, - par, RFAPI_MONITOR_EXTERIOR (rn_interior)->source); - - /* move all monitors */ - /* - * We will use and delete every element of the source skiplist - */ - while (!skiplist_first (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, - (void **) &bi_exterior, (void **) &pfx_exterior)) - { - - struct prefix *pfx_mon = prefix_new (); - - prefix_copy (pfx_mon, pfx_exterior); - - if (par) - { - - struct bgp_info *bi; - - /* - * Add monitor to parent node - */ - if (!RFAPI_MONITOR_EXTERIOR (par)->source) - { - RFAPI_MONITOR_EXTERIOR (par)->source = - skiplist_new (0, NULL, (void (*)(void *)) prefix_free); - route_lock_node (par); /* sl */ - } - skiplist_insert (RFAPI_MONITOR_EXTERIOR (par)->source, - bi_exterior, pfx_mon); - route_lock_node (par); /* sl entry */ - - /* Add constructed exterior routes based on parent */ - for (bi = par->info; bi; bi = bi->next) - { - - struct prefix_rd *prd; - struct attr new_attr; - u_int32_t label = 0; - - if (bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) - continue; - - if (bi->extra) - { - prd = &bi->extra->vnc.import.rd; - label = decode_label (&bi->extra->label); - } - else - prd = NULL; - - /* use local_pref from unicast route */ - memset (&new_attr, 0, sizeof (struct attr)); - bgp_attr_dup (&new_attr, bi->attr); - if (bi_exterior && - (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) - { - new_attr.local_pref = bi_exterior->attr->local_pref; - new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); - } - - rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi->peer, NULL, /* rfd */ - pfx_exterior, - NULL, - afi, - prd, - &new_attr, - ZEBRA_ROUTE_BGP_DIRECT_EXT, - BGP_ROUTE_REDISTRIBUTE, &label); - - } - - } - else - { - - /* - * No interior route for exterior's nexthop. Save monitor - * in orphan list to await future route. - */ - skiplist_insert (it->monitor_exterior_orphans, - bi_exterior, pfx_mon); - } - - skiplist_delete_first (RFAPI_MONITOR_EXTERIOR (rn_interior)->source); - route_unlock_node (rn_interior); /* sl entry */ - } - if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn_interior)->source)) - { - skiplist_free (RFAPI_MONITOR_EXTERIOR (rn_interior)->source); - RFAPI_MONITOR_EXTERIOR (rn_interior)->source = NULL; - route_unlock_node (rn_interior); /* sl itself */ - } + afi_t afi = family2afi(rn_interior->p.family); + struct route_node *par; + struct bgp_info *bi_exterior; + struct prefix *pfx_exterior; /* exterior pfx */ + void *cursor; + int rc; + + if (!VALID_INTERIOR_TYPE(bi_interior->type)) { + vnc_zlog_debug_verbose( + "%s: type %d not valid interior type, skipping", + __func__, bi_interior->type); + return; + } + + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vnc_zlog_debug_verbose( + "%s: redist of exterior routes no enabled, skipping", + __func__); + return; + } + + if (it == bgp->rfapi->it_ce) { + vnc_zlog_debug_verbose("%s: it is it_ce, skipping", __func__); + return; + } + + /* If no exterior routes depend on this prefix, nothing to do */ + if (!RFAPI_HAS_MONITOR_EXTERIOR(rn_interior)) { + vnc_zlog_debug_verbose("%s: no exterior monitor, skipping", + __func__); + return; + } + + /*debugging */ + { + char str_pfx[BUFSIZ]; + + prefix2str(&rn_interior->p, str_pfx, BUFSIZ); + str_pfx[BUFSIZ - 1] = 0; + + vnc_zlog_debug_verbose("%s: interior prefix=%s, bi type=%d", + __func__, str_pfx, bi_interior->type); + } + + /* + * Remove constructed routes based on the deleted interior route + */ + cursor = NULL; + for (rc = skiplist_next(RFAPI_MONITOR_EXTERIOR(rn_interior)->source, + (void **)&bi_exterior, (void **)&pfx_exterior, + &cursor); + !rc; + rc = skiplist_next(RFAPI_MONITOR_EXTERIOR(rn_interior)->source, + (void **)&bi_exterior, (void **)&pfx_exterior, + &cursor)) { + + struct prefix_rd *prd; + u_int32_t label = 0; + + if (bi_interior->extra) { + prd = &bi_interior->extra->vnc.import.rd; + label = decode_label(&bi_interior->extra->label); + } else + prd = NULL; + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_KILL, bi_interior->peer, NULL, /* rfd */ + pfx_exterior, NULL, afi, prd, bi_interior->attr, + ZEBRA_ROUTE_BGP_DIRECT_EXT, BGP_ROUTE_REDISTRIBUTE, + &label); + } + + /* + * If there are no remaining valid interior routes at this prefix, + * we need to look up the tree for a possible node to move monitors to + */ + if (RFAPI_MONITOR_EXTERIOR(rn_interior)->valid_interior_count) { + vnc_zlog_debug_verbose( + "%s: interior routes still present, skipping", + __func__); + return; + } + /* + * Find nearest parent with at least one valid interior route + * If none is found, par will end up NULL, and we will move + * the monitors to the orphan list for this import table + */ + for (par = rn_interior->parent; par; par = par->parent) { + if (RFAPI_MONITOR_EXTERIOR(par)->valid_interior_count) + break; + } + + vnc_zlog_debug_verbose("%s: par=%p, ext src: %p", __func__, par, + RFAPI_MONITOR_EXTERIOR(rn_interior)->source); + + /* move all monitors */ + /* + * We will use and delete every element of the source skiplist + */ + while (!skiplist_first(RFAPI_MONITOR_EXTERIOR(rn_interior)->source, + (void **)&bi_exterior, (void **)&pfx_exterior)) { + + struct prefix *pfx_mon = prefix_new(); + + prefix_copy(pfx_mon, pfx_exterior); + + if (par) { + + struct bgp_info *bi; + + /* + * Add monitor to parent node + */ + if (!RFAPI_MONITOR_EXTERIOR(par)->source) { + RFAPI_MONITOR_EXTERIOR(par)->source = + skiplist_new( + 0, NULL, + (void (*)(void *))prefix_free); + route_lock_node(par); /* sl */ + } + skiplist_insert(RFAPI_MONITOR_EXTERIOR(par)->source, + bi_exterior, pfx_mon); + route_lock_node(par); /* sl entry */ + + /* Add constructed exterior routes based on parent */ + for (bi = par->info; bi; bi = bi->next) { + + struct prefix_rd *prd; + struct attr new_attr; + u_int32_t label = 0; + + if (bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) + continue; + + if (bi->extra) { + prd = &bi->extra->vnc.import.rd; + label = decode_label(&bi->extra->label); + } else + prd = NULL; + + /* use local_pref from unicast route */ + memset(&new_attr, 0, sizeof(struct attr)); + bgp_attr_dup(&new_attr, bi->attr); + if (bi_exterior + && (bi_exterior->attr->flag + & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { + new_attr.local_pref = + bi_exterior->attr->local_pref; + new_attr.flag |= ATTR_FLAG_BIT( + BGP_ATTR_LOCAL_PREF); + } + + rfapiBgpInfoFilteredImportVPN( + it, FIF_ACTION_UPDATE, bi->peer, + NULL, /* rfd */ + pfx_exterior, NULL, afi, prd, &new_attr, + ZEBRA_ROUTE_BGP_DIRECT_EXT, + BGP_ROUTE_REDISTRIBUTE, &label); + } + + } else { + + /* + * No interior route for exterior's nexthop. Save + * monitor + * in orphan list to await future route. + */ + skiplist_insert(it->monitor_exterior_orphans, + bi_exterior, pfx_mon); + } + + skiplist_delete_first( + RFAPI_MONITOR_EXTERIOR(rn_interior)->source); + route_unlock_node(rn_interior); /* sl entry */ + } + if (skiplist_empty(RFAPI_MONITOR_EXTERIOR(rn_interior)->source)) { + skiplist_free(RFAPI_MONITOR_EXTERIOR(rn_interior)->source); + RFAPI_MONITOR_EXTERIOR(rn_interior)->source = NULL; + route_unlock_node(rn_interior); /* sl itself */ + } } /*********************************************************************** * Generic add/delete unicast routes ***********************************************************************/ -void -vnc_import_bgp_add_route ( - struct bgp *bgp, - struct prefix *prefix, - struct bgp_info *info) +void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix, + struct bgp_info *info) { - afi_t afi = family2afi (prefix->family); + afi_t afi = family2afi(prefix->family); - { - struct prefix pfx_nexthop; - char buf[BUFSIZ]; - char buf_nh[BUFSIZ]; + { + struct prefix pfx_nexthop; + char buf[BUFSIZ]; + char buf_nh[BUFSIZ]; - prefix2str (prefix, buf, BUFSIZ); - rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_nexthop); - prefix2str (&pfx_nexthop, buf_nh, BUFSIZ); + prefix2str(prefix, buf, BUFSIZ); + rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop); + prefix2str(&pfx_nexthop, buf_nh, BUFSIZ); - vnc_zlog_debug_verbose ("%s: pfx %s, nh %s", __func__, buf, buf_nh); - } + vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf, + buf_nh); + } #if DEBUG_RHN_LIST - print_rhn_list(__func__, "ENTER "); + print_rhn_list(__func__, "ENTER "); #endif - VNC_RHNCK (enter); - - if (!afi) - { - zlog_err ("%s: can't get afi of prefix", __func__); - return; - } - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - /* check vnc redist flag for bgp direct routes */ - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose - ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", - __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); - return; - } - - switch (bgp->rfapi_cfg->redist_mode) - { - case VNC_REDIST_MODE_PLAIN: - vnc_import_bgp_add_route_mode_plain (bgp, prefix, info); - break; - - case VNC_REDIST_MODE_RFG: - if (bgp->rfapi_cfg->rfg_redist) - vnc_import_bgp_add_route_mode_nvegroup (bgp, prefix, info, - bgp->rfapi_cfg->rfg_redist); - else - vnc_zlog_debug_verbose ("%s: mode RFG but no redist RFG", __func__); - break; - - case VNC_REDIST_MODE_RESOLVE_NVE: - vnc_import_bgp_add_route_mode_resolve_nve (bgp, prefix, info); - break; - } + VNC_RHNCK(enter); + + if (!afi) { + zlog_err("%s: can't get afi of prefix", __func__); + return; + } + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + /* check vnc redist flag for bgp direct routes */ + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", + __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); + return; + } + + switch (bgp->rfapi_cfg->redist_mode) { + case VNC_REDIST_MODE_PLAIN: + vnc_import_bgp_add_route_mode_plain(bgp, prefix, info); + break; + + case VNC_REDIST_MODE_RFG: + if (bgp->rfapi_cfg->rfg_redist) + vnc_import_bgp_add_route_mode_nvegroup( + bgp, prefix, info, bgp->rfapi_cfg->rfg_redist); + else + vnc_zlog_debug_verbose("%s: mode RFG but no redist RFG", + __func__); + break; + + case VNC_REDIST_MODE_RESOLVE_NVE: + vnc_import_bgp_add_route_mode_resolve_nve(bgp, prefix, info); + break; + } #if DEBUG_RHN_LIST - print_rhn_list(__func__, "LEAVE "); + print_rhn_list(__func__, "LEAVE "); #endif - VNC_RHNCK (leave); + VNC_RHNCK(leave); } /* * "Withdrawing a Route" import process */ -void -vnc_import_bgp_del_route ( - struct bgp *bgp, - struct prefix *prefix, - struct bgp_info *info) /* unicast info */ +void vnc_import_bgp_del_route(struct bgp *bgp, struct prefix *prefix, + struct bgp_info *info) /* unicast info */ { - afi_t afi = family2afi (prefix->family); + afi_t afi = family2afi(prefix->family); - assert (afi); + assert(afi); - { - struct prefix pfx_nexthop; - char buf[BUFSIZ]; - char buf_nh[BUFSIZ]; + { + struct prefix pfx_nexthop; + char buf[BUFSIZ]; + char buf_nh[BUFSIZ]; - prefix2str (prefix, buf, BUFSIZ); - rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_nexthop); - prefix2str (&pfx_nexthop, buf_nh, BUFSIZ); + prefix2str(prefix, buf, BUFSIZ); + rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop); + prefix2str(&pfx_nexthop, buf_nh, BUFSIZ); - vnc_zlog_debug_verbose ("%s: pfx %s, nh %s", __func__, buf, buf_nh); - } + vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf, + buf_nh); + } #if DEBUG_RHN_LIST - print_rhn_list(__func__, "ENTER "); + print_rhn_list(__func__, "ENTER "); #endif - VNC_RHNCK (enter); - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - /* check bgp redist flag for vnc direct ("vpn") routes */ - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: bgp redistribution of afi=%d VNC direct routes is off", - __func__, afi); - return; - } - - switch (bgp->rfapi_cfg->redist_mode) - { - case VNC_REDIST_MODE_PLAIN: - vnc_import_bgp_del_route_mode_plain (bgp, prefix, info); - break; - - case VNC_REDIST_MODE_RFG: - if (bgp->rfapi_cfg->rfg_redist) - vnc_import_bgp_del_route_mode_nvegroup (bgp, prefix, info); - else - vnc_zlog_debug_verbose ("%s: mode RFG but no redist RFG", __func__); - break; - - case VNC_REDIST_MODE_RESOLVE_NVE: - vnc_import_bgp_del_route_mode_resolve_nve (bgp, afi, prefix, info); - break; - - } + VNC_RHNCK(enter); + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + /* check bgp redist flag for vnc direct ("vpn") routes */ + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: bgp redistribution of afi=%d VNC direct routes is off", + __func__, afi); + return; + } + + switch (bgp->rfapi_cfg->redist_mode) { + case VNC_REDIST_MODE_PLAIN: + vnc_import_bgp_del_route_mode_plain(bgp, prefix, info); + break; + + case VNC_REDIST_MODE_RFG: + if (bgp->rfapi_cfg->rfg_redist) + vnc_import_bgp_del_route_mode_nvegroup(bgp, prefix, + info); + else + vnc_zlog_debug_verbose("%s: mode RFG but no redist RFG", + __func__); + break; + + case VNC_REDIST_MODE_RESOLVE_NVE: + vnc_import_bgp_del_route_mode_resolve_nve(bgp, afi, prefix, + info); + break; + } #if DEBUG_RHN_LIST - print_rhn_list(__func__, "LEAVE "); + print_rhn_list(__func__, "LEAVE "); #endif - VNC_RHNCK (leave); + VNC_RHNCK(leave); } @@ -2901,257 +2768,257 @@ vnc_import_bgp_del_route ( * Enable/Disable ***********************************************************************/ -void -vnc_import_bgp_redist_enable (struct bgp *bgp, afi_t afi) +void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi) { - /* iterate over bgp unicast v4 and v6 routes, call vnc_import_bgp_add_route */ + /* iterate over bgp unicast v4 and v6 routes, call + * vnc_import_bgp_add_route */ - struct bgp_node *rn; + struct bgp_node *rn; - vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); + vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); - if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: already enabled for afi %d, skipping", __func__, afi); - return; - } - bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 1; + if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: already enabled for afi %d, skipping", __func__, + afi); + return; + } + bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 1; - for (rn = bgp_table_top (bgp->rib[afi][SAFI_UNICAST]); - rn; rn = bgp_route_next (rn)) - { + for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; + rn = bgp_route_next(rn)) { - struct bgp_info *bi; + struct bgp_info *bi; - for (bi = rn->info; bi; bi = bi->next) - { + for (bi = rn->info; bi; bi = bi->next) { - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + continue; - vnc_import_bgp_add_route (bgp, &rn->p, bi); - } - } - vnc_zlog_debug_verbose ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return", - __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); + vnc_import_bgp_add_route(bgp, &rn->p, bi); + } + } + vnc_zlog_debug_verbose( + "%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return", + __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); } -void -vnc_import_bgp_exterior_redist_enable (struct bgp *bgp, afi_t afi) +void vnc_import_bgp_exterior_redist_enable(struct bgp *bgp, afi_t afi) { - struct bgp *bgp_exterior; - struct bgp_node *rn; - - bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view; + struct bgp *bgp_exterior; + struct bgp_node *rn; - if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vnc_zlog_debug_verbose ("%s: already enabled for afi %d, skipping", __func__, afi); - return; - } - bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 1; + bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view; - if (!bgp_exterior) - { - vnc_zlog_debug_verbose ("%s: no exterior view set yet, no routes to import yet", - __func__); - return; - } + if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vnc_zlog_debug_verbose( + "%s: already enabled for afi %d, skipping", __func__, + afi); + return; + } + bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 1; - for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]); - rn; rn = bgp_route_next (rn)) - { + if (!bgp_exterior) { + vnc_zlog_debug_verbose( + "%s: no exterior view set yet, no routes to import yet", + __func__); + return; + } - struct bgp_info *bi; + for (rn = bgp_table_top(bgp_exterior->rib[afi][SAFI_UNICAST]); rn; + rn = bgp_route_next(rn)) { - for (bi = rn->info; bi; bi = bi->next) - { + struct bgp_info *bi; - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; + for (bi = rn->info; bi; bi = bi->next) { - vnc_import_bgp_exterior_add_route (bgp_exterior, &rn->p, bi); - } - } - vnc_zlog_debug_verbose ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return", - __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + continue; + vnc_import_bgp_exterior_add_route(bgp_exterior, &rn->p, + bi); + } + } + vnc_zlog_debug_verbose( + "%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return", + __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); } /* * This function is for populating a newly-created Import Table */ -void -vnc_import_bgp_exterior_redist_enable_it ( - struct bgp *bgp, - afi_t afi, - struct rfapi_import_table *it_only) +void vnc_import_bgp_exterior_redist_enable_it( + struct bgp *bgp, afi_t afi, struct rfapi_import_table *it_only) { - struct bgp *bgp_exterior; - struct bgp_node *rn; + struct bgp *bgp_exterior; + struct bgp_node *rn; - vnc_zlog_debug_verbose ("%s: entry", __func__); + vnc_zlog_debug_verbose("%s: entry", __func__); - bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view; + bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view; - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vnc_zlog_debug_verbose ("%s: not enabled for afi %d, skipping", __func__, afi); - return; - } - - if (!bgp_exterior) - { - vnc_zlog_debug_verbose ("%s: no exterior view set yet, no routes to import yet", - __func__); - return; - } + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vnc_zlog_debug_verbose("%s: not enabled for afi %d, skipping", + __func__, afi); + return; + } - for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]); - rn; rn = bgp_route_next (rn)) - { + if (!bgp_exterior) { + vnc_zlog_debug_verbose( + "%s: no exterior view set yet, no routes to import yet", + __func__); + return; + } - struct bgp_info *bi; + for (rn = bgp_table_top(bgp_exterior->rib[afi][SAFI_UNICAST]); rn; + rn = bgp_route_next(rn)) { - for (bi = rn->info; bi; bi = bi->next) - { + struct bgp_info *bi; - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; + for (bi = rn->info; bi; bi = bi->next) { - vnc_import_bgp_exterior_add_route_it (bgp_exterior, &rn->p, bi, - it_only); - } - } + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + continue; + vnc_import_bgp_exterior_add_route_it( + bgp_exterior, &rn->p, bi, it_only); + } + } } -void -vnc_import_bgp_redist_disable (struct bgp *bgp, afi_t afi) +void vnc_import_bgp_redist_disable(struct bgp *bgp, afi_t afi) { - /* - * iterate over vpn routes, find routes of type ZEBRA_ROUTE_BGP_DIRECT, - * delete (call timer expire immediately) - */ - struct bgp_node *rn1; - struct bgp_node *rn2; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - - if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) - { - vnc_zlog_debug_verbose ("%s: already disabled for afi %d, skipping", __func__, afi); - return; - } - - /* - * Two-level table for SAFI_MPLS_VPN - * Be careful when changing the things we iterate over - */ - for (rn1 = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); - rn1; rn1 = bgp_route_next (rn1)) - { - - if (rn1->info) - { - for (rn2 = bgp_table_top (rn1->info); - rn2; rn2 = bgp_route_next (rn2)) - { - - struct bgp_info *bi; - struct bgp_info *nextbi; - - for (bi = rn2->info; bi; bi = nextbi) - { - - nextbi = bi->next; - - if (bi->type == ZEBRA_ROUTE_BGP_DIRECT) - { - - struct rfapi_descriptor *rfd; - vncHDBgpDirect.peer = bi->peer; - - rfd = bi->extra->vnc.export.rfapi_handle; - - vnc_zlog_debug_verbose - ("%s: deleting bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p [passing rfd=%p]", - __func__, bi, bi->peer, bi->type, bi->sub_type, - (bi->extra ? bi->extra->vnc. - export.rfapi_handle : NULL), rfd); - - - del_vnc_route (rfd, bi->peer, bgp, SAFI_MPLS_VPN, &rn2->p, (struct prefix_rd *) &rn1->p, bi->type, bi->sub_type, NULL, 1); /* kill */ - - vncHDBgpDirect.peer = NULL; - } - } - } - } - } - /* Clear RHN list */ - if (bgp->rfapi->resolve_nve_nexthop) - { - struct prefix_bag *pb; - struct bgp_info *info; - while (!skiplist_first - (bgp->rfapi->resolve_nve_nexthop, NULL, (void *) &pb)) - { - info = pb->ubi; - skiplist_delete_first (bgp->rfapi->resolve_nve_nexthop); - bgp_info_unlock (info); - } - } - - bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 0; - vnc_zlog_debug_verbose ("%s: return", __func__); + /* + * iterate over vpn routes, find routes of type ZEBRA_ROUTE_BGP_DIRECT, + * delete (call timer expire immediately) + */ + struct bgp_node *rn1; + struct bgp_node *rn2; + + vnc_zlog_debug_verbose("%s: entry", __func__); + + if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { + vnc_zlog_debug_verbose( + "%s: already disabled for afi %d, skipping", __func__, + afi); + return; + } + + /* + * Two-level table for SAFI_MPLS_VPN + * Be careful when changing the things we iterate over + */ + for (rn1 = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn1; + rn1 = bgp_route_next(rn1)) { + + if (rn1->info) { + for (rn2 = bgp_table_top(rn1->info); rn2; + rn2 = bgp_route_next(rn2)) { + + struct bgp_info *bi; + struct bgp_info *nextbi; + + for (bi = rn2->info; bi; bi = nextbi) { + + nextbi = bi->next; + + if (bi->type + == ZEBRA_ROUTE_BGP_DIRECT) { + + struct rfapi_descriptor *rfd; + vncHDBgpDirect.peer = bi->peer; + + rfd = bi->extra->vnc.export + .rfapi_handle; + + vnc_zlog_debug_verbose( + "%s: deleting bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p [passing rfd=%p]", + __func__, bi, bi->peer, + bi->type, bi->sub_type, + (bi->extra + ? bi->extra + ->vnc + .export + .rfapi_handle + : NULL), + rfd); + + + del_vnc_route( + rfd, bi->peer, bgp, + SAFI_MPLS_VPN, &rn2->p, + (struct prefix_rd *)&rn1 + ->p, + bi->type, bi->sub_type, + NULL, 1); /* kill */ + + vncHDBgpDirect.peer = NULL; + } + } + } + } + } + /* Clear RHN list */ + if (bgp->rfapi->resolve_nve_nexthop) { + struct prefix_bag *pb; + struct bgp_info *info; + while (!skiplist_first(bgp->rfapi->resolve_nve_nexthop, NULL, + (void *)&pb)) { + info = pb->ubi; + skiplist_delete_first(bgp->rfapi->resolve_nve_nexthop); + bgp_info_unlock(info); + } + } + + bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 0; + vnc_zlog_debug_verbose("%s: return", __func__); } -void -vnc_import_bgp_exterior_redist_disable (struct bgp *bgp, afi_t afi) +void vnc_import_bgp_exterior_redist_disable(struct bgp *bgp, afi_t afi) { - struct rfapi_cfg *hc = bgp->rfapi_cfg; - struct bgp *bgp_exterior = hc->redist_bgp_exterior_view; + struct rfapi_cfg *hc = bgp->rfapi_cfg; + struct bgp *bgp_exterior = hc->redist_bgp_exterior_view; - vnc_zlog_debug_verbose ("%s: entry", __func__); + vnc_zlog_debug_verbose("%s: entry", __func__); - if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) - { - vnc_zlog_debug_verbose ("%s: already disabled for afi %d, skipping", __func__, afi); - return; - } + if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { + vnc_zlog_debug_verbose( + "%s: already disabled for afi %d, skipping", __func__, + afi); + return; + } - if (!bgp_exterior) - { - vnc_zlog_debug_verbose ("%s: bgp exterior view not defined, skipping", __func__); - return; - } + if (!bgp_exterior) { + vnc_zlog_debug_verbose( + "%s: bgp exterior view not defined, skipping", + __func__); + return; + } - { - struct bgp_node *rn; - for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]); - rn; rn = bgp_route_next (rn)) - { + { + struct bgp_node *rn; + for (rn = bgp_table_top(bgp_exterior->rib[afi][SAFI_UNICAST]); + rn; rn = bgp_route_next(rn)) { - struct bgp_info *bi; + struct bgp_info *bi; - for (bi = rn->info; bi; bi = bi->next) - { + for (bi = rn->info; bi; bi = bi->next) { - if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) - continue; + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + continue; - vnc_import_bgp_exterior_del_route (bgp_exterior, &rn->p, bi); - } - } + vnc_import_bgp_exterior_del_route(bgp_exterior, + &rn->p, bi); + } + } #if DEBUG_RHN_LIST - print_rhn_list (__func__, NULL); + print_rhn_list(__func__, NULL); #endif - } + } - bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 0; - vnc_zlog_debug_verbose ("%s: return", __func__); + bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 0; + vnc_zlog_debug_verbose("%s: return", __func__); } diff --git a/bgpd/rfapi/vnc_import_bgp.h b/bgpd/rfapi/vnc_import_bgp.h index 9a7261067a..7c15939904 100644 --- a/bgpd/rfapi/vnc_import_bgp.h +++ b/bgpd/rfapi/vnc_import_bgp.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -27,66 +27,48 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_route.h" -#define VALID_INTERIOR_TYPE(type) \ - (((type) == ZEBRA_ROUTE_BGP) || ((type) == ZEBRA_ROUTE_BGP_DIRECT)) +#define VALID_INTERIOR_TYPE(type) \ + (((type) == ZEBRA_ROUTE_BGP) || ((type) == ZEBRA_ROUTE_BGP_DIRECT)) -extern uint32_t -calc_local_pref (struct attr *attr, struct peer *peer); +extern uint32_t calc_local_pref(struct attr *attr, struct peer *peer); -extern int -vnc_prefix_cmp (void *pfx1, void *pfx2); +extern int vnc_prefix_cmp(void *pfx1, void *pfx2); -extern void -vnc_import_bgp_add_route ( - struct bgp *bgp, - struct prefix *prefix, - struct bgp_info *info); +extern void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix, + struct bgp_info *info); -extern void -vnc_import_bgp_del_route ( - struct bgp *bgp, - struct prefix *prefix, - struct bgp_info *info); +extern void vnc_import_bgp_del_route(struct bgp *bgp, struct prefix *prefix, + struct bgp_info *info); -extern void -vnc_import_bgp_redist_enable (struct bgp *bgp, afi_t afi); +extern void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi); -extern void -vnc_import_bgp_redist_disable (struct bgp *bgp, afi_t afi); +extern void vnc_import_bgp_redist_disable(struct bgp *bgp, afi_t afi); -extern void -vnc_import_bgp_exterior_redist_enable (struct bgp *bgp, afi_t afi); +extern void vnc_import_bgp_exterior_redist_enable(struct bgp *bgp, afi_t afi); -extern void -vnc_import_bgp_exterior_redist_disable (struct bgp *bgp, afi_t afi); +extern void vnc_import_bgp_exterior_redist_disable(struct bgp *bgp, afi_t afi); -extern void -vnc_import_bgp_exterior_add_route ( - struct bgp *bgp, /* exterior instance, we hope */ - struct prefix *prefix,/* unicast prefix */ - struct bgp_info *info); /* unicast info */ - -extern void -vnc_import_bgp_exterior_del_route ( - struct bgp *bgp, - struct prefix *prefix,/* unicast prefix */ - struct bgp_info *info); /* unicast info */ - -extern void -vnc_import_bgp_add_vnc_host_route_mode_resolve_nve ( - struct bgp *bgp, - struct prefix_rd *prd, /* RD */ - struct bgp_table *table_rd, /* per-rd VPN route table */ - struct prefix *prefix, /* VPN prefix */ - struct bgp_info *bi); /* new VPN host route */ +extern void vnc_import_bgp_exterior_add_route( + struct bgp *bgp, /* exterior instance, we hope */ + struct prefix *prefix, /* unicast prefix */ + struct bgp_info *info); /* unicast info */ extern void -vnc_import_bgp_del_vnc_host_route_mode_resolve_nve ( - struct bgp *bgp, - struct prefix_rd *prd, /* RD */ - struct bgp_table *table_rd, /* per-rd VPN route table */ - struct prefix *prefix, /* VPN prefix */ - struct bgp_info *bi); /* old VPN host route */ +vnc_import_bgp_exterior_del_route(struct bgp *bgp, + struct prefix *prefix, /* unicast prefix */ + struct bgp_info *info); /* unicast info */ + +extern void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( + struct bgp *bgp, struct prefix_rd *prd, /* RD */ + struct bgp_table *table_rd, /* per-rd VPN route table */ + struct prefix *prefix, /* VPN prefix */ + struct bgp_info *bi); /* new VPN host route */ + +extern void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( + struct bgp *bgp, struct prefix_rd *prd, /* RD */ + struct bgp_table *table_rd, /* per-rd VPN route table */ + struct prefix *prefix, /* VPN prefix */ + struct bgp_info *bi); /* old VPN host route */ #endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_ */ diff --git a/bgpd/rfapi/vnc_import_bgp_p.h b/bgpd/rfapi/vnc_import_bgp_p.h index 19bcd19253..b38fa2276a 100644 --- a/bgpd/rfapi/vnc_import_bgp_p.h +++ b/bgpd/rfapi/vnc_import_bgp_p.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -27,24 +27,18 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_route.h" -extern void -vnc_import_bgp_exterior_add_route_interior ( - struct bgp *bgp, - struct rfapi_import_table *it, - struct route_node *rn_interior, /* VPN IT node */ - struct bgp_info *bi_interior); /* VPN IT route */ +extern void vnc_import_bgp_exterior_add_route_interior( + struct bgp *bgp, struct rfapi_import_table *it, + struct route_node *rn_interior, /* VPN IT node */ + struct bgp_info *bi_interior); /* VPN IT route */ -extern void -vnc_import_bgp_exterior_del_route_interior ( - struct bgp *bgp, - struct rfapi_import_table *it, - struct route_node *rn_interior, /* VPN IT node */ - struct bgp_info *bi_interior); /* VPN IT route */ +extern void vnc_import_bgp_exterior_del_route_interior( + struct bgp *bgp, struct rfapi_import_table *it, + struct route_node *rn_interior, /* VPN IT node */ + struct bgp_info *bi_interior); /* VPN IT route */ extern void -vnc_import_bgp_exterior_redist_enable_it ( - struct bgp *bgp, - afi_t afi, - struct rfapi_import_table *it_only); +vnc_import_bgp_exterior_redist_enable_it(struct bgp *bgp, afi_t afi, + struct rfapi_import_table *it_only); #endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_P_H_ */ diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index de1249ff2c..3075d4109f 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -47,7 +47,7 @@ #include "bgpd/rfapi/rfapi_backend.h" #include "bgpd/rfapi/vnc_debug.h" -static struct rfapi_descriptor vncHD1VR; /* Single-VR export dummy nve descr */ +static struct rfapi_descriptor vncHD1VR; /* Single-VR export dummy nve descr */ static struct zclient *zclient_vnc = NULL; /*********************************************************************** @@ -57,281 +57,271 @@ static struct zclient *zclient_vnc = NULL; /* * Routes coming from zebra get added to VNC here */ -static void -vnc_redistribute_add ( - struct prefix *p, - struct in_addr *nexthop, - u_int32_t metric, - uint8_t type) +static void vnc_redistribute_add(struct prefix *p, struct in_addr *nexthop, + u_int32_t metric, uint8_t type) { - struct bgp *bgp = bgp_get_default (); - struct prefix_rd prd; - struct rfapi_ip_addr vnaddr; - afi_t afi; - uint32_t local_pref = rfp_cost_to_localpref (metric > 255 ? 255 : metric); - - if (!bgp) - return; - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - afi = family2afi (p->family); - if (!afi) - { - vnc_zlog_debug_verbose ("%s: unknown prefix address family %d", __func__, - p->family); - return; - } - - if (!bgp->rfapi_cfg->redist[afi][type]) - { - vnc_zlog_debug_verbose - ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping", - __func__, afi, type); - return; - } - if (!bgp->rfapi_cfg->rfg_redist) - { - vnc_zlog_debug_verbose ("%s: no redist nve group, skipping", __func__); - return; - } - - /* - * Assume nve group's configured VN address prefix is a host - * route which also happens to give the NVE VN address to use - * for redistributing into VNC. - */ - vnaddr.addr_family = bgp->rfapi_cfg->rfg_redist->vn_prefix.family; - switch (bgp->rfapi_cfg->rfg_redist->vn_prefix.family) - { - case AF_INET: - if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 32) - { - vnc_zlog_debug_verbose - ("%s: redist nve group VN prefix len (%d) != 32, skipping", - __func__, bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen); - return; - } - vnaddr.addr.v4 = bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix4; - break; - case AF_INET6: - if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 128) - { - vnc_zlog_debug_verbose - ("%s: redist nve group VN prefix len (%d) != 128, skipping", - __func__, bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen); - return; - } - vnaddr.addr.v6 = bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix6; - break; - default: - vnc_zlog_debug_verbose - ("%s: no redist nve group VN host prefix configured, skipping", - __func__); - return; - } - - /* - * Assume nve group's configured UN address prefix is a host - * route which also happens to give the NVE UN address to use - * for redistributing into VNC. - */ - - /* - * Set UN address in dummy nve descriptor so add_vnc_route - * can use it in VNC tunnel SubTLV - */ - { - struct rfapi_ip_prefix pfx_un; - - rfapiQprefix2Rprefix (&bgp->rfapi_cfg->rfg_redist->un_prefix, &pfx_un); - - switch (pfx_un.prefix.addr_family) - { - case AF_INET: - if (pfx_un.length != 32) - { - vnc_zlog_debug_verbose - ("%s: redist nve group UN prefix len (%d) != 32, skipping", - __func__, pfx_un.length); - return; - } - break; - case AF_INET6: - if (pfx_un.length != 128) - { - vnc_zlog_debug_verbose - ("%s: redist nve group UN prefix len (%d) != 128, skipping", - __func__, pfx_un.length); - return; - } - break; - default: - vnc_zlog_debug_verbose - ("%s: no redist nve group UN host prefix configured, skipping", - __func__); - return; - } - - vncHD1VR.un_addr = pfx_un.prefix; - - if (!vncHD1VR.peer) - { - /* - * Same setup as in rfapi_open() - */ - vncHD1VR.peer = peer_new (bgp); - vncHD1VR.peer->status = Established; /* keep bgp core happy */ - bgp_sync_delete (vncHD1VR.peer); /* don't need these */ - if (vncHD1VR.peer->ibuf) - { - stream_free (vncHD1VR.peer->ibuf); /* don't need it */ - vncHD1VR.peer->ibuf = NULL; - } - if (vncHD1VR.peer->obuf) - { - stream_fifo_free (vncHD1VR.peer->obuf); /* don't need it */ - vncHD1VR.peer->obuf = NULL; - } - if (vncHD1VR.peer->work) - { - stream_free (vncHD1VR.peer->work); /* don't need it */ - vncHD1VR.peer->work = NULL; - } - /* base code assumes have valid host pointer */ - vncHD1VR.peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, ".zebra."); - - /* Mark peer as belonging to HD */ - SET_FLAG (vncHD1VR.peer->flags, PEER_FLAG_IS_RFAPI_HD); - } - } - - memset (&prd, 0, sizeof (prd)); - prd = bgp->rfapi_cfg->rfg_redist->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - add_vnc_route (&vncHD1VR, /* cookie + UN addr */ - bgp, SAFI_MPLS_VPN, p, &prd, &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), NULL, /* RFP options */ - NULL, /* struct rfapi_un_option */ - NULL, /* struct rfapi_vn_option */ - bgp->rfapi_cfg->rfg_redist->rt_export_list, NULL, NULL, /* label: default */ - type, BGP_ROUTE_REDISTRIBUTE, 0); /* flags */ + struct bgp *bgp = bgp_get_default(); + struct prefix_rd prd; + struct rfapi_ip_addr vnaddr; + afi_t afi; + uint32_t local_pref = + rfp_cost_to_localpref(metric > 255 ? 255 : metric); + + if (!bgp) + return; + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + afi = family2afi(p->family); + if (!afi) { + vnc_zlog_debug_verbose("%s: unknown prefix address family %d", + __func__, p->family); + return; + } + + if (!bgp->rfapi_cfg->redist[afi][type]) { + vnc_zlog_debug_verbose( + "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping", + __func__, afi, type); + return; + } + if (!bgp->rfapi_cfg->rfg_redist) { + vnc_zlog_debug_verbose("%s: no redist nve group, skipping", + __func__); + return; + } + + /* + * Assume nve group's configured VN address prefix is a host + * route which also happens to give the NVE VN address to use + * for redistributing into VNC. + */ + vnaddr.addr_family = bgp->rfapi_cfg->rfg_redist->vn_prefix.family; + switch (bgp->rfapi_cfg->rfg_redist->vn_prefix.family) { + case AF_INET: + if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 32) { + vnc_zlog_debug_verbose( + "%s: redist nve group VN prefix len (%d) != 32, skipping", + __func__, + bgp->rfapi_cfg->rfg_redist->vn_prefix + .prefixlen); + return; + } + vnaddr.addr.v4 = + bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix4; + break; + case AF_INET6: + if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 128) { + vnc_zlog_debug_verbose( + "%s: redist nve group VN prefix len (%d) != 128, skipping", + __func__, + bgp->rfapi_cfg->rfg_redist->vn_prefix + .prefixlen); + return; + } + vnaddr.addr.v6 = + bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix6; + break; + default: + vnc_zlog_debug_verbose( + "%s: no redist nve group VN host prefix configured, skipping", + __func__); + return; + } + + /* + * Assume nve group's configured UN address prefix is a host + * route which also happens to give the NVE UN address to use + * for redistributing into VNC. + */ + + /* + * Set UN address in dummy nve descriptor so add_vnc_route + * can use it in VNC tunnel SubTLV + */ + { + struct rfapi_ip_prefix pfx_un; + + rfapiQprefix2Rprefix(&bgp->rfapi_cfg->rfg_redist->un_prefix, + &pfx_un); + + switch (pfx_un.prefix.addr_family) { + case AF_INET: + if (pfx_un.length != 32) { + vnc_zlog_debug_verbose( + "%s: redist nve group UN prefix len (%d) != 32, skipping", + __func__, pfx_un.length); + return; + } + break; + case AF_INET6: + if (pfx_un.length != 128) { + vnc_zlog_debug_verbose( + "%s: redist nve group UN prefix len (%d) != 128, skipping", + __func__, pfx_un.length); + return; + } + break; + default: + vnc_zlog_debug_verbose( + "%s: no redist nve group UN host prefix configured, skipping", + __func__); + return; + } + + vncHD1VR.un_addr = pfx_un.prefix; + + if (!vncHD1VR.peer) { + /* + * Same setup as in rfapi_open() + */ + vncHD1VR.peer = peer_new(bgp); + vncHD1VR.peer->status = + Established; /* keep bgp core happy */ + bgp_sync_delete(vncHD1VR.peer); /* don't need these */ + if (vncHD1VR.peer->ibuf) { + stream_free(vncHD1VR.peer + ->ibuf); /* don't need it */ + vncHD1VR.peer->ibuf = NULL; + } + if (vncHD1VR.peer->obuf) { + stream_fifo_free( + vncHD1VR.peer + ->obuf); /* don't need it */ + vncHD1VR.peer->obuf = NULL; + } + if (vncHD1VR.peer->work) { + stream_free(vncHD1VR.peer + ->work); /* don't need it */ + vncHD1VR.peer->work = NULL; + } + /* base code assumes have valid host pointer */ + vncHD1VR.peer->host = + XSTRDUP(MTYPE_BGP_PEER_HOST, ".zebra."); + + /* Mark peer as belonging to HD */ + SET_FLAG(vncHD1VR.peer->flags, PEER_FLAG_IS_RFAPI_HD); + } + } + + memset(&prd, 0, sizeof(prd)); + prd = bgp->rfapi_cfg->rfg_redist->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + add_vnc_route(&vncHD1VR, /* cookie + UN addr */ + bgp, SAFI_MPLS_VPN, p, &prd, &vnaddr, &local_pref, + &(bgp->rfapi_cfg->redist_lifetime), + NULL, /* RFP options */ + NULL, /* struct rfapi_un_option */ + NULL, /* struct rfapi_vn_option */ + bgp->rfapi_cfg->rfg_redist->rt_export_list, NULL, + NULL, /* label: default */ + type, BGP_ROUTE_REDISTRIBUTE, 0); /* flags */ } /* * Route deletions from zebra propagate to VNC here */ -static void -vnc_redistribute_delete (struct prefix *p, uint8_t type) +static void vnc_redistribute_delete(struct prefix *p, uint8_t type) { - struct bgp *bgp = bgp_get_default (); - struct prefix_rd prd; - afi_t afi; - - if (!bgp) - return; - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - afi = family2afi (p->family); - if (!afi) - { - vnc_zlog_debug_verbose ("%s: unknown prefix address family %d", __func__, - p->family); - return; - } - if (!bgp->rfapi_cfg->redist[afi][type]) - { - vnc_zlog_debug_verbose - ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping", - __func__, afi, type); - return; - } - if (!bgp->rfapi_cfg->rfg_redist) - { - vnc_zlog_debug_verbose ("%s: no redist nve group, skipping", __func__); - return; - } - - memset (&prd, 0, sizeof (prd)); - prd = bgp->rfapi_cfg->rfg_redist->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - del_vnc_route (&vncHD1VR, /* use dummy ptr as cookie */ - vncHD1VR.peer, - bgp, - SAFI_MPLS_VPN, - p, &prd, type, BGP_ROUTE_REDISTRIBUTE, NULL, 0); + struct bgp *bgp = bgp_get_default(); + struct prefix_rd prd; + afi_t afi; + + if (!bgp) + return; + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + afi = family2afi(p->family); + if (!afi) { + vnc_zlog_debug_verbose("%s: unknown prefix address family %d", + __func__, p->family); + return; + } + if (!bgp->rfapi_cfg->redist[afi][type]) { + vnc_zlog_debug_verbose( + "%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping", + __func__, afi, type); + return; + } + if (!bgp->rfapi_cfg->rfg_redist) { + vnc_zlog_debug_verbose("%s: no redist nve group, skipping", + __func__); + return; + } + + memset(&prd, 0, sizeof(prd)); + prd = bgp->rfapi_cfg->rfg_redist->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + del_vnc_route(&vncHD1VR, /* use dummy ptr as cookie */ + vncHD1VR.peer, bgp, SAFI_MPLS_VPN, p, &prd, type, + BGP_ROUTE_REDISTRIBUTE, NULL, 0); } /* * Flush all redistributed routes of type <type> */ -static void -vnc_redistribute_withdraw (struct bgp *bgp, afi_t afi, uint8_t type) +static void vnc_redistribute_withdraw(struct bgp *bgp, afi_t afi, uint8_t type) { - struct prefix_rd prd; - struct bgp_table *table; - struct bgp_node *prn; - struct bgp_node *rn; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - - if (!bgp) - return; - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - /* - * Loop over all the RDs - */ - for (prn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); prn; - prn = bgp_route_next (prn)) - { - memset (&prd, 0, sizeof (prd)); - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - memcpy (prd.val, prn->p.u.val, 8); - - /* This is the per-RD table of prefixes */ - table = prn->info; - - for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) - { - - struct bgp_info *ri; - - for (ri = rn->info; ri; ri = ri->next) - { - if (ri->type == type) - { /* has matching redist type */ - break; - } - } - if (ri) - { - del_vnc_route (&vncHD1VR, /* use dummy ptr as cookie */ - vncHD1VR.peer, - bgp, - SAFI_MPLS_VPN, - &(rn->p), - &prd, type, BGP_ROUTE_REDISTRIBUTE, NULL, 0); - } - } - } - vnc_zlog_debug_verbose ("%s: return", __func__); + struct prefix_rd prd; + struct bgp_table *table; + struct bgp_node *prn; + struct bgp_node *rn; + + vnc_zlog_debug_verbose("%s: entry", __func__); + + if (!bgp) + return; + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + /* + * Loop over all the RDs + */ + for (prn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); prn; + prn = bgp_route_next(prn)) { + memset(&prd, 0, sizeof(prd)); + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + memcpy(prd.val, prn->p.u.val, 8); + + /* This is the per-RD table of prefixes */ + table = prn->info; + + for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { + + struct bgp_info *ri; + + for (ri = rn->info; ri; ri = ri->next) { + if (ri->type + == type) { /* has matching redist type */ + break; + } + } + if (ri) { + del_vnc_route( + &vncHD1VR, /* use dummy ptr as cookie */ + vncHD1VR.peer, bgp, SAFI_MPLS_VPN, + &(rn->p), &prd, type, + BGP_ROUTE_REDISTRIBUTE, NULL, 0); + } + } + } + vnc_zlog_debug_verbose("%s: return", __func__); } /* @@ -339,177 +329,159 @@ vnc_redistribute_withdraw (struct bgp *bgp, afi_t afi, uint8_t type) * * Assumes 1 nexthop */ -static int -vnc_zebra_read_ipv4 ( - int command, - struct zclient *zclient, - zebra_size_t length, - vrf_id_t vrf_id) +static int vnc_zebra_read_ipv4(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv4 api; - struct in_addr nexthop; - struct prefix_ipv4 p; - - s = zclient->ibuf; - nexthop.s_addr = 0; - - /* Type, flags, message. */ - api.type = stream_getc (s); - api.flags = stream_getc (s); - api.message = stream_getc (s); - - /* IPv4 prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = stream_getc (s); - stream_get (&p.prefix, s, PSIZE (p.prefixlen)); - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - { - api.nexthop_num = stream_getc (s); - nexthop.s_addr = stream_get_ipv4 (s); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) - { - api.ifindex_num = stream_getc (s); - stream_getl (s); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (s); - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (s); - else - api.metric = 0; - - if (command == ZEBRA_IPV4_ROUTE_ADD) - { - if (BGP_DEBUG (zebra, ZEBRA)) - { - char buf[2][INET_ADDRSTRLEN]; - vnc_zlog_debug_verbose - ("%s: Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u", - __func__, zebra_route_string (api.type), inet_ntop (AF_INET, - &p.prefix, - buf[0], - sizeof (buf - [0])), - p.prefixlen, inet_ntop (AF_INET, &nexthop, buf[1], - sizeof (buf[1])), api.metric); - } - vnc_redistribute_add ((struct prefix *) &p, &nexthop, api.metric, - api.type); - } - else - { - if (BGP_DEBUG (zebra, ZEBRA)) - { - char buf[2][INET_ADDRSTRLEN]; - vnc_zlog_debug_verbose ("%s: Zebra rcvd: IPv4 route delete %s %s/%d " - "nexthop %s metric %u", - __func__, - zebra_route_string (api.type), - inet_ntop (AF_INET, &p.prefix, buf[0], sizeof (buf[0])), - p.prefixlen, - inet_ntop (AF_INET, &nexthop, buf[1], sizeof (buf[1])), - api.metric); - } - vnc_redistribute_delete ((struct prefix *) &p, api.type); - } - - return 0; + struct stream *s; + struct zapi_ipv4 api; + struct in_addr nexthop; + struct prefix_ipv4 p; + + s = zclient->ibuf; + nexthop.s_addr = 0; + + /* Type, flags, message. */ + api.type = stream_getc(s); + api.flags = stream_getc(s); + api.message = stream_getc(s); + + /* IPv4 prefix. */ + memset(&p, 0, sizeof(struct prefix_ipv4)); + p.family = AF_INET; + p.prefixlen = stream_getc(s); + stream_get(&p.prefix, s, PSIZE(p.prefixlen)); + + /* Nexthop, ifindex, distance, metric. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + api.nexthop_num = stream_getc(s); + nexthop.s_addr = stream_get_ipv4(s); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { + api.ifindex_num = stream_getc(s); + stream_getl(s); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + api.distance = stream_getc(s); + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + api.metric = stream_getl(s); + else + api.metric = 0; + + if (command == ZEBRA_IPV4_ROUTE_ADD) { + if (BGP_DEBUG(zebra, ZEBRA)) { + char buf[2][INET_ADDRSTRLEN]; + vnc_zlog_debug_verbose( + "%s: Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u", + __func__, zebra_route_string(api.type), + inet_ntop(AF_INET, &p.prefix, buf[0], + sizeof(buf[0])), + p.prefixlen, inet_ntop(AF_INET, &nexthop, + buf[1], sizeof(buf[1])), + api.metric); + } + vnc_redistribute_add((struct prefix *)&p, &nexthop, api.metric, + api.type); + } else { + if (BGP_DEBUG(zebra, ZEBRA)) { + char buf[2][INET_ADDRSTRLEN]; + vnc_zlog_debug_verbose( + "%s: Zebra rcvd: IPv4 route delete %s %s/%d " + "nexthop %s metric %u", + __func__, zebra_route_string(api.type), + inet_ntop(AF_INET, &p.prefix, buf[0], + sizeof(buf[0])), + p.prefixlen, inet_ntop(AF_INET, &nexthop, + buf[1], sizeof(buf[1])), + api.metric); + } + vnc_redistribute_delete((struct prefix *)&p, api.type); + } + + return 0; } /* Zebra route add and delete treatment. */ -static int -vnc_zebra_read_ipv6 ( - int command, - struct zclient *zclient, - zebra_size_t length, - vrf_id_t vrf_id) +static int vnc_zebra_read_ipv6(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) { - struct stream *s; - struct zapi_ipv6 api; - struct in6_addr nexthop; - struct prefix_ipv6 p, src_p; - - s = zclient->ibuf; - memset (&nexthop, 0, sizeof (struct in6_addr)); - - /* Type, flags, message. */ - api.type = stream_getc (s); - api.flags = stream_getc (s); - api.message = stream_getc (s); - - /* IPv6 prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = stream_getc (s); - stream_get (&p.prefix, s, PSIZE (p.prefixlen)); - - memset (&src_p, 0, sizeof (struct prefix_ipv6)); - src_p.family = AF_INET6; - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX)) - { - src_p.prefixlen = stream_getc (s); - stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen)); - } - - if (src_p.prefixlen) - /* we completely ignore srcdest routes for now. */ - return 0; - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - { - api.nexthop_num = stream_getc (s); - stream_get (&nexthop, s, 16); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) - { - api.ifindex_num = stream_getc (s); - stream_getl (s); - } - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (s); - else - api.distance = 0; - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (s); - else - api.metric = 0; - - /* Simply ignore link-local address. */ - if (IN6_IS_ADDR_LINKLOCAL (&p.prefix)) - return 0; - - if (command == ZEBRA_IPV6_ROUTE_ADD) - { - if (BGP_DEBUG (zebra, ZEBRA)) - { - char buf[INET6_ADDRSTRLEN]; - vnc_zlog_debug_verbose ("Zebra rcvd: IPv6 route add %s %s/%d metric %u", - zebra_route_string (api.type), - inet_ntop (AF_INET6, &p.prefix, buf, sizeof (buf)), - p.prefixlen, api.metric); - } - vnc_redistribute_add ((struct prefix *) &p, NULL, api.metric, api.type); - } - else - { - if (BGP_DEBUG (zebra, ZEBRA)) - { - char buf[INET6_ADDRSTRLEN]; - vnc_zlog_debug_verbose ("Zebra rcvd: IPv6 route delete %s %s/%d metric %u", - zebra_route_string (api.type), - inet_ntop (AF_INET6, &p.prefix, buf, sizeof (buf)), - p.prefixlen, api.metric); - } - vnc_redistribute_delete ((struct prefix *) &p, api.type); - } - - return 0; + struct stream *s; + struct zapi_ipv6 api; + struct in6_addr nexthop; + struct prefix_ipv6 p, src_p; + + s = zclient->ibuf; + memset(&nexthop, 0, sizeof(struct in6_addr)); + + /* Type, flags, message. */ + api.type = stream_getc(s); + api.flags = stream_getc(s); + api.message = stream_getc(s); + + /* IPv6 prefix. */ + memset(&p, 0, sizeof(struct prefix_ipv6)); + p.family = AF_INET6; + p.prefixlen = stream_getc(s); + stream_get(&p.prefix, s, PSIZE(p.prefixlen)); + + memset(&src_p, 0, sizeof(struct prefix_ipv6)); + src_p.family = AF_INET6; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { + src_p.prefixlen = stream_getc(s); + stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); + } + + if (src_p.prefixlen) + /* we completely ignore srcdest routes for now. */ + return 0; + + /* Nexthop, ifindex, distance, metric. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + api.nexthop_num = stream_getc(s); + stream_get(&nexthop, s, 16); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { + api.ifindex_num = stream_getc(s); + stream_getl(s); + } + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + api.distance = stream_getc(s); + else + api.distance = 0; + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + api.metric = stream_getl(s); + else + api.metric = 0; + + /* Simply ignore link-local address. */ + if (IN6_IS_ADDR_LINKLOCAL(&p.prefix)) + return 0; + + if (command == ZEBRA_IPV6_ROUTE_ADD) { + if (BGP_DEBUG(zebra, ZEBRA)) { + char buf[INET6_ADDRSTRLEN]; + vnc_zlog_debug_verbose( + "Zebra rcvd: IPv6 route add %s %s/%d metric %u", + zebra_route_string(api.type), + inet_ntop(AF_INET6, &p.prefix, buf, + sizeof(buf)), + p.prefixlen, api.metric); + } + vnc_redistribute_add((struct prefix *)&p, NULL, api.metric, + api.type); + } else { + if (BGP_DEBUG(zebra, ZEBRA)) { + char buf[INET6_ADDRSTRLEN]; + vnc_zlog_debug_verbose( + "Zebra rcvd: IPv6 route delete %s %s/%d metric %u", + zebra_route_string(api.type), + inet_ntop(AF_INET6, &p.prefix, buf, + sizeof(buf)), + p.prefixlen, api.metric); + } + vnc_redistribute_delete((struct prefix *)&p, api.type); + } + + return 0; } /*********************************************************************** @@ -519,509 +491,465 @@ vnc_zebra_read_ipv6 ( /* * low-level message builder */ -static void -vnc_zebra_route_msg ( - struct prefix *p, - int nhp_count, - void *nhp_ary, - int add) /* 1 = add, 0 = del */ +static void vnc_zebra_route_msg(struct prefix *p, int nhp_count, void *nhp_ary, + int add) /* 1 = add, 0 = del */ { - if (!nhp_count) - { - vnc_zlog_debug_verbose ("%s: empty nexthop list, skipping", __func__); - return; - } - - if (p->family == AF_INET) - { - - struct zapi_ipv4 api; - - api.flags = 0; - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_VNC; - api.message = 0; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); /* TBD what's it mean? */ - api.nexthop_num = nhp_count; - api.nexthop = nhp_ary; - api.ifindex_num = 0; - api.instance = 0; - api.safi = SAFI_UNICAST; - - if (BGP_DEBUG (zebra, ZEBRA)) - { - - char buf[INET_ADDRSTRLEN]; - vnc_zlog_debug_verbose ("%s: Zebra send: IPv4 route %s %s/%d, nhp_count=%d", - __func__, - (add ? "add" : "del"), - inet_ntop (AF_INET, &p->u.prefix4, buf, sizeof (buf)), - p->prefixlen, nhp_count); - } - - zapi_ipv4_route ((add ? ZEBRA_IPV4_NEXTHOP_ADD : - ZEBRA_IPV4_NEXTHOP_DELETE), zclient_vnc, - (struct prefix_ipv4 *) p, &api); - - } - else if (p->family == AF_INET6) - { - - struct zapi_ipv6 api; - ifindex_t ifindex = 0; - - /* Make Zebra API structure. */ - api.flags = 0; - api.vrf_id = VRF_DEFAULT; - api.type = ZEBRA_ROUTE_VNC; - api.message = 0; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); /* TBD means? */ - api.nexthop_num = nhp_count; - api.nexthop = nhp_ary; - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &ifindex; - api.instance = 0; - api.safi = SAFI_UNICAST; - - if (BGP_DEBUG (zebra, ZEBRA)) - { - - char buf[INET6_ADDRSTRLEN]; - vnc_zlog_debug_verbose ("%s: Zebra send: IPv6 route %s %s/%d nhp_count=%d", - __func__, - (add ? "add" : "del"), - inet_ntop (AF_INET6, &p->u.prefix6, buf, sizeof (buf)), - p->prefixlen, nhp_count); - } - - zapi_ipv6_route ((add ? ZEBRA_IPV6_NEXTHOP_ADD : - ZEBRA_IPV6_NEXTHOP_DELETE), zclient_vnc, - (struct prefix_ipv6 *) p, NULL, &api); - } - else - { - vnc_zlog_debug_verbose ("%s: unknown prefix address family, skipping", __func__); - return; - } + if (!nhp_count) { + vnc_zlog_debug_verbose("%s: empty nexthop list, skipping", + __func__); + return; + } + + if (p->family == AF_INET) { + + struct zapi_ipv4 api; + + api.flags = 0; + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_VNC; + api.message = 0; + SET_FLAG(api.message, + ZAPI_MESSAGE_NEXTHOP); /* TBD what's it mean? */ + api.nexthop_num = nhp_count; + api.nexthop = nhp_ary; + api.ifindex_num = 0; + api.instance = 0; + api.safi = SAFI_UNICAST; + + if (BGP_DEBUG(zebra, ZEBRA)) { + + char buf[INET_ADDRSTRLEN]; + vnc_zlog_debug_verbose( + "%s: Zebra send: IPv4 route %s %s/%d, nhp_count=%d", + __func__, (add ? "add" : "del"), + inet_ntop(AF_INET, &p->u.prefix4, buf, + sizeof(buf)), + p->prefixlen, nhp_count); + } + + zapi_ipv4_route((add ? ZEBRA_IPV4_NEXTHOP_ADD + : ZEBRA_IPV4_NEXTHOP_DELETE), + zclient_vnc, (struct prefix_ipv4 *)p, &api); + + } else if (p->family == AF_INET6) { + + struct zapi_ipv6 api; + ifindex_t ifindex = 0; + + /* Make Zebra API structure. */ + api.flags = 0; + api.vrf_id = VRF_DEFAULT; + api.type = ZEBRA_ROUTE_VNC; + api.message = 0; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); /* TBD means? */ + api.nexthop_num = nhp_count; + api.nexthop = nhp_ary; + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = 1; + api.ifindex = &ifindex; + api.instance = 0; + api.safi = SAFI_UNICAST; + + if (BGP_DEBUG(zebra, ZEBRA)) { + + char buf[INET6_ADDRSTRLEN]; + vnc_zlog_debug_verbose( + "%s: Zebra send: IPv6 route %s %s/%d nhp_count=%d", + __func__, (add ? "add" : "del"), + inet_ntop(AF_INET6, &p->u.prefix6, buf, + sizeof(buf)), + p->prefixlen, nhp_count); + } + + zapi_ipv6_route((add ? ZEBRA_IPV6_NEXTHOP_ADD + : ZEBRA_IPV6_NEXTHOP_DELETE), + zclient_vnc, (struct prefix_ipv6 *)p, NULL, + &api); + } else { + vnc_zlog_debug_verbose( + "%s: unknown prefix address family, skipping", + __func__); + return; + } } static void -nve_list_to_nh_array ( - u_char family, - struct list *nve_list, - int *nh_count_ret, - void **nh_ary_ret, /* returned address array */ - void **nhp_ary_ret) /* returned pointer array */ +nve_list_to_nh_array(u_char family, struct list *nve_list, int *nh_count_ret, + void **nh_ary_ret, /* returned address array */ + void **nhp_ary_ret) /* returned pointer array */ { - int nve_count = listcount (nve_list); + int nve_count = listcount(nve_list); - *nh_count_ret = 0; - *nh_ary_ret = NULL; - *nhp_ary_ret = NULL; + *nh_count_ret = 0; + *nh_ary_ret = NULL; + *nhp_ary_ret = NULL; - if (!nve_count) - { - vnc_zlog_debug_verbose ("%s: empty nve_list, skipping", __func__); - return; - } + if (!nve_count) { + vnc_zlog_debug_verbose("%s: empty nve_list, skipping", + __func__); + return; + } - if (family == AF_INET) - { - struct listnode *ln; - struct in_addr *iap; - struct in_addr **v; + if (family == AF_INET) { + struct listnode *ln; + struct in_addr *iap; + struct in_addr **v; - /* - * Array of nexthop addresses - */ - *nh_ary_ret = XCALLOC (MTYPE_TMP, nve_count * sizeof (struct in_addr)); + /* + * Array of nexthop addresses + */ + *nh_ary_ret = + XCALLOC(MTYPE_TMP, nve_count * sizeof(struct in_addr)); - /* - * Array of pointers to nexthop addresses - */ - *nhp_ary_ret = - XCALLOC (MTYPE_TMP, nve_count * sizeof (struct in_addr *)); - iap = *nh_ary_ret; - v = *nhp_ary_ret; + /* + * Array of pointers to nexthop addresses + */ + *nhp_ary_ret = XCALLOC(MTYPE_TMP, + nve_count * sizeof(struct in_addr *)); + iap = *nh_ary_ret; + v = *nhp_ary_ret; - for (ln = listhead (nve_list); ln; ln = listnextnode (ln)) - { + for (ln = listhead(nve_list); ln; ln = listnextnode(ln)) { - struct rfapi_descriptor *irfd; - struct prefix nhp; + struct rfapi_descriptor *irfd; + struct prefix nhp; - irfd = listgetdata (ln); + irfd = listgetdata(ln); - if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) - continue; + if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) + continue; - *iap = nhp.u.prefix4; - *v = iap; - vnc_zlog_debug_verbose ("%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p", - __func__, iap, nhp.u.prefix4.s_addr, v, iap); + *iap = nhp.u.prefix4; + *v = iap; + vnc_zlog_debug_verbose( + "%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p", + __func__, iap, nhp.u.prefix4.s_addr, v, iap); - ++iap; - ++v; - ++*nh_count_ret; - } + ++iap; + ++v; + ++*nh_count_ret; + } - } - else if (family == AF_INET6) - { + } else if (family == AF_INET6) { - struct listnode *ln; + struct listnode *ln; - *nh_ary_ret = XCALLOC (MTYPE_TMP, nve_count * sizeof (struct in6_addr)); + *nh_ary_ret = + XCALLOC(MTYPE_TMP, nve_count * sizeof(struct in6_addr)); - *nhp_ary_ret = XCALLOC (MTYPE_TMP, - nve_count * sizeof (struct in6_addr *)); + *nhp_ary_ret = XCALLOC(MTYPE_TMP, + nve_count * sizeof(struct in6_addr *)); - for (ln = listhead (nve_list); ln; ln = listnextnode (ln)) - { + for (ln = listhead(nve_list); ln; ln = listnextnode(ln)) { - struct rfapi_descriptor *irfd; - struct in6_addr *iap = *nh_ary_ret; - struct in6_addr **v = *nhp_ary_ret; - struct prefix nhp; + struct rfapi_descriptor *irfd; + struct in6_addr *iap = *nh_ary_ret; + struct in6_addr **v = *nhp_ary_ret; + struct prefix nhp; - irfd = listgetdata (ln); + irfd = listgetdata(ln); - if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) - continue; + if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) + continue; - *iap = nhp.u.prefix6; - *v = iap; + *iap = nhp.u.prefix6; + *v = iap; - ++iap; - ++v; - ++*nh_count_ret; - } - } + ++iap; + ++v; + ++*nh_count_ret; + } + } } -static void -import_table_to_nve_list_zebra ( - struct bgp *bgp, - struct rfapi_import_table *it, - struct list **nves, - uint8_t family) +static void import_table_to_nve_list_zebra(struct bgp *bgp, + struct rfapi_import_table *it, + struct list **nves, uint8_t family) { - struct listnode *node; - struct rfapi_rfg_name *rfgn; - - /* - * Loop over the list of NVE-Groups configured for - * exporting to direct-bgp. - * - * Build a list of NVEs that use this import table - */ - *nves = NULL; - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) - { - - /* - * If this NVE-Group's import table matches the current one - */ - if (rfgn->rfg && rfgn->rfg->nves && rfgn->rfg->rfapi_import_table == it) - { - - nve_group_to_nve_list (rfgn->rfg, nves, family); - } - } + struct listnode *node; + struct rfapi_rfg_name *rfgn; + + /* + * Loop over the list of NVE-Groups configured for + * exporting to direct-bgp. + * + * Build a list of NVEs that use this import table + */ + *nves = NULL; + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, + rfgn)) { + + /* + * If this NVE-Group's import table matches the current one + */ + if (rfgn->rfg && rfgn->rfg->nves + && rfgn->rfg->rfapi_import_table == it) { + + nve_group_to_nve_list(rfgn->rfg, nves, family); + } + } } -static void -vnc_zebra_add_del_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn, - int add) /* !0 = add, 0 = del */ +static void vnc_zebra_add_del_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn, + int add) /* !0 = add, 0 = del */ { - struct list *nves; - - int nexthop_count = 0; - void *nh_ary = NULL; - void *nhp_ary = NULL; - - vnc_zlog_debug_verbose ("%s: entry, add=%d", __func__, add); - - if (zclient_vnc->sock < 0) - return; - - if (rn->p.family != AF_INET - && rn->p.family != AF_INET6) - { - zlog_err ("%s: invalid route node addr family", __func__); - return; - } - - if (!zclient_vnc->redist[family2afi(rn->p.family)][ZEBRA_ROUTE_VNC]) - return; - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - if (!listcount (bgp->rfapi_cfg->rfg_export_zebra_l)) - { - vnc_zlog_debug_verbose ("%s: no zebra export nve group, skipping", __func__); - return; - } - - import_table_to_nve_list_zebra (bgp, import_table, &nves, rn->p.family); - - if (nves) - { - nve_list_to_nh_array (rn->p.family, - nves, &nexthop_count, &nh_ary, &nhp_ary); - - list_delete (nves); - - if (nexthop_count) - vnc_zebra_route_msg (&rn->p, nexthop_count, nhp_ary, add); - } - - if (nhp_ary) - XFREE (MTYPE_TMP, nhp_ary); - if (nh_ary) - XFREE (MTYPE_TMP, nh_ary); + struct list *nves; + + int nexthop_count = 0; + void *nh_ary = NULL; + void *nhp_ary = NULL; + + vnc_zlog_debug_verbose("%s: entry, add=%d", __func__, add); + + if (zclient_vnc->sock < 0) + return; + + if (rn->p.family != AF_INET && rn->p.family != AF_INET6) { + zlog_err("%s: invalid route node addr family", __func__); + return; + } + + if (!zclient_vnc->redist[family2afi(rn->p.family)][ZEBRA_ROUTE_VNC]) + return; + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + if (!listcount(bgp->rfapi_cfg->rfg_export_zebra_l)) { + vnc_zlog_debug_verbose( + "%s: no zebra export nve group, skipping", __func__); + return; + } + + import_table_to_nve_list_zebra(bgp, import_table, &nves, rn->p.family); + + if (nves) { + nve_list_to_nh_array(rn->p.family, nves, &nexthop_count, + &nh_ary, &nhp_ary); + + list_delete(nves); + + if (nexthop_count) + vnc_zebra_route_msg(&rn->p, nexthop_count, nhp_ary, + add); + } + + if (nhp_ary) + XFREE(MTYPE_TMP, nhp_ary); + if (nh_ary) + XFREE(MTYPE_TMP, nh_ary); } -void -vnc_zebra_add_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn) +void vnc_zebra_add_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn) { - vnc_zebra_add_del_prefix (bgp, import_table, rn, 1); + vnc_zebra_add_del_prefix(bgp, import_table, rn, 1); } -void -vnc_zebra_del_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn) +void vnc_zebra_del_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn) { - vnc_zebra_add_del_prefix (bgp, import_table, rn, 0); + vnc_zebra_add_del_prefix(bgp, import_table, rn, 0); } - -static void -vnc_zebra_add_del_nve ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - int add) /* 0 = del, !0 = add */ +static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd, + int add) /* 0 = del, !0 = add */ { - struct listnode *node; - struct rfapi_rfg_name *rfgn; - struct rfapi_nve_group_cfg *rfg = rfd->rfg; - afi_t afi = family2afi (rfd->vn_addr.addr_family); - struct prefix nhp; -// struct prefix *nhpp; - void *pAddr; - - vnc_zlog_debug_verbose ("%s: entry, add=%d", __func__, add); - - if (zclient_vnc->sock < 0) - return; - - if (!zclient_vnc->redist[afi][ZEBRA_ROUTE_VNC]) - return; - - if (afi != AFI_IP && afi != AFI_IP6) - { - zlog_err ("%s: invalid vn addr family", __func__); - return; - } - - if (!bgp) - return; - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); - return; - } - - if (rfapiRaddr2Qprefix (&rfd->vn_addr, &nhp)) - { - vnc_zlog_debug_verbose ("%s: can't convert vn address, skipping", __func__); - return; - } - - pAddr = &nhp.u.prefix4; - - /* - * Loop over the list of NVE-Groups configured for - * exporting to zebra and see if this new NVE's - * group is among them. - */ - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) - { - - /* - * Yes, this NVE's group is configured for export to zebra - */ - if (rfgn->rfg == rfg) - { - - struct route_table *rt = NULL; - struct route_node *rn; - struct rfapi_import_table *import_table; - import_table = rfg->rfapi_import_table; - - vnc_zlog_debug_verbose ("%s: this nve's group is in zebra export list", - __func__); - - rt = import_table->imported_vpn[afi]; - - /* - * Walk the NVE-Group's VNC Import table - */ - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - - if (rn->info) - { - - vnc_zlog_debug_verbose ("%s: sending %s", __func__, - (add ? "add" : "del")); - vnc_zebra_route_msg (&rn->p, 1, &pAddr, add); - } - } - } - } + struct listnode *node; + struct rfapi_rfg_name *rfgn; + struct rfapi_nve_group_cfg *rfg = rfd->rfg; + afi_t afi = family2afi(rfd->vn_addr.addr_family); + struct prefix nhp; + // struct prefix *nhpp; + void *pAddr; + + vnc_zlog_debug_verbose("%s: entry, add=%d", __func__, add); + + if (zclient_vnc->sock < 0) + return; + + if (!zclient_vnc->redist[afi][ZEBRA_ROUTE_VNC]) + return; + + if (afi != AFI_IP && afi != AFI_IP6) { + zlog_err("%s: invalid vn addr family", __func__); + return; + } + + if (!bgp) + return; + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", + __func__); + return; + } + + if (rfapiRaddr2Qprefix(&rfd->vn_addr, &nhp)) { + vnc_zlog_debug_verbose("%s: can't convert vn address, skipping", + __func__); + return; + } + + pAddr = &nhp.u.prefix4; + + /* + * Loop over the list of NVE-Groups configured for + * exporting to zebra and see if this new NVE's + * group is among them. + */ + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, + rfgn)) { + + /* + * Yes, this NVE's group is configured for export to zebra + */ + if (rfgn->rfg == rfg) { + + struct route_table *rt = NULL; + struct route_node *rn; + struct rfapi_import_table *import_table; + import_table = rfg->rfapi_import_table; + + vnc_zlog_debug_verbose( + "%s: this nve's group is in zebra export list", + __func__); + + rt = import_table->imported_vpn[afi]; + + /* + * Walk the NVE-Group's VNC Import table + */ + for (rn = route_top(rt); rn; rn = route_next(rn)) { + + if (rn->info) { + + vnc_zlog_debug_verbose( + "%s: sending %s", __func__, + (add ? "add" : "del")); + vnc_zebra_route_msg(&rn->p, 1, &pAddr, + add); + } + } + } + } } -void -vnc_zebra_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd) +void vnc_zebra_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) { - vnc_zebra_add_del_nve (bgp, rfd, 1); + vnc_zebra_add_del_nve(bgp, rfd, 1); } -void -vnc_zebra_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd) +void vnc_zebra_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd) { - vnc_zebra_add_del_nve (bgp, rfd, 0); + vnc_zebra_add_del_nve(bgp, rfd, 0); } -static void -vnc_zebra_add_del_group_afi ( - struct bgp *bgp, - struct rfapi_nve_group_cfg *rfg, - afi_t afi, - int add) +static void vnc_zebra_add_del_group_afi(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg, + afi_t afi, int add) { - struct route_table *rt = NULL; - struct route_node *rn; - struct rfapi_import_table *import_table; - uint8_t family = afi2family (afi); - - struct list *nves = NULL; - int nexthop_count = 0; - void *nh_ary = NULL; - void *nhp_ary = NULL; - - vnc_zlog_debug_verbose ("%s: entry", __func__); - import_table = rfg->rfapi_import_table; - if (!import_table) - { - vnc_zlog_debug_verbose ("%s: import table not defined, returning", __func__); - return; - } - - if (afi == AFI_IP - || afi == AFI_IP6) - { - rt = import_table->imported_vpn[afi]; - } - else - { - zlog_err ("%s: bad afi %d", __func__, afi); - return; - } - - if (!family) - { - zlog_err ("%s: computed bad family: %d", __func__, family); - return; - } - - if (!rfg->nves) - { - /* avoid segfault below if list doesn't exist */ - vnc_zlog_debug_verbose ("%s: no NVEs in this group", __func__); - return; - } - - nve_group_to_nve_list (rfg, &nves, family); - if (nves) - { - vnc_zlog_debug_verbose ("%s: have nves", __func__); - nve_list_to_nh_array (family, nves, &nexthop_count, &nh_ary, &nhp_ary); - - vnc_zlog_debug_verbose ("%s: family: %d, nve count: %d", __func__, family, - nexthop_count); - - list_delete (nves); - - if (nexthop_count) - { - /* - * Walk the NVE-Group's VNC Import table - */ - for (rn = route_top (rt); rn; rn = route_next (rn)) - { - if (rn->info) - { - vnc_zebra_route_msg (&rn->p, nexthop_count, nhp_ary, add); - } - } - } - if (nhp_ary) - XFREE (MTYPE_TMP, nhp_ary); - if (nh_ary) - XFREE (MTYPE_TMP, nh_ary); - } + struct route_table *rt = NULL; + struct route_node *rn; + struct rfapi_import_table *import_table; + uint8_t family = afi2family(afi); + + struct list *nves = NULL; + int nexthop_count = 0; + void *nh_ary = NULL; + void *nhp_ary = NULL; + + vnc_zlog_debug_verbose("%s: entry", __func__); + import_table = rfg->rfapi_import_table; + if (!import_table) { + vnc_zlog_debug_verbose( + "%s: import table not defined, returning", __func__); + return; + } + + if (afi == AFI_IP || afi == AFI_IP6) { + rt = import_table->imported_vpn[afi]; + } else { + zlog_err("%s: bad afi %d", __func__, afi); + return; + } + + if (!family) { + zlog_err("%s: computed bad family: %d", __func__, family); + return; + } + + if (!rfg->nves) { + /* avoid segfault below if list doesn't exist */ + vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__); + return; + } + + nve_group_to_nve_list(rfg, &nves, family); + if (nves) { + vnc_zlog_debug_verbose("%s: have nves", __func__); + nve_list_to_nh_array(family, nves, &nexthop_count, &nh_ary, + &nhp_ary); + + vnc_zlog_debug_verbose("%s: family: %d, nve count: %d", + __func__, family, nexthop_count); + + list_delete(nves); + + if (nexthop_count) { + /* + * Walk the NVE-Group's VNC Import table + */ + for (rn = route_top(rt); rn; rn = route_next(rn)) { + if (rn->info) { + vnc_zebra_route_msg(&rn->p, + nexthop_count, + nhp_ary, add); + } + } + } + if (nhp_ary) + XFREE(MTYPE_TMP, nhp_ary); + if (nh_ary) + XFREE(MTYPE_TMP, nh_ary); + } } -void -vnc_zebra_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) +void vnc_zebra_add_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) { - vnc_zebra_add_del_group_afi (bgp, rfg, AFI_IP, 1); - vnc_zebra_add_del_group_afi (bgp, rfg, AFI_IP6, 1); + vnc_zebra_add_del_group_afi(bgp, rfg, AFI_IP, 1); + vnc_zebra_add_del_group_afi(bgp, rfg, AFI_IP6, 1); } -void -vnc_zebra_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) +void vnc_zebra_del_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) { - vnc_zlog_debug_verbose ("%s: entry", __func__); - vnc_zebra_add_del_group_afi (bgp, rfg, AFI_IP, 0); - vnc_zebra_add_del_group_afi (bgp, rfg, AFI_IP6, 0); + vnc_zlog_debug_verbose("%s: entry", __func__); + vnc_zebra_add_del_group_afi(bgp, rfg, AFI_IP, 0); + vnc_zebra_add_del_group_afi(bgp, rfg, AFI_IP6, 0); } -void -vnc_zebra_reexport_group_afi ( - struct bgp *bgp, - struct rfapi_nve_group_cfg *rfg, - afi_t afi) +void vnc_zebra_reexport_group_afi(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg, afi_t afi) { - struct listnode *node; - struct rfapi_rfg_name *rfgn; - - for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) - { - - if (rfgn->rfg == rfg) - { - vnc_zebra_add_del_group_afi (bgp, rfg, afi, 0); - vnc_zebra_add_del_group_afi (bgp, rfg, afi, 1); - break; - } - } + struct listnode *node; + struct rfapi_rfg_name *rfgn; + + for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, + rfgn)) { + + if (rfgn->rfg == rfg) { + vnc_zebra_add_del_group_afi(bgp, rfg, afi, 0); + vnc_zebra_add_del_group_afi(bgp, rfg, afi, 1); + break; + } + } } @@ -1031,77 +959,76 @@ vnc_zebra_reexport_group_afi ( /* Other routes redistribution into BGP. */ -int -vnc_redistribute_set (struct bgp *bgp, afi_t afi, int type) +int vnc_redistribute_set(struct bgp *bgp, afi_t afi, int type) { - if (!bgp->rfapi_cfg) - { - return CMD_WARNING_CONFIG_FAILED; - } + if (!bgp->rfapi_cfg) { + return CMD_WARNING_CONFIG_FAILED; + } - /* Set flag to BGP instance. */ - bgp->rfapi_cfg->redist[afi][type] = 1; + /* Set flag to BGP instance. */ + bgp->rfapi_cfg->redist[afi][type] = 1; -// bgp->redist[afi][type] = 1; + // bgp->redist[afi][type] = 1; - /* Return if already redistribute flag is set. */ - if (zclient_vnc->redist[afi][type]) - return CMD_WARNING_CONFIG_FAILED; + /* Return if already redistribute flag is set. */ + if (zclient_vnc->redist[afi][type]) + return CMD_WARNING_CONFIG_FAILED; - vrf_bitmap_set (zclient_vnc->redist[afi][type], VRF_DEFAULT); + vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT); - //zclient_vnc->redist[afi][type] = 1; + // zclient_vnc->redist[afi][type] = 1; - /* Return if zebra connection is not established. */ - if (zclient_vnc->sock < 0) - return CMD_WARNING_CONFIG_FAILED; + /* Return if zebra connection is not established. */ + if (zclient_vnc->sock < 0) + return CMD_WARNING_CONFIG_FAILED; - if (BGP_DEBUG (zebra, ZEBRA)) - vnc_zlog_debug_verbose ("Zebra send: redistribute add %s", zebra_route_string (type)); + if (BGP_DEBUG(zebra, ZEBRA)) + vnc_zlog_debug_verbose("Zebra send: redistribute add %s", + zebra_route_string(type)); - /* Send distribute add message to zebra. */ - zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient_vnc, afi, type, 0, VRF_DEFAULT); + /* Send distribute add message to zebra. */ + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient_vnc, afi, type, + 0, VRF_DEFAULT); - return CMD_SUCCESS; + return CMD_SUCCESS; } /* Unset redistribution. */ -int -vnc_redistribute_unset (struct bgp *bgp, afi_t afi, int type) +int vnc_redistribute_unset(struct bgp *bgp, afi_t afi, int type) { - vnc_zlog_debug_verbose ("%s: type=%d entry", __func__, type); - - if (!bgp->rfapi_cfg) - { - vnc_zlog_debug_verbose ("%s: return (no rfapi_cfg)", __func__); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Unset flag from BGP instance. */ - bgp->rfapi_cfg->redist[afi][type] = 0; - - /* Return if zebra connection is disabled. */ - if (!zclient_vnc->redist[afi][type]) - return CMD_WARNING_CONFIG_FAILED; - zclient_vnc->redist[afi][type] = 0; - - if (bgp->rfapi_cfg->redist[AFI_IP][type] == 0 - && bgp->rfapi_cfg->redist[AFI_IP6][type] == 0 && zclient_vnc->sock >= 0) - { - /* Send distribute delete message to zebra. */ - if (BGP_DEBUG (zebra, ZEBRA)) - vnc_zlog_debug_verbose ("Zebra send: redistribute delete %s", - zebra_route_string (type)); - zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient_vnc, afi, type, - 0, VRF_DEFAULT); - } - - /* Withdraw redistributed routes from current BGP's routing table. */ - vnc_redistribute_withdraw (bgp, afi, type); - - vnc_zlog_debug_verbose ("%s: return", __func__); - - return CMD_SUCCESS; + vnc_zlog_debug_verbose("%s: type=%d entry", __func__, type); + + if (!bgp->rfapi_cfg) { + vnc_zlog_debug_verbose("%s: return (no rfapi_cfg)", __func__); + return CMD_WARNING_CONFIG_FAILED; + } + + /* Unset flag from BGP instance. */ + bgp->rfapi_cfg->redist[afi][type] = 0; + + /* Return if zebra connection is disabled. */ + if (!zclient_vnc->redist[afi][type]) + return CMD_WARNING_CONFIG_FAILED; + zclient_vnc->redist[afi][type] = 0; + + if (bgp->rfapi_cfg->redist[AFI_IP][type] == 0 + && bgp->rfapi_cfg->redist[AFI_IP6][type] == 0 + && zclient_vnc->sock >= 0) { + /* Send distribute delete message to zebra. */ + if (BGP_DEBUG(zebra, ZEBRA)) + vnc_zlog_debug_verbose( + "Zebra send: redistribute delete %s", + zebra_route_string(type)); + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient_vnc, + afi, type, 0, VRF_DEFAULT); + } + + /* Withdraw redistributed routes from current BGP's routing table. */ + vnc_redistribute_withdraw(bgp, afi, type); + + vnc_zlog_debug_verbose("%s: return", __func__); + + return CMD_SUCCESS; } @@ -1109,25 +1036,23 @@ vnc_redistribute_unset (struct bgp *bgp, afi_t afi, int type) * Modeled after bgp_zebra.c'bgp_zebra_init() * Charriere asks, "Is it possible to carry two?" */ -void -vnc_zebra_init (struct thread_master *master) +void vnc_zebra_init(struct thread_master *master) { - /* Set default values. */ - zclient_vnc = zclient_new (master); - zclient_init (zclient_vnc, ZEBRA_ROUTE_VNC, 0); - - zclient_vnc->redistribute_route_ipv4_add = vnc_zebra_read_ipv4; - zclient_vnc->redistribute_route_ipv4_del = vnc_zebra_read_ipv4; - zclient_vnc->redistribute_route_ipv6_add = vnc_zebra_read_ipv6; - zclient_vnc->redistribute_route_ipv6_del = vnc_zebra_read_ipv6; + /* Set default values. */ + zclient_vnc = zclient_new(master); + zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0); + + zclient_vnc->redistribute_route_ipv4_add = vnc_zebra_read_ipv4; + zclient_vnc->redistribute_route_ipv4_del = vnc_zebra_read_ipv4; + zclient_vnc->redistribute_route_ipv6_add = vnc_zebra_read_ipv6; + zclient_vnc->redistribute_route_ipv6_del = vnc_zebra_read_ipv6; } -void -vnc_zebra_destroy (void) +void vnc_zebra_destroy(void) { - if (zclient_vnc == NULL) - return; - zclient_stop (zclient_vnc); - zclient_free (zclient_vnc); - zclient_vnc = NULL; + if (zclient_vnc == NULL) + return; + zclient_stop(zclient_vnc); + zclient_free(zclient_vnc); + zclient_vnc = NULL; } diff --git a/bgpd/rfapi/vnc_zebra.h b/bgpd/rfapi/vnc_zebra.h index 68e567ec35..708aaeef50 100644 --- a/bgpd/rfapi/vnc_zebra.h +++ b/bgpd/rfapi/vnc_zebra.h @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -27,40 +27,30 @@ #include "lib/zebra.h" -extern void -vnc_zebra_add_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn); +extern void vnc_zebra_add_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn); -extern void -vnc_zebra_del_prefix ( - struct bgp *bgp, - struct rfapi_import_table *import_table, - struct route_node *rn); +extern void vnc_zebra_del_prefix(struct bgp *bgp, + struct rfapi_import_table *import_table, + struct route_node *rn); -extern void -vnc_zebra_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd); +extern void vnc_zebra_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd); -extern void -vnc_zebra_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd); +extern void vnc_zebra_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd); -extern void -vnc_zebra_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); +extern void vnc_zebra_add_group(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg); -extern void -vnc_zebra_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); +extern void vnc_zebra_del_group(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg); -extern void -vnc_zebra_reexport_group_afi ( - struct bgp *bgp, - struct rfapi_nve_group_cfg *rfg, - afi_t afi); +extern void vnc_zebra_reexport_group_afi(struct bgp *bgp, + struct rfapi_nve_group_cfg *rfg, + afi_t afi); -extern int -vnc_redistribute_set (struct bgp *bgp, afi_t afi, int type); +extern int vnc_redistribute_set(struct bgp *bgp, afi_t afi, int type); -extern int -vnc_redistribute_unset (struct bgp *bgp, afi_t afi, int type); +extern int vnc_redistribute_unset(struct bgp *bgp, afi_t afi, int type); #endif /* _QUAGGA_BGP_VNC_ZEBRA_H */ |
