summaryrefslogtreecommitdiff
path: root/bgpd/rfapi/vnc_export_bgp.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/rfapi/vnc_export_bgp.c')
-rw-r--r--bgpd/rfapi/vnc_export_bgp.c3660
1 files changed, 1781 insertions, 1879 deletions
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);
}