From: Roi Dayan <[email protected]>

Even though cited commit states that userspace declaration of
OVS_KEY_ATTR_IPV6_EXTHDRS is not required, without it TC offload of IPv6
flows fails with following error:

2022-04-08T19:47:12.405Z|00001|odp_util(handler1)|ERR|internal error parsing 
flow key 
recirc_id(0),dp_hash(0),skb_priority(0),in_port(2),skb_mark(0),ct_state(0),ct_zone(0),ct_mark(0),ct_label(0),eth(src=e4:f9:05:08:00:02,dst=33:33:00:00:00:
16),eth_type(0x86dd),ipv6(src=fe80::e6f9:5ff:fe08:2,dst=ff02::16,label=0,proto=58,tclass=0,hlimit=1,frag=no)(bad
 key length 2, expected -1)(40 00),icmpv6(type=143,code=0)

To fix the error until proper IPv6 extensions support is implemented, add
the attribute OVS_KEY_ATTR_IPV6_EXTHDRS and skip it with a warning during
parsing.

Issue: 3030660
Fixes: d96d14b14733 ("openvswitch.h: Align uAPI definition with the kernel.")
Signed-off-by: Roi Dayan <[email protected]>
Signed-off-by: Vlad Buslov <[email protected]>
Acked-by: Maor Dickman <[email protected]>
---
 datapath/flow_netlink.c                           |  2 +-
 datapath/linux/compat/include/linux/openvswitch.h |  6 ++++++
 lib/odp-execute.c                                 |  2 ++
 lib/odp-util.c                                    | 11 +++++++++++
 ofproto/ofproto-dpif-sflow.c                      |  1 +
 5 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index caed443863ed..3532c38f61e2 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -359,7 +359,7 @@ size_t ovs_key_attr_size(void)
        /* Whenever adding new OVS_KEY_ FIELDS, we should consider
         * updating this function.
         */
-       BUILD_BUG_ON(OVS_KEY_ATTR_MAX != 31);
+       BUILD_BUG_ON(OVS_KEY_ATTR_MAX != 32);
 
        return    nla_total_size(4)   /* OVS_KEY_ATTR_PRIORITY */
                + nla_total_size(0)   /* OVS_KEY_ATTR_TUNNEL */
diff --git a/datapath/linux/compat/include/linux/openvswitch.h 
b/datapath/linux/compat/include/linux/openvswitch.h
index 8bb5abdc8349..acd047fbfe9a 100644
--- a/datapath/linux/compat/include/linux/openvswitch.h
+++ b/datapath/linux/compat/include/linux/openvswitch.h
@@ -401,6 +401,7 @@ enum ovs_key_attr {
        OVS_KEY_ATTR_TUNNEL_INFO,   /* struct ip_tunnel_info.
                                     * For in-kernel use only.
                                     */
+       OVS_KEY_ATTR_IPV6_EXTHDRS, /* struct ovs_key_ipv6_exthdr */
        __OVS_KEY_ATTR_MAX
 };
 
@@ -500,6 +501,11 @@ struct ovs_key_ipv6 {
        __u8   ipv6_frag;       /* One of OVS_FRAG_TYPE_*. */
 };
 
+/* separate structure to support backward compatibility with older user space 
*/
+struct ovs_key_ipv6_exthdrs {
+    __u16  hdrs;
+};
+
 struct ovs_key_tcp {
        __be16 tcp_src;
        __be16 tcp_dst;
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 7da56793d0ff..93921acb7412 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -554,6 +554,7 @@ odp_execute_set_action(struct dp_packet *packet, const 
struct nlattr *a)
     case OVS_KEY_ATTR_CT_MARK:
     case OVS_KEY_ATTR_CT_LABELS:
     case OVS_KEY_ATTR_TUNNEL_INFO:
+    case OVS_KEY_ATTR_IPV6_EXTHDRS:
     case __OVS_KEY_ATTR_MAX:
     default:
         OVS_NOT_REACHED();
@@ -667,6 +668,7 @@ odp_execute_masked_set_action(struct dp_packet *packet,
     case OVS_KEY_ATTR_ICMPV6:
     case OVS_KEY_ATTR_TCP_FLAGS:
     case OVS_KEY_ATTR_TUNNEL_INFO:
+    case OVS_KEY_ATTR_IPV6_EXTHDRS:
     case __OVS_KEY_ATTR_MAX:
     default:
         OVS_NOT_REACHED();
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 073fc20d9f7f..0964d5f3eb6b 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -192,6 +192,7 @@ ovs_key_attr_to_string(enum ovs_key_attr attr, char 
*namebuf, size_t bufsize)
     case OVS_KEY_ATTR_RECIRC_ID: return "recirc_id";
     case OVS_KEY_ATTR_PACKET_TYPE: return "packet_type";
     case OVS_KEY_ATTR_NSH: return "nsh";
+    case OVS_KEY_ATTR_IPV6_EXTHDRS: return "ipv6_exthdrs";
 
     case OVS_KEY_ATTR_TUNNEL_INFO: return "<error: kernel-only tunnel_info>";
     case __OVS_KEY_ATTR_MAX:
@@ -2747,6 +2748,7 @@ const struct attr_len_tbl 
ovs_flow_key_attr_lens[OVS_KEY_ATTR_MAX + 1] = {
     [OVS_KEY_ATTR_NSH]       = { .len = ATTR_LEN_NESTED,
                                  .next = ovs_nsh_key_attr_lens,
                                  .next_max = OVS_NSH_KEY_ATTR_MAX },
+    [OVS_KEY_ATTR_IPV6_EXTHDRS] = { .len = sizeof(struct ovs_key_ipv6_exthdrs) 
},
 };
 
 /* Returns the correct length of the payload for a flow key attribute of the
@@ -3263,6 +3265,7 @@ odp_mask_is_constant__(enum ovs_key_attr attr, const void 
*mask, size_t size,
     case OVS_KEY_ATTR_UNSPEC:
     case OVS_KEY_ATTR_ENCAP:
     case OVS_KEY_ATTR_TUNNEL_INFO:
+    case OVS_KEY_ATTR_IPV6_EXTHDRS:
     case __OVS_KEY_ATTR_MAX:
     default:
         return false;
@@ -4415,6 +4418,7 @@ format_odp_key_attr__(const struct nlattr *a, const 
struct nlattr *ma,
     }
     case OVS_KEY_ATTR_UNSPEC:
     case OVS_KEY_ATTR_TUNNEL_INFO:
+    case OVS_KEY_ATTR_IPV6_EXTHDRS:
     case __OVS_KEY_ATTR_MAX:
     default:
         format_generic_odp_key(a, ds);
@@ -6620,6 +6624,7 @@ odp_key_to_dp_packet(const struct nlattr *key, size_t 
key_len,
         case OVS_KEY_ATTR_PACKET_TYPE:
         case OVS_KEY_ATTR_NSH:
         case OVS_KEY_ATTR_TUNNEL_INFO:
+        case OVS_KEY_ATTR_IPV6_EXTHDRS:
         case __OVS_KEY_ATTR_MAX:
         default:
             break;
@@ -6979,6 +6984,12 @@ parse_l2_5_onward(const struct nlattr 
*attrs[OVS_KEY_ATTR_MAX + 1],
                 expected_bit = OVS_KEY_ATTR_IPV6;
             }
         }
+        if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV6_EXTHDRS)) {
+            if (!is_mask) {
+                *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV6_EXTHDRS;
+                VLOG_WARN_RL(&rl, "not parsing ipv6 exthdrs");
+            }
+        }
     } else if (src_flow->dl_type == htons(ETH_TYPE_ARP) ||
                src_flow->dl_type == htons(ETH_TYPE_RARP)) {
         if (!is_mask) {
diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c
index ab4941364c0d..6a1ceadfa4dd 100644
--- a/ofproto/ofproto-dpif-sflow.c
+++ b/ofproto/ofproto-dpif-sflow.c
@@ -1067,6 +1067,7 @@ sflow_read_set_action(const struct nlattr *attr,
     case OVS_KEY_ATTR_PACKET_TYPE:
     case OVS_KEY_ATTR_NSH:
     case OVS_KEY_ATTR_TUNNEL_INFO:
+    case OVS_KEY_ATTR_IPV6_EXTHDRS:
     case __OVS_KEY_ATTR_MAX:
     default:
         break;
-- 
2.31.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to