diff mbox series

[ovs-dev,v4,2/5] netdev-offload-tc: Move flower_to_match action handling to isolated function.

Message ID 165424653103.2267517.7612570877476082284.stgit@ebuild
State Changes Requested
Headers show
Series netdev-offload-tc: Add support for the check_pkt_len action. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Eelco Chaudron June 3, 2022, 8:55 a.m. UTC
Move handling of the individual actions in the parse_tc_flower_to_match()
function to a separate function that will make recursive action handling
easier.

Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Acked-by: Mike Pattrick <mkp@redhat.com>
Acked-by: Roi Dayan <roid@nvidia.com>
---
 lib/netdev-offload-tc.c |  422 +++++++++++++++++++++++++----------------------
 1 file changed, 221 insertions(+), 201 deletions(-)
diff mbox series

Patch

diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 3c2e8f510..f657af0fd 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -617,6 +617,226 @@  parse_tc_flower_terse_to_match(struct tc_flower *flower,
     return 0;
 }
 
+static int
+_parse_tc_flower_to_actions(struct tc_flower *flower, struct ofpbuf *buf,
+                            int start_index, int max_index)
+{
+    struct tc_action *action;
+    int i;
+
+    if (max_index <= 0 || max_index > flower->action_count) {
+        max_index = flower->action_count;
+    }
+
+    for (i = start_index; i < max_index; i++) {
+        action = &flower->actions[i];
+
+        switch (action->type) {
+        case TC_ACT_VLAN_POP: {
+            nl_msg_put_flag(buf, OVS_ACTION_ATTR_POP_VLAN);
+        }
+        break;
+        case TC_ACT_VLAN_PUSH: {
+            struct ovs_action_push_vlan *push;
+
+            push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_VLAN,
+                                          sizeof *push);
+            push->vlan_tpid = action->vlan.vlan_push_tpid;
+            push->vlan_tci = htons(action->vlan.vlan_push_id
+                                   | (action->vlan.vlan_push_prio << 13)
+                                   | VLAN_CFI);
+        }
+        break;
+        case TC_ACT_MPLS_POP: {
+            nl_msg_put_be16(buf, OVS_ACTION_ATTR_POP_MPLS,
+                            action->mpls.proto);
+        }
+        break;
+        case TC_ACT_MPLS_PUSH: {
+            struct ovs_action_push_mpls *push;
+            ovs_be32 mpls_lse = 0;
+
+            flow_set_mpls_lse_label(&mpls_lse, action->mpls.label);
+            flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc);
+            flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl);
+            flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos);
+
+            push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_MPLS,
+                                          sizeof *push);
+            push->mpls_ethertype = action->mpls.proto;
+            push->mpls_lse = mpls_lse;
+        }
+        break;
+        case TC_ACT_MPLS_SET: {
+            size_t set_offset = nl_msg_start_nested(buf,
+                                                    OVS_ACTION_ATTR_SET);
+            struct ovs_key_mpls *set_mpls;
+            ovs_be32 mpls_lse = 0;
+
+            flow_set_mpls_lse_label(&mpls_lse, action->mpls.label);
+            flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc);
+            flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl);
+            flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos);
+
+            set_mpls = nl_msg_put_unspec_zero(buf, OVS_KEY_ATTR_MPLS,
+                                              sizeof *set_mpls);
+            set_mpls->mpls_lse = mpls_lse;
+            nl_msg_end_nested(buf, set_offset);
+        }
+        break;
+        case TC_ACT_PEDIT: {
+            parse_flower_rewrite_to_netlink_action(buf, action);
+        }
+        break;
+        case TC_ACT_ENCAP: {
+            size_t set_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SET);
+            size_t tunnel_offset =
+                nl_msg_start_nested(buf, OVS_KEY_ATTR_TUNNEL);
+
+            if (action->encap.id_present) {
+                nl_msg_put_be64(buf, OVS_TUNNEL_KEY_ATTR_ID, action->encap.id);
+            }
+            if (action->encap.ipv4.ipv4_src) {
+                nl_msg_put_be32(buf, OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
+                                action->encap.ipv4.ipv4_src);
+            }
+            if (action->encap.ipv4.ipv4_dst) {
+                nl_msg_put_be32(buf, OVS_TUNNEL_KEY_ATTR_IPV4_DST,
+                                action->encap.ipv4.ipv4_dst);
+            }
+            if (ipv6_addr_is_set(&action->encap.ipv6.ipv6_src)) {
+                nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_SRC,
+                                    &action->encap.ipv6.ipv6_src);
+            }
+            if (ipv6_addr_is_set(&action->encap.ipv6.ipv6_dst)) {
+                nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_DST,
+                                    &action->encap.ipv6.ipv6_dst);
+            }
+            if (action->encap.tos) {
+                nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TOS,
+                              action->encap.tos);
+            }
+            if (action->encap.ttl) {
+                nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TTL,
+                              action->encap.ttl);
+            }
+            if (action->encap.tp_dst) {
+                nl_msg_put_be16(buf, OVS_TUNNEL_KEY_ATTR_TP_DST,
+                                action->encap.tp_dst);
+            }
+            if (!action->encap.no_csum) {
+                nl_msg_put_flag(buf, OVS_TUNNEL_KEY_ATTR_CSUM);
+            }
+
+            parse_tc_flower_geneve_opts(action, buf);
+            nl_msg_end_nested(buf, tunnel_offset);
+            nl_msg_end_nested(buf, set_offset);
+        }
+        break;
+        case TC_ACT_OUTPUT: {
+            odp_port_t outport = 0;
+
+            if (action->out.ifindex_out) {
+                outport =
+                    netdev_ifindex_to_odp_port(action->out.ifindex_out);
+                if (!outport) {
+                    return ENOENT;
+                }
+            }
+            nl_msg_put_u32(buf, OVS_ACTION_ATTR_OUTPUT, odp_to_u32(outport));
+        }
+        break;
+        case TC_ACT_CT: {
+            size_t ct_offset;
+
+            if (action->ct.clear) {
+                nl_msg_put_flag(buf, OVS_ACTION_ATTR_CT_CLEAR);
+                break;
+            }
+
+            ct_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_CT);
+
+            if (action->ct.commit) {
+                nl_msg_put_flag(buf, OVS_CT_ATTR_COMMIT);
+            }
+
+            if (action->ct.zone) {
+                nl_msg_put_u16(buf, OVS_CT_ATTR_ZONE, action->ct.zone);
+            }
+
+            if (action->ct.mark_mask) {
+                uint32_t mark_and_mask[2] = { action->ct.mark,
+                                              action->ct.mark_mask };
+                nl_msg_put_unspec(buf, OVS_CT_ATTR_MARK, &mark_and_mask,
+                                  sizeof mark_and_mask);
+            }
+
+            if (!ovs_u128_is_zero(action->ct.label_mask)) {
+                struct {
+                    ovs_u128 key;
+                    ovs_u128 mask;
+                } *ct_label;
+
+                ct_label = nl_msg_put_unspec_uninit(buf,
+                                                    OVS_CT_ATTR_LABELS,
+                                                    sizeof *ct_label);
+                ct_label->key = action->ct.label;
+                ct_label->mask = action->ct.label_mask;
+            }
+
+            if (action->ct.nat_type) {
+                size_t nat_offset = nl_msg_start_nested(buf,
+                                                        OVS_CT_ATTR_NAT);
+
+                if (action->ct.nat_type == TC_NAT_SRC) {
+                    nl_msg_put_flag(buf, OVS_NAT_ATTR_SRC);
+                } else if (action->ct.nat_type == TC_NAT_DST) {
+                    nl_msg_put_flag(buf, OVS_NAT_ATTR_DST);
+                }
+
+                if (action->ct.range.ip_family == AF_INET) {
+                    nl_msg_put_be32(buf, OVS_NAT_ATTR_IP_MIN,
+                                    action->ct.range.ipv4.min);
+                    nl_msg_put_be32(buf, OVS_NAT_ATTR_IP_MAX,
+                                    action->ct.range.ipv4.max);
+                } else if (action->ct.range.ip_family == AF_INET6) {
+                    nl_msg_put_in6_addr(buf, OVS_NAT_ATTR_IP_MIN,
+                                        &action->ct.range.ipv6.min);
+                    nl_msg_put_in6_addr(buf, OVS_NAT_ATTR_IP_MAX,
+                                        &action->ct.range.ipv6.max);
+                }
+
+                if (action->ct.range.port.min) {
+                    nl_msg_put_u16(buf, OVS_NAT_ATTR_PROTO_MIN,
+                                   ntohs(action->ct.range.port.min));
+                    if (action->ct.range.port.max) {
+                        nl_msg_put_u16(buf, OVS_NAT_ATTR_PROTO_MAX,
+                                       ntohs(action->ct.range.port.max));
+                    }
+                }
+
+                nl_msg_end_nested(buf, nat_offset);
+            }
+
+            nl_msg_end_nested(buf, ct_offset);
+        }
+        break;
+        case TC_ACT_GOTO: {
+            nl_msg_put_u32(buf, OVS_ACTION_ATTR_RECIRC, action->chain);
+        }
+        break;
+        }
+    }
+    return i;
+}
+
+static void
+parse_tc_flower_to_actions(struct tc_flower *flower,
+                           struct ofpbuf *buf)
+{
+    _parse_tc_flower_to_actions(flower, buf, 0, 0);
+}
+
 static int
 parse_tc_flower_to_match(struct tc_flower *flower,
                          struct match *match,
@@ -629,9 +849,6 @@  parse_tc_flower_to_match(struct tc_flower *flower,
     size_t act_off;
     struct tc_flower_key *key = &flower->key;
     struct tc_flower_key *mask = &flower->mask;
-    odp_port_t outport = 0;
-    struct tc_action *action;
-    int i;
 
     if (terse) {
         return parse_tc_flower_terse_to_match(flower, match, stats, attrs);
@@ -822,204 +1039,7 @@  parse_tc_flower_to_match(struct tc_flower *flower,
     }
 
     act_off = nl_msg_start_nested(buf, OVS_FLOW_ATTR_ACTIONS);
-    {
-        action = flower->actions;
-        for (i = 0; i < flower->action_count; i++, action++) {
-            switch (action->type) {
-            case TC_ACT_VLAN_POP: {
-                nl_msg_put_flag(buf, OVS_ACTION_ATTR_POP_VLAN);
-            }
-            break;
-            case TC_ACT_VLAN_PUSH: {
-                struct ovs_action_push_vlan *push;
-
-                push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_VLAN,
-                                              sizeof *push);
-                push->vlan_tpid = action->vlan.vlan_push_tpid;
-                push->vlan_tci = htons(action->vlan.vlan_push_id
-                                       | (action->vlan.vlan_push_prio << 13)
-                                       | VLAN_CFI);
-            }
-            break;
-            case TC_ACT_MPLS_POP: {
-                nl_msg_put_be16(buf, OVS_ACTION_ATTR_POP_MPLS,
-                                action->mpls.proto);
-            }
-            break;
-            case TC_ACT_MPLS_PUSH: {
-                struct ovs_action_push_mpls *push;
-                ovs_be32 mpls_lse = 0;
-
-                flow_set_mpls_lse_label(&mpls_lse, action->mpls.label);
-                flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc);
-                flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl);
-                flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos);
-
-                push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_MPLS,
-                                              sizeof *push);
-                push->mpls_ethertype = action->mpls.proto;
-                push->mpls_lse = mpls_lse;
-            }
-            break;
-            case TC_ACT_MPLS_SET: {
-                size_t set_offset = nl_msg_start_nested(buf,
-                                                        OVS_ACTION_ATTR_SET);
-                struct ovs_key_mpls *set_mpls;
-                ovs_be32 mpls_lse = 0;
-
-                flow_set_mpls_lse_label(&mpls_lse, action->mpls.label);
-                flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc);
-                flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl);
-                flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos);
-
-                set_mpls = nl_msg_put_unspec_zero(buf, OVS_KEY_ATTR_MPLS,
-                                                  sizeof *set_mpls);
-                set_mpls->mpls_lse = mpls_lse;
-                nl_msg_end_nested(buf, set_offset);
-            }
-            break;
-            case TC_ACT_PEDIT: {
-                parse_flower_rewrite_to_netlink_action(buf, action);
-            }
-            break;
-            case TC_ACT_ENCAP: {
-                size_t set_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SET);
-                size_t tunnel_offset =
-                    nl_msg_start_nested(buf, OVS_KEY_ATTR_TUNNEL);
-
-                if (action->encap.id_present) {
-                    nl_msg_put_be64(buf, OVS_TUNNEL_KEY_ATTR_ID, action->encap.id);
-                }
-                if (action->encap.ipv4.ipv4_src) {
-                    nl_msg_put_be32(buf, OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
-                                    action->encap.ipv4.ipv4_src);
-                }
-                if (action->encap.ipv4.ipv4_dst) {
-                    nl_msg_put_be32(buf, OVS_TUNNEL_KEY_ATTR_IPV4_DST,
-                                    action->encap.ipv4.ipv4_dst);
-                }
-                if (ipv6_addr_is_set(&action->encap.ipv6.ipv6_src)) {
-                    nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_SRC,
-                                        &action->encap.ipv6.ipv6_src);
-                }
-                if (ipv6_addr_is_set(&action->encap.ipv6.ipv6_dst)) {
-                    nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_DST,
-                                        &action->encap.ipv6.ipv6_dst);
-                }
-                if (action->encap.tos) {
-                    nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TOS,
-                                  action->encap.tos);
-                }
-                if (action->encap.ttl) {
-                    nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TTL,
-                                  action->encap.ttl);
-                }
-                if (action->encap.tp_dst) {
-                    nl_msg_put_be16(buf, OVS_TUNNEL_KEY_ATTR_TP_DST,
-                                    action->encap.tp_dst);
-                }
-                if (!action->encap.no_csum) {
-                    nl_msg_put_flag(buf, OVS_TUNNEL_KEY_ATTR_CSUM);
-                }
-
-                parse_tc_flower_geneve_opts(action, buf);
-                nl_msg_end_nested(buf, tunnel_offset);
-                nl_msg_end_nested(buf, set_offset);
-            }
-            break;
-            case TC_ACT_OUTPUT: {
-                if (action->out.ifindex_out) {
-                    outport =
-                        netdev_ifindex_to_odp_port(action->out.ifindex_out);
-                    if (!outport) {
-                        return ENOENT;
-                    }
-                }
-                nl_msg_put_u32(buf, OVS_ACTION_ATTR_OUTPUT, odp_to_u32(outport));
-            }
-            break;
-            case TC_ACT_CT: {
-                size_t ct_offset;
-
-                if (action->ct.clear) {
-                    nl_msg_put_flag(buf, OVS_ACTION_ATTR_CT_CLEAR);
-                    break;
-                }
-
-                ct_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_CT);
-
-                if (action->ct.commit) {
-                    nl_msg_put_flag(buf, OVS_CT_ATTR_COMMIT);
-                }
-
-                if (action->ct.zone) {
-                    nl_msg_put_u16(buf, OVS_CT_ATTR_ZONE, action->ct.zone);
-                }
-
-                if (action->ct.mark_mask) {
-                    uint32_t mark_and_mask[2] = { action->ct.mark,
-                                                  action->ct.mark_mask };
-                    nl_msg_put_unspec(buf, OVS_CT_ATTR_MARK, &mark_and_mask,
-                                      sizeof mark_and_mask);
-                }
-
-                if (!ovs_u128_is_zero(action->ct.label_mask)) {
-                    struct {
-                        ovs_u128 key;
-                        ovs_u128 mask;
-                    } *ct_label;
-
-                    ct_label = nl_msg_put_unspec_uninit(buf,
-                                                        OVS_CT_ATTR_LABELS,
-                                                        sizeof *ct_label);
-                    ct_label->key = action->ct.label;
-                    ct_label->mask = action->ct.label_mask;
-                }
-
-                if (action->ct.nat_type) {
-                    size_t nat_offset = nl_msg_start_nested(buf,
-                                                            OVS_CT_ATTR_NAT);
-
-                    if (action->ct.nat_type == TC_NAT_SRC) {
-                        nl_msg_put_flag(buf, OVS_NAT_ATTR_SRC);
-                    } else if (action->ct.nat_type == TC_NAT_DST) {
-                        nl_msg_put_flag(buf, OVS_NAT_ATTR_DST);
-                    }
-
-                    if (action->ct.range.ip_family == AF_INET) {
-                        nl_msg_put_be32(buf, OVS_NAT_ATTR_IP_MIN,
-                                        action->ct.range.ipv4.min);
-                        nl_msg_put_be32(buf, OVS_NAT_ATTR_IP_MAX,
-                                        action->ct.range.ipv4.max);
-                    } else if (action->ct.range.ip_family == AF_INET6) {
-                        nl_msg_put_in6_addr(buf, OVS_NAT_ATTR_IP_MIN,
-                                            &action->ct.range.ipv6.min);
-                        nl_msg_put_in6_addr(buf, OVS_NAT_ATTR_IP_MAX,
-                                            &action->ct.range.ipv6.max);
-                    }
-
-                    if (action->ct.range.port.min) {
-                        nl_msg_put_u16(buf, OVS_NAT_ATTR_PROTO_MIN,
-                                       ntohs(action->ct.range.port.min));
-                        if (action->ct.range.port.max) {
-                            nl_msg_put_u16(buf, OVS_NAT_ATTR_PROTO_MAX,
-                                           ntohs(action->ct.range.port.max));
-                        }
-                    }
-
-                    nl_msg_end_nested(buf, nat_offset);
-                }
-
-                nl_msg_end_nested(buf, ct_offset);
-            }
-            break;
-            case TC_ACT_GOTO: {
-                nl_msg_put_u32(buf, OVS_ACTION_ATTR_RECIRC, action->chain);
-            }
-            break;
-            }
-        }
-    }
+    parse_tc_flower_to_actions(flower, buf);
     nl_msg_end_nested(buf, act_off);
 
     *actions = ofpbuf_at_assert(buf, act_off, sizeof(struct nlattr));