Blame view
net/ipv4/netfilter/arptable_filter.c
2.34 KB
1da177e4c
|
1 2 3 4 5 6 7 8 |
/* * Filtering ARP tables module. * * Copyright (C) 2002 David S. Miller (davem@redhat.com) * */ #include <linux/module.h> |
e3eaa9910
|
9 |
#include <linux/netfilter/x_tables.h> |
1da177e4c
|
10 |
#include <linux/netfilter_arp/arp_tables.h> |
5a0e3ad6a
|
11 |
#include <linux/slab.h> |
1da177e4c
|
12 13 14 15 16 17 18 |
MODULE_LICENSE("GPL"); MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); MODULE_DESCRIPTION("arptables filter table"); #define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \ (1 << NF_ARP_FORWARD)) |
b9e69e127
|
19 |
static int __net_init arptable_filter_table_init(struct net *net); |
35aad0ffd
|
20 |
static const struct xt_table packet_filter = { |
1da177e4c
|
21 22 |
.name = "filter", .valid_hooks = FILTER_VALID_HOOKS, |
1da177e4c
|
23 |
.me = THIS_MODULE, |
ee999d8b9
|
24 |
.af = NFPROTO_ARP, |
2b95efe7f
|
25 |
.priority = NF_IP_PRI_FILTER, |
b9e69e127
|
26 |
.table_init = arptable_filter_table_init, |
1da177e4c
|
27 28 29 |
}; /* The work comes in here from netfilter.c */ |
737535c5c
|
30 |
static unsigned int |
06198b34a
|
31 |
arptable_filter_hook(void *priv, struct sk_buff *skb, |
238e54c9c
|
32 |
const struct nf_hook_state *state) |
1da177e4c
|
33 |
{ |
6cb8ff3f1
|
34 |
return arpt_do_table(skb, state, state->net->ipv4.arptable_filter); |
3918fed5f
|
35 |
} |
2b95efe7f
|
36 |
static struct nf_hook_ops *arpfilter_ops __read_mostly; |
1da177e4c
|
37 |
|
b9e69e127
|
38 |
static int __net_init arptable_filter_table_init(struct net *net) |
9ea0cb260
|
39 |
{ |
e3eaa9910
|
40 |
struct arpt_replace *repl; |
a67dd266a
|
41 |
int err; |
b9e69e127
|
42 43 |
if (net->ipv4.arptable_filter) return 0; |
e3eaa9910
|
44 45 46 |
repl = arpt_alloc_initial_table(&packet_filter); if (repl == NULL) return -ENOMEM; |
a67dd266a
|
47 48 |
err = arpt_register_table(net, &packet_filter, repl, arpfilter_ops, &net->ipv4.arptable_filter); |
e3eaa9910
|
49 |
kfree(repl); |
a67dd266a
|
50 |
return err; |
9ea0cb260
|
51 52 53 54 |
} static void __net_exit arptable_filter_net_exit(struct net *net) { |
b9e69e127
|
55 56 |
if (!net->ipv4.arptable_filter) return; |
a67dd266a
|
57 |
arpt_unregister_table(net, net->ipv4.arptable_filter, arpfilter_ops); |
b9e69e127
|
58 |
net->ipv4.arptable_filter = NULL; |
9ea0cb260
|
59 60 61 |
} static struct pernet_operations arptable_filter_net_ops = { |
9ea0cb260
|
62 63 |
.exit = arptable_filter_net_exit, }; |
65b4b4e81
|
64 |
static int __init arptable_filter_init(void) |
1da177e4c
|
65 |
{ |
964ddaa10
|
66 |
int ret; |
1da177e4c
|
67 |
|
b9e69e127
|
68 69 70 |
arpfilter_ops = xt_hook_ops_alloc(&packet_filter, arptable_filter_hook); if (IS_ERR(arpfilter_ops)) return PTR_ERR(arpfilter_ops); |
9ea0cb260
|
71 |
ret = register_pernet_subsys(&arptable_filter_net_ops); |
b9e69e127
|
72 73 |
if (ret < 0) { kfree(arpfilter_ops); |
9ea0cb260
|
74 |
return ret; |
2b95efe7f
|
75 |
} |
1da177e4c
|
76 |
|
ff76def3b
|
77 78 79 80 81 |
ret = arptable_filter_table_init(&init_net); if (ret) { unregister_pernet_subsys(&arptable_filter_net_ops); kfree(arpfilter_ops); } |
1da177e4c
|
82 83 |
return ret; } |
65b4b4e81
|
84 |
static void __exit arptable_filter_fini(void) |
1da177e4c
|
85 |
{ |
9ea0cb260
|
86 |
unregister_pernet_subsys(&arptable_filter_net_ops); |
b9e69e127
|
87 |
kfree(arpfilter_ops); |
1da177e4c
|
88 |
} |
65b4b4e81
|
89 90 |
module_init(arptable_filter_init); module_exit(arptable_filter_fini); |