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