* [PATCH net] net: openvswitch: remove never-working support for setting nsh fields
@ 2025-11-12 11:14 Ilya Maximets
2025-11-12 13:28 ` Eelco Chaudron
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Ilya Maximets @ 2025-11-12 11:14 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-kernel, dev, Eelco Chaudron, Aaron Conole,
Willy Tarreau, LePremierHomme, Ilya Maximets, Junvy Yang
The validation of the set(nsh(...)) action is completely wrong.
It runs through the nsh_key_put_from_nlattr() function that is the
same function that validates NSH keys for the flow match and the
push_nsh() action. However, the set(nsh(...)) has a very different
memory layout. Nested attributes in there are doubled in size in
case of the masked set(). That makes proper validation impossible.
There is also confusion in the code between the 'masked' flag, that
says that the nested attributes are doubled in size containing both
the value and the mask, and the 'is_mask' that says that the value
we're parsing is the mask. This is causing kernel crash on trying to
write into mask part of the match with SW_FLOW_KEY_PUT() during
validation, while validate_nsh() doesn't allocate any memory for it:
BUG: kernel NULL pointer dereference, address: 0000000000000018
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 1c2383067 P4D 1c2383067 PUD 20b703067 PMD 0
Oops: Oops: 0000 [#1] SMP NOPTI
CPU: 8 UID: 0 Kdump: loaded Not tainted 6.17.0-rc4+ #107 PREEMPT(voluntary)
RIP: 0010:nsh_key_put_from_nlattr+0x19d/0x610 [openvswitch]
Call Trace:
<TASK>
validate_nsh+0x60/0x90 [openvswitch]
validate_set.constprop.0+0x270/0x3c0 [openvswitch]
__ovs_nla_copy_actions+0x477/0x860 [openvswitch]
ovs_nla_copy_actions+0x8d/0x100 [openvswitch]
ovs_packet_cmd_execute+0x1cc/0x310 [openvswitch]
genl_family_rcv_msg_doit+0xdb/0x130
genl_family_rcv_msg+0x14b/0x220
genl_rcv_msg+0x47/0xa0
netlink_rcv_skb+0x53/0x100
genl_rcv+0x24/0x40
netlink_unicast+0x280/0x3b0
netlink_sendmsg+0x1f7/0x430
____sys_sendmsg+0x36b/0x3a0
___sys_sendmsg+0x87/0xd0
__sys_sendmsg+0x6d/0xd0
do_syscall_64+0x7b/0x2c0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
The third issue with this process is that while trying to convert
the non-masked set into masked one, validate_set() copies and doubles
the size of the OVS_KEY_ATTR_NSH as if it didn't have any nested
attributes. It should be copying each nested attribute and doubling
them in size independently. And the process must be properly reversed
during the conversion back from masked to a non-masked variant during
the flow dump.
In the end, the only two outcomes of trying to use this action are
either validation failure or a kernel crash. And if somehow someone
manages to install a flow with such an action, it will most definitely
not do what it is supposed to, since all the keys and the masks are
mixed up.
Fixing all the issues is a complex task as it requires re-writing
most of the validation code.
Given that and the fact that this functionality never worked since
introduction, let's just remove it altogether. It's better to
re-introduce it later with a proper implementation instead of trying
to fix it in stable releases.
Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
Reported-by: Junvy Yang <zhuque@tencent.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
net/openvswitch/actions.c | 68 +---------------------------------
net/openvswitch/flow_netlink.c | 64 ++++----------------------------
net/openvswitch/flow_netlink.h | 2 -
3 files changed, 9 insertions(+), 125 deletions(-)
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 2832e0794197..792ca44a461d 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -572,69 +572,6 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,
return 0;
}
-static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
- const struct nlattr *a)
-{
- struct nshhdr *nh;
- size_t length;
- int err;
- u8 flags;
- u8 ttl;
- int i;
-
- struct ovs_key_nsh key;
- struct ovs_key_nsh mask;
-
- err = nsh_key_from_nlattr(a, &key, &mask);
- if (err)
- return err;
-
- /* Make sure the NSH base header is there */
- if (!pskb_may_pull(skb, skb_network_offset(skb) + NSH_BASE_HDR_LEN))
- return -ENOMEM;
-
- nh = nsh_hdr(skb);
- length = nsh_hdr_len(nh);
-
- /* Make sure the whole NSH header is there */
- err = skb_ensure_writable(skb, skb_network_offset(skb) +
- length);
- if (unlikely(err))
- return err;
-
- nh = nsh_hdr(skb);
- skb_postpull_rcsum(skb, nh, length);
- flags = nsh_get_flags(nh);
- flags = OVS_MASKED(flags, key.base.flags, mask.base.flags);
- flow_key->nsh.base.flags = flags;
- ttl = nsh_get_ttl(nh);
- ttl = OVS_MASKED(ttl, key.base.ttl, mask.base.ttl);
- flow_key->nsh.base.ttl = ttl;
- nsh_set_flags_and_ttl(nh, flags, ttl);
- nh->path_hdr = OVS_MASKED(nh->path_hdr, key.base.path_hdr,
- mask.base.path_hdr);
- flow_key->nsh.base.path_hdr = nh->path_hdr;
- switch (nh->mdtype) {
- case NSH_M_TYPE1:
- for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) {
- nh->md1.context[i] =
- OVS_MASKED(nh->md1.context[i], key.context[i],
- mask.context[i]);
- }
- memcpy(flow_key->nsh.context, nh->md1.context,
- sizeof(nh->md1.context));
- break;
- case NSH_M_TYPE2:
- memset(flow_key->nsh.context, 0,
- sizeof(flow_key->nsh.context));
- break;
- default:
- return -EINVAL;
- }
- skb_postpush_rcsum(skb, nh, length);
- return 0;
-}
-
/* Must follow skb_ensure_writable() since that can move the skb data. */
static void set_tp_port(struct sk_buff *skb, __be16 *port,
__be16 new_port, __sum16 *check)
@@ -1130,10 +1067,6 @@ static int execute_masked_set_action(struct sk_buff *skb,
get_mask(a, struct ovs_key_ethernet *));
break;
- case OVS_KEY_ATTR_NSH:
- err = set_nsh(skb, flow_key, a);
- break;
-
case OVS_KEY_ATTR_IPV4:
err = set_ipv4(skb, flow_key, nla_data(a),
get_mask(a, struct ovs_key_ipv4 *));
@@ -1170,6 +1103,7 @@ static int execute_masked_set_action(struct sk_buff *skb,
case OVS_KEY_ATTR_CT_LABELS:
case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4:
case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6:
+ case OVS_KEY_ATTR_NSH:
err = -EINVAL;
break;
}
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index ad64bb9ab5e2..1cb4f97335d8 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1305,6 +1305,11 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
return 0;
}
+/*
+ * Constructs NSH header 'nh' from attributes of OVS_ACTION_ATTR_PUSH_NSH,
+ * where 'nh' points to a memory block of 'size' bytes. It's assumed that
+ * attributes were previously validated with validate_push_nsh().
+ */
int nsh_hdr_from_nlattr(const struct nlattr *attr,
struct nshhdr *nh, size_t size)
{
@@ -1314,8 +1319,6 @@ int nsh_hdr_from_nlattr(const struct nlattr *attr,
u8 ttl = 0;
int mdlen = 0;
- /* validate_nsh has check this, so we needn't do duplicate check here
- */
if (size < NSH_BASE_HDR_LEN)
return -ENOBUFS;
@@ -1359,46 +1362,6 @@ int nsh_hdr_from_nlattr(const struct nlattr *attr,
return 0;
}
-int nsh_key_from_nlattr(const struct nlattr *attr,
- struct ovs_key_nsh *nsh, struct ovs_key_nsh *nsh_mask)
-{
- struct nlattr *a;
- int rem;
-
- /* validate_nsh has check this, so we needn't do duplicate check here
- */
- nla_for_each_nested(a, attr, rem) {
- int type = nla_type(a);
-
- switch (type) {
- case OVS_NSH_KEY_ATTR_BASE: {
- const struct ovs_nsh_key_base *base = nla_data(a);
- const struct ovs_nsh_key_base *base_mask = base + 1;
-
- nsh->base = *base;
- nsh_mask->base = *base_mask;
- break;
- }
- case OVS_NSH_KEY_ATTR_MD1: {
- const struct ovs_nsh_key_md1 *md1 = nla_data(a);
- const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
-
- memcpy(nsh->context, md1->context, sizeof(*md1));
- memcpy(nsh_mask->context, md1_mask->context,
- sizeof(*md1_mask));
- break;
- }
- case OVS_NSH_KEY_ATTR_MD2:
- /* Not supported yet */
- return -ENOTSUPP;
- default:
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
static int nsh_key_put_from_nlattr(const struct nlattr *attr,
struct sw_flow_match *match, bool is_mask,
bool is_push_nsh, bool log)
@@ -2839,17 +2802,13 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
return err;
}
-static bool validate_nsh(const struct nlattr *attr, bool is_mask,
- bool is_push_nsh, bool log)
+static bool validate_push_nsh(const struct nlattr *attr, bool log)
{
struct sw_flow_match match;
struct sw_flow_key key;
- int ret = 0;
ovs_match_init(&match, &key, true, NULL);
- ret = nsh_key_put_from_nlattr(attr, &match, is_mask,
- is_push_nsh, log);
- return !ret;
+ return !nsh_key_put_from_nlattr(attr, &match, false, true, log);
}
/* Return false if there are any non-masked bits set.
@@ -2997,13 +2956,6 @@ static int validate_set(const struct nlattr *a,
break;
- case OVS_KEY_ATTR_NSH:
- if (eth_type != htons(ETH_P_NSH))
- return -EINVAL;
- if (!validate_nsh(nla_data(a), masked, false, log))
- return -EINVAL;
- break;
-
default:
return -EINVAL;
}
@@ -3437,7 +3389,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
return -EINVAL;
}
mac_proto = MAC_PROTO_NONE;
- if (!validate_nsh(nla_data(a), false, true, true))
+ if (!validate_push_nsh(nla_data(a), log))
return -EINVAL;
break;
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index fe7f77fc5f18..ff8cdecbe346 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -65,8 +65,6 @@ int ovs_nla_put_actions(const struct nlattr *attr,
void ovs_nla_free_flow_actions(struct sw_flow_actions *);
void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *);
-int nsh_key_from_nlattr(const struct nlattr *attr, struct ovs_key_nsh *nsh,
- struct ovs_key_nsh *nsh_mask);
int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh,
size_t size);
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net] net: openvswitch: remove never-working support for setting nsh fields
2025-11-12 11:14 [PATCH net] net: openvswitch: remove never-working support for setting nsh fields Ilya Maximets
@ 2025-11-12 13:28 ` Eelco Chaudron
2025-11-12 14:55 ` Aaron Conole
2025-11-15 2:20 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 5+ messages in thread
From: Eelco Chaudron @ 2025-11-12 13:28 UTC (permalink / raw)
To: Ilya Maximets
Cc: netdev, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, dev, Aaron Conole,
Willy Tarreau, LePremierHomme, Junvy Yang
On 12 Nov 2025, at 12:14, Ilya Maximets wrote:
> The validation of the set(nsh(...)) action is completely wrong.
> It runs through the nsh_key_put_from_nlattr() function that is the
> same function that validates NSH keys for the flow match and the
> push_nsh() action. However, the set(nsh(...)) has a very different
> memory layout. Nested attributes in there are doubled in size in
> case of the masked set(). That makes proper validation impossible.
>
> There is also confusion in the code between the 'masked' flag, that
> says that the nested attributes are doubled in size containing both
> the value and the mask, and the 'is_mask' that says that the value
> we're parsing is the mask. This is causing kernel crash on trying to
> write into mask part of the match with SW_FLOW_KEY_PUT() during
> validation, while validate_nsh() doesn't allocate any memory for it:
>
> BUG: kernel NULL pointer dereference, address: 0000000000000018
> #PF: supervisor read access in kernel mode
> #PF: error_code(0x0000) - not-present page
> PGD 1c2383067 P4D 1c2383067 PUD 20b703067 PMD 0
> Oops: Oops: 0000 [#1] SMP NOPTI
> CPU: 8 UID: 0 Kdump: loaded Not tainted 6.17.0-rc4+ #107 PREEMPT(voluntary)
> RIP: 0010:nsh_key_put_from_nlattr+0x19d/0x610 [openvswitch]
> Call Trace:
> <TASK>
> validate_nsh+0x60/0x90 [openvswitch]
> validate_set.constprop.0+0x270/0x3c0 [openvswitch]
> __ovs_nla_copy_actions+0x477/0x860 [openvswitch]
> ovs_nla_copy_actions+0x8d/0x100 [openvswitch]
> ovs_packet_cmd_execute+0x1cc/0x310 [openvswitch]
> genl_family_rcv_msg_doit+0xdb/0x130
> genl_family_rcv_msg+0x14b/0x220
> genl_rcv_msg+0x47/0xa0
> netlink_rcv_skb+0x53/0x100
> genl_rcv+0x24/0x40
> netlink_unicast+0x280/0x3b0
> netlink_sendmsg+0x1f7/0x430
> ____sys_sendmsg+0x36b/0x3a0
> ___sys_sendmsg+0x87/0xd0
> __sys_sendmsg+0x6d/0xd0
> do_syscall_64+0x7b/0x2c0
> entry_SYSCALL_64_after_hwframe+0x76/0x7e
>
> The third issue with this process is that while trying to convert
> the non-masked set into masked one, validate_set() copies and doubles
> the size of the OVS_KEY_ATTR_NSH as if it didn't have any nested
> attributes. It should be copying each nested attribute and doubling
> them in size independently. And the process must be properly reversed
> during the conversion back from masked to a non-masked variant during
> the flow dump.
>
> In the end, the only two outcomes of trying to use this action are
> either validation failure or a kernel crash. And if somehow someone
> manages to install a flow with such an action, it will most definitely
> not do what it is supposed to, since all the keys and the masks are
> mixed up.
>
> Fixing all the issues is a complex task as it requires re-writing
> most of the validation code.
>
> Given that and the fact that this functionality never worked since
> introduction, let's just remove it altogether. It's better to
> re-introduce it later with a proper implementation instead of trying
> to fix it in stable releases.
>
> Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
> Reported-by: Junvy Yang <zhuque@tencent.com>
> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Hi Ilya, thanks for taking the time to look into this issue.
Acked-by: Eelco Chaudron <echaudro@redhat.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net: openvswitch: remove never-working support for setting nsh fields
2025-11-12 11:14 [PATCH net] net: openvswitch: remove never-working support for setting nsh fields Ilya Maximets
2025-11-12 13:28 ` Eelco Chaudron
@ 2025-11-12 14:55 ` Aaron Conole
2025-11-12 15:02 ` Ilya Maximets
2025-11-15 2:20 ` patchwork-bot+netdevbpf
2 siblings, 1 reply; 5+ messages in thread
From: Aaron Conole @ 2025-11-12 14:55 UTC (permalink / raw)
To: Ilya Maximets
Cc: netdev, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, dev, Eelco Chaudron,
Willy Tarreau, LePremierHomme, Junvy Yang
Ilya Maximets <i.maximets@ovn.org> writes:
> The validation of the set(nsh(...)) action is completely wrong.
> It runs through the nsh_key_put_from_nlattr() function that is the
> same function that validates NSH keys for the flow match and the
> push_nsh() action. However, the set(nsh(...)) has a very different
> memory layout. Nested attributes in there are doubled in size in
> case of the masked set(). That makes proper validation impossible.
>
> There is also confusion in the code between the 'masked' flag, that
> says that the nested attributes are doubled in size containing both
> the value and the mask, and the 'is_mask' that says that the value
> we're parsing is the mask. This is causing kernel crash on trying to
> write into mask part of the match with SW_FLOW_KEY_PUT() during
> validation, while validate_nsh() doesn't allocate any memory for it:
>
> BUG: kernel NULL pointer dereference, address: 0000000000000018
> #PF: supervisor read access in kernel mode
> #PF: error_code(0x0000) - not-present page
> PGD 1c2383067 P4D 1c2383067 PUD 20b703067 PMD 0
> Oops: Oops: 0000 [#1] SMP NOPTI
> CPU: 8 UID: 0 Kdump: loaded Not tainted 6.17.0-rc4+ #107 PREEMPT(voluntary)
> RIP: 0010:nsh_key_put_from_nlattr+0x19d/0x610 [openvswitch]
> Call Trace:
> <TASK>
> validate_nsh+0x60/0x90 [openvswitch]
> validate_set.constprop.0+0x270/0x3c0 [openvswitch]
> __ovs_nla_copy_actions+0x477/0x860 [openvswitch]
> ovs_nla_copy_actions+0x8d/0x100 [openvswitch]
> ovs_packet_cmd_execute+0x1cc/0x310 [openvswitch]
> genl_family_rcv_msg_doit+0xdb/0x130
> genl_family_rcv_msg+0x14b/0x220
> genl_rcv_msg+0x47/0xa0
> netlink_rcv_skb+0x53/0x100
> genl_rcv+0x24/0x40
> netlink_unicast+0x280/0x3b0
> netlink_sendmsg+0x1f7/0x430
> ____sys_sendmsg+0x36b/0x3a0
> ___sys_sendmsg+0x87/0xd0
> __sys_sendmsg+0x6d/0xd0
> do_syscall_64+0x7b/0x2c0
> entry_SYSCALL_64_after_hwframe+0x76/0x7e
>
> The third issue with this process is that while trying to convert
> the non-masked set into masked one, validate_set() copies and doubles
> the size of the OVS_KEY_ATTR_NSH as if it didn't have any nested
> attributes. It should be copying each nested attribute and doubling
> them in size independently. And the process must be properly reversed
> during the conversion back from masked to a non-masked variant during
> the flow dump.
>
> In the end, the only two outcomes of trying to use this action are
> either validation failure or a kernel crash. And if somehow someone
> manages to install a flow with such an action, it will most definitely
> not do what it is supposed to, since all the keys and the masks are
> mixed up.
>
> Fixing all the issues is a complex task as it requires re-writing
> most of the validation code.
>
> Given that and the fact that this functionality never worked since
> introduction, let's just remove it altogether. It's better to
> re-introduce it later with a proper implementation instead of trying
> to fix it in stable releases.
>
> Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
> Reported-by: Junvy Yang <zhuque@tencent.com>
> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
> ---
Thanks, this makes sense to me. As you noted, the "fix" (I don't really
know if it is the right word since the functionality never worked) is
quite complex, and still might not be 'good enough' to not have further
issues. It makes more sense not to try and support something that never
worked to begin with - especially since even in the userspace side we
never really did a set(nsh()) thing (because it doesn't exist as
functionality).
Reviewed-by: Aaron Conole <aconole@redhat.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net: openvswitch: remove never-working support for setting nsh fields
2025-11-12 14:55 ` Aaron Conole
@ 2025-11-12 15:02 ` Ilya Maximets
0 siblings, 0 replies; 5+ messages in thread
From: Ilya Maximets @ 2025-11-12 15:02 UTC (permalink / raw)
To: Aaron Conole
Cc: i.maximets, netdev, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, dev, Eelco Chaudron,
Willy Tarreau, LePremierHomme, Junvy Yang
On 11/12/25 3:55 PM, Aaron Conole wrote:
> Ilya Maximets <i.maximets@ovn.org> writes:
>
>> The validation of the set(nsh(...)) action is completely wrong.
>> It runs through the nsh_key_put_from_nlattr() function that is the
>> same function that validates NSH keys for the flow match and the
>> push_nsh() action. However, the set(nsh(...)) has a very different
>> memory layout. Nested attributes in there are doubled in size in
>> case of the masked set(). That makes proper validation impossible.
>>
>> There is also confusion in the code between the 'masked' flag, that
>> says that the nested attributes are doubled in size containing both
>> the value and the mask, and the 'is_mask' that says that the value
>> we're parsing is the mask. This is causing kernel crash on trying to
>> write into mask part of the match with SW_FLOW_KEY_PUT() during
>> validation, while validate_nsh() doesn't allocate any memory for it:
>>
>> BUG: kernel NULL pointer dereference, address: 0000000000000018
>> #PF: supervisor read access in kernel mode
>> #PF: error_code(0x0000) - not-present page
>> PGD 1c2383067 P4D 1c2383067 PUD 20b703067 PMD 0
>> Oops: Oops: 0000 [#1] SMP NOPTI
>> CPU: 8 UID: 0 Kdump: loaded Not tainted 6.17.0-rc4+ #107 PREEMPT(voluntary)
>> RIP: 0010:nsh_key_put_from_nlattr+0x19d/0x610 [openvswitch]
>> Call Trace:
>> <TASK>
>> validate_nsh+0x60/0x90 [openvswitch]
>> validate_set.constprop.0+0x270/0x3c0 [openvswitch]
>> __ovs_nla_copy_actions+0x477/0x860 [openvswitch]
>> ovs_nla_copy_actions+0x8d/0x100 [openvswitch]
>> ovs_packet_cmd_execute+0x1cc/0x310 [openvswitch]
>> genl_family_rcv_msg_doit+0xdb/0x130
>> genl_family_rcv_msg+0x14b/0x220
>> genl_rcv_msg+0x47/0xa0
>> netlink_rcv_skb+0x53/0x100
>> genl_rcv+0x24/0x40
>> netlink_unicast+0x280/0x3b0
>> netlink_sendmsg+0x1f7/0x430
>> ____sys_sendmsg+0x36b/0x3a0
>> ___sys_sendmsg+0x87/0xd0
>> __sys_sendmsg+0x6d/0xd0
>> do_syscall_64+0x7b/0x2c0
>> entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>
>> The third issue with this process is that while trying to convert
>> the non-masked set into masked one, validate_set() copies and doubles
>> the size of the OVS_KEY_ATTR_NSH as if it didn't have any nested
>> attributes. It should be copying each nested attribute and doubling
>> them in size independently. And the process must be properly reversed
>> during the conversion back from masked to a non-masked variant during
>> the flow dump.
>>
>> In the end, the only two outcomes of trying to use this action are
>> either validation failure or a kernel crash. And if somehow someone
>> manages to install a flow with such an action, it will most definitely
>> not do what it is supposed to, since all the keys and the masks are
>> mixed up.
>>
>> Fixing all the issues is a complex task as it requires re-writing
>> most of the validation code.
>>
>> Given that and the fact that this functionality never worked since
>> introduction, let's just remove it altogether. It's better to
>> re-introduce it later with a proper implementation instead of trying
>> to fix it in stable releases.
>>
>> Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
>> Reported-by: Junvy Yang <zhuque@tencent.com>
>> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
>> ---
>
> Thanks, this makes sense to me. As you noted, the "fix" (I don't really
> know if it is the right word since the functionality never worked) is
> quite complex, and still might not be 'good enough' to not have further
> issues. It makes more sense not to try and support something that never
> worked to begin with - especially since even in the userspace side we
> never really did a set(nsh()) thing (because it doesn't exist as
> functionality).
The functionality exists in userspace, ovs-vswitchd is able to create
set(nsh()) actions when set_field OpenFlow actions are used. It doesn't
work with the kernel datapath, since the implementation inside the kernel
is broken, but it works with userspace datapath. So, just to clarify,
the implementation on userspace side does exist. It's not ideal, has its
own bugs and doesn't work for kernel datapath, obviously, but it exists.
Best regards, Ilya Maximets.
>
> Reviewed-by: Aaron Conole <aconole@redhat.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net: openvswitch: remove never-working support for setting nsh fields
2025-11-12 11:14 [PATCH net] net: openvswitch: remove never-working support for setting nsh fields Ilya Maximets
2025-11-12 13:28 ` Eelco Chaudron
2025-11-12 14:55 ` Aaron Conole
@ 2025-11-15 2:20 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-11-15 2:20 UTC (permalink / raw)
To: Ilya Maximets
Cc: netdev, davem, edumazet, kuba, pabeni, horms, linux-kernel, dev,
echaudro, aconole, w, kwqcheii, zhuque
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 12 Nov 2025 12:14:03 +0100 you wrote:
> The validation of the set(nsh(...)) action is completely wrong.
> It runs through the nsh_key_put_from_nlattr() function that is the
> same function that validates NSH keys for the flow match and the
> push_nsh() action. However, the set(nsh(...)) has a very different
> memory layout. Nested attributes in there are doubled in size in
> case of the masked set(). That makes proper validation impossible.
>
> [...]
Here is the summary with links:
- [net] net: openvswitch: remove never-working support for setting nsh fields
https://git.kernel.org/netdev/net/c/dfe28c4167a9
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-11-15 2:20 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-12 11:14 [PATCH net] net: openvswitch: remove never-working support for setting nsh fields Ilya Maximets
2025-11-12 13:28 ` Eelco Chaudron
2025-11-12 14:55 ` Aaron Conole
2025-11-12 15:02 ` Ilya Maximets
2025-11-15 2:20 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).