summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_pbr.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-03-22 13:26:27 +0100
committerDonald Sharp <sharpd@cumulusnetworks.com>2018-03-22 18:58:30 +0100
commit8c3cd6c65ce1b557187ae2e74395a59b9b08a714 (patch)
tree955e9c2a5bc7774c7f4d8bc533f09fe4d7d2c6fc /zebra/zebra_pbr.c
parentMerge pull request #1947 from LabNConsulting/working/master/bgp-vpn-leak-cras... (diff)
downloadfrr-8c3cd6c65ce1b557187ae2e74395a59b9b08a714.tar.xz
frr-8c3cd6c65ce1b557187ae2e74395a59b9b08a714.zip
zebra: Allow rule replace semantics
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>
Diffstat (limited to 'zebra/zebra_pbr.c')
-rw-r--r--zebra/zebra_pbr.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 090ec2c50..a9bc8450e 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -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)