Skip to content

Commit 6f022c2

Browse files
Paul Blakeykuba-moo
authored andcommitted
net: openvswitch: Fix ct_state nat flags for conns arriving from tc
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 <[email protected]> Acked-by: Jamal Hadi Salim <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f4bb93a commit 6f022c2

File tree

5 files changed

+27
-5
lines changed

5 files changed

+27
-5
lines changed

include/linux/skbuff.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,9 @@ struct tc_skb_ext {
287287
__u32 chain;
288288
__u16 mru;
289289
__u16 zone;
290-
bool post_ct;
290+
u8 post_ct:1;
291+
u8 post_ct_snat:1;
292+
u8 post_ct_dnat:1;
291293
};
292294
#endif
293295

include/net/pkt_sched.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,9 @@ struct tc_skb_cb {
197197
struct qdisc_skb_cb qdisc_cb;
198198

199199
u16 mru;
200-
bool post_ct;
200+
u8 post_ct:1;
201+
u8 post_ct_snat:1;
202+
u8 post_ct_dnat:1;
201203
u16 zone; /* Only valid if post_ct = true */
202204
};
203205

net/openvswitch/flow.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
859859
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
860860
struct tc_skb_ext *tc_ext;
861861
#endif
862-
bool post_ct = false;
862+
bool post_ct = false, post_ct_snat = false, post_ct_dnat = false;
863863
int res, err;
864864
u16 zone = 0;
865865

@@ -900,6 +900,8 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
900900
key->recirc_id = tc_ext ? tc_ext->chain : 0;
901901
OVS_CB(skb)->mru = tc_ext ? tc_ext->mru : 0;
902902
post_ct = tc_ext ? tc_ext->post_ct : false;
903+
post_ct_snat = post_ct ? tc_ext->post_ct_snat : false;
904+
post_ct_dnat = post_ct ? tc_ext->post_ct_dnat : false;
903905
zone = post_ct ? tc_ext->zone : 0;
904906
} else {
905907
key->recirc_id = 0;
@@ -911,8 +913,16 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
911913
err = key_extract(skb, key);
912914
if (!err) {
913915
ovs_ct_fill_key(skb, key, post_ct); /* Must be after key_extract(). */
914-
if (post_ct && !skb_get_nfct(skb))
915-
key->ct_zone = zone;
916+
if (post_ct) {
917+
if (!skb_get_nfct(skb)) {
918+
key->ct_zone = zone;
919+
} else {
920+
if (!post_ct_dnat)
921+
key->ct_state &= ~OVS_CS_F_DST_NAT;
922+
if (!post_ct_snat)
923+
key->ct_state &= ~OVS_CS_F_SRC_NAT;
924+
}
925+
}
916926
}
917927
return err;
918928
}

net/sched/act_ct.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,12 @@ static int ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
839839
}
840840

841841
err = nf_nat_packet(ct, ctinfo, hooknum, skb);
842+
if (err == NF_ACCEPT) {
843+
if (maniptype == NF_NAT_MANIP_SRC)
844+
tc_skb_cb(skb)->post_ct_snat = 1;
845+
if (maniptype == NF_NAT_MANIP_DST)
846+
tc_skb_cb(skb)->post_ct_dnat = 1;
847+
}
842848
out:
843849
return err;
844850
}

net/sched/cls_api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,8 @@ int tcf_classify(struct sk_buff *skb,
16251625
ext->chain = last_executed_chain;
16261626
ext->mru = cb->mru;
16271627
ext->post_ct = cb->post_ct;
1628+
ext->post_ct_snat = cb->post_ct_snat;
1629+
ext->post_ct_dnat = cb->post_ct_dnat;
16281630
ext->zone = cb->zone;
16291631
}
16301632

0 commit comments

Comments
 (0)