Skip to content

Commit 88c67ae

Browse files
lxinPaolo Abeni
authored andcommitted
sched: act_ct: add netns into the key of tcf_ct_flow_table
zones_ht is a global hashtable for flow_table with zone as key. However, it does not consider netns when getting a flow_table from zones_ht in tcf_ct_init(), and it means an act_ct action in netns A may get a flow_table that belongs to netns B if it has the same zone value. In Shuang's test with the TOPO: tcf2_c <---> tcf2_sw1 <---> tcf2_sw2 <---> tcf2_s tcf2_sw1 and tcf2_sw2 saw the same flow and used the same flow table, which caused their ct entries entering unexpected states and the TCP connection not able to end normally. This patch fixes the issue simply by adding netns into the key of tcf_ct_flow_table so that an act_ct action gets a flow_table that belongs to its own netns in tcf_ct_init(). Note that for easy coding we don't use tcf_ct_flow_table.nf_ft.net, as the ct_ft is initialized after inserting it to the hashtable in tcf_ct_flow_table_get() and also it requires to implement several functions in rhashtable_params including hashfn, obj_hashfn and obj_cmpfn. Fixes: 64ff70b ("net/sched: act_ct: Offload established connections to flow table") Reported-by: Shuang Li <[email protected]> Signed-off-by: Xin Long <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://lore.kernel.org/r/1db5b6cc6902c5fc6f8c6cbd85494a2008087be5.1718488050.git.lucien.xin@gmail.com Signed-off-by: Paolo Abeni <[email protected]>
1 parent 2ebe8f8 commit 88c67ae

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

net/sched/act_ct.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,26 @@ static struct workqueue_struct *act_ct_wq;
4141
static struct rhashtable zones_ht;
4242
static DEFINE_MUTEX(zones_mutex);
4343

44+
struct zones_ht_key {
45+
struct net *net;
46+
u16 zone;
47+
};
48+
4449
struct tcf_ct_flow_table {
4550
struct rhash_head node; /* In zones tables */
4651

4752
struct rcu_work rwork;
4853
struct nf_flowtable nf_ft;
4954
refcount_t ref;
50-
u16 zone;
55+
struct zones_ht_key key;
5156

5257
bool dying;
5358
};
5459

5560
static const struct rhashtable_params zones_params = {
5661
.head_offset = offsetof(struct tcf_ct_flow_table, node),
57-
.key_offset = offsetof(struct tcf_ct_flow_table, zone),
58-
.key_len = sizeof_field(struct tcf_ct_flow_table, zone),
62+
.key_offset = offsetof(struct tcf_ct_flow_table, key),
63+
.key_len = sizeof_field(struct tcf_ct_flow_table, key),
5964
.automatic_shrinking = true,
6065
};
6166

@@ -316,11 +321,12 @@ static struct nf_flowtable_type flowtable_ct = {
316321

317322
static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params)
318323
{
324+
struct zones_ht_key key = { .net = net, .zone = params->zone };
319325
struct tcf_ct_flow_table *ct_ft;
320326
int err = -ENOMEM;
321327

322328
mutex_lock(&zones_mutex);
323-
ct_ft = rhashtable_lookup_fast(&zones_ht, &params->zone, zones_params);
329+
ct_ft = rhashtable_lookup_fast(&zones_ht, &key, zones_params);
324330
if (ct_ft && refcount_inc_not_zero(&ct_ft->ref))
325331
goto out_unlock;
326332

@@ -329,7 +335,7 @@ static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params)
329335
goto err_alloc;
330336
refcount_set(&ct_ft->ref, 1);
331337

332-
ct_ft->zone = params->zone;
338+
ct_ft->key = key;
333339
err = rhashtable_insert_fast(&zones_ht, &ct_ft->node, zones_params);
334340
if (err)
335341
goto err_insert;

0 commit comments

Comments
 (0)