diff options
-rw-r--r-- | include/net/netns/x_tables.h | 1 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_nat.c | 47 |
2 files changed, 33 insertions, 15 deletions
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h index d258e16c894e..9554a644a8f8 100644 --- a/include/net/netns/x_tables.h +++ b/include/net/netns/x_tables.h | |||
@@ -10,5 +10,6 @@ struct netns_xt { | |||
10 | struct list_head tables[NFPROTO_NUMPROTO]; | 10 | struct list_head tables[NFPROTO_NUMPROTO]; |
11 | struct ebt_table *broute_table; | 11 | struct ebt_table *broute_table; |
12 | struct ebt_table *frame_filter; | 12 | struct ebt_table *frame_filter; |
13 | struct ebt_table *frame_nat; | ||
13 | }; | 14 | }; |
14 | #endif | 15 | #endif |
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 0d8fc5bcddd1..3fe1ae87e35f 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c | |||
@@ -50,48 +50,47 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks) | |||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | static struct ebt_table __frame_nat = | 53 | static struct ebt_table frame_nat = |
54 | { | 54 | { |
55 | .name = "nat", | 55 | .name = "nat", |
56 | .table = &initial_table, | 56 | .table = &initial_table, |
57 | .valid_hooks = NAT_VALID_HOOKS, | 57 | .valid_hooks = NAT_VALID_HOOKS, |
58 | .lock = __RW_LOCK_UNLOCKED(__frame_nat.lock), | 58 | .lock = __RW_LOCK_UNLOCKED(frame_nat.lock), |
59 | .check = check, | 59 | .check = check, |
60 | .me = THIS_MODULE, | 60 | .me = THIS_MODULE, |
61 | }; | 61 | }; |
62 | static struct ebt_table *frame_nat; | ||
63 | 62 | ||
64 | static unsigned int | 63 | static unsigned int |
65 | ebt_nat_dst(unsigned int hook, struct sk_buff *skb, const struct net_device *in | 64 | ebt_nat_in(unsigned int hook, struct sk_buff *skb, const struct net_device *in |
66 | , const struct net_device *out, int (*okfn)(struct sk_buff *)) | 65 | , const struct net_device *out, int (*okfn)(struct sk_buff *)) |
67 | { | 66 | { |
68 | return ebt_do_table(hook, skb, in, out, frame_nat); | 67 | return ebt_do_table(hook, skb, in, out, dev_net(in)->xt.frame_nat); |
69 | } | 68 | } |
70 | 69 | ||
71 | static unsigned int | 70 | static unsigned int |
72 | ebt_nat_src(unsigned int hook, struct sk_buff *skb, const struct net_device *in | 71 | ebt_nat_out(unsigned int hook, struct sk_buff *skb, const struct net_device *in |
73 | , const struct net_device *out, int (*okfn)(struct sk_buff *)) | 72 | , const struct net_device *out, int (*okfn)(struct sk_buff *)) |
74 | { | 73 | { |
75 | return ebt_do_table(hook, skb, in, out, frame_nat); | 74 | return ebt_do_table(hook, skb, in, out, dev_net(out)->xt.frame_nat); |
76 | } | 75 | } |
77 | 76 | ||
78 | static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { | 77 | static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { |
79 | { | 78 | { |
80 | .hook = ebt_nat_dst, | 79 | .hook = ebt_nat_out, |
81 | .owner = THIS_MODULE, | 80 | .owner = THIS_MODULE, |
82 | .pf = PF_BRIDGE, | 81 | .pf = PF_BRIDGE, |
83 | .hooknum = NF_BR_LOCAL_OUT, | 82 | .hooknum = NF_BR_LOCAL_OUT, |
84 | .priority = NF_BR_PRI_NAT_DST_OTHER, | 83 | .priority = NF_BR_PRI_NAT_DST_OTHER, |
85 | }, | 84 | }, |
86 | { | 85 | { |
87 | .hook = ebt_nat_src, | 86 | .hook = ebt_nat_out, |
88 | .owner = THIS_MODULE, | 87 | .owner = THIS_MODULE, |
89 | .pf = PF_BRIDGE, | 88 | .pf = PF_BRIDGE, |
90 | .hooknum = NF_BR_POST_ROUTING, | 89 | .hooknum = NF_BR_POST_ROUTING, |
91 | .priority = NF_BR_PRI_NAT_SRC, | 90 | .priority = NF_BR_PRI_NAT_SRC, |
92 | }, | 91 | }, |
93 | { | 92 | { |
94 | .hook = ebt_nat_dst, | 93 | .hook = ebt_nat_in, |
95 | .owner = THIS_MODULE, | 94 | .owner = THIS_MODULE, |
96 | .pf = PF_BRIDGE, | 95 | .pf = PF_BRIDGE, |
97 | .hooknum = NF_BR_PRE_ROUTING, | 96 | .hooknum = NF_BR_PRE_ROUTING, |
@@ -99,23 +98,41 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = { | |||
99 | }, | 98 | }, |
100 | }; | 99 | }; |
101 | 100 | ||
101 | static int __net_init frame_nat_net_init(struct net *net) | ||
102 | { | ||
103 | net->xt.frame_nat = ebt_register_table(net, &frame_nat); | ||
104 | if (IS_ERR(net->xt.frame_nat)) | ||
105 | return PTR_ERR(net->xt.frame_nat); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void __net_exit frame_nat_net_exit(struct net *net) | ||
110 | { | ||
111 | ebt_unregister_table(net->xt.frame_nat); | ||
112 | } | ||
113 | |||
114 | static struct pernet_operations frame_nat_net_ops = { | ||
115 | .init = frame_nat_net_init, | ||
116 | .exit = frame_nat_net_exit, | ||
117 | }; | ||
118 | |||
102 | static int __init ebtable_nat_init(void) | 119 | static int __init ebtable_nat_init(void) |
103 | { | 120 | { |
104 | int ret; | 121 | int ret; |
105 | 122 | ||
106 | frame_nat = ebt_register_table(&init_net, &__frame_nat); | 123 | ret = register_pernet_subsys(&frame_nat_net_ops); |
107 | if (IS_ERR(frame_nat)) | 124 | if (ret < 0) |
108 | return PTR_ERR(frame_nat); | 125 | return ret; |
109 | ret = nf_register_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat)); | 126 | ret = nf_register_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat)); |
110 | if (ret < 0) | 127 | if (ret < 0) |
111 | ebt_unregister_table(frame_nat); | 128 | unregister_pernet_subsys(&frame_nat_net_ops); |
112 | return ret; | 129 | return ret; |
113 | } | 130 | } |
114 | 131 | ||
115 | static void __exit ebtable_nat_fini(void) | 132 | static void __exit ebtable_nat_fini(void) |
116 | { | 133 | { |
117 | nf_unregister_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat)); | 134 | nf_unregister_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat)); |
118 | ebt_unregister_table(frame_nat); | 135 | unregister_pernet_subsys(&frame_nat_net_ops); |
119 | } | 136 | } |
120 | 137 | ||
121 | module_init(ebtable_nat_init); | 138 | module_init(ebtable_nat_init); |