mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-11 15:33:03 +00:00
kernel: fix dst reference leak in flow offload
Fixes a significant amount of leaked memory with lots of connections Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
07ce940b77
commit
c6c4701def
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
||||||
@@ -0,0 +1,421 @@
|
@@ -0,0 +1,422 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
|
+ * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
|
||||||
+ *
|
+ *
|
||||||
@ -330,15 +330,16 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+
|
+
|
||||||
+ this_dst = xt_flowoffload_dst(ct, !dir, par, xt_out(par)->ifindex);
|
+ this_dst = xt_flowoffload_dst(ct, !dir, par, xt_out(par)->ifindex);
|
||||||
+ other_dst = xt_flowoffload_dst(ct, dir, par, xt_in(par)->ifindex);
|
+ other_dst = xt_flowoffload_dst(ct, dir, par, xt_in(par)->ifindex);
|
||||||
|
+
|
||||||
|
+ route->tuple[dir].dst = this_dst;
|
||||||
|
+ route->tuple[!dir].dst = other_dst;
|
||||||
|
+
|
||||||
+ if (!this_dst || !other_dst)
|
+ if (!this_dst || !other_dst)
|
||||||
+ return -ENOENT;
|
+ return -ENOENT;
|
||||||
+
|
+
|
||||||
+ if (dst_xfrm(this_dst) || dst_xfrm(other_dst))
|
+ if (dst_xfrm(this_dst) || dst_xfrm(other_dst))
|
||||||
+ return -EINVAL;
|
+ return -EINVAL;
|
||||||
+
|
+
|
||||||
+ route->tuple[dir].dst = this_dst;
|
|
||||||
+ route->tuple[!dir].dst = other_dst;
|
|
||||||
+
|
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
@ -350,7 +351,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ enum ip_conntrack_info ctinfo;
|
+ enum ip_conntrack_info ctinfo;
|
||||||
+ enum ip_conntrack_dir dir;
|
+ enum ip_conntrack_dir dir;
|
||||||
+ struct nf_flow_route route;
|
+ struct nf_flow_route route;
|
||||||
+ struct flow_offload *flow;
|
+ struct flow_offload *flow = NULL;
|
||||||
+ struct nf_conn *ct;
|
+ struct nf_conn *ct;
|
||||||
+ struct net *net;
|
+ struct net *net;
|
||||||
+
|
+
|
||||||
@ -392,12 +393,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+
|
+
|
||||||
+ dir = CTINFO2DIR(ctinfo);
|
+ dir = CTINFO2DIR(ctinfo);
|
||||||
+
|
+
|
||||||
+ if (xt_flowoffload_route(skb, ct, par, &route, dir) < 0)
|
+ if (xt_flowoffload_route(skb, ct, par, &route, dir) == 0)
|
||||||
+ goto err_flow_route;
|
|
||||||
+
|
|
||||||
+ flow = flow_offload_alloc(ct, &route);
|
+ flow = flow_offload_alloc(ct, &route);
|
||||||
|
+
|
||||||
|
+ dst_release(route.tuple[dir].dst);
|
||||||
|
+ dst_release(route.tuple[!dir].dst);
|
||||||
|
+
|
||||||
+ if (!flow)
|
+ if (!flow)
|
||||||
+ goto err_flow_alloc;
|
+ goto err_flow_route;
|
||||||
+
|
+
|
||||||
+ if (tcph) {
|
+ if (tcph) {
|
||||||
+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
||||||
@ -421,8 +424,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+
|
+
|
||||||
+err_flow_add:
|
+err_flow_add:
|
||||||
+ flow_offload_free(flow);
|
+ flow_offload_free(flow);
|
||||||
+err_flow_alloc:
|
|
||||||
+ dst_release(route.tuple[!dir].dst);
|
|
||||||
+err_flow_route:
|
+err_flow_route:
|
||||||
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
||||||
+ return XT_CONTINUE;
|
+ return XT_CONTINUE;
|
||||||
|
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
||||||
@@ -0,0 +1,421 @@
|
@@ -0,0 +1,422 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
|
+ * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
|
||||||
+ *
|
+ *
|
||||||
@ -330,15 +330,16 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+
|
+
|
||||||
+ this_dst = xt_flowoffload_dst(ct, !dir, par, xt_out(par)->ifindex);
|
+ this_dst = xt_flowoffload_dst(ct, !dir, par, xt_out(par)->ifindex);
|
||||||
+ other_dst = xt_flowoffload_dst(ct, dir, par, xt_in(par)->ifindex);
|
+ other_dst = xt_flowoffload_dst(ct, dir, par, xt_in(par)->ifindex);
|
||||||
|
+
|
||||||
|
+ route->tuple[dir].dst = this_dst;
|
||||||
|
+ route->tuple[!dir].dst = other_dst;
|
||||||
|
+
|
||||||
+ if (!this_dst || !other_dst)
|
+ if (!this_dst || !other_dst)
|
||||||
+ return -ENOENT;
|
+ return -ENOENT;
|
||||||
+
|
+
|
||||||
+ if (dst_xfrm(this_dst) || dst_xfrm(other_dst))
|
+ if (dst_xfrm(this_dst) || dst_xfrm(other_dst))
|
||||||
+ return -EINVAL;
|
+ return -EINVAL;
|
||||||
+
|
+
|
||||||
+ route->tuple[dir].dst = this_dst;
|
|
||||||
+ route->tuple[!dir].dst = other_dst;
|
|
||||||
+
|
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
@ -350,7 +351,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+ enum ip_conntrack_info ctinfo;
|
+ enum ip_conntrack_info ctinfo;
|
||||||
+ enum ip_conntrack_dir dir;
|
+ enum ip_conntrack_dir dir;
|
||||||
+ struct nf_flow_route route;
|
+ struct nf_flow_route route;
|
||||||
+ struct flow_offload *flow;
|
+ struct flow_offload *flow = NULL;
|
||||||
+ struct nf_conn *ct;
|
+ struct nf_conn *ct;
|
||||||
+ struct net *net;
|
+ struct net *net;
|
||||||
+
|
+
|
||||||
@ -392,12 +393,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+
|
+
|
||||||
+ dir = CTINFO2DIR(ctinfo);
|
+ dir = CTINFO2DIR(ctinfo);
|
||||||
+
|
+
|
||||||
+ if (xt_flowoffload_route(skb, ct, par, &route, dir) < 0)
|
+ if (xt_flowoffload_route(skb, ct, par, &route, dir) == 0)
|
||||||
+ goto err_flow_route;
|
|
||||||
+
|
|
||||||
+ flow = flow_offload_alloc(ct, &route);
|
+ flow = flow_offload_alloc(ct, &route);
|
||||||
|
+
|
||||||
|
+ dst_release(route.tuple[dir].dst);
|
||||||
|
+ dst_release(route.tuple[!dir].dst);
|
||||||
|
+
|
||||||
+ if (!flow)
|
+ if (!flow)
|
||||||
+ goto err_flow_alloc;
|
+ goto err_flow_route;
|
||||||
+
|
+
|
||||||
+ if (tcph) {
|
+ if (tcph) {
|
||||||
+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
||||||
@ -421,8 +424,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
+
|
+
|
||||||
+err_flow_add:
|
+err_flow_add:
|
||||||
+ flow_offload_free(flow);
|
+ flow_offload_free(flow);
|
||||||
+err_flow_alloc:
|
|
||||||
+ dst_release(route.tuple[!dir].dst);
|
|
||||||
+err_flow_route:
|
+err_flow_route:
|
||||||
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
||||||
+ return XT_CONTINUE;
|
+ return XT_CONTINUE;
|
||||||
|
Loading…
Reference in New Issue
Block a user