diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-08-29 04:45:06 +0200 |
---|---|---|
committer | Philippe Guibert <philippe.guibert@6wind.com> | 2018-08-31 11:29:27 +0200 |
commit | f591b309f2c938de48e826c9e669fe88110dd9ed (patch) | |
tree | 9e59b33649210fb9d80cf4047eb3a6f77da9699f /staticd | |
parent | vtysh: Let staticd know about vrf sub-mode (diff) | |
download | frr-f591b309f2c938de48e826c9e669fe88110dd9ed.tar.xz frr-f591b309f2c938de48e826c9e669fe88110dd9ed.zip |
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>
Diffstat (limited to 'staticd')
-rw-r--r-- | staticd/static_nht.c | 66 | ||||
-rw-r--r-- | staticd/static_zebra.c | 22 |
2 files changed, 55 insertions, 33 deletions
diff --git a/staticd/static_nht.c b/staticd/static_nht.c index c6e4587b6..44f7fb79d 100644 --- a/staticd/static_nht.c +++ b/staticd/static_nht.c @@ -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; + } } } } diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index a87dc074d..4692dc00d 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -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; |