NAK: [SRU][F:linux-bluefield][PATCH V2 5/5] UBUNTU: SAUCE: net: openvswitch: Fix ct_state nat flags for conns arriving from tc

Tim Gardner tim.gardner at canonical.com
Mon Jan 17 17:12:18 UTC 2022


This patch is almost upstream: commit 
6f022c2ddbcefaee79502ce5386dfe351d457070 ("net: openvswitch: Fix 
ct_state nat flags for conns arriving from tc") from linux-next.

How about a v3 ?

On 1/14/22 11:57 AM, Bodong Wang wrote:
> From: Paul Blakey <paulb at nvidia.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1957807
> 
> Netfilter conntrack maintains NAT flags per connection indicating
> whether NAT was configured for the connection. Openvswitch maintains
> NAT flags on the per packet flow key ct_state field, indicating
> whether NAT was actually executed on the packet.
> 
> When a packet misses from tc to ovs the conntrack NAT flags are set.
> However, NAT was not necessarily executed on the packet because the
> connection's state might still be in NEW state. As such, openvswitch
> wrongly assumes that NAT was executed and sets an incorrect flow key
> NAT flags.
> 
> Fix this, by flagging to openvswitch which NAT was actually done in
> act_ct via tc_skb_ext and tc_skb_cb to the openvswitch module, so
> the packet flow key NAT flags will be correctly set.
> 
> Fixes: b57dc7c13ea9 ("net/sched: Introduce action ct")
> Signed-off-by: Paul Blakey <paulb at nvidia.com>
> Signed-off-by: Bodong Wang <bodong at nvidia.com>
> ---
>   include/linux/skbuff.h  |  4 +++-
>   include/net/pkt_sched.h |  4 +++-
>   net/openvswitch/flow.c  | 16 +++++++++++++---
>   net/sched/act_ct.c      |  6 ++++++
>   net/sched/cls_api.c     |  2 ++
>   5 files changed, 27 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index b53877d..9701643 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -285,7 +285,9 @@ struct tc_skb_ext {
>   	__u32 chain;
>   	__u16 mru;
>   	__u16 zone;
> -	bool post_ct;
> +	u8 post_ct:1;
> +	u8 post_ct_snat:1;
> +	u8 post_ct_dnat:1;
>   };
>   #endif
>   
> diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
> index b52882e..6250acb 100644
> --- a/include/net/pkt_sched.h
> +++ b/include/net/pkt_sched.h
> @@ -178,7 +178,9 @@ struct tc_skb_cb {
>   	struct qdisc_skb_cb qdisc_cb;
>   
>   	u16 mru;
> -	bool post_ct;
> +	u8 post_ct:1;
> +	u8 post_ct_snat:1;
> +	u8 post_ct_dnat:1;
>   	u16 zone; /* Only valid if post_ct = true */
>   };
>   
> diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
> index 89e00eb..090dc2f 100644
> --- a/net/openvswitch/flow.c
> +++ b/net/openvswitch/flow.c
> @@ -846,7 +846,7 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
>   #if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
>   	struct tc_skb_ext *tc_ext;
>   #endif
> -	bool post_ct = false;
> +	bool post_ct = false, post_ct_snat = false, post_ct_dnat = false;
>   	int res, err;
>   	u16 zone = 0;
>   
> @@ -887,6 +887,8 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
>   		key->recirc_id = tc_ext ? tc_ext->chain : 0;
>   		OVS_CB(skb)->mru = tc_ext ? tc_ext->mru : 0;
>   		post_ct = tc_ext ? tc_ext->post_ct : false;
> +		post_ct_snat = post_ct ? tc_ext->post_ct_snat : false;
> +		post_ct_dnat = post_ct ? tc_ext->post_ct_dnat : false;
>   		zone = post_ct ? tc_ext->zone : 0;
>   	} else {
>   		key->recirc_id = 0;
> @@ -898,8 +900,16 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
>   	err = key_extract(skb, key);
>   	if (!err) {
>   		ovs_ct_fill_key(skb, key, post_ct);   /* Must be after key_extract(). */
> -		if (post_ct && !skb_get_nfct(skb))
> -			key->ct_zone = zone;
> +		if (post_ct) {
> +			if (!skb_get_nfct(skb)) {
> +				key->ct_zone = zone;
> +			} else {
> +				if (!post_ct_dnat)
> +					key->ct_state &= ~OVS_CS_F_DST_NAT;
> +				if (!post_ct_snat)
> +					key->ct_state &= ~OVS_CS_F_SRC_NAT;
> +			}
> +		}
>   	}
>   	return err;
>   }
> diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
> index 796089c..8a78cbd 100644
> --- a/net/sched/act_ct.c
> +++ b/net/sched/act_ct.c
> @@ -832,6 +832,12 @@ static int ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
>   	}
>   
>   	err = nf_nat_packet(ct, ctinfo, hooknum, skb);
> +	if (err == NF_ACCEPT) {
> +		if (maniptype == NF_NAT_MANIP_SRC)
> +			tc_skb_cb(skb)->post_ct_snat = 1;
> +		if (maniptype == NF_NAT_MANIP_DST)
> +			tc_skb_cb(skb)->post_ct_dnat = 1;
> +	}
>   out:
>   	return err;
>   }
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index 5df4155..aecc4f0 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -1683,6 +1683,8 @@ int tcf_classify_ingress(struct sk_buff *skb,
>   		ext->chain = last_executed_chain;
>   		ext->mru = cb->mru;
>   		ext->post_ct = cb->post_ct;
> +		ext->post_ct_snat = cb->post_ct_snat;
> +		ext->post_ct_dnat = cb->post_ct_dnat;
>   		ext->zone = cb->zone;
>   	}
>   
> 

-- 
-----------
Tim Gardner
Canonical, Inc



More information about the kernel-team mailing list