diff mbox series

[ovs-dev] netdev-offload-tc: verify the flower rule installed

Message ID 162125761321.4661.6113737795293023919.stgit@wsfd-netdev64.ntdv.lab.eng.bos.redhat.com
State New
Headers show
Series [ovs-dev] netdev-offload-tc: verify the flower rule installed | expand

Commit Message

Eelco Chaudron May 17, 2021, 1:20 p.m. UTC
When OVs installs the flower rule, it only checks for the OK from the
kernel. It does not check if the rule requested matches the one
actually programmed. This change will add this check and warns the
user if this is not the case.

Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
---
 lib/tc.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

Comments

Marcelo Ricardo Leitner May 21, 2021, 2:29 p.m. UTC | #1
On Mon, May 17, 2021 at 09:20:28AM -0400, Eelco Chaudron wrote:
> When OVs installs the flower rule, it only checks for the OK from the
> kernel. It does not check if the rule requested matches the one
> actually programmed. This change will add this check and warns the
> user if this is not the case.
> 
> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>

Reviewed-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
diff mbox series

Patch

diff --git a/lib/tc.c b/lib/tc.c
index a27cca2cc..e134f6a06 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -2979,6 +2979,50 @@  nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower)
     return 0;
 }
 
+static bool
+cmp_tc_flower_match_action(const struct tc_flower *a,
+                           const struct tc_flower *b)
+{
+    if (memcmp(&a->mask, &b->mask, sizeof a->mask)) {
+        VLOG_DBG_RL(&error_rl, "tc flower compare failed mask compare");
+        return false;
+    }
+
+    /* We can not memcmp() the key as some keys might be set while the mask
+     * is not.*/
+
+    for (int i = 0; i < sizeof a->key; i++) {
+        uint8_t mask = ((uint8_t *)&a->mask)[i];
+        uint8_t key_a = ((uint8_t *)&a->key)[i] & mask;
+        uint8_t key_b = ((uint8_t *)&b->key)[i] & mask;
+
+        if (key_a != key_b) {
+            VLOG_DBG_RL(&error_rl, "tc flower compare failed key compare at "
+                        "%d", i);
+            return false;
+        }
+    }
+
+    /* Compare the actions. */
+    const struct tc_action *action_a = a->actions;
+    const struct tc_action *action_b = b->actions;
+
+    if (a->action_count != b->action_count) {
+        VLOG_DBG_RL(&error_rl, "tc flower compare failed action length check");
+        return false;
+    }
+
+    for (int i = 0; i < a->action_count; i++, action_a++, action_b++) {
+        if (memcmp(action_a, action_b, sizeof *action_a)) {
+            VLOG_DBG_RL(&error_rl, "tc flower compare failed action compare "
+                        "for %d", i);
+            return false;
+        }
+    }
+
+    return true;
+}
+
 int
 tc_replace_flower(struct tcf_id *id, struct tc_flower *flower)
 {
@@ -3010,6 +3054,21 @@  tc_replace_flower(struct tcf_id *id, struct tc_flower *flower)
 
         id->prio = tc_get_major(tc->tcm_info);
         id->handle = tc->tcm_handle;
+
+        if (id->prio != TC_RESERVED_PRIORITY_POLICE) {
+            struct tc_flower flower_out;
+            struct tcf_id id_out;
+            int ret;
+
+            ret = parse_netlink_to_tc_flower(reply, &id_out, &flower_out,
+                                             false);
+
+            if (ret || !cmp_tc_flower_match_action(flower, &flower_out)) {
+                VLOG_WARN_RL(&error_rl, "Kernel flower acknowledgment does "
+                             "not match request!\n Set dpif_netlink to dbg to "
+                             "see which rule caused this error.");
+            }
+        }
         ofpbuf_delete(reply);
     }