diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-03-22 13:26:27 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-03-22 18:58:30 +0100 |
commit | 8c3cd6c65ce1b557187ae2e74395a59b9b08a714 (patch) | |
tree | 955e9c2a5bc7774c7f4d8bc533f09fe4d7d2c6fc /zebra/zebra_pbr.c | |
parent | Merge pull request #1947 from LabNConsulting/working/master/bgp-vpn-leak-cras... (diff) | |
download | frr-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.c | 40 |
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) |