mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-25 07:28:41 +00:00
staticd: Fix mixup in vrf translations
When we store the nexthop for ref-counting, keep track of the nexthop vrf_id as well. This will allow us to track the nexthop per vrf! Additionally when we get the callback from zebra about a nexthop update, iterate over all static routes to see if the nexthop we are getting a callback is one we are concerned about. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
533ab00846
commit
31e2232baa
@ -29,8 +29,8 @@
|
||||
#include "static_zebra.h"
|
||||
#include "static_nht.h"
|
||||
|
||||
void static_nht_update(struct prefix *p, uint32_t nh_num,
|
||||
afi_t afi, vrf_id_t vrf_id)
|
||||
void static_nht_update(struct prefix *p, uint32_t nh_num, afi_t afi,
|
||||
vrf_id_t nh_vrf_id)
|
||||
{
|
||||
struct route_table *stable;
|
||||
struct static_route *si;
|
||||
@ -40,41 +40,47 @@ void static_nht_update(struct prefix *p, uint32_t nh_num,
|
||||
bool orig;
|
||||
bool reinstall;
|
||||
|
||||
vrf = vrf_lookup_by_id(vrf_id);
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
||||
svrf = vrf->info;
|
||||
if (!svrf)
|
||||
continue;
|
||||
|
||||
if (!vrf || !vrf->info)
|
||||
return;
|
||||
stable = static_vrf_static_table(afi, SAFI_UNICAST, svrf);
|
||||
if (!stable)
|
||||
continue;
|
||||
|
||||
svrf = vrf->info;
|
||||
stable = static_vrf_static_table(afi, SAFI_UNICAST, svrf);
|
||||
if (!stable)
|
||||
return;
|
||||
for (rn = route_top(stable); rn; rn = route_next(rn)) {
|
||||
reinstall = false;
|
||||
for (si = rn->info; si; si = si->next) {
|
||||
if (si->nh_vrf_id != nh_vrf_id)
|
||||
continue;
|
||||
|
||||
for (rn = route_top(stable); rn; rn = route_next(rn)) {
|
||||
reinstall = false;
|
||||
for (si = rn->info; si; si = si->next) {
|
||||
if (si->type != STATIC_IPV4_GATEWAY &&
|
||||
si->type != STATIC_IPV4_GATEWAY_IFNAME &&
|
||||
si->type != STATIC_IPV6_GATEWAY &&
|
||||
si->type != STATIC_IPV6_GATEWAY_IFNAME)
|
||||
continue;
|
||||
if (si->type != STATIC_IPV4_GATEWAY
|
||||
&& si->type != STATIC_IPV4_GATEWAY_IFNAME
|
||||
&& si->type != STATIC_IPV6_GATEWAY
|
||||
&& si->type != STATIC_IPV6_GATEWAY_IFNAME)
|
||||
continue;
|
||||
|
||||
orig = si->nh_valid;
|
||||
if (p->family == AF_INET &&
|
||||
p->u.prefix4.s_addr == si->addr.ipv4.s_addr)
|
||||
si->nh_valid = !!nh_num;
|
||||
orig = si->nh_valid;
|
||||
if (p->family == AF_INET
|
||||
&& p->u.prefix4.s_addr
|
||||
== si->addr.ipv4.s_addr)
|
||||
si->nh_valid = !!nh_num;
|
||||
|
||||
if (p->family == AF_INET6 &&
|
||||
memcmp(&p->u.prefix6, &si->addr.ipv6, 16) == 0)
|
||||
si->nh_valid = !!nh_num;
|
||||
if (p->family == AF_INET6
|
||||
&& memcmp(&p->u.prefix6, &si->addr.ipv6, 16)
|
||||
== 0)
|
||||
si->nh_valid = !!nh_num;
|
||||
|
||||
if (orig != si->nh_valid)
|
||||
reinstall = true;
|
||||
if (orig != si->nh_valid)
|
||||
reinstall = true;
|
||||
|
||||
if (reinstall) {
|
||||
static_zebra_route_add(rn, si, vrf_id,
|
||||
SAFI_UNICAST, true);
|
||||
reinstall = false;
|
||||
if (reinstall) {
|
||||
static_zebra_route_add(
|
||||
rn, si, vrf->vrf_id,
|
||||
SAFI_UNICAST, true);
|
||||
reinstall = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "nexthop.h"
|
||||
#include "nexthop_group.h"
|
||||
#include "hash.h"
|
||||
#include "jhash.h"
|
||||
|
||||
#include "static_vrf.h"
|
||||
#include "static_routes.h"
|
||||
@ -180,6 +181,9 @@ static void zebra_connected(struct zclient *zclient)
|
||||
|
||||
struct static_nht_data {
|
||||
struct prefix *nh;
|
||||
|
||||
vrf_id_t nh_vrf_id;
|
||||
|
||||
uint32_t refcount;
|
||||
uint8_t nh_num;
|
||||
};
|
||||
@ -201,13 +205,18 @@ static int static_zebra_nexthop_update(int command, struct zclient *zclient,
|
||||
|
||||
memset(&lookup, 0, sizeof(lookup));
|
||||
lookup.nh = &nhr.prefix;
|
||||
lookup.nh_vrf_id = vrf_id;
|
||||
|
||||
nhtd = hash_lookup(static_nht_hash, &lookup);
|
||||
if (nhtd)
|
||||
|
||||
if (nhtd) {
|
||||
nhtd->nh_num = nhr.nexthop_num;
|
||||
|
||||
static_nht_update(&nhr.prefix, nhr.nexthop_num, afi,
|
||||
nhtd->nh_vrf_id);
|
||||
} else
|
||||
zlog_err("No nhtd?");
|
||||
|
||||
static_nht_update(&nhr.prefix, nhr.nexthop_num, afi, vrf_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -219,8 +228,10 @@ static void static_zebra_capabilities(struct zclient_capabilities *cap)
|
||||
static unsigned int static_nht_hash_key(void *data)
|
||||
{
|
||||
struct static_nht_data *nhtd = data;
|
||||
unsigned int key = 0;
|
||||
|
||||
return prefix_hash_key(nhtd->nh);
|
||||
key = prefix_hash_key(nhtd->nh);
|
||||
return jhash_1word(nhtd->nh_vrf_id, key);
|
||||
}
|
||||
|
||||
static int static_nht_hash_cmp(const void *d1, const void *d2)
|
||||
@ -228,6 +239,9 @@ static int static_nht_hash_cmp(const void *d1, const void *d2)
|
||||
const struct static_nht_data *nhtd1 = d1;
|
||||
const struct static_nht_data *nhtd2 = d2;
|
||||
|
||||
if (nhtd1->nh_vrf_id != nhtd2->nh_vrf_id)
|
||||
return 0;
|
||||
|
||||
return prefix_same(nhtd1->nh, nhtd2->nh);
|
||||
}
|
||||
|
||||
@ -242,6 +256,7 @@ static void *static_nht_hash_alloc(void *data)
|
||||
prefix_copy(new->nh, copy->nh);
|
||||
new->refcount = 0;
|
||||
new->nh_num = 0;
|
||||
new->nh_vrf_id = copy->nh_vrf_id;
|
||||
|
||||
return new;
|
||||
}
|
||||
@ -293,6 +308,7 @@ void static_zebra_nht_register(struct static_route *si, bool reg)
|
||||
|
||||
memset(&lookup, 0, sizeof(lookup));
|
||||
lookup.nh = &p;
|
||||
lookup.nh_vrf_id = si->nh_vrf_id;
|
||||
|
||||
si->nh_registered = reg;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user