kernel: fix conntrack fixup of offloaded flows on timeout
Fixes excessively long conntrack timeout of short lived connections Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
		| @@ -0,0 +1,24 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Thu, 14 Jun 2018 11:20:09 +0200 | ||||||
|  | Subject: [PATCH] netfilter: nf_flow_table: fix up ct state of flows after | ||||||
|  |  timeout | ||||||
|  |  | ||||||
|  | If a connection simply times out instead of being torn down, it is left | ||||||
|  | active with a long timeout. Fix this by calling flow_offload_fixup_ct_state | ||||||
|  | here as well. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/net/netfilter/nf_flow_table_core.c | ||||||
|  | +++ b/net/netfilter/nf_flow_table_core.c | ||||||
|  | @@ -233,6 +233,9 @@ static void flow_offload_del(struct nf_f | ||||||
|  |  	e = container_of(flow, struct flow_offload_entry, flow); | ||||||
|  |  	clear_bit(IPS_OFFLOAD_BIT, &e->ct->status); | ||||||
|  |   | ||||||
|  | +	if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN)) | ||||||
|  | +		flow_offload_fixup_ct_state(e->ct); | ||||||
|  | + | ||||||
|  |  	flow_offload_free(flow); | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -173,9 +173,9 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|   |   | ||||||
|  	rhashtable_remove_fast(&flow_table->rhashtable, |  	rhashtable_remove_fast(&flow_table->rhashtable, | ||||||
|  			       &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, |  			       &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, | ||||||
| @@ -233,6 +239,9 @@ static void flow_offload_del(struct nf_f | @@ -236,6 +242,9 @@ static void flow_offload_del(struct nf_f | ||||||
|  	e = container_of(flow, struct flow_offload_entry, flow); |  	if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN)) | ||||||
|  	clear_bit(IPS_OFFLOAD_BIT, &e->ct->status); |  		flow_offload_fixup_ct_state(e->ct); | ||||||
|   |   | ||||||
| +	if (nf_flow_in_hw(flow)) | +	if (nf_flow_in_hw(flow)) | ||||||
| +		nf_flow_offload_hw_del(net, flow); | +		nf_flow_offload_hw_del(net, flow); | ||||||
| @@ -183,7 +183,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  	flow_offload_free(flow); |  	flow_offload_free(flow); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -346,6 +355,9 @@ static int nf_flow_offload_gc_step(struc | @@ -349,6 +358,9 @@ static int nf_flow_offload_gc_step(struc | ||||||
|  		if (!teardown) |  		if (!teardown) | ||||||
|  			nf_ct_offload_timeout(flow); |  			nf_ct_offload_timeout(flow); | ||||||
|   |   | ||||||
| @@ -193,7 +193,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  		if (nf_flow_has_expired(flow) || teardown) |  		if (nf_flow_has_expired(flow) || teardown) | ||||||
|  			flow_offload_del(flow_table, flow); |  			flow_offload_del(flow_table, flow); | ||||||
|  	} |  	} | ||||||
| @@ -481,10 +493,43 @@ int nf_flow_dnat_port(const struct flow_ | @@ -484,10 +496,43 @@ int nf_flow_dnat_port(const struct flow_ | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL_GPL(nf_flow_dnat_port); |  EXPORT_SYMBOL_GPL(nf_flow_dnat_port); | ||||||
|   |   | ||||||
| @@ -237,7 +237,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  	INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); |  	INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); | ||||||
|   |   | ||||||
|  	err = rhashtable_init(&flowtable->rhashtable, |  	err = rhashtable_init(&flowtable->rhashtable, | ||||||
| @@ -522,6 +567,8 @@ static void nf_flow_table_iterate_cleanu | @@ -525,6 +570,8 @@ static void nf_flow_table_iterate_cleanu | ||||||
|  { |  { | ||||||
|  	nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev); |  	nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev); | ||||||
|  	flush_delayed_work(&flowtable->gc_work); |  	flush_delayed_work(&flowtable->gc_work); | ||||||
| @@ -246,7 +246,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  void nf_flow_table_cleanup(struct net *net, struct net_device *dev) |  void nf_flow_table_cleanup(struct net *net, struct net_device *dev) | ||||||
| @@ -535,6 +582,26 @@ void nf_flow_table_cleanup(struct net *n | @@ -538,6 +585,26 @@ void nf_flow_table_cleanup(struct net *n | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); |  EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); | ||||||
|   |   | ||||||
| @@ -273,7 +273,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  void nf_flow_table_free(struct nf_flowtable *flow_table) |  void nf_flow_table_free(struct nf_flowtable *flow_table) | ||||||
|  { |  { | ||||||
|  	mutex_lock(&flowtable_lock); |  	mutex_lock(&flowtable_lock); | ||||||
| @@ -544,9 +611,58 @@ void nf_flow_table_free(struct nf_flowta | @@ -547,9 +614,58 @@ void nf_flow_table_free(struct nf_flowta | ||||||
|  	nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); |  	nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); | ||||||
|  	WARN_ON(!nf_flow_offload_gc_step(flow_table)); |  	WARN_ON(!nf_flow_offload_gc_step(flow_table)); | ||||||
|  	rhashtable_destroy(&flow_table->rhashtable); |  	rhashtable_destroy(&flow_table->rhashtable); | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX]; |  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX]; | ||||||
| --- a/net/netfilter/nf_flow_table_core.c | --- a/net/netfilter/nf_flow_table_core.c | ||||||
| +++ b/net/netfilter/nf_flow_table_core.c | +++ b/net/netfilter/nf_flow_table_core.c | ||||||
| @@ -355,7 +355,7 @@ static int nf_flow_offload_gc_step(struc | @@ -358,7 +358,7 @@ static int nf_flow_offload_gc_step(struc | ||||||
|  		if (!teardown) |  		if (!teardown) | ||||||
|  			nf_ct_offload_timeout(flow); |  			nf_ct_offload_timeout(flow); | ||||||
|   |   | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Felix Fietkau
					Felix Fietkau