From: Lou Berger Date: Sun, 15 Jan 2017 21:43:20 +0000 (-0500) Subject: bgpd rfapi: fix issue where advertised prefixes were not being disambiguated X-Git-Tag: frr-3.0-branchpoint~64^2~4^2~4 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=cedb5a712431fcb6b1c2eb80d01dc3e0b9ea19f9;p=matthieu%2Ffrr.git bgpd rfapi: fix issue where advertised prefixes were not being disambiguated by RD Signed-off-by: Lou Berger --- diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 61da18a308..6353f7dacf 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -2777,7 +2777,7 @@ rfapi_register ( NULL, action == RFAPI_REGISTER_KILL); - if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &adv_tunnel)) + if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &prd, &adv_tunnel)) { if (adv_tunnel) rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime); diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c index 4b8eb9511b..4c415504fa 100644 --- a/bgpd/rfapi/rfapi_ap.c +++ b/bgpd/rfapi/rfapi_ap.c @@ -103,12 +103,11 @@ sl_adb_lifetime_cmp (void *adb1, void *adb2) return 0; } - void rfapiApInit (struct rfapi_advertised_prefixes *ap) { - ap->ipN_by_prefix = skiplist_new (0, vnc_prefix_cmp, NULL); - ap->ip0_by_ether = skiplist_new (0, vnc_prefix_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); } @@ -192,7 +191,7 @@ rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd) * 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->prefix_ip, &prd, /* RD to use (0 for ENCAP) */ + 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 */ @@ -221,11 +220,11 @@ rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd) struct prefix pfx_vn_buf; struct prefix *pfx_ip; - if (!(RFAPI_0_PREFIX (&adb->prefix_ip) && - RFAPI_HOST_PREFIX (&adb->prefix_ip))) + if (!(RFAPI_0_PREFIX (&adb->u.s.prefix_ip) && + RFAPI_HOST_PREFIX (&adb->u.s.prefix_ip))) { - pfx_ip = &adb->prefix_ip; + pfx_ip = &adb->u.s.prefix_ip; } else @@ -247,7 +246,7 @@ rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd) } } - del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->prd, /* RD to use (0 for ENCAP) */ + 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); } } @@ -404,19 +403,19 @@ rfapiApAdjustLifetimeStats ( { void *cursor; - struct prefix *prefix; - struct rfapi_adb *adb; + 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 **) &prefix, (void **) &adb, + (void **) &rk, (void **) &adb, &cursor); !rc; rc = skiplist_next (rfd->advertised.ipN_by_prefix, - (void **) &prefix, (void **) &adb, &cursor)) + (void **) &rk, (void **) &adb, &cursor)) { uint32_t lt = adb->lifetime; @@ -428,10 +427,10 @@ rfapiApAdjustLifetimeStats ( } cursor = NULL; for (rc = skiplist_next (rfd->advertised.ip0_by_ether, - (void **) &prefix, (void **) &adb, + (void **) &rk, (void **) &adb, &cursor); !rc; rc = - skiplist_next (rfd->advertised.ip0_by_ether, (void **) &prefix, + skiplist_next (rfd->advertised.ip0_by_ether, (void **) &rk, (void **) &adb, &cursor)) { @@ -483,14 +482,15 @@ rfapiApAdd ( 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, pfx_eth, + skiplist_search (rfd->advertised.ip0_by_ether, &rk, (void **) &adb); } @@ -499,7 +499,7 @@ rfapiApAdd ( /* find prefix in advertised prefixes list */ rc = - skiplist_search (rfd->advertised.ipN_by_prefix, pfx_ip, + skiplist_search (rfd->advertised.ipN_by_prefix, &rk, (void **) &adb); } @@ -510,19 +510,17 @@ rfapiApAdd ( adb = XCALLOC (MTYPE_RFAPI_ADB, sizeof (struct rfapi_adb)); assert (adb); adb->lifetime = lifetime; - adb->prefix_ip = *pfx_ip; - if (pfx_eth) - adb->prefix_eth = *pfx_eth; + adb->u.key = rk; if (use_ip0) { assert (pfx_eth); - skiplist_insert (rfd->advertised.ip0_by_ether, &adb->prefix_eth, + skiplist_insert (rfd->advertised.ip0_by_ether, &adb->u.key, adb); } else { - skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->prefix_ip, + skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->u.key, adb); } @@ -537,19 +535,12 @@ rfapiApAdd ( adb->lifetime = lifetime; assert (!skiplist_insert (rfd->advertised.by_lifetime, adb, adb)); } - - if (!use_ip0 && pfx_eth && prefix_cmp (&adb->prefix_eth, pfx_eth)) - { - /* mac address changed */ - adb->prefix_eth = *pfx_eth; - } } adb->cost = cost; if (l2o) adb->l2o = *l2o; else memset (&adb->l2o, 0, sizeof (struct rfapi_l2address_option)); - adb->prd = *prd; if (rfapiApAdjustLifetimeStats (rfd, (rc ? NULL : &old_lifetime), &lifetime)) @@ -568,16 +559,19 @@ rfapiApDelete ( 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)) { @@ -585,7 +579,7 @@ rfapiApDelete ( assert (pfx_eth); rc = - skiplist_search (rfd->advertised.ip0_by_ether, pfx_eth, + skiplist_search (rfd->advertised.ip0_by_ether, &rk, (void **) &adb); } @@ -594,7 +588,7 @@ rfapiApDelete ( /* find prefix in advertised prefixes list */ rc = - skiplist_search (rfd->advertised.ipN_by_prefix, pfx_ip, + skiplist_search (rfd->advertised.ipN_by_prefix, &rk, (void **) &adb); } @@ -607,11 +601,11 @@ rfapiApDelete ( if (use_ip0) { - rc = skiplist_delete (rfd->advertised.ip0_by_ether, pfx_eth, NULL); + rc = skiplist_delete (rfd->advertised.ip0_by_ether, &rk, NULL); } else { - rc = skiplist_delete (rfd->advertised.ipN_by_prefix, pfx_ip, NULL); + rc = skiplist_delete (rfd->advertised.ipN_by_prefix, &rk, NULL); } assert (!rc); diff --git a/bgpd/rfapi/rfapi_ap.h b/bgpd/rfapi/rfapi_ap.h index f2805f49cb..8a59f05274 100644 --- a/bgpd/rfapi/rfapi_ap.h +++ b/bgpd/rfapi/rfapi_ap.h @@ -93,6 +93,7 @@ rfapiApDelete ( struct rfapi_descriptor *rfd, struct prefix *pfx_ip, struct prefix *pfx_eth, + struct prefix_rd *prd, int *advertise_tunnel); /* out */ diff --git a/bgpd/rfapi/rfapi_private.h b/bgpd/rfapi/rfapi_private.h index 33390c4f55..00f90e35fc 100644 --- a/bgpd/rfapi/rfapi_private.h +++ b/bgpd/rfapi/rfapi_private.h @@ -34,21 +34,6 @@ #include "rfapi.h" -/* - * RFAPI Advertisement Data Block - * - * Holds NVE prefix advertisement information - */ -struct rfapi_adb -{ - struct prefix prefix_ip; - struct prefix prefix_eth; /* now redundant with l2o */ - struct prefix_rd prd; - uint32_t lifetime; - uint8_t cost; - struct rfapi_l2address_option l2o; -}; - /* * Lists of rfapi_adb. Each rfapi_adb is referenced twice: * @@ -62,7 +47,6 @@ struct rfapi_advertised_prefixes struct skiplist *by_lifetime; /* all */ }; - struct rfapi_descriptor { struct route_node *un_node; /* backref to un table */ @@ -378,9 +362,6 @@ rfp_cost_to_localpref (uint8_t cost); extern int rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn); -extern void -rfapiAdbFree (struct rfapi_adb *adb); - extern struct rfapi_nexthop * rfapi_nexthop_new (struct rfapi_nexthop *copyme); diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 6aae35e635..3a4a159215 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -405,10 +405,26 @@ rfapiRibStartTimer ( 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) + +{ + 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 s */ -static int +int rfapi_rib_key_cmp (void *k1, void *k2) { struct rfapi_rib_key *a = (struct rfapi_rib_key *) k1; diff --git a/bgpd/rfapi/rfapi_rib.h b/bgpd/rfapi/rfapi_rib.h index 2a111946f7..74331a28d0 100644 --- a/bgpd/rfapi/rfapi_rib.h +++ b/bgpd/rfapi/rfapi_rib.h @@ -45,6 +45,27 @@ struct rfapi_rib_key */ struct prefix aux_prefix; }; +#include "rfapi.h" + +/* + * RFAPI Advertisement Data Block + * + * 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_info { @@ -151,4 +172,16 @@ 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 int +rfapi_rib_key_cmp (void *k1, void *k2); + +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 3e179b7f72..ed3155307d 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -1846,14 +1846,14 @@ rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd) { /* group like family prefixes together in output */ - if (family != adb->prefix_ip.family) + if (family != adb->u.s.prefix_ip.family) continue; - prefix2str (&adb->prefix_ip, buf, BUFSIZ); + prefix2str (&adb->u.s.prefix_ip, buf, BUFSIZ); buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ vty_out (vty, " Adv Pfx: %s%s", buf, HVTY_NEWLINE); - rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->prefix_ip); + rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip); } } for (rc = @@ -1864,14 +1864,14 @@ rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd) &cursor)) { - prefix2str (&adb->prefix_eth, buf, BUFSIZ); + prefix2str (&adb->u.s.prefix_eth, buf, BUFSIZ); buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ vty_out (vty, " Adv Pfx: %s%s", buf, HVTY_NEWLINE); /* TBD update the following function to print ethernet info */ /* Also need to pass/use rd */ - rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->prefix_ip); + rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip); } vty_out (vty, "%s", HVTY_NEWLINE); } @@ -3375,7 +3375,7 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) if (pPrefix) { - if (!prefix_same (pPrefix, &adb->prefix_ip)) + 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", @@ -3388,7 +3388,7 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) { if (memcmp (cda->l2o.o.macaddr.octet, - adb->prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN)) + 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", @@ -3430,24 +3430,23 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) this_advertisement_prefix_count = 1; - rfapiQprefix2Rprefix (&adb->prefix_ip, &rp); + rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp); /* if mac addr present in advert, make l2o vn option */ - if (adb->prefix_eth.family == AF_ETHERNET) + if (adb->u.s.prefix_eth.family == AF_ETHERNET) { - memset (&vn1, 0, sizeof (vn1)); memset (&vn2, 0, sizeof (vn2)); vn1.type = RFAPI_VN_OPTION_TYPE_L2ADDR; - vn1.v.l2addr.macaddr = adb->prefix_eth.u.prefix_eth; + vn1.v.l2addr.macaddr = adb->u.s.prefix_eth.u.prefix_eth; /* * use saved RD value instead of trying to invert * complex L2-style RD computation in rfapi_register() */ vn2.type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; - vn2.v.internal_rd = adb->prd; + vn2.v.internal_rd = adb->u.s.prd; vn1.next = &vn2; @@ -3499,7 +3498,7 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR)) { if (memcmp (cda->l2o.o.macaddr.octet, - adb->prefix_eth.u.prefix_eth.octet, + adb->u.s.prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN)) { @@ -3526,7 +3525,7 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) struct rfapi_vn_option vn; - rfapiQprefix2Rprefix (&adb->prefix_ip, &rp); + rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp); memset (&vn, 0, sizeof (vn)); vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR;