]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: define some explicit rule replace code paths
authorStephen Worley <sworley@cumulusnetworks.com>
Thu, 19 Dec 2019 22:11:26 +0000 (17:11 -0500)
committerStephen Worley <sworley@cumulusnetworks.com>
Thu, 9 Apr 2020 17:37:55 +0000 (13:37 -0400)
Define some explicit rule replace code paths into the dataplane
code and improve the handling around it/releasing the the old
rule from the hash table.

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

index c9699c7d957a8f6ff3579aee60cae8156fd9a349..34df2485c0b2a00ec53fe96868d4a6927a9657bc 100644 (file)
@@ -173,6 +173,31 @@ enum zebra_dplane_result kernel_del_pbr_rule(struct zebra_pbr_rule *rule)
        return ZEBRA_DPLANE_REQUEST_SUCCESS;
 }
 
+/*
+ * Update specified rule for a specific interface.
+ */
+enum zebra_dplane_result kernel_update_pbr_rule(struct zebra_pbr_rule *old_rule,
+                                               struct zebra_pbr_rule *new_rule)
+{
+       int ret = 0;
+
+       /* Add the new, updated one */
+       ret = netlink_rule_update(RTM_NEWRULE, new_rule);
+
+       /**
+        * Delete the old one.
+        *
+        * Don't care about this result right?
+        */
+       netlink_rule_update(RTM_DELRULE, old_rule);
+
+       kernel_pbr_rule_add_del_status(new_rule,
+                                      (!ret) ? ZEBRA_DPLANE_INSTALL_SUCCESS
+                                             : ZEBRA_DPLANE_INSTALL_FAILURE);
+
+       return ZEBRA_DPLANE_REQUEST_SUCCESS;
+}
+
 /*
  * Handle netlink notification informing a rule add or delete.
  * Handling of an ADD is TBD.
index e2c650b4adb7c20f314a49755fc5f86a2101e42d..219fa7de6f273dbfe3bb626b1a42fc7721356a9e 100644 (file)
@@ -57,4 +57,12 @@ enum zebra_dplane_result kernel_del_pbr_rule(struct zebra_pbr_rule *rule)
        return ZEBRA_DPLANE_REQUEST_FAILURE;
 }
 
+enum zebra_dplane_result kernel_update_pbr_rule(struct zebra_pbr_rule *old_rule,
+                                               struct zebra_pbr_rule *new_rule)
+{
+       flog_err(EC_LIB_UNAVAILABLE, "%s not Implemented for this platform",
+                __PRETTY_FUNCTION__);
+       return ZEBRA_DPLANE_REQUEST_FAILURE;
+}
+
 #endif
index 6728567e6edce45ab35cdae536ce15fc0cbc9e4a..c049aa14f67f68ab52adbb19efb6c7d032c7aa6e 100644 (file)
@@ -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__);
 }
index b7fbc9b7d544f979dcfef85ff6afe6c0d9e80099..83797b95219b15922b39976fb47944fc1d9aa674 100644 (file)
@@ -182,6 +182,13 @@ extern enum zebra_dplane_result kernel_add_pbr_rule(struct zebra_pbr_rule *rule)
  */
 extern enum zebra_dplane_result kernel_del_pbr_rule(struct zebra_pbr_rule *rule);
 
+/*
+ * Update specified rule for a specific interface.
+ */
+extern enum zebra_dplane_result
+kernel_update_pbr_rule(struct zebra_pbr_rule *old_rule,
+                      struct zebra_pbr_rule *new_rule);
+
 /*
  * Get to know existing PBR rules in the kernel - typically called at startup.
  */