]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: Use the rule ifindex as a hash key, not ifp
authorStephen Worley <sworley@cumulusnetworks.com>
Tue, 15 Oct 2019 18:50:10 +0000 (14:50 -0400)
committerStephen Worley <sworley@cumulusnetworks.com>
Tue, 15 Oct 2019 19:03:46 +0000 (15:03 -0400)
Use the ifindex value as a primary hash key/identifier, not
the ifp pointer. It is possible for that data to be freed
and then we would not be able to hash and find the rule entry
anymore. Using the ifindex, we can still find the rule even
if the interface is removed.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
zebra/rule_netlink.c
zebra/zapi_msg.c
zebra/zebra_pbr.c

index 711c4e087749559bb5a5f0adc1a0327670833318..1b465b03356da2cc615065838013b73ef0ae55d8 100644 (file)
@@ -123,7 +123,7 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule)
                        "Tx %s family %s IF %s(%u) Pref %u Fwmark %u Src %s Dst %s Table %u",
                        nl_msg_type_to_str(cmd), nl_family_to_str(family),
                        rule->ifp ? rule->ifp->name : "Unknown",
-                       rule->ifp ? rule->ifp->ifindex : 0, rule->rule.priority,
+                       rule->rule.ifindex, rule->rule.priority,
                        rule->rule.filter.fwmark,
                        prefix2str(&rule->rule.filter.src_ip, buf1,
                                   sizeof(buf1)),
index b0488b7559155ba0cc98165cee0e7f4a4d060b48..96faf6f1f79302d103bc6d371edc7e2f9af54087 100644 (file)
@@ -2294,7 +2294,6 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
        struct zebra_pbr_rule zpr;
        struct stream *s;
        uint32_t total, i;
-       ifindex_t ifindex;
 
        s = msg;
        STREAM_GETL(s, total);
@@ -2319,15 +2318,14 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
                STREAM_GETW(s, zpr.rule.filter.dst_port);
                STREAM_GETL(s, zpr.rule.filter.fwmark);
                STREAM_GETL(s, zpr.rule.action.table);
-               STREAM_GETL(s, ifindex);
+               STREAM_GETL(s, zpr.rule.ifindex);
 
-               if (ifindex) {
-                       zpr.ifp = if_lookup_by_index_per_ns(
-                                               zvrf->zns,
-                                               ifindex);
+               if (zpr.rule.ifindex) {
+                       zpr.ifp = if_lookup_by_index_per_ns(zvrf->zns,
+                                                           zpr.rule.ifindex);
                        if (!zpr.ifp) {
                                zlog_debug("Failed to lookup ifindex: %u",
-                                          ifindex);
+                                          zpr.rule.ifindex);
                                return;
                        }
                }
index 9a7d506731a93218c5e45e44068c9ef550bbeb1b..e77e29f13a05ebfd553e56a2be6c49c5c2f18bc5 100644 (file)
@@ -144,17 +144,12 @@ uint32_t zebra_pbr_rules_hash_key(const void *arg)
        key = jhash_3words(rule->rule.seq, rule->rule.priority,
                           rule->rule.action.table,
                           prefix_hash_key(&rule->rule.filter.src_ip));
-       if (rule->ifp)
-               key = jhash_1word(rule->ifp->ifindex, key);
-       else
-               key = jhash_1word(0, key);
 
        if (rule->rule.filter.fwmark)
-               key = jhash_1word(rule->rule.filter.fwmark, key);
+               key = jhash_3words(rule->rule.filter.fwmark, rule->vrf_id,
+                                  rule->rule.ifindex, key);
        else
-               key = jhash_1word(0, key);
-
-       key = jhash_1word(rule->vrf_id, key);
+               key = jhash_2words(rule->vrf_id, rule->rule.ifindex, key);
 
        return jhash_3words(rule->rule.filter.src_port,
                            rule->rule.filter.dst_port,
@@ -208,7 +203,7 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
 struct pbr_rule_unique_lookup {
        struct zebra_pbr_rule *rule;
        uint32_t unique;
-       struct interface *ifp;
+       ifindex_t ifindex;
        vrf_id_t vrf_id;
 };
 
@@ -218,7 +213,7 @@ static int pbr_rule_lookup_unique_walker(struct hash_bucket *b, void *data)
        struct zebra_pbr_rule *rule = b->data;
 
        if (pul->unique == rule->rule.unique
-           && pul->ifp == rule->ifp
+           && pul->ifindex == rule->rule.ifindex
            && pul->vrf_id == rule->vrf_id) {
                pul->rule = rule;
                return HASHWALK_ABORT;
@@ -233,7 +228,7 @@ pbr_rule_lookup_unique(struct zebra_pbr_rule *zrule)
        struct pbr_rule_unique_lookup pul;
 
        pul.unique = zrule->rule.unique;
-       pul.ifp = zrule->ifp;
+       pul.ifindex = zrule->rule.ifindex;
        pul.rule = NULL;
        pul.vrf_id = zrule->vrf_id;
        hash_walk(zrouter.rules_hash, &pbr_rule_lookup_unique_walker, &pul);