Skip to content

Commit

Permalink
net: openvswitch: Fix ct_state nat flags for conns arriving from tc
Browse files Browse the repository at this point in the history
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: b57dc7c ("net/sched: Introduce action ct")
Signed-off-by: Paul Blakey <paulb@nvidia.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://lore.kernel.org/r/20220106153804.26451-1-paulb@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Paul Blakey authored and Jakub Kicinski committed Jan 10, 2022
1 parent f4bb93a commit 6f022c2
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 5 deletions.
4 changes: 3 additions & 1 deletion include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,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

Expand Down
4 changes: 3 additions & 1 deletion include/net/pkt_sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,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 */
};

Expand Down
16 changes: 13 additions & 3 deletions net/openvswitch/flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,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;

Expand Down Expand Up @@ -900,6 +900,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;
Expand All @@ -911,8 +913,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;
}
Expand Down
6 changes: 6 additions & 0 deletions net/sched/act_ct.c
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,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;
}
Expand Down
2 changes: 2 additions & 0 deletions net/sched/cls_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,8 @@ int tcf_classify(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;
}

Expand Down

0 comments on commit 6f022c2

Please sign in to comment.