NAK: [SRU][I][PATCH] net: openvswitch: fix misuse of the cached connection on tuple changes
Kleber Souza
kleber.sacilotto.de.souza at canonical.com
Wed Jul 6 10:33:27 UTC 2022
Please comment for the Jammy submission.
On 06.07.22 11:57, Frode Nordahl wrote:
> Buglink: https://launchpad.net/bugs/1967856
>
> SRU Justification:
>
> [Impact]
>
> Users of Open vSwitch on Impish will be affected by this bug and
> have no user space fix available.
>
> [Fix]
>
> * 6bb3c77c74f5de28c78c74ef23af4c63e06e881e "net: openvswitch: fix
> misuse of the cached connection on tuple changes"
>
> [Test Plan]
>
> A reproducer has been attached to the bug and can be executed with
> the OVS system testsuite.
>
> [Where problems could occur]
>
> The regression potential can be considered as low because:
> - The calls added in the openvswitch kernel datapath code would
> prior to Open vSwitch 2.16.0 have been initiated from the
> userspace code and by chance concealed this bug.
> - After an optimization done in 2.16.0 the kernel bug was
> revealed and these calls now must be made from the kernel
> datapath to retain functionality in use in the wild.
>
> From b5a07004998db55c18789caac1faa61fb6268c94 Mon Sep 17 00:00:00 2001
> From: Ilya Maximets <i.maximets at ovn.org>
> Date: Tue, 7 Jun 2022 00:11:40 +0200
> Subject: [SRU][J][PATCH] net: openvswitch: fix misuse of the cached connection
> on tuple changes
> To: kernel-team at lists.ubuntu.com
>
> commit 2061ecfdf2350994e5b61c43e50e98a7a70e95ee upstream.
>
> If packet headers changed, the cached nfct is no longer relevant
> for the packet and attempt to re-use it leads to the incorrect packet
> classification.
>
> This issue is causing broken connectivity in OpenStack deployments
> with OVS/OVN due to hairpin traffic being unexpectedly dropped.
>
> The setup has datapath flows with several conntrack actions and tuple
> changes between them:
>
> actions:ct(commit,zone=8,mark=0/0x1,nat(src)),
> set(eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:06)),
> set(ipv4(src=172.18.2.10,dst=192.168.100.6,ttl=62)),
> ct(zone=8),recirc(0x4)
>
> After the first ct() action the packet headers are almost fully
> re-written. The next ct() tries to re-use the existing nfct entry
> and marks the packet as invalid, so it gets dropped later in the
> pipeline.
>
> Clearing the cached conntrack entry whenever packet tuple is changed
> to avoid the issue.
>
> The flow key should not be cleared though, because we should still
> be able to match on the ct_state if the recirculation happens after
> the tuple change but before the next ct() action.
>
> Cc: stable at vger.kernel.org
> Fixes: 7f8a436eaa2c ("openvswitch: Add conntrack action")
> Reported-by: Frode Nordahl <frode.nordahl at canonical.com>
> Link: https://mail.openvswitch.org/pipermail/ovs-discuss/2022-May/051829.html
> Link: https://bugs.launchpad.net/ubuntu/+source/ovn/+bug/1967856
> Signed-off-by: Ilya Maximets <i.maximets at ovn.org>
> Link: https://lore.kernel.org/r/20220606221140.488984-1-i.maximets@ovn.org
> Signed-off-by: Jakub Kicinski <kuba at kernel.org>
> [Backport to 5.10: minor rebase in ovs_ct_clear function.
> This version also applicable to and tested on 5.4 and 4.19.]
> Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> (backported from commit 6bb3c77c74f5de28c78c74ef23af4c63e06e881e 5.4.y)
> Signed-off-by: Frode Nordahl <frode.nordahl at canonical.com>
> ---
> net/openvswitch/actions.c | 6 ++++++
> net/openvswitch/conntrack.c | 4 +++-
> 2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> index 0c49b63f3e2a..4afe83ec1057 100644
> --- a/net/openvswitch/actions.c
> +++ b/net/openvswitch/actions.c
> @@ -372,6 +372,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
> update_ip_l4_checksum(skb, nh, *addr, new_addr);
> csum_replace4(&nh->check, *addr, new_addr);
> skb_clear_hash(skb);
> + ovs_ct_clear(skb, NULL);
> *addr = new_addr;
> }
>
> @@ -419,6 +420,7 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto,
> update_ipv6_checksum(skb, l4_proto, addr, new_addr);
>
> skb_clear_hash(skb);
> + ovs_ct_clear(skb, NULL);
> memcpy(addr, new_addr, sizeof(__be32[4]));
> }
>
> @@ -659,6 +661,7 @@ static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
> static void set_tp_port(struct sk_buff *skb, __be16 *port,
> __be16 new_port, __sum16 *check)
> {
> + ovs_ct_clear(skb, NULL);
> inet_proto_csum_replace2(check, skb, *port, new_port, false);
> *port = new_port;
> }
> @@ -698,6 +701,7 @@ static int set_udp(struct sk_buff *skb, struct sw_flow_key *flow_key,
> uh->dest = dst;
> flow_key->tp.src = src;
> flow_key->tp.dst = dst;
> + ovs_ct_clear(skb, NULL);
> }
>
> skb_clear_hash(skb);
> @@ -760,6 +764,8 @@ static int set_sctp(struct sk_buff *skb, struct sw_flow_key *flow_key,
> sh->checksum = old_csum ^ old_correct_csum ^ new_csum;
>
> skb_clear_hash(skb);
> + ovs_ct_clear(skb, NULL);
> +
> flow_key->tp.src = sh->source;
> flow_key->tp.dst = sh->dest;
>
> diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
> index cadb6a29b285..95c835e014d5 100644
> --- a/net/openvswitch/conntrack.c
> +++ b/net/openvswitch/conntrack.c
> @@ -1332,7 +1332,9 @@ int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key)
> if (skb_nfct(skb)) {
> nf_conntrack_put(skb_nfct(skb));
> nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
> - ovs_ct_fill_key(skb, key, false);
> +
> + if (key)
> + ovs_ct_fill_key(skb, key, false);
> }
>
> return 0;
More information about the kernel-team
mailing list