summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLou Berger <lberger@labn.net>2017-01-15 16:43:20 -0500
committerLou Berger <lberger@labn.net>2017-01-22 20:54:39 -0500
commitcedb5a712431fcb6b1c2eb80d01dc3e0b9ea19f9 (patch)
treeea125d67d6309484402510a6a841d284e7ec20b8
parente5fe6d593123657f82786d568a9e8969dda35e59 (diff)
bgpd rfapi: fix issue where advertised prefixes were not being disambiguated
by RD Signed-off-by: Lou Berger <lberger@labn.net>
-rw-r--r--bgpd/rfapi/rfapi.c2
-rw-r--r--bgpd/rfapi/rfapi_ap.c60
-rw-r--r--bgpd/rfapi/rfapi_ap.h1
-rw-r--r--bgpd/rfapi/rfapi_private.h19
-rw-r--r--bgpd/rfapi/rfapi_rib.c18
-rw-r--r--bgpd/rfapi/rfapi_rib.h33
-rw-r--r--bgpd/rfapi/rfapi_vty.c27
7 files changed, 92 insertions, 68 deletions
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
@@ -35,21 +35,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:
*
* 1. each is referenced in by_lifetime
@@ -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 <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;
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;