netfilter: netns ebtables: ebtable_filter in netns
[safe/jmp/linux-2.6] / net / bridge / netfilter / ebtable_nat.c
1 /*
2  *  ebtable_nat
3  *
4  *      Authors:
5  *      Bart De Schuymer <bdschuym@pandora.be>
6  *
7  *  April, 2002
8  *
9  */
10
11 #include <linux/netfilter_bridge/ebtables.h>
12 #include <linux/module.h>
13
14 #define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \
15    (1 << NF_BR_POST_ROUTING))
16
17 static struct ebt_entries initial_chains[] =
18 {
19         {
20                 .name   = "PREROUTING",
21                 .policy = EBT_ACCEPT,
22         },
23         {
24                 .name   = "OUTPUT",
25                 .policy = EBT_ACCEPT,
26         },
27         {
28                 .name   = "POSTROUTING",
29                 .policy = EBT_ACCEPT,
30         }
31 };
32
33 static struct ebt_replace_kernel initial_table =
34 {
35         .name           = "nat",
36         .valid_hooks    = NAT_VALID_HOOKS,
37         .entries_size   = 3 * sizeof(struct ebt_entries),
38         .hook_entry     = {
39                 [NF_BR_PRE_ROUTING]     = &initial_chains[0],
40                 [NF_BR_LOCAL_OUT]       = &initial_chains[1],
41                 [NF_BR_POST_ROUTING]    = &initial_chains[2],
42         },
43         .entries        = (char *)initial_chains,
44 };
45
46 static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
47 {
48         if (valid_hooks & ~NAT_VALID_HOOKS)
49                 return -EINVAL;
50         return 0;
51 }
52
53 static struct ebt_table __frame_nat =
54 {
55         .name           = "nat",
56         .table          = &initial_table,
57         .valid_hooks    = NAT_VALID_HOOKS,
58         .lock           = __RW_LOCK_UNLOCKED(__frame_nat.lock),
59         .check          = check,
60         .me             = THIS_MODULE,
61 };
62 static struct ebt_table *frame_nat;
63
64 static unsigned int
65 ebt_nat_dst(unsigned int hook, struct sk_buff *skb, const struct net_device *in
66    , const struct net_device *out, int (*okfn)(struct sk_buff *))
67 {
68         return ebt_do_table(hook, skb, in, out, frame_nat);
69 }
70
71 static unsigned int
72 ebt_nat_src(unsigned int hook, struct sk_buff *skb, const struct net_device *in
73    , const struct net_device *out, int (*okfn)(struct sk_buff *))
74 {
75         return ebt_do_table(hook, skb, in, out, frame_nat);
76 }
77
78 static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
79         {
80                 .hook           = ebt_nat_dst,
81                 .owner          = THIS_MODULE,
82                 .pf             = PF_BRIDGE,
83                 .hooknum        = NF_BR_LOCAL_OUT,
84                 .priority       = NF_BR_PRI_NAT_DST_OTHER,
85         },
86         {
87                 .hook           = ebt_nat_src,
88                 .owner          = THIS_MODULE,
89                 .pf             = PF_BRIDGE,
90                 .hooknum        = NF_BR_POST_ROUTING,
91                 .priority       = NF_BR_PRI_NAT_SRC,
92         },
93         {
94                 .hook           = ebt_nat_dst,
95                 .owner          = THIS_MODULE,
96                 .pf             = PF_BRIDGE,
97                 .hooknum        = NF_BR_PRE_ROUTING,
98                 .priority       = NF_BR_PRI_NAT_DST_BRIDGED,
99         },
100 };
101
102 static int __init ebtable_nat_init(void)
103 {
104         int ret;
105
106         frame_nat = ebt_register_table(&init_net, &__frame_nat);
107         if (IS_ERR(frame_nat))
108                 return PTR_ERR(frame_nat);
109         ret = nf_register_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat));
110         if (ret < 0)
111                 ebt_unregister_table(frame_nat);
112         return ret;
113 }
114
115 static void __exit ebtable_nat_fini(void)
116 {
117         nf_unregister_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat));
118         ebt_unregister_table(frame_nat);
119 }
120
121 module_init(ebtable_nat_init);
122 module_exit(ebtable_nat_fini);
123 MODULE_LICENSE("GPL");