mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-25 09:10:57 +00:00
bgpd rfapi: fix issue where advertised prefixes were not being disambiguated
by RD Signed-off-by: Lou Berger <lberger@labn.net>
This commit is contained in:
parent
764581d286
commit
d1dc07bb04
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 <struct rfapi_rib_key>s
|
||||
*/
|
||||
static int
|
||||
int
|
||||
rfapi_rib_key_cmp (void *k1, void *k2)
|
||||
{
|
||||
struct rfapi_rib_key *a = (struct rfapi_rib_key *) k1;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
@ -3363,7 +3363,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",
|
||||
@ -3376,7 +3376,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",
|
||||
@ -3418,24 +3418,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;
|
||||
|
||||
@ -3487,7 +3486,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))
|
||||
{
|
||||
|
||||
@ -3514,7 +3513,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;
|
||||
|
Loading…
Reference in New Issue
Block a user