OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From: Felix Fietkau <nbd@nbd.name> |
2 | Subject: netfilter: add support for flushing conntrack via /proc |
||
3 | |||
4 | lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314 |
||
5 | Signed-off-by: Felix Fietkau <nbd@nbd.name> |
||
6 | --- |
||
7 | net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++- |
||
8 | 1 file changed, 58 insertions(+), 1 deletion(-) |
||
9 | |||
10 | --- a/net/netfilter/nf_conntrack_standalone.c |
||
11 | +++ b/net/netfilter/nf_conntrack_standalone.c |
||
12 | @@ -17,6 +17,7 @@ |
||
13 | #include <linux/percpu.h> |
||
14 | #include <linux/netdevice.h> |
||
15 | #include <linux/security.h> |
||
16 | +#include <linux/inet.h> |
||
17 | #include <net/net_namespace.h> |
||
18 | #ifdef CONFIG_SYSCTL |
||
19 | #include <linux/sysctl.h> |
||
20 | @@ -381,10 +382,66 @@ static int ct_open(struct inode *inode, |
||
21 | sizeof(struct ct_iter_state)); |
||
22 | } |
||
23 | |||
24 | +struct kill_request { |
||
25 | + u16 family; |
||
26 | + union nf_inet_addr addr; |
||
27 | +}; |
||
28 | + |
||
29 | +static int kill_matching(struct nf_conn *i, void *data) |
||
30 | +{ |
||
31 | + struct kill_request *kr = data; |
||
32 | + struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple; |
||
33 | + struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple; |
||
34 | + |
||
35 | + if (!kr->family) |
||
36 | + return 1; |
||
37 | + |
||
38 | + if (t1->src.l3num != kr->family) |
||
39 | + return 0; |
||
40 | + |
||
41 | + return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) || |
||
42 | + nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) || |
||
43 | + nf_inet_addr_cmp(&kr->addr, &t2->src.u3) || |
||
44 | + nf_inet_addr_cmp(&kr->addr, &t2->dst.u3)); |
||
45 | +} |
||
46 | + |
||
47 | +static ssize_t ct_file_write(struct file *file, const char __user *buf, |
||
48 | + size_t count, loff_t *ppos) |
||
49 | +{ |
||
50 | + struct seq_file *seq = file->private_data; |
||
51 | + struct net *net = seq_file_net(seq); |
||
52 | + struct kill_request kr = { }; |
||
53 | + char req[INET6_ADDRSTRLEN] = { }; |
||
54 | + |
||
55 | + if (count == 0) |
||
56 | + return 0; |
||
57 | + |
||
58 | + if (count >= INET6_ADDRSTRLEN) |
||
59 | + count = INET6_ADDRSTRLEN - 1; |
||
60 | + |
||
61 | + if (copy_from_user(req, buf, count)) |
||
62 | + return -EFAULT; |
||
63 | + |
||
64 | + if (strnchr(req, count, ':')) { |
||
65 | + kr.family = AF_INET6; |
||
66 | + if (!in6_pton(req, count, (void *)&kr.addr, '\n', NULL)) |
||
67 | + return -EINVAL; |
||
68 | + } else if (strnchr(req, count, '.')) { |
||
69 | + kr.family = AF_INET; |
||
70 | + if (!in4_pton(req, count, (void *)&kr.addr, '\n', NULL)) |
||
71 | + return -EINVAL; |
||
72 | + } |
||
73 | + |
||
74 | + nf_ct_iterate_cleanup_net(net, kill_matching, &kr, 0, 0); |
||
75 | + |
||
76 | + return count; |
||
77 | +} |
||
78 | + |
||
79 | static const struct file_operations ct_file_ops = { |
||
80 | .owner = THIS_MODULE, |
||
81 | .open = ct_open, |
||
82 | .read = seq_read, |
||
83 | + .write = ct_file_write, |
||
84 | .llseek = seq_lseek, |
||
85 | .release = seq_release_net, |
||
86 | }; |
||
87 | @@ -488,7 +545,7 @@ static int nf_conntrack_standalone_init_ |
||
88 | kuid_t root_uid; |
||
89 | kgid_t root_gid; |
||
90 | |||
91 | - pde = proc_create("nf_conntrack", 0440, net->proc_net, &ct_file_ops); |
||
92 | + pde = proc_create("nf_conntrack", 0660, net->proc_net, &ct_file_ops); |
||
93 | if (!pde) |
||
94 | goto out_nf_conntrack; |
||
95 |