diff options
Diffstat (limited to 'zebra/zebra_pbr.c')
| -rw-r--r-- | zebra/zebra_pbr.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 6728567e6e..c049aa14f6 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -431,32 +431,51 @@ static void *pbr_rule_alloc_intern(void *arg) return new; } +static int pbr_rule_release(struct zebra_pbr_rule *rule) +{ + struct zebra_pbr_rule *lookup; + + lookup = hash_lookup(zrouter.rules_hash, rule); + + if (!lookup) + return -ENOENT; + + hash_release(zrouter.rules_hash, lookup); + XFREE(MTYPE_TMP, lookup); + + return 0; +} + void zebra_pbr_add_rule(struct zebra_pbr_rule *rule) { - struct zebra_pbr_rule *unique = - pbr_rule_lookup_unique(rule); + struct zebra_pbr_rule *found; - (void)hash_get(zrouter.rules_hash, rule, pbr_rule_alloc_intern); - (void)kernel_add_pbr_rule(rule); - /* - * Rule Replace semantics, if we have an old, install the - * new rule, look above, and then delete the old + /** + * Check if we already have it (this checks via a unique ID, walking + * over the hash table, not via a hash operation). */ - if (unique) - zebra_pbr_del_rule(unique); + found = pbr_rule_lookup_unique(rule); + + (void)hash_get(zrouter.rules_hash, rule, pbr_rule_alloc_intern); + + /* If found, this is an update */ + if (found) { + (void)kernel_update_pbr_rule(found, rule); + + if (pbr_rule_release(found)) + zlog_debug( + "%s: Rule being updated we know nothing about", + __PRETTY_FUNCTION__); + + } else + (void)kernel_add_pbr_rule(rule); } void zebra_pbr_del_rule(struct zebra_pbr_rule *rule) { - struct zebra_pbr_rule *lookup; - - lookup = hash_lookup(zrouter.rules_hash, rule); (void)kernel_del_pbr_rule(rule); - if (lookup) { - hash_release(zrouter.rules_hash, lookup); - XFREE(MTYPE_TMP, lookup); - } else + if (pbr_rule_release(rule)) zlog_debug("%s: Rule being deleted we know nothing about", __func__); } |
