]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Allow rule replace semantics
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Mar 2018 12:26:27 +0000 (08:26 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Mar 2018 17:58:30 +0000 (13:58 -0400)
When we get a rule that is supposed to replace
an existing rule, make it look like a rule replace
semantics.

Install new rule, then delete the old original rule.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/zebra_pbr.c

index 090ec2c502d5b38f09c0c05602384fd75cecf49b..a9bc8450eeb499c36d7f511815354ab487333148 100644 (file)
@@ -99,6 +99,36 @@ int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
        return 1;
 }
 
+struct pbr_unique_lookup {
+       struct zebra_pbr_rule *rule;
+       uint32_t unique;
+};
+
+static int pbr_rule_lookup_unique_walker(struct hash_backet *b, void *data)
+{
+       struct pbr_unique_lookup *pul = data;
+       struct zebra_pbr_rule *rule = b->data;
+
+       if (pul->unique == rule->unique) {
+               pul->rule = rule;
+               return HASHWALK_ABORT;
+       }
+
+       return HASHWALK_CONTINUE;
+}
+
+static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_ns *zns,
+                                                    uint32_t unique)
+{
+       struct pbr_unique_lookup pul;
+
+       pul.unique = unique;
+       pul.rule = NULL;
+       hash_walk(zns->rules_hash, &pbr_rule_lookup_unique_walker, &pul);
+
+       return pul.rule;
+}
+
 static void *pbr_rule_alloc_intern(void *arg)
 {
        struct zebra_pbr_rule *zpr;
@@ -115,8 +145,18 @@ static void *pbr_rule_alloc_intern(void *arg)
 
 void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
 {
+       struct zebra_pbr_rule *unique =
+               pbr_rule_lookup_unique(zns, rule->unique);
+
        (void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern);
        kernel_add_pbr_rule(rule);
+
+       /*
+        * Rule Replace semantics, if we have an old, install the
+        * new rule, look above, and then delete the old
+        */
+       if (unique)
+               zebra_pbr_del_rule(zns, unique);
 }
 
 void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)