]> git.puffer.fish Git - mirror/frr.git/commitdiff
staticd: Fix mixup in vrf translations
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 29 Aug 2018 02:45:06 +0000 (22:45 -0400)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 31 Aug 2018 09:29:27 +0000 (11:29 +0200)
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>
staticd/static_nht.c
staticd/static_zebra.c

index c6e4587b6aafa1691cffb49082a7c12c73b1fea9..44f7fb79da8d45eb6fba677a93078d1d9cb6941e 100644 (file)
@@ -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;
+                               }
                        }
                }
        }
index a87dc074dfc07e2d5f1bfcd41adae3917dc2dde2..4692dc00d7143a9c988a69748e06b31fcb339139 100644 (file)
@@ -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;