diff options
Diffstat (limited to 'net/bridge')
29 files changed, 704 insertions, 790 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c index 573acdf6f9ff..4d2c1f1cb524 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c | |||
@@ -28,6 +28,10 @@ static const struct stp_proto br_stp_proto = { | |||
28 | .rcv = br_stp_rcv, | 28 | .rcv = br_stp_rcv, |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static struct pernet_operations br_net_ops = { | ||
32 | .exit = br_net_exit, | ||
33 | }; | ||
34 | |||
31 | static int __init br_init(void) | 35 | static int __init br_init(void) |
32 | { | 36 | { |
33 | int err; | 37 | int err; |
@@ -42,18 +46,22 @@ static int __init br_init(void) | |||
42 | if (err) | 46 | if (err) |
43 | goto err_out; | 47 | goto err_out; |
44 | 48 | ||
45 | err = br_netfilter_init(); | 49 | err = register_pernet_subsys(&br_net_ops); |
46 | if (err) | 50 | if (err) |
47 | goto err_out1; | 51 | goto err_out1; |
48 | 52 | ||
49 | err = register_netdevice_notifier(&br_device_notifier); | 53 | err = br_netfilter_init(); |
50 | if (err) | 54 | if (err) |
51 | goto err_out2; | 55 | goto err_out2; |
52 | 56 | ||
53 | err = br_netlink_init(); | 57 | err = register_netdevice_notifier(&br_device_notifier); |
54 | if (err) | 58 | if (err) |
55 | goto err_out3; | 59 | goto err_out3; |
56 | 60 | ||
61 | err = br_netlink_init(); | ||
62 | if (err) | ||
63 | goto err_out4; | ||
64 | |||
57 | brioctl_set(br_ioctl_deviceless_stub); | 65 | brioctl_set(br_ioctl_deviceless_stub); |
58 | br_handle_frame_hook = br_handle_frame; | 66 | br_handle_frame_hook = br_handle_frame; |
59 | 67 | ||
@@ -61,10 +69,12 @@ static int __init br_init(void) | |||
61 | br_fdb_put_hook = br_fdb_put; | 69 | br_fdb_put_hook = br_fdb_put; |
62 | 70 | ||
63 | return 0; | 71 | return 0; |
64 | err_out3: | 72 | err_out4: |
65 | unregister_netdevice_notifier(&br_device_notifier); | 73 | unregister_netdevice_notifier(&br_device_notifier); |
66 | err_out2: | 74 | err_out3: |
67 | br_netfilter_fini(); | 75 | br_netfilter_fini(); |
76 | err_out2: | ||
77 | unregister_pernet_subsys(&br_net_ops); | ||
68 | err_out1: | 78 | err_out1: |
69 | br_fdb_fini(); | 79 | br_fdb_fini(); |
70 | err_out: | 80 | err_out: |
@@ -80,7 +90,7 @@ static void __exit br_deinit(void) | |||
80 | unregister_netdevice_notifier(&br_device_notifier); | 90 | unregister_netdevice_notifier(&br_device_notifier); |
81 | brioctl_set(NULL); | 91 | brioctl_set(NULL); |
82 | 92 | ||
83 | br_cleanup_bridges(); | 93 | unregister_pernet_subsys(&br_net_ops); |
84 | 94 | ||
85 | synchronize_net(); | 95 | synchronize_net(); |
86 | 96 | ||
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 4f52c3d50ebe..22ba8632196f 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -178,5 +178,6 @@ void br_dev_setup(struct net_device *dev) | |||
178 | dev->priv_flags = IFF_EBRIDGE; | 178 | dev->priv_flags = IFF_EBRIDGE; |
179 | 179 | ||
180 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | | 180 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | |
181 | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX; | 181 | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | |
182 | NETIF_F_NETNS_LOCAL; | ||
182 | } | 183 | } |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 63c18aacde8c..573e20f7dba4 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -168,7 +168,7 @@ static void del_br(struct net_bridge *br) | |||
168 | unregister_netdevice(br->dev); | 168 | unregister_netdevice(br->dev); |
169 | } | 169 | } |
170 | 170 | ||
171 | static struct net_device *new_bridge_dev(const char *name) | 171 | static struct net_device *new_bridge_dev(struct net *net, const char *name) |
172 | { | 172 | { |
173 | struct net_bridge *br; | 173 | struct net_bridge *br; |
174 | struct net_device *dev; | 174 | struct net_device *dev; |
@@ -178,6 +178,7 @@ static struct net_device *new_bridge_dev(const char *name) | |||
178 | 178 | ||
179 | if (!dev) | 179 | if (!dev) |
180 | return NULL; | 180 | return NULL; |
181 | dev_net_set(dev, net); | ||
181 | 182 | ||
182 | br = netdev_priv(dev); | 183 | br = netdev_priv(dev); |
183 | br->dev = dev; | 184 | br->dev = dev; |
@@ -262,12 +263,12 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, | |||
262 | return p; | 263 | return p; |
263 | } | 264 | } |
264 | 265 | ||
265 | int br_add_bridge(const char *name) | 266 | int br_add_bridge(struct net *net, const char *name) |
266 | { | 267 | { |
267 | struct net_device *dev; | 268 | struct net_device *dev; |
268 | int ret; | 269 | int ret; |
269 | 270 | ||
270 | dev = new_bridge_dev(name); | 271 | dev = new_bridge_dev(net, name); |
271 | if (!dev) | 272 | if (!dev) |
272 | return -ENOMEM; | 273 | return -ENOMEM; |
273 | 274 | ||
@@ -294,13 +295,13 @@ out_free: | |||
294 | goto out; | 295 | goto out; |
295 | } | 296 | } |
296 | 297 | ||
297 | int br_del_bridge(const char *name) | 298 | int br_del_bridge(struct net *net, const char *name) |
298 | { | 299 | { |
299 | struct net_device *dev; | 300 | struct net_device *dev; |
300 | int ret = 0; | 301 | int ret = 0; |
301 | 302 | ||
302 | rtnl_lock(); | 303 | rtnl_lock(); |
303 | dev = __dev_get_by_name(&init_net, name); | 304 | dev = __dev_get_by_name(net, name); |
304 | if (dev == NULL) | 305 | if (dev == NULL) |
305 | ret = -ENXIO; /* Could not find device */ | 306 | ret = -ENXIO; /* Could not find device */ |
306 | 307 | ||
@@ -445,13 +446,13 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
445 | return 0; | 446 | return 0; |
446 | } | 447 | } |
447 | 448 | ||
448 | void __exit br_cleanup_bridges(void) | 449 | void br_net_exit(struct net *net) |
449 | { | 450 | { |
450 | struct net_device *dev; | 451 | struct net_device *dev; |
451 | 452 | ||
452 | rtnl_lock(); | 453 | rtnl_lock(); |
453 | restart: | 454 | restart: |
454 | for_each_netdev(&init_net, dev) { | 455 | for_each_netdev(net, dev) { |
455 | if (dev->priv_flags & IFF_EBRIDGE) { | 456 | if (dev->priv_flags & IFF_EBRIDGE) { |
456 | del_br(dev->priv); | 457 | del_br(dev->priv); |
457 | goto restart; | 458 | goto restart; |
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 5bbf07362172..6a6433daaf27 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c | |||
@@ -21,12 +21,12 @@ | |||
21 | #include "br_private.h" | 21 | #include "br_private.h" |
22 | 22 | ||
23 | /* called with RTNL */ | 23 | /* called with RTNL */ |
24 | static int get_bridge_ifindices(int *indices, int num) | 24 | static int get_bridge_ifindices(struct net *net, int *indices, int num) |
25 | { | 25 | { |
26 | struct net_device *dev; | 26 | struct net_device *dev; |
27 | int i = 0; | 27 | int i = 0; |
28 | 28 | ||
29 | for_each_netdev(&init_net, dev) { | 29 | for_each_netdev(net, dev) { |
30 | if (i >= num) | 30 | if (i >= num) |
31 | break; | 31 | break; |
32 | if (dev->priv_flags & IFF_EBRIDGE) | 32 | if (dev->priv_flags & IFF_EBRIDGE) |
@@ -89,7 +89,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) | |||
89 | if (!capable(CAP_NET_ADMIN)) | 89 | if (!capable(CAP_NET_ADMIN)) |
90 | return -EPERM; | 90 | return -EPERM; |
91 | 91 | ||
92 | dev = dev_get_by_index(&init_net, ifindex); | 92 | dev = dev_get_by_index(dev_net(br->dev), ifindex); |
93 | if (dev == NULL) | 93 | if (dev == NULL) |
94 | return -EINVAL; | 94 | return -EINVAL; |
95 | 95 | ||
@@ -315,7 +315,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
315 | return -EOPNOTSUPP; | 315 | return -EOPNOTSUPP; |
316 | } | 316 | } |
317 | 317 | ||
318 | static int old_deviceless(void __user *uarg) | 318 | static int old_deviceless(struct net *net, void __user *uarg) |
319 | { | 319 | { |
320 | unsigned long args[3]; | 320 | unsigned long args[3]; |
321 | 321 | ||
@@ -337,7 +337,7 @@ static int old_deviceless(void __user *uarg) | |||
337 | if (indices == NULL) | 337 | if (indices == NULL) |
338 | return -ENOMEM; | 338 | return -ENOMEM; |
339 | 339 | ||
340 | args[2] = get_bridge_ifindices(indices, args[2]); | 340 | args[2] = get_bridge_ifindices(net, indices, args[2]); |
341 | 341 | ||
342 | ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) | 342 | ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) |
343 | ? -EFAULT : args[2]; | 343 | ? -EFAULT : args[2]; |
@@ -360,9 +360,9 @@ static int old_deviceless(void __user *uarg) | |||
360 | buf[IFNAMSIZ-1] = 0; | 360 | buf[IFNAMSIZ-1] = 0; |
361 | 361 | ||
362 | if (args[0] == BRCTL_ADD_BRIDGE) | 362 | if (args[0] == BRCTL_ADD_BRIDGE) |
363 | return br_add_bridge(buf); | 363 | return br_add_bridge(net, buf); |
364 | 364 | ||
365 | return br_del_bridge(buf); | 365 | return br_del_bridge(net, buf); |
366 | } | 366 | } |
367 | } | 367 | } |
368 | 368 | ||
@@ -374,7 +374,7 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar | |||
374 | switch (cmd) { | 374 | switch (cmd) { |
375 | case SIOCGIFBR: | 375 | case SIOCGIFBR: |
376 | case SIOCSIFBR: | 376 | case SIOCSIFBR: |
377 | return old_deviceless(uarg); | 377 | return old_deviceless(net, uarg); |
378 | 378 | ||
379 | case SIOCBRADDBR: | 379 | case SIOCBRADDBR: |
380 | case SIOCBRDELBR: | 380 | case SIOCBRDELBR: |
@@ -389,9 +389,9 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar | |||
389 | 389 | ||
390 | buf[IFNAMSIZ-1] = 0; | 390 | buf[IFNAMSIZ-1] = 0; |
391 | if (cmd == SIOCBRADDBR) | 391 | if (cmd == SIOCBRADDBR) |
392 | return br_add_bridge(buf); | 392 | return br_add_bridge(net, buf); |
393 | 393 | ||
394 | return br_del_bridge(buf); | 394 | return br_del_bridge(net, buf); |
395 | } | 395 | } |
396 | } | 396 | } |
397 | return -EOPNOTSUPP; | 397 | return -EOPNOTSUPP; |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 6a9a6cd74b1e..a4abed5b4c44 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -657,7 +657,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, | |||
657 | { | 657 | { |
658 | struct nf_bridge_info *nf_bridge; | 658 | struct nf_bridge_info *nf_bridge; |
659 | struct net_device *parent; | 659 | struct net_device *parent; |
660 | int pf; | 660 | u_int8_t pf; |
661 | 661 | ||
662 | if (!skb->nf_bridge) | 662 | if (!skb->nf_bridge) |
663 | return NF_ACCEPT; | 663 | return NF_ACCEPT; |
@@ -791,7 +791,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, | |||
791 | { | 791 | { |
792 | struct nf_bridge_info *nf_bridge = skb->nf_bridge; | 792 | struct nf_bridge_info *nf_bridge = skb->nf_bridge; |
793 | struct net_device *realoutdev = bridge_parent(skb->dev); | 793 | struct net_device *realoutdev = bridge_parent(skb->dev); |
794 | int pf; | 794 | u_int8_t pf; |
795 | 795 | ||
796 | #ifdef CONFIG_NETFILTER_DEBUG | 796 | #ifdef CONFIG_NETFILTER_DEBUG |
797 | /* Be very paranoid. This probably won't happen anymore, but let's | 797 | /* Be very paranoid. This probably won't happen anymore, but let's |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index f155e6ce8a21..ba7be195803c 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -82,6 +82,7 @@ nla_put_failure: | |||
82 | */ | 82 | */ |
83 | void br_ifinfo_notify(int event, struct net_bridge_port *port) | 83 | void br_ifinfo_notify(int event, struct net_bridge_port *port) |
84 | { | 84 | { |
85 | struct net *net = dev_net(port->dev); | ||
85 | struct sk_buff *skb; | 86 | struct sk_buff *skb; |
86 | int err = -ENOBUFS; | 87 | int err = -ENOBUFS; |
87 | 88 | ||
@@ -97,10 +98,10 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port) | |||
97 | kfree_skb(skb); | 98 | kfree_skb(skb); |
98 | goto errout; | 99 | goto errout; |
99 | } | 100 | } |
100 | err = rtnl_notify(skb, &init_net,0, RTNLGRP_LINK, NULL, GFP_ATOMIC); | 101 | err = rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); |
101 | errout: | 102 | errout: |
102 | if (err < 0) | 103 | if (err < 0) |
103 | rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err); | 104 | rtnl_set_sk_err(net, RTNLGRP_LINK, err); |
104 | } | 105 | } |
105 | 106 | ||
106 | /* | 107 | /* |
@@ -112,11 +113,8 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
112 | struct net_device *dev; | 113 | struct net_device *dev; |
113 | int idx; | 114 | int idx; |
114 | 115 | ||
115 | if (net != &init_net) | ||
116 | return 0; | ||
117 | |||
118 | idx = 0; | 116 | idx = 0; |
119 | for_each_netdev(&init_net, dev) { | 117 | for_each_netdev(net, dev) { |
120 | /* not a bridge port */ | 118 | /* not a bridge port */ |
121 | if (dev->br_port == NULL || idx < cb->args[0]) | 119 | if (dev->br_port == NULL || idx < cb->args[0]) |
122 | goto skip; | 120 | goto skip; |
@@ -147,9 +145,6 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
147 | struct net_bridge_port *p; | 145 | struct net_bridge_port *p; |
148 | u8 new_state; | 146 | u8 new_state; |
149 | 147 | ||
150 | if (net != &init_net) | ||
151 | return -EINVAL; | ||
152 | |||
153 | if (nlmsg_len(nlh) < sizeof(*ifm)) | 148 | if (nlmsg_len(nlh) < sizeof(*ifm)) |
154 | return -EINVAL; | 149 | return -EINVAL; |
155 | 150 | ||
@@ -165,7 +160,7 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
165 | if (new_state > BR_STATE_BLOCKING) | 160 | if (new_state > BR_STATE_BLOCKING) |
166 | return -EINVAL; | 161 | return -EINVAL; |
167 | 162 | ||
168 | dev = __dev_get_by_index(&init_net, ifm->ifi_index); | 163 | dev = __dev_get_by_index(net, ifm->ifi_index); |
169 | if (!dev) | 164 | if (!dev) |
170 | return -ENODEV; | 165 | return -ENODEV; |
171 | 166 | ||
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 76340bdd052e..763a3ec292e5 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
@@ -35,9 +35,6 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
35 | struct net_bridge_port *p = dev->br_port; | 35 | struct net_bridge_port *p = dev->br_port; |
36 | struct net_bridge *br; | 36 | struct net_bridge *br; |
37 | 37 | ||
38 | if (!net_eq(dev_net(dev), &init_net)) | ||
39 | return NOTIFY_DONE; | ||
40 | |||
41 | /* not a port of a bridge */ | 38 | /* not a port of a bridge */ |
42 | if (p == NULL) | 39 | if (p == NULL) |
43 | return NOTIFY_DONE; | 40 | return NOTIFY_DONE; |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index c3dc18ddc043..b6c3b71974dc 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -178,9 +178,9 @@ extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb); | |||
178 | 178 | ||
179 | /* br_if.c */ | 179 | /* br_if.c */ |
180 | extern void br_port_carrier_check(struct net_bridge_port *p); | 180 | extern void br_port_carrier_check(struct net_bridge_port *p); |
181 | extern int br_add_bridge(const char *name); | 181 | extern int br_add_bridge(struct net *net, const char *name); |
182 | extern int br_del_bridge(const char *name); | 182 | extern int br_del_bridge(struct net *net, const char *name); |
183 | extern void br_cleanup_bridges(void); | 183 | extern void br_net_exit(struct net *net); |
184 | extern int br_add_if(struct net_bridge *br, | 184 | extern int br_add_if(struct net_bridge *br, |
185 | struct net_device *dev); | 185 | struct net_device *dev); |
186 | extern int br_del_if(struct net_bridge *br, | 186 | extern int br_del_if(struct net_bridge *br, |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 8b200f96f722..81ae40b3f655 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
@@ -140,9 +140,6 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, | |||
140 | struct net_bridge *br; | 140 | struct net_bridge *br; |
141 | const unsigned char *buf; | 141 | const unsigned char *buf; |
142 | 142 | ||
143 | if (!net_eq(dev_net(dev), &init_net)) | ||
144 | goto err; | ||
145 | |||
146 | if (!p) | 143 | if (!p) |
147 | goto err; | 144 | goto err; |
148 | 145 | ||
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index 909479794999..ba6f73eb06c6 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig | |||
@@ -2,21 +2,22 @@ | |||
2 | # Bridge netfilter configuration | 2 | # Bridge netfilter configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "Bridge: Netfilter Configuration" | 5 | menuconfig BRIDGE_NF_EBTABLES |
6 | depends on BRIDGE && BRIDGE_NETFILTER | ||
7 | |||
8 | config BRIDGE_NF_EBTABLES | ||
9 | tristate "Ethernet Bridge tables (ebtables) support" | 6 | tristate "Ethernet Bridge tables (ebtables) support" |
7 | depends on BRIDGE && BRIDGE_NETFILTER | ||
8 | select NETFILTER_XTABLES | ||
10 | help | 9 | help |
11 | ebtables is a general, extensible frame/packet identification | 10 | ebtables is a general, extensible frame/packet identification |
12 | framework. Say 'Y' or 'M' here if you want to do Ethernet | 11 | framework. Say 'Y' or 'M' here if you want to do Ethernet |
13 | filtering/NAT/brouting on the Ethernet bridge. | 12 | filtering/NAT/brouting on the Ethernet bridge. |
13 | |||
14 | if BRIDGE_NF_EBTABLES | ||
15 | |||
14 | # | 16 | # |
15 | # tables | 17 | # tables |
16 | # | 18 | # |
17 | config BRIDGE_EBT_BROUTE | 19 | config BRIDGE_EBT_BROUTE |
18 | tristate "ebt: broute table support" | 20 | tristate "ebt: broute table support" |
19 | depends on BRIDGE_NF_EBTABLES | ||
20 | help | 21 | help |
21 | The ebtables broute table is used to define rules that decide between | 22 | The ebtables broute table is used to define rules that decide between |
22 | bridging and routing frames, giving Linux the functionality of a | 23 | bridging and routing frames, giving Linux the functionality of a |
@@ -27,7 +28,6 @@ config BRIDGE_EBT_BROUTE | |||
27 | 28 | ||
28 | config BRIDGE_EBT_T_FILTER | 29 | config BRIDGE_EBT_T_FILTER |
29 | tristate "ebt: filter table support" | 30 | tristate "ebt: filter table support" |
30 | depends on BRIDGE_NF_EBTABLES | ||
31 | help | 31 | help |
32 | The ebtables filter table is used to define frame filtering rules at | 32 | The ebtables filter table is used to define frame filtering rules at |
33 | local input, forwarding and local output. See the man page for | 33 | local input, forwarding and local output. See the man page for |
@@ -37,7 +37,6 @@ config BRIDGE_EBT_T_FILTER | |||
37 | 37 | ||
38 | config BRIDGE_EBT_T_NAT | 38 | config BRIDGE_EBT_T_NAT |
39 | tristate "ebt: nat table support" | 39 | tristate "ebt: nat table support" |
40 | depends on BRIDGE_NF_EBTABLES | ||
41 | help | 40 | help |
42 | The ebtables nat table is used to define rules that alter the MAC | 41 | The ebtables nat table is used to define rules that alter the MAC |
43 | source address (MAC SNAT) or the MAC destination address (MAC DNAT). | 42 | source address (MAC SNAT) or the MAC destination address (MAC DNAT). |
@@ -49,7 +48,6 @@ config BRIDGE_EBT_T_NAT | |||
49 | # | 48 | # |
50 | config BRIDGE_EBT_802_3 | 49 | config BRIDGE_EBT_802_3 |
51 | tristate "ebt: 802.3 filter support" | 50 | tristate "ebt: 802.3 filter support" |
52 | depends on BRIDGE_NF_EBTABLES | ||
53 | help | 51 | help |
54 | This option adds matching support for 802.3 Ethernet frames. | 52 | This option adds matching support for 802.3 Ethernet frames. |
55 | 53 | ||
@@ -57,7 +55,6 @@ config BRIDGE_EBT_802_3 | |||
57 | 55 | ||
58 | config BRIDGE_EBT_AMONG | 56 | config BRIDGE_EBT_AMONG |
59 | tristate "ebt: among filter support" | 57 | tristate "ebt: among filter support" |
60 | depends on BRIDGE_NF_EBTABLES | ||
61 | help | 58 | help |
62 | This option adds the among match, which allows matching the MAC source | 59 | This option adds the among match, which allows matching the MAC source |
63 | and/or destination address on a list of addresses. Optionally, | 60 | and/or destination address on a list of addresses. Optionally, |
@@ -67,7 +64,6 @@ config BRIDGE_EBT_AMONG | |||
67 | 64 | ||
68 | config BRIDGE_EBT_ARP | 65 | config BRIDGE_EBT_ARP |
69 | tristate "ebt: ARP filter support" | 66 | tristate "ebt: ARP filter support" |
70 | depends on BRIDGE_NF_EBTABLES | ||
71 | help | 67 | help |
72 | This option adds the ARP match, which allows ARP and RARP header field | 68 | This option adds the ARP match, which allows ARP and RARP header field |
73 | filtering. | 69 | filtering. |
@@ -76,7 +72,6 @@ config BRIDGE_EBT_ARP | |||
76 | 72 | ||
77 | config BRIDGE_EBT_IP | 73 | config BRIDGE_EBT_IP |
78 | tristate "ebt: IP filter support" | 74 | tristate "ebt: IP filter support" |
79 | depends on BRIDGE_NF_EBTABLES | ||
80 | help | 75 | help |
81 | This option adds the IP match, which allows basic IP header field | 76 | This option adds the IP match, which allows basic IP header field |
82 | filtering. | 77 | filtering. |
@@ -94,7 +89,6 @@ config BRIDGE_EBT_IP6 | |||
94 | 89 | ||
95 | config BRIDGE_EBT_LIMIT | 90 | config BRIDGE_EBT_LIMIT |
96 | tristate "ebt: limit match support" | 91 | tristate "ebt: limit match support" |
97 | depends on BRIDGE_NF_EBTABLES | ||
98 | help | 92 | help |
99 | This option adds the limit match, which allows you to control | 93 | This option adds the limit match, which allows you to control |
100 | the rate at which a rule can be matched. This match is the | 94 | the rate at which a rule can be matched. This match is the |
@@ -105,7 +99,6 @@ config BRIDGE_EBT_LIMIT | |||
105 | 99 | ||
106 | config BRIDGE_EBT_MARK | 100 | config BRIDGE_EBT_MARK |
107 | tristate "ebt: mark filter support" | 101 | tristate "ebt: mark filter support" |
108 | depends on BRIDGE_NF_EBTABLES | ||
109 | help | 102 | help |
110 | This option adds the mark match, which allows matching frames based on | 103 | This option adds the mark match, which allows matching frames based on |
111 | the 'nfmark' value in the frame. This can be set by the mark target. | 104 | the 'nfmark' value in the frame. This can be set by the mark target. |
@@ -116,7 +109,6 @@ config BRIDGE_EBT_MARK | |||
116 | 109 | ||
117 | config BRIDGE_EBT_PKTTYPE | 110 | config BRIDGE_EBT_PKTTYPE |
118 | tristate "ebt: packet type filter support" | 111 | tristate "ebt: packet type filter support" |
119 | depends on BRIDGE_NF_EBTABLES | ||
120 | help | 112 | help |
121 | This option adds the packet type match, which allows matching on the | 113 | This option adds the packet type match, which allows matching on the |
122 | type of packet based on its Ethernet "class" (as determined by | 114 | type of packet based on its Ethernet "class" (as determined by |
@@ -127,7 +119,6 @@ config BRIDGE_EBT_PKTTYPE | |||
127 | 119 | ||
128 | config BRIDGE_EBT_STP | 120 | config BRIDGE_EBT_STP |
129 | tristate "ebt: STP filter support" | 121 | tristate "ebt: STP filter support" |
130 | depends on BRIDGE_NF_EBTABLES | ||
131 | help | 122 | help |
132 | This option adds the Spanning Tree Protocol match, which | 123 | This option adds the Spanning Tree Protocol match, which |
133 | allows STP header field filtering. | 124 | allows STP header field filtering. |
@@ -136,7 +127,6 @@ config BRIDGE_EBT_STP | |||
136 | 127 | ||
137 | config BRIDGE_EBT_VLAN | 128 | config BRIDGE_EBT_VLAN |
138 | tristate "ebt: 802.1Q VLAN filter support" | 129 | tristate "ebt: 802.1Q VLAN filter support" |
139 | depends on BRIDGE_NF_EBTABLES | ||
140 | help | 130 | help |
141 | This option adds the 802.1Q vlan match, which allows the filtering of | 131 | This option adds the 802.1Q vlan match, which allows the filtering of |
142 | 802.1Q vlan fields. | 132 | 802.1Q vlan fields. |
@@ -156,7 +146,6 @@ config BRIDGE_EBT_ARPREPLY | |||
156 | 146 | ||
157 | config BRIDGE_EBT_DNAT | 147 | config BRIDGE_EBT_DNAT |
158 | tristate "ebt: dnat target support" | 148 | tristate "ebt: dnat target support" |
159 | depends on BRIDGE_NF_EBTABLES | ||
160 | help | 149 | help |
161 | This option adds the MAC DNAT target, which allows altering the MAC | 150 | This option adds the MAC DNAT target, which allows altering the MAC |
162 | destination address of frames. | 151 | destination address of frames. |
@@ -165,7 +154,6 @@ config BRIDGE_EBT_DNAT | |||
165 | 154 | ||
166 | config BRIDGE_EBT_MARK_T | 155 | config BRIDGE_EBT_MARK_T |
167 | tristate "ebt: mark target support" | 156 | tristate "ebt: mark target support" |
168 | depends on BRIDGE_NF_EBTABLES | ||
169 | help | 157 | help |
170 | This option adds the mark target, which allows marking frames by | 158 | This option adds the mark target, which allows marking frames by |
171 | setting the 'nfmark' value in the frame. | 159 | setting the 'nfmark' value in the frame. |
@@ -176,7 +164,6 @@ config BRIDGE_EBT_MARK_T | |||
176 | 164 | ||
177 | config BRIDGE_EBT_REDIRECT | 165 | config BRIDGE_EBT_REDIRECT |
178 | tristate "ebt: redirect target support" | 166 | tristate "ebt: redirect target support" |
179 | depends on BRIDGE_NF_EBTABLES | ||
180 | help | 167 | help |
181 | This option adds the MAC redirect target, which allows altering the MAC | 168 | This option adds the MAC redirect target, which allows altering the MAC |
182 | destination address of a frame to that of the device it arrived on. | 169 | destination address of a frame to that of the device it arrived on. |
@@ -185,7 +172,6 @@ config BRIDGE_EBT_REDIRECT | |||
185 | 172 | ||
186 | config BRIDGE_EBT_SNAT | 173 | config BRIDGE_EBT_SNAT |
187 | tristate "ebt: snat target support" | 174 | tristate "ebt: snat target support" |
188 | depends on BRIDGE_NF_EBTABLES | ||
189 | help | 175 | help |
190 | This option adds the MAC SNAT target, which allows altering the MAC | 176 | This option adds the MAC SNAT target, which allows altering the MAC |
191 | source address of frames. | 177 | source address of frames. |
@@ -196,7 +182,6 @@ config BRIDGE_EBT_SNAT | |||
196 | # | 182 | # |
197 | config BRIDGE_EBT_LOG | 183 | config BRIDGE_EBT_LOG |
198 | tristate "ebt: log support" | 184 | tristate "ebt: log support" |
199 | depends on BRIDGE_NF_EBTABLES | ||
200 | help | 185 | help |
201 | This option adds the log watcher, that you can use in any rule | 186 | This option adds the log watcher, that you can use in any rule |
202 | in any ebtables table. It records info about the frame header | 187 | in any ebtables table. It records info about the frame header |
@@ -206,7 +191,6 @@ config BRIDGE_EBT_LOG | |||
206 | 191 | ||
207 | config BRIDGE_EBT_ULOG | 192 | config BRIDGE_EBT_ULOG |
208 | tristate "ebt: ulog support (OBSOLETE)" | 193 | tristate "ebt: ulog support (OBSOLETE)" |
209 | depends on BRIDGE_NF_EBTABLES | ||
210 | help | 194 | help |
211 | This option enables the old bridge-specific "ebt_ulog" implementation | 195 | This option enables the old bridge-specific "ebt_ulog" implementation |
212 | which has been obsoleted by the new "nfnetlink_log" code (see | 196 | which has been obsoleted by the new "nfnetlink_log" code (see |
@@ -223,7 +207,6 @@ config BRIDGE_EBT_ULOG | |||
223 | 207 | ||
224 | config BRIDGE_EBT_NFLOG | 208 | config BRIDGE_EBT_NFLOG |
225 | tristate "ebt: nflog support" | 209 | tristate "ebt: nflog support" |
226 | depends on BRIDGE_NF_EBTABLES | ||
227 | help | 210 | help |
228 | This option enables the nflog watcher, which allows to LOG | 211 | This option enables the nflog watcher, which allows to LOG |
229 | messages through the netfilter logging API, which can use | 212 | messages through the netfilter logging API, which can use |
@@ -235,4 +218,4 @@ config BRIDGE_EBT_NFLOG | |||
235 | 218 | ||
236 | To compile it as a module, choose M here. If unsure, say N. | 219 | To compile it as a module, choose M here. If unsure, say N. |
237 | 220 | ||
238 | endmenu | 221 | endif # BRIDGE_NF_EBTABLES |
diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c index 98534025360f..bd91dc58d49b 100644 --- a/net/bridge/netfilter/ebt_802_3.c +++ b/net/bridge/netfilter/ebt_802_3.c | |||
@@ -7,64 +7,63 @@ | |||
7 | * May 2003 | 7 | * May 2003 |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | #include <linux/module.h> | |
11 | #include <linux/netfilter/x_tables.h> | ||
11 | #include <linux/netfilter_bridge/ebtables.h> | 12 | #include <linux/netfilter_bridge/ebtables.h> |
12 | #include <linux/netfilter_bridge/ebt_802_3.h> | 13 | #include <linux/netfilter_bridge/ebt_802_3.h> |
13 | #include <linux/module.h> | ||
14 | 14 | ||
15 | static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, | 15 | static bool |
16 | const struct net_device *out, const void *data, unsigned int datalen) | 16 | ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
17 | { | 17 | { |
18 | const struct ebt_802_3_info *info = data; | 18 | const struct ebt_802_3_info *info = par->matchinfo; |
19 | const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb); | 19 | const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb); |
20 | __be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type; | 20 | __be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type; |
21 | 21 | ||
22 | if (info->bitmask & EBT_802_3_SAP) { | 22 | if (info->bitmask & EBT_802_3_SAP) { |
23 | if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP)) | 23 | if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP)) |
24 | return EBT_NOMATCH; | 24 | return false; |
25 | if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP)) | 25 | if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP)) |
26 | return EBT_NOMATCH; | 26 | return false; |
27 | } | 27 | } |
28 | 28 | ||
29 | if (info->bitmask & EBT_802_3_TYPE) { | 29 | if (info->bitmask & EBT_802_3_TYPE) { |
30 | if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE)) | 30 | if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE)) |
31 | return EBT_NOMATCH; | 31 | return false; |
32 | if (FWINV(info->type != type, EBT_802_3_TYPE)) | 32 | if (FWINV(info->type != type, EBT_802_3_TYPE)) |
33 | return EBT_NOMATCH; | 33 | return false; |
34 | } | 34 | } |
35 | 35 | ||
36 | return EBT_MATCH; | 36 | return true; |
37 | } | 37 | } |
38 | 38 | ||
39 | static struct ebt_match filter_802_3; | 39 | static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par) |
40 | static int ebt_802_3_check(const char *tablename, unsigned int hookmask, | ||
41 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
42 | { | 40 | { |
43 | const struct ebt_802_3_info *info = data; | 41 | const struct ebt_802_3_info *info = par->matchinfo; |
44 | 42 | ||
45 | if (datalen < sizeof(struct ebt_802_3_info)) | ||
46 | return -EINVAL; | ||
47 | if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) | 43 | if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) |
48 | return -EINVAL; | 44 | return false; |
49 | 45 | ||
50 | return 0; | 46 | return true; |
51 | } | 47 | } |
52 | 48 | ||
53 | static struct ebt_match filter_802_3 __read_mostly = { | 49 | static struct xt_match ebt_802_3_mt_reg __read_mostly = { |
54 | .name = EBT_802_3_MATCH, | 50 | .name = "802_3", |
55 | .match = ebt_filter_802_3, | 51 | .revision = 0, |
56 | .check = ebt_802_3_check, | 52 | .family = NFPROTO_BRIDGE, |
53 | .match = ebt_802_3_mt, | ||
54 | .checkentry = ebt_802_3_mt_check, | ||
55 | .matchsize = XT_ALIGN(sizeof(struct ebt_802_3_info)), | ||
57 | .me = THIS_MODULE, | 56 | .me = THIS_MODULE, |
58 | }; | 57 | }; |
59 | 58 | ||
60 | static int __init ebt_802_3_init(void) | 59 | static int __init ebt_802_3_init(void) |
61 | { | 60 | { |
62 | return ebt_register_match(&filter_802_3); | 61 | return xt_register_match(&ebt_802_3_mt_reg); |
63 | } | 62 | } |
64 | 63 | ||
65 | static void __exit ebt_802_3_fini(void) | 64 | static void __exit ebt_802_3_fini(void) |
66 | { | 65 | { |
67 | ebt_unregister_match(&filter_802_3); | 66 | xt_unregister_match(&ebt_802_3_mt_reg); |
68 | } | 67 | } |
69 | 68 | ||
70 | module_init(ebt_802_3_init); | 69 | module_init(ebt_802_3_init); |
diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c index 70b6dca5ea75..b595f091f35b 100644 --- a/net/bridge/netfilter/ebt_among.c +++ b/net/bridge/netfilter/ebt_among.c | |||
@@ -7,15 +7,15 @@ | |||
7 | * August, 2003 | 7 | * August, 2003 |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | |||
11 | #include <linux/netfilter_bridge/ebtables.h> | ||
12 | #include <linux/netfilter_bridge/ebt_among.h> | ||
13 | #include <linux/ip.h> | 10 | #include <linux/ip.h> |
14 | #include <linux/if_arp.h> | 11 | #include <linux/if_arp.h> |
15 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/netfilter/x_tables.h> | ||
14 | #include <linux/netfilter_bridge/ebtables.h> | ||
15 | #include <linux/netfilter_bridge/ebt_among.h> | ||
16 | 16 | ||
17 | static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, | 17 | static bool ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, |
18 | const char *mac, __be32 ip) | 18 | const char *mac, __be32 ip) |
19 | { | 19 | { |
20 | /* You may be puzzled as to how this code works. | 20 | /* You may be puzzled as to how this code works. |
21 | * Some tricks were used, refer to | 21 | * Some tricks were used, refer to |
@@ -33,23 +33,19 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, | |||
33 | if (ip) { | 33 | if (ip) { |
34 | for (i = start; i < limit; i++) { | 34 | for (i = start; i < limit; i++) { |
35 | p = &wh->pool[i]; | 35 | p = &wh->pool[i]; |
36 | if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { | 36 | if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) |
37 | if (p->ip == 0 || p->ip == ip) { | 37 | if (p->ip == 0 || p->ip == ip) |
38 | return 1; | 38 | return true; |
39 | } | ||
40 | } | ||
41 | } | 39 | } |
42 | } else { | 40 | } else { |
43 | for (i = start; i < limit; i++) { | 41 | for (i = start; i < limit; i++) { |
44 | p = &wh->pool[i]; | 42 | p = &wh->pool[i]; |
45 | if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { | 43 | if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) |
46 | if (p->ip == 0) { | 44 | if (p->ip == 0) |
47 | return 1; | 45 | return true; |
48 | } | ||
49 | } | ||
50 | } | 46 | } |
51 | } | 47 | } |
52 | return 0; | 48 | return false; |
53 | } | 49 | } |
54 | 50 | ||
55 | static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash | 51 | static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash |
@@ -131,12 +127,10 @@ static int get_ip_src(const struct sk_buff *skb, __be32 *addr) | |||
131 | return 0; | 127 | return 0; |
132 | } | 128 | } |
133 | 129 | ||
134 | static int ebt_filter_among(const struct sk_buff *skb, | 130 | static bool |
135 | const struct net_device *in, | 131 | ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
136 | const struct net_device *out, const void *data, | ||
137 | unsigned int datalen) | ||
138 | { | 132 | { |
139 | const struct ebt_among_info *info = data; | 133 | const struct ebt_among_info *info = par->matchinfo; |
140 | const char *dmac, *smac; | 134 | const char *dmac, *smac; |
141 | const struct ebt_mac_wormhash *wh_dst, *wh_src; | 135 | const struct ebt_mac_wormhash *wh_dst, *wh_src; |
142 | __be32 dip = 0, sip = 0; | 136 | __be32 dip = 0, sip = 0; |
@@ -147,41 +141,41 @@ static int ebt_filter_among(const struct sk_buff *skb, | |||
147 | if (wh_src) { | 141 | if (wh_src) { |
148 | smac = eth_hdr(skb)->h_source; | 142 | smac = eth_hdr(skb)->h_source; |
149 | if (get_ip_src(skb, &sip)) | 143 | if (get_ip_src(skb, &sip)) |
150 | return EBT_NOMATCH; | 144 | return false; |
151 | if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { | 145 | if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { |
152 | /* we match only if it contains */ | 146 | /* we match only if it contains */ |
153 | if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) | 147 | if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) |
154 | return EBT_NOMATCH; | 148 | return false; |
155 | } else { | 149 | } else { |
156 | /* we match only if it DOES NOT contain */ | 150 | /* we match only if it DOES NOT contain */ |
157 | if (ebt_mac_wormhash_contains(wh_src, smac, sip)) | 151 | if (ebt_mac_wormhash_contains(wh_src, smac, sip)) |
158 | return EBT_NOMATCH; | 152 | return false; |
159 | } | 153 | } |
160 | } | 154 | } |
161 | 155 | ||
162 | if (wh_dst) { | 156 | if (wh_dst) { |
163 | dmac = eth_hdr(skb)->h_dest; | 157 | dmac = eth_hdr(skb)->h_dest; |
164 | if (get_ip_dst(skb, &dip)) | 158 | if (get_ip_dst(skb, &dip)) |
165 | return EBT_NOMATCH; | 159 | return false; |
166 | if (!(info->bitmask & EBT_AMONG_DST_NEG)) { | 160 | if (!(info->bitmask & EBT_AMONG_DST_NEG)) { |
167 | /* we match only if it contains */ | 161 | /* we match only if it contains */ |
168 | if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) | 162 | if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) |
169 | return EBT_NOMATCH; | 163 | return false; |
170 | } else { | 164 | } else { |
171 | /* we match only if it DOES NOT contain */ | 165 | /* we match only if it DOES NOT contain */ |
172 | if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) | 166 | if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) |
173 | return EBT_NOMATCH; | 167 | return false; |
174 | } | 168 | } |
175 | } | 169 | } |
176 | 170 | ||
177 | return EBT_MATCH; | 171 | return true; |
178 | } | 172 | } |
179 | 173 | ||
180 | static int ebt_among_check(const char *tablename, unsigned int hookmask, | 174 | static bool ebt_among_mt_check(const struct xt_mtchk_param *par) |
181 | const struct ebt_entry *e, void *data, | ||
182 | unsigned int datalen) | ||
183 | { | 175 | { |
184 | const struct ebt_among_info *info = data; | 176 | const struct ebt_among_info *info = par->matchinfo; |
177 | const struct ebt_entry_match *em = | ||
178 | container_of(par->matchinfo, const struct ebt_entry_match, data); | ||
185 | int expected_length = sizeof(struct ebt_among_info); | 179 | int expected_length = sizeof(struct ebt_among_info); |
186 | const struct ebt_mac_wormhash *wh_dst, *wh_src; | 180 | const struct ebt_mac_wormhash *wh_dst, *wh_src; |
187 | int err; | 181 | int err; |
@@ -191,42 +185,45 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask, | |||
191 | expected_length += ebt_mac_wormhash_size(wh_dst); | 185 | expected_length += ebt_mac_wormhash_size(wh_dst); |
192 | expected_length += ebt_mac_wormhash_size(wh_src); | 186 | expected_length += ebt_mac_wormhash_size(wh_src); |
193 | 187 | ||
194 | if (datalen != EBT_ALIGN(expected_length)) { | 188 | if (em->match_size != EBT_ALIGN(expected_length)) { |
195 | printk(KERN_WARNING | 189 | printk(KERN_WARNING |
196 | "ebtables: among: wrong size: %d " | 190 | "ebtables: among: wrong size: %d " |
197 | "against expected %d, rounded to %Zd\n", | 191 | "against expected %d, rounded to %Zd\n", |
198 | datalen, expected_length, | 192 | em->match_size, expected_length, |
199 | EBT_ALIGN(expected_length)); | 193 | EBT_ALIGN(expected_length)); |
200 | return -EINVAL; | 194 | return false; |
201 | } | 195 | } |
202 | if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) { | 196 | if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) { |
203 | printk(KERN_WARNING | 197 | printk(KERN_WARNING |
204 | "ebtables: among: dst integrity fail: %x\n", -err); | 198 | "ebtables: among: dst integrity fail: %x\n", -err); |
205 | return -EINVAL; | 199 | return false; |
206 | } | 200 | } |
207 | if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) { | 201 | if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) { |
208 | printk(KERN_WARNING | 202 | printk(KERN_WARNING |
209 | "ebtables: among: src integrity fail: %x\n", -err); | 203 | "ebtables: among: src integrity fail: %x\n", -err); |
210 | return -EINVAL; | 204 | return false; |
211 | } | 205 | } |
212 | return 0; | 206 | return true; |
213 | } | 207 | } |
214 | 208 | ||
215 | static struct ebt_match filter_among __read_mostly = { | 209 | static struct xt_match ebt_among_mt_reg __read_mostly = { |
216 | .name = EBT_AMONG_MATCH, | 210 | .name = "among", |
217 | .match = ebt_filter_among, | 211 | .revision = 0, |
218 | .check = ebt_among_check, | 212 | .family = NFPROTO_BRIDGE, |
213 | .match = ebt_among_mt, | ||
214 | .checkentry = ebt_among_mt_check, | ||
215 | .matchsize = -1, /* special case */ | ||
219 | .me = THIS_MODULE, | 216 | .me = THIS_MODULE, |
220 | }; | 217 | }; |
221 | 218 | ||
222 | static int __init ebt_among_init(void) | 219 | static int __init ebt_among_init(void) |
223 | { | 220 | { |
224 | return ebt_register_match(&filter_among); | 221 | return xt_register_match(&ebt_among_mt_reg); |
225 | } | 222 | } |
226 | 223 | ||
227 | static void __exit ebt_among_fini(void) | 224 | static void __exit ebt_among_fini(void) |
228 | { | 225 | { |
229 | ebt_unregister_match(&filter_among); | 226 | xt_unregister_match(&ebt_among_mt_reg); |
230 | } | 227 | } |
231 | 228 | ||
232 | module_init(ebt_among_init); | 229 | module_init(ebt_among_init); |
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c index 7c535be75665..b7ad60419f9a 100644 --- a/net/bridge/netfilter/ebt_arp.c +++ b/net/bridge/netfilter/ebt_arp.c | |||
@@ -8,58 +8,58 @@ | |||
8 | * April, 2002 | 8 | * April, 2002 |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
12 | #include <linux/netfilter_bridge/ebtables.h> | ||
13 | #include <linux/netfilter_bridge/ebt_arp.h> | ||
14 | #include <linux/if_arp.h> | 11 | #include <linux/if_arp.h> |
15 | #include <linux/if_ether.h> | 12 | #include <linux/if_ether.h> |
16 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/netfilter/x_tables.h> | ||
15 | #include <linux/netfilter_bridge/ebtables.h> | ||
16 | #include <linux/netfilter_bridge/ebt_arp.h> | ||
17 | 17 | ||
18 | static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in, | 18 | static bool |
19 | const struct net_device *out, const void *data, unsigned int datalen) | 19 | ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
20 | { | 20 | { |
21 | const struct ebt_arp_info *info = data; | 21 | const struct ebt_arp_info *info = par->matchinfo; |
22 | const struct arphdr *ah; | 22 | const struct arphdr *ah; |
23 | struct arphdr _arph; | 23 | struct arphdr _arph; |
24 | 24 | ||
25 | ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); | 25 | ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); |
26 | if (ah == NULL) | 26 | if (ah == NULL) |
27 | return EBT_NOMATCH; | 27 | return false; |
28 | if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode != | 28 | if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode != |
29 | ah->ar_op, EBT_ARP_OPCODE)) | 29 | ah->ar_op, EBT_ARP_OPCODE)) |
30 | return EBT_NOMATCH; | 30 | return false; |
31 | if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype != | 31 | if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype != |
32 | ah->ar_hrd, EBT_ARP_HTYPE)) | 32 | ah->ar_hrd, EBT_ARP_HTYPE)) |
33 | return EBT_NOMATCH; | 33 | return false; |
34 | if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype != | 34 | if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype != |
35 | ah->ar_pro, EBT_ARP_PTYPE)) | 35 | ah->ar_pro, EBT_ARP_PTYPE)) |
36 | return EBT_NOMATCH; | 36 | return false; |
37 | 37 | ||
38 | if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) { | 38 | if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) { |
39 | const __be32 *sap, *dap; | 39 | const __be32 *sap, *dap; |
40 | __be32 saddr, daddr; | 40 | __be32 saddr, daddr; |
41 | 41 | ||
42 | if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP)) | 42 | if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP)) |
43 | return EBT_NOMATCH; | 43 | return false; |
44 | sap = skb_header_pointer(skb, sizeof(struct arphdr) + | 44 | sap = skb_header_pointer(skb, sizeof(struct arphdr) + |
45 | ah->ar_hln, sizeof(saddr), | 45 | ah->ar_hln, sizeof(saddr), |
46 | &saddr); | 46 | &saddr); |
47 | if (sap == NULL) | 47 | if (sap == NULL) |
48 | return EBT_NOMATCH; | 48 | return false; |
49 | dap = skb_header_pointer(skb, sizeof(struct arphdr) + | 49 | dap = skb_header_pointer(skb, sizeof(struct arphdr) + |
50 | 2*ah->ar_hln+sizeof(saddr), | 50 | 2*ah->ar_hln+sizeof(saddr), |
51 | sizeof(daddr), &daddr); | 51 | sizeof(daddr), &daddr); |
52 | if (dap == NULL) | 52 | if (dap == NULL) |
53 | return EBT_NOMATCH; | 53 | return false; |
54 | if (info->bitmask & EBT_ARP_SRC_IP && | 54 | if (info->bitmask & EBT_ARP_SRC_IP && |
55 | FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP)) | 55 | FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP)) |
56 | return EBT_NOMATCH; | 56 | return false; |
57 | if (info->bitmask & EBT_ARP_DST_IP && | 57 | if (info->bitmask & EBT_ARP_DST_IP && |
58 | FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP)) | 58 | FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP)) |
59 | return EBT_NOMATCH; | 59 | return false; |
60 | if (info->bitmask & EBT_ARP_GRAT && | 60 | if (info->bitmask & EBT_ARP_GRAT && |
61 | FWINV(*dap != *sap, EBT_ARP_GRAT)) | 61 | FWINV(*dap != *sap, EBT_ARP_GRAT)) |
62 | return EBT_NOMATCH; | 62 | return false; |
63 | } | 63 | } |
64 | 64 | ||
65 | if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) { | 65 | if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) { |
@@ -68,18 +68,18 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in | |||
68 | uint8_t verdict, i; | 68 | uint8_t verdict, i; |
69 | 69 | ||
70 | if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER)) | 70 | if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER)) |
71 | return EBT_NOMATCH; | 71 | return false; |
72 | if (info->bitmask & EBT_ARP_SRC_MAC) { | 72 | if (info->bitmask & EBT_ARP_SRC_MAC) { |
73 | mp = skb_header_pointer(skb, sizeof(struct arphdr), | 73 | mp = skb_header_pointer(skb, sizeof(struct arphdr), |
74 | sizeof(_mac), &_mac); | 74 | sizeof(_mac), &_mac); |
75 | if (mp == NULL) | 75 | if (mp == NULL) |
76 | return EBT_NOMATCH; | 76 | return false; |
77 | verdict = 0; | 77 | verdict = 0; |
78 | for (i = 0; i < 6; i++) | 78 | for (i = 0; i < 6; i++) |
79 | verdict |= (mp[i] ^ info->smaddr[i]) & | 79 | verdict |= (mp[i] ^ info->smaddr[i]) & |
80 | info->smmsk[i]; | 80 | info->smmsk[i]; |
81 | if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) | 81 | if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) |
82 | return EBT_NOMATCH; | 82 | return false; |
83 | } | 83 | } |
84 | 84 | ||
85 | if (info->bitmask & EBT_ARP_DST_MAC) { | 85 | if (info->bitmask & EBT_ARP_DST_MAC) { |
@@ -87,50 +87,51 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in | |||
87 | ah->ar_hln + ah->ar_pln, | 87 | ah->ar_hln + ah->ar_pln, |
88 | sizeof(_mac), &_mac); | 88 | sizeof(_mac), &_mac); |
89 | if (mp == NULL) | 89 | if (mp == NULL) |
90 | return EBT_NOMATCH; | 90 | return false; |
91 | verdict = 0; | 91 | verdict = 0; |
92 | for (i = 0; i < 6; i++) | 92 | for (i = 0; i < 6; i++) |
93 | verdict |= (mp[i] ^ info->dmaddr[i]) & | 93 | verdict |= (mp[i] ^ info->dmaddr[i]) & |
94 | info->dmmsk[i]; | 94 | info->dmmsk[i]; |
95 | if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) | 95 | if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) |
96 | return EBT_NOMATCH; | 96 | return false; |
97 | } | 97 | } |
98 | } | 98 | } |
99 | 99 | ||
100 | return EBT_MATCH; | 100 | return true; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int ebt_arp_check(const char *tablename, unsigned int hookmask, | 103 | static bool ebt_arp_mt_check(const struct xt_mtchk_param *par) |
104 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
105 | { | 104 | { |
106 | const struct ebt_arp_info *info = data; | 105 | const struct ebt_arp_info *info = par->matchinfo; |
106 | const struct ebt_entry *e = par->entryinfo; | ||
107 | 107 | ||
108 | if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info))) | ||
109 | return -EINVAL; | ||
110 | if ((e->ethproto != htons(ETH_P_ARP) && | 108 | if ((e->ethproto != htons(ETH_P_ARP) && |
111 | e->ethproto != htons(ETH_P_RARP)) || | 109 | e->ethproto != htons(ETH_P_RARP)) || |
112 | e->invflags & EBT_IPROTO) | 110 | e->invflags & EBT_IPROTO) |
113 | return -EINVAL; | 111 | return false; |
114 | if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK) | 112 | if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK) |
115 | return -EINVAL; | 113 | return false; |
116 | return 0; | 114 | return true; |
117 | } | 115 | } |
118 | 116 | ||
119 | static struct ebt_match filter_arp __read_mostly = { | 117 | static struct xt_match ebt_arp_mt_reg __read_mostly = { |
120 | .name = EBT_ARP_MATCH, | 118 | .name = "arp", |
121 | .match = ebt_filter_arp, | 119 | .revision = 0, |
122 | .check = ebt_arp_check, | 120 | .family = NFPROTO_BRIDGE, |
121 | .match = ebt_arp_mt, | ||
122 | .checkentry = ebt_arp_mt_check, | ||
123 | .matchsize = XT_ALIGN(sizeof(struct ebt_arp_info)), | ||
123 | .me = THIS_MODULE, | 124 | .me = THIS_MODULE, |
124 | }; | 125 | }; |
125 | 126 | ||
126 | static int __init ebt_arp_init(void) | 127 | static int __init ebt_arp_init(void) |
127 | { | 128 | { |
128 | return ebt_register_match(&filter_arp); | 129 | return xt_register_match(&ebt_arp_mt_reg); |
129 | } | 130 | } |
130 | 131 | ||
131 | static void __exit ebt_arp_fini(void) | 132 | static void __exit ebt_arp_fini(void) |
132 | { | 133 | { |
133 | ebt_unregister_match(&filter_arp); | 134 | xt_unregister_match(&ebt_arp_mt_reg); |
134 | } | 135 | } |
135 | 136 | ||
136 | module_init(ebt_arp_init); | 137 | module_init(ebt_arp_init); |
diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c index 0c4279590fc7..76584cd72e57 100644 --- a/net/bridge/netfilter/ebt_arpreply.c +++ b/net/bridge/netfilter/ebt_arpreply.c | |||
@@ -8,18 +8,17 @@ | |||
8 | * August, 2003 | 8 | * August, 2003 |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
12 | #include <linux/netfilter_bridge/ebtables.h> | ||
13 | #include <linux/netfilter_bridge/ebt_arpreply.h> | ||
14 | #include <linux/if_arp.h> | 11 | #include <linux/if_arp.h> |
15 | #include <net/arp.h> | 12 | #include <net/arp.h> |
16 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/netfilter/x_tables.h> | ||
15 | #include <linux/netfilter_bridge/ebtables.h> | ||
16 | #include <linux/netfilter_bridge/ebt_arpreply.h> | ||
17 | 17 | ||
18 | static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr, | 18 | static unsigned int |
19 | const struct net_device *in, const struct net_device *out, | 19 | ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par) |
20 | const void *data, unsigned int datalen) | ||
21 | { | 20 | { |
22 | struct ebt_arpreply_info *info = (void *)data; | 21 | const struct ebt_arpreply_info *info = par->targinfo; |
23 | const __be32 *siptr, *diptr; | 22 | const __be32 *siptr, *diptr; |
24 | __be32 _sip, _dip; | 23 | __be32 _sip, _dip; |
25 | const struct arphdr *ap; | 24 | const struct arphdr *ap; |
@@ -52,45 +51,45 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr, | |||
52 | if (diptr == NULL) | 51 | if (diptr == NULL) |
53 | return EBT_DROP; | 52 | return EBT_DROP; |
54 | 53 | ||
55 | arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)in, | 54 | arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)par->in, |
56 | *diptr, shp, info->mac, shp); | 55 | *diptr, shp, info->mac, shp); |
57 | 56 | ||
58 | return info->target; | 57 | return info->target; |
59 | } | 58 | } |
60 | 59 | ||
61 | static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, | 60 | static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par) |
62 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
63 | { | 61 | { |
64 | const struct ebt_arpreply_info *info = data; | 62 | const struct ebt_arpreply_info *info = par->targinfo; |
63 | const struct ebt_entry *e = par->entryinfo; | ||
65 | 64 | ||
66 | if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info))) | ||
67 | return -EINVAL; | ||
68 | if (BASE_CHAIN && info->target == EBT_RETURN) | 65 | if (BASE_CHAIN && info->target == EBT_RETURN) |
69 | return -EINVAL; | 66 | return false; |
70 | if (e->ethproto != htons(ETH_P_ARP) || | 67 | if (e->ethproto != htons(ETH_P_ARP) || |
71 | e->invflags & EBT_IPROTO) | 68 | e->invflags & EBT_IPROTO) |
72 | return -EINVAL; | 69 | return false; |
73 | CLEAR_BASE_CHAIN_BIT; | 70 | return true; |
74 | if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) | ||
75 | return -EINVAL; | ||
76 | return 0; | ||
77 | } | 71 | } |
78 | 72 | ||
79 | static struct ebt_target reply_target __read_mostly = { | 73 | static struct xt_target ebt_arpreply_tg_reg __read_mostly = { |
80 | .name = EBT_ARPREPLY_TARGET, | 74 | .name = "arpreply", |
81 | .target = ebt_target_reply, | 75 | .revision = 0, |
82 | .check = ebt_target_reply_check, | 76 | .family = NFPROTO_BRIDGE, |
77 | .table = "nat", | ||
78 | .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING), | ||
79 | .target = ebt_arpreply_tg, | ||
80 | .checkentry = ebt_arpreply_tg_check, | ||
81 | .targetsize = XT_ALIGN(sizeof(struct ebt_arpreply_info)), | ||
83 | .me = THIS_MODULE, | 82 | .me = THIS_MODULE, |
84 | }; | 83 | }; |
85 | 84 | ||
86 | static int __init ebt_arpreply_init(void) | 85 | static int __init ebt_arpreply_init(void) |
87 | { | 86 | { |
88 | return ebt_register_target(&reply_target); | 87 | return xt_register_target(&ebt_arpreply_tg_reg); |
89 | } | 88 | } |
90 | 89 | ||
91 | static void __exit ebt_arpreply_fini(void) | 90 | static void __exit ebt_arpreply_fini(void) |
92 | { | 91 | { |
93 | ebt_unregister_target(&reply_target); | 92 | xt_unregister_target(&ebt_arpreply_tg_reg); |
94 | } | 93 | } |
95 | 94 | ||
96 | module_init(ebt_arpreply_init); | 95 | module_init(ebt_arpreply_init); |
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index ca64c1cc1b47..6b49ea9e31fb 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c | |||
@@ -7,18 +7,17 @@ | |||
7 | * June, 2002 | 7 | * June, 2002 |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | #include <linux/module.h> | |
11 | #include <net/sock.h> | ||
11 | #include <linux/netfilter.h> | 12 | #include <linux/netfilter.h> |
13 | #include <linux/netfilter/x_tables.h> | ||
12 | #include <linux/netfilter_bridge/ebtables.h> | 14 | #include <linux/netfilter_bridge/ebtables.h> |
13 | #include <linux/netfilter_bridge/ebt_nat.h> | 15 | #include <linux/netfilter_bridge/ebt_nat.h> |
14 | #include <linux/module.h> | ||
15 | #include <net/sock.h> | ||
16 | 16 | ||
17 | static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, | 17 | static unsigned int |
18 | const struct net_device *in, const struct net_device *out, | 18 | ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par) |
19 | const void *data, unsigned int datalen) | ||
20 | { | 19 | { |
21 | const struct ebt_nat_info *info = data; | 20 | const struct ebt_nat_info *info = par->targinfo; |
22 | 21 | ||
23 | if (!skb_make_writable(skb, 0)) | 22 | if (!skb_make_writable(skb, 0)) |
24 | return EBT_DROP; | 23 | return EBT_DROP; |
@@ -27,40 +26,46 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, | |||
27 | return info->target; | 26 | return info->target; |
28 | } | 27 | } |
29 | 28 | ||
30 | static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, | 29 | static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par) |
31 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
32 | { | 30 | { |
33 | const struct ebt_nat_info *info = data; | 31 | const struct ebt_nat_info *info = par->targinfo; |
32 | unsigned int hook_mask; | ||
34 | 33 | ||
35 | if (BASE_CHAIN && info->target == EBT_RETURN) | 34 | if (BASE_CHAIN && info->target == EBT_RETURN) |
36 | return -EINVAL; | 35 | return false; |
37 | CLEAR_BASE_CHAIN_BIT; | 36 | |
38 | if ( (strcmp(tablename, "nat") || | 37 | hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS); |
39 | (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && | 38 | if ((strcmp(par->table, "nat") != 0 || |
40 | (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) | 39 | (hook_mask & ~((1 << NF_BR_PRE_ROUTING) | |
41 | return -EINVAL; | 40 | (1 << NF_BR_LOCAL_OUT)))) && |
42 | if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) | 41 | (strcmp(par->table, "broute") != 0 || |
43 | return -EINVAL; | 42 | hook_mask & ~(1 << NF_BR_BROUTING))) |
43 | return false; | ||
44 | if (INVALID_TARGET) | 44 | if (INVALID_TARGET) |
45 | return -EINVAL; | 45 | return false; |
46 | return 0; | 46 | return true; |
47 | } | 47 | } |
48 | 48 | ||
49 | static struct ebt_target dnat __read_mostly = { | 49 | static struct xt_target ebt_dnat_tg_reg __read_mostly = { |
50 | .name = EBT_DNAT_TARGET, | 50 | .name = "dnat", |
51 | .target = ebt_target_dnat, | 51 | .revision = 0, |
52 | .check = ebt_target_dnat_check, | 52 | .family = NFPROTO_BRIDGE, |
53 | .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) | | ||
54 | (1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_BROUTING), | ||
55 | .target = ebt_dnat_tg, | ||
56 | .checkentry = ebt_dnat_tg_check, | ||
57 | .targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)), | ||
53 | .me = THIS_MODULE, | 58 | .me = THIS_MODULE, |
54 | }; | 59 | }; |
55 | 60 | ||
56 | static int __init ebt_dnat_init(void) | 61 | static int __init ebt_dnat_init(void) |
57 | { | 62 | { |
58 | return ebt_register_target(&dnat); | 63 | return xt_register_target(&ebt_dnat_tg_reg); |
59 | } | 64 | } |
60 | 65 | ||
61 | static void __exit ebt_dnat_fini(void) | 66 | static void __exit ebt_dnat_fini(void) |
62 | { | 67 | { |
63 | ebt_unregister_target(&dnat); | 68 | xt_unregister_target(&ebt_dnat_tg_reg); |
64 | } | 69 | } |
65 | 70 | ||
66 | module_init(ebt_dnat_init); | 71 | module_init(ebt_dnat_init); |
diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c index 65caa00dcf2a..d771bbfbcbe6 100644 --- a/net/bridge/netfilter/ebt_ip.c +++ b/net/bridge/netfilter/ebt_ip.c | |||
@@ -11,24 +11,23 @@ | |||
11 | * Innominate Security Technologies AG <mhopf@innominate.com> | 11 | * Innominate Security Technologies AG <mhopf@innominate.com> |
12 | * September, 2002 | 12 | * September, 2002 |
13 | */ | 13 | */ |
14 | |||
15 | #include <linux/netfilter_bridge/ebtables.h> | ||
16 | #include <linux/netfilter_bridge/ebt_ip.h> | ||
17 | #include <linux/ip.h> | 14 | #include <linux/ip.h> |
18 | #include <net/ip.h> | 15 | #include <net/ip.h> |
19 | #include <linux/in.h> | 16 | #include <linux/in.h> |
20 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/netfilter/x_tables.h> | ||
19 | #include <linux/netfilter_bridge/ebtables.h> | ||
20 | #include <linux/netfilter_bridge/ebt_ip.h> | ||
21 | 21 | ||
22 | struct tcpudphdr { | 22 | struct tcpudphdr { |
23 | __be16 src; | 23 | __be16 src; |
24 | __be16 dst; | 24 | __be16 dst; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, | 27 | static bool |
28 | const struct net_device *out, const void *data, | 28 | ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
29 | unsigned int datalen) | ||
30 | { | 29 | { |
31 | const struct ebt_ip_info *info = data; | 30 | const struct ebt_ip_info *info = par->matchinfo; |
32 | const struct iphdr *ih; | 31 | const struct iphdr *ih; |
33 | struct iphdr _iph; | 32 | struct iphdr _iph; |
34 | const struct tcpudphdr *pptr; | 33 | const struct tcpudphdr *pptr; |
@@ -36,92 +35,93 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, | |||
36 | 35 | ||
37 | ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); | 36 | ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); |
38 | if (ih == NULL) | 37 | if (ih == NULL) |
39 | return EBT_NOMATCH; | 38 | return false; |
40 | if (info->bitmask & EBT_IP_TOS && | 39 | if (info->bitmask & EBT_IP_TOS && |
41 | FWINV(info->tos != ih->tos, EBT_IP_TOS)) | 40 | FWINV(info->tos != ih->tos, EBT_IP_TOS)) |
42 | return EBT_NOMATCH; | 41 | return false; |
43 | if (info->bitmask & EBT_IP_SOURCE && | 42 | if (info->bitmask & EBT_IP_SOURCE && |
44 | FWINV((ih->saddr & info->smsk) != | 43 | FWINV((ih->saddr & info->smsk) != |
45 | info->saddr, EBT_IP_SOURCE)) | 44 | info->saddr, EBT_IP_SOURCE)) |
46 | return EBT_NOMATCH; | 45 | return false; |
47 | if ((info->bitmask & EBT_IP_DEST) && | 46 | if ((info->bitmask & EBT_IP_DEST) && |
48 | FWINV((ih->daddr & info->dmsk) != | 47 | FWINV((ih->daddr & info->dmsk) != |
49 | info->daddr, EBT_IP_DEST)) | 48 | info->daddr, EBT_IP_DEST)) |
50 | return EBT_NOMATCH; | 49 | return false; |
51 | if (info->bitmask & EBT_IP_PROTO) { | 50 | if (info->bitmask & EBT_IP_PROTO) { |
52 | if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO)) | 51 | if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO)) |
53 | return EBT_NOMATCH; | 52 | return false; |
54 | if (!(info->bitmask & EBT_IP_DPORT) && | 53 | if (!(info->bitmask & EBT_IP_DPORT) && |
55 | !(info->bitmask & EBT_IP_SPORT)) | 54 | !(info->bitmask & EBT_IP_SPORT)) |
56 | return EBT_MATCH; | 55 | return true; |
57 | if (ntohs(ih->frag_off) & IP_OFFSET) | 56 | if (ntohs(ih->frag_off) & IP_OFFSET) |
58 | return EBT_NOMATCH; | 57 | return false; |
59 | pptr = skb_header_pointer(skb, ih->ihl*4, | 58 | pptr = skb_header_pointer(skb, ih->ihl*4, |
60 | sizeof(_ports), &_ports); | 59 | sizeof(_ports), &_ports); |
61 | if (pptr == NULL) | 60 | if (pptr == NULL) |
62 | return EBT_NOMATCH; | 61 | return false; |
63 | if (info->bitmask & EBT_IP_DPORT) { | 62 | if (info->bitmask & EBT_IP_DPORT) { |
64 | u32 dst = ntohs(pptr->dst); | 63 | u32 dst = ntohs(pptr->dst); |
65 | if (FWINV(dst < info->dport[0] || | 64 | if (FWINV(dst < info->dport[0] || |
66 | dst > info->dport[1], | 65 | dst > info->dport[1], |
67 | EBT_IP_DPORT)) | 66 | EBT_IP_DPORT)) |
68 | return EBT_NOMATCH; | 67 | return false; |
69 | } | 68 | } |
70 | if (info->bitmask & EBT_IP_SPORT) { | 69 | if (info->bitmask & EBT_IP_SPORT) { |
71 | u32 src = ntohs(pptr->src); | 70 | u32 src = ntohs(pptr->src); |
72 | if (FWINV(src < info->sport[0] || | 71 | if (FWINV(src < info->sport[0] || |
73 | src > info->sport[1], | 72 | src > info->sport[1], |
74 | EBT_IP_SPORT)) | 73 | EBT_IP_SPORT)) |
75 | return EBT_NOMATCH; | 74 | return false; |
76 | } | 75 | } |
77 | } | 76 | } |
78 | return EBT_MATCH; | 77 | return true; |
79 | } | 78 | } |
80 | 79 | ||
81 | static int ebt_ip_check(const char *tablename, unsigned int hookmask, | 80 | static bool ebt_ip_mt_check(const struct xt_mtchk_param *par) |
82 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
83 | { | 81 | { |
84 | const struct ebt_ip_info *info = data; | 82 | const struct ebt_ip_info *info = par->matchinfo; |
83 | const struct ebt_entry *e = par->entryinfo; | ||
85 | 84 | ||
86 | if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info))) | ||
87 | return -EINVAL; | ||
88 | if (e->ethproto != htons(ETH_P_IP) || | 85 | if (e->ethproto != htons(ETH_P_IP) || |
89 | e->invflags & EBT_IPROTO) | 86 | e->invflags & EBT_IPROTO) |
90 | return -EINVAL; | 87 | return false; |
91 | if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) | 88 | if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) |
92 | return -EINVAL; | 89 | return false; |
93 | if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { | 90 | if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { |
94 | if (info->invflags & EBT_IP_PROTO) | 91 | if (info->invflags & EBT_IP_PROTO) |
95 | return -EINVAL; | 92 | return false; |
96 | if (info->protocol != IPPROTO_TCP && | 93 | if (info->protocol != IPPROTO_TCP && |
97 | info->protocol != IPPROTO_UDP && | 94 | info->protocol != IPPROTO_UDP && |
98 | info->protocol != IPPROTO_UDPLITE && | 95 | info->protocol != IPPROTO_UDPLITE && |
99 | info->protocol != IPPROTO_SCTP && | 96 | info->protocol != IPPROTO_SCTP && |
100 | info->protocol != IPPROTO_DCCP) | 97 | info->protocol != IPPROTO_DCCP) |
101 | return -EINVAL; | 98 | return false; |
102 | } | 99 | } |
103 | if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) | 100 | if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) |
104 | return -EINVAL; | 101 | return false; |
105 | if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) | 102 | if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) |
106 | return -EINVAL; | 103 | return false; |
107 | return 0; | 104 | return true; |
108 | } | 105 | } |
109 | 106 | ||
110 | static struct ebt_match filter_ip __read_mostly = { | 107 | static struct xt_match ebt_ip_mt_reg __read_mostly = { |
111 | .name = EBT_IP_MATCH, | 108 | .name = "ip", |
112 | .match = ebt_filter_ip, | 109 | .revision = 0, |
113 | .check = ebt_ip_check, | 110 | .family = NFPROTO_BRIDGE, |
111 | .match = ebt_ip_mt, | ||
112 | .checkentry = ebt_ip_mt_check, | ||
113 | .matchsize = XT_ALIGN(sizeof(struct ebt_ip_info)), | ||
114 | .me = THIS_MODULE, | 114 | .me = THIS_MODULE, |
115 | }; | 115 | }; |
116 | 116 | ||
117 | static int __init ebt_ip_init(void) | 117 | static int __init ebt_ip_init(void) |
118 | { | 118 | { |
119 | return ebt_register_match(&filter_ip); | 119 | return xt_register_match(&ebt_ip_mt_reg); |
120 | } | 120 | } |
121 | 121 | ||
122 | static void __exit ebt_ip_fini(void) | 122 | static void __exit ebt_ip_fini(void) |
123 | { | 123 | { |
124 | ebt_unregister_match(&filter_ip); | 124 | xt_unregister_match(&ebt_ip_mt_reg); |
125 | } | 125 | } |
126 | 126 | ||
127 | module_init(ebt_ip_init); | 127 | module_init(ebt_ip_init); |
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c index 36efb3a75249..784a6573876c 100644 --- a/net/bridge/netfilter/ebt_ip6.c +++ b/net/bridge/netfilter/ebt_ip6.c | |||
@@ -13,26 +13,24 @@ | |||
13 | * | 13 | * |
14 | * Jan, 2008 | 14 | * Jan, 2008 |
15 | */ | 15 | */ |
16 | |||
17 | #include <linux/netfilter_bridge/ebtables.h> | ||
18 | #include <linux/netfilter_bridge/ebt_ip6.h> | ||
19 | #include <linux/ipv6.h> | 16 | #include <linux/ipv6.h> |
20 | #include <net/ipv6.h> | 17 | #include <net/ipv6.h> |
21 | #include <linux/in.h> | 18 | #include <linux/in.h> |
22 | #include <linux/module.h> | 19 | #include <linux/module.h> |
23 | #include <net/dsfield.h> | 20 | #include <net/dsfield.h> |
21 | #include <linux/netfilter/x_tables.h> | ||
22 | #include <linux/netfilter_bridge/ebtables.h> | ||
23 | #include <linux/netfilter_bridge/ebt_ip6.h> | ||
24 | 24 | ||
25 | struct tcpudphdr { | 25 | struct tcpudphdr { |
26 | __be16 src; | 26 | __be16 src; |
27 | __be16 dst; | 27 | __be16 dst; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static int ebt_filter_ip6(const struct sk_buff *skb, | 30 | static bool |
31 | const struct net_device *in, | 31 | ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
32 | const struct net_device *out, const void *data, | ||
33 | unsigned int datalen) | ||
34 | { | 32 | { |
35 | const struct ebt_ip6_info *info = (struct ebt_ip6_info *)data; | 33 | const struct ebt_ip6_info *info = par->matchinfo; |
36 | const struct ipv6hdr *ih6; | 34 | const struct ipv6hdr *ih6; |
37 | struct ipv6hdr _ip6h; | 35 | struct ipv6hdr _ip6h; |
38 | const struct tcpudphdr *pptr; | 36 | const struct tcpudphdr *pptr; |
@@ -42,100 +40,100 @@ static int ebt_filter_ip6(const struct sk_buff *skb, | |||
42 | 40 | ||
43 | ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h); | 41 | ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h); |
44 | if (ih6 == NULL) | 42 | if (ih6 == NULL) |
45 | return EBT_NOMATCH; | 43 | return false; |
46 | if (info->bitmask & EBT_IP6_TCLASS && | 44 | if (info->bitmask & EBT_IP6_TCLASS && |
47 | FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS)) | 45 | FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS)) |
48 | return EBT_NOMATCH; | 46 | return false; |
49 | for (i = 0; i < 4; i++) | 47 | for (i = 0; i < 4; i++) |
50 | tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] & | 48 | tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] & |
51 | info->smsk.in6_u.u6_addr32[i]; | 49 | info->smsk.in6_u.u6_addr32[i]; |
52 | if (info->bitmask & EBT_IP6_SOURCE && | 50 | if (info->bitmask & EBT_IP6_SOURCE && |
53 | FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0), | 51 | FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0), |
54 | EBT_IP6_SOURCE)) | 52 | EBT_IP6_SOURCE)) |
55 | return EBT_NOMATCH; | 53 | return false; |
56 | for (i = 0; i < 4; i++) | 54 | for (i = 0; i < 4; i++) |
57 | tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] & | 55 | tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] & |
58 | info->dmsk.in6_u.u6_addr32[i]; | 56 | info->dmsk.in6_u.u6_addr32[i]; |
59 | if (info->bitmask & EBT_IP6_DEST && | 57 | if (info->bitmask & EBT_IP6_DEST && |
60 | FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST)) | 58 | FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST)) |
61 | return EBT_NOMATCH; | 59 | return false; |
62 | if (info->bitmask & EBT_IP6_PROTO) { | 60 | if (info->bitmask & EBT_IP6_PROTO) { |
63 | uint8_t nexthdr = ih6->nexthdr; | 61 | uint8_t nexthdr = ih6->nexthdr; |
64 | int offset_ph; | 62 | int offset_ph; |
65 | 63 | ||
66 | offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr); | 64 | offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr); |
67 | if (offset_ph == -1) | 65 | if (offset_ph == -1) |
68 | return EBT_NOMATCH; | 66 | return false; |
69 | if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) | 67 | if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) |
70 | return EBT_NOMATCH; | 68 | return false; |
71 | if (!(info->bitmask & EBT_IP6_DPORT) && | 69 | if (!(info->bitmask & EBT_IP6_DPORT) && |
72 | !(info->bitmask & EBT_IP6_SPORT)) | 70 | !(info->bitmask & EBT_IP6_SPORT)) |
73 | return EBT_MATCH; | 71 | return true; |
74 | pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports), | 72 | pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports), |
75 | &_ports); | 73 | &_ports); |
76 | if (pptr == NULL) | 74 | if (pptr == NULL) |
77 | return EBT_NOMATCH; | 75 | return false; |
78 | if (info->bitmask & EBT_IP6_DPORT) { | 76 | if (info->bitmask & EBT_IP6_DPORT) { |
79 | u32 dst = ntohs(pptr->dst); | 77 | u32 dst = ntohs(pptr->dst); |
80 | if (FWINV(dst < info->dport[0] || | 78 | if (FWINV(dst < info->dport[0] || |
81 | dst > info->dport[1], EBT_IP6_DPORT)) | 79 | dst > info->dport[1], EBT_IP6_DPORT)) |
82 | return EBT_NOMATCH; | 80 | return false; |
83 | } | 81 | } |
84 | if (info->bitmask & EBT_IP6_SPORT) { | 82 | if (info->bitmask & EBT_IP6_SPORT) { |
85 | u32 src = ntohs(pptr->src); | 83 | u32 src = ntohs(pptr->src); |
86 | if (FWINV(src < info->sport[0] || | 84 | if (FWINV(src < info->sport[0] || |
87 | src > info->sport[1], EBT_IP6_SPORT)) | 85 | src > info->sport[1], EBT_IP6_SPORT)) |
88 | return EBT_NOMATCH; | 86 | return false; |
89 | } | 87 | } |
90 | return EBT_MATCH; | 88 | return true; |
91 | } | 89 | } |
92 | return EBT_MATCH; | 90 | return true; |
93 | } | 91 | } |
94 | 92 | ||
95 | static int ebt_ip6_check(const char *tablename, unsigned int hookmask, | 93 | static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par) |
96 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
97 | { | 94 | { |
98 | struct ebt_ip6_info *info = (struct ebt_ip6_info *)data; | 95 | const struct ebt_entry *e = par->entryinfo; |
96 | struct ebt_ip6_info *info = par->matchinfo; | ||
99 | 97 | ||
100 | if (datalen != EBT_ALIGN(sizeof(struct ebt_ip6_info))) | ||
101 | return -EINVAL; | ||
102 | if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO) | 98 | if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO) |
103 | return -EINVAL; | 99 | return false; |
104 | if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK) | 100 | if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK) |
105 | return -EINVAL; | 101 | return false; |
106 | if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) { | 102 | if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) { |
107 | if (info->invflags & EBT_IP6_PROTO) | 103 | if (info->invflags & EBT_IP6_PROTO) |
108 | return -EINVAL; | 104 | return false; |
109 | if (info->protocol != IPPROTO_TCP && | 105 | if (info->protocol != IPPROTO_TCP && |
110 | info->protocol != IPPROTO_UDP && | 106 | info->protocol != IPPROTO_UDP && |
111 | info->protocol != IPPROTO_UDPLITE && | 107 | info->protocol != IPPROTO_UDPLITE && |
112 | info->protocol != IPPROTO_SCTP && | 108 | info->protocol != IPPROTO_SCTP && |
113 | info->protocol != IPPROTO_DCCP) | 109 | info->protocol != IPPROTO_DCCP) |
114 | return -EINVAL; | 110 | return false; |
115 | } | 111 | } |
116 | if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1]) | 112 | if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1]) |
117 | return -EINVAL; | 113 | return false; |
118 | if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1]) | 114 | if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1]) |
119 | return -EINVAL; | 115 | return false; |
120 | return 0; | 116 | return true; |
121 | } | 117 | } |
122 | 118 | ||
123 | static struct ebt_match filter_ip6 = | 119 | static struct xt_match ebt_ip6_mt_reg __read_mostly = { |
124 | { | 120 | .name = "ip6", |
125 | .name = EBT_IP6_MATCH, | 121 | .revision = 0, |
126 | .match = ebt_filter_ip6, | 122 | .family = NFPROTO_BRIDGE, |
127 | .check = ebt_ip6_check, | 123 | .match = ebt_ip6_mt, |
124 | .checkentry = ebt_ip6_mt_check, | ||
125 | .matchsize = XT_ALIGN(sizeof(struct ebt_ip6_info)), | ||
128 | .me = THIS_MODULE, | 126 | .me = THIS_MODULE, |
129 | }; | 127 | }; |
130 | 128 | ||
131 | static int __init ebt_ip6_init(void) | 129 | static int __init ebt_ip6_init(void) |
132 | { | 130 | { |
133 | return ebt_register_match(&filter_ip6); | 131 | return xt_register_match(&ebt_ip6_mt_reg); |
134 | } | 132 | } |
135 | 133 | ||
136 | static void __exit ebt_ip6_fini(void) | 134 | static void __exit ebt_ip6_fini(void) |
137 | { | 135 | { |
138 | ebt_unregister_match(&filter_ip6); | 136 | xt_unregister_match(&ebt_ip6_mt_reg); |
139 | } | 137 | } |
140 | 138 | ||
141 | module_init(ebt_ip6_init); | 139 | module_init(ebt_ip6_init); |
diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c index 8cbdc01c253e..f7bd9192ff0c 100644 --- a/net/bridge/netfilter/ebt_limit.c +++ b/net/bridge/netfilter/ebt_limit.c | |||
@@ -10,13 +10,12 @@ | |||
10 | * September, 2003 | 10 | * September, 2003 |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | |||
14 | #include <linux/netfilter_bridge/ebtables.h> | ||
15 | #include <linux/netfilter_bridge/ebt_limit.h> | ||
16 | #include <linux/module.h> | 13 | #include <linux/module.h> |
17 | |||
18 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
19 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
16 | #include <linux/netfilter/x_tables.h> | ||
17 | #include <linux/netfilter_bridge/ebtables.h> | ||
18 | #include <linux/netfilter_bridge/ebt_limit.h> | ||
20 | 19 | ||
21 | static DEFINE_SPINLOCK(limit_lock); | 20 | static DEFINE_SPINLOCK(limit_lock); |
22 | 21 | ||
@@ -31,11 +30,10 @@ static DEFINE_SPINLOCK(limit_lock); | |||
31 | 30 | ||
32 | #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) | 31 | #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) |
33 | 32 | ||
34 | static int ebt_limit_match(const struct sk_buff *skb, | 33 | static bool |
35 | const struct net_device *in, const struct net_device *out, | 34 | ebt_limit_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
36 | const void *data, unsigned int datalen) | ||
37 | { | 35 | { |
38 | struct ebt_limit_info *info = (struct ebt_limit_info *)data; | 36 | struct ebt_limit_info *info = (void *)par->matchinfo; |
39 | unsigned long now = jiffies; | 37 | unsigned long now = jiffies; |
40 | 38 | ||
41 | spin_lock_bh(&limit_lock); | 39 | spin_lock_bh(&limit_lock); |
@@ -47,11 +45,11 @@ static int ebt_limit_match(const struct sk_buff *skb, | |||
47 | /* We're not limited. */ | 45 | /* We're not limited. */ |
48 | info->credit -= info->cost; | 46 | info->credit -= info->cost; |
49 | spin_unlock_bh(&limit_lock); | 47 | spin_unlock_bh(&limit_lock); |
50 | return EBT_MATCH; | 48 | return true; |
51 | } | 49 | } |
52 | 50 | ||
53 | spin_unlock_bh(&limit_lock); | 51 | spin_unlock_bh(&limit_lock); |
54 | return EBT_NOMATCH; | 52 | return false; |
55 | } | 53 | } |
56 | 54 | ||
57 | /* Precision saver. */ | 55 | /* Precision saver. */ |
@@ -66,20 +64,16 @@ user2credits(u_int32_t user) | |||
66 | return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; | 64 | return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; |
67 | } | 65 | } |
68 | 66 | ||
69 | static int ebt_limit_check(const char *tablename, unsigned int hookmask, | 67 | static bool ebt_limit_mt_check(const struct xt_mtchk_param *par) |
70 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
71 | { | 68 | { |
72 | struct ebt_limit_info *info = data; | 69 | struct ebt_limit_info *info = par->matchinfo; |
73 | |||
74 | if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info))) | ||
75 | return -EINVAL; | ||
76 | 70 | ||
77 | /* Check for overflow. */ | 71 | /* Check for overflow. */ |
78 | if (info->burst == 0 || | 72 | if (info->burst == 0 || |
79 | user2credits(info->avg * info->burst) < user2credits(info->avg)) { | 73 | user2credits(info->avg * info->burst) < user2credits(info->avg)) { |
80 | printk("Overflow in ebt_limit, try lower: %u/%u\n", | 74 | printk("Overflow in ebt_limit, try lower: %u/%u\n", |
81 | info->avg, info->burst); | 75 | info->avg, info->burst); |
82 | return -EINVAL; | 76 | return false; |
83 | } | 77 | } |
84 | 78 | ||
85 | /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */ | 79 | /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */ |
@@ -87,24 +81,27 @@ static int ebt_limit_check(const char *tablename, unsigned int hookmask, | |||
87 | info->credit = user2credits(info->avg * info->burst); | 81 | info->credit = user2credits(info->avg * info->burst); |
88 | info->credit_cap = user2credits(info->avg * info->burst); | 82 | info->credit_cap = user2credits(info->avg * info->burst); |
89 | info->cost = user2credits(info->avg); | 83 | info->cost = user2credits(info->avg); |
90 | return 0; | 84 | return true; |
91 | } | 85 | } |
92 | 86 | ||
93 | static struct ebt_match ebt_limit_reg __read_mostly = { | 87 | static struct xt_match ebt_limit_mt_reg __read_mostly = { |
94 | .name = EBT_LIMIT_MATCH, | 88 | .name = "limit", |
95 | .match = ebt_limit_match, | 89 | .revision = 0, |
96 | .check = ebt_limit_check, | 90 | .family = NFPROTO_BRIDGE, |
91 | .match = ebt_limit_mt, | ||
92 | .checkentry = ebt_limit_mt_check, | ||
93 | .matchsize = XT_ALIGN(sizeof(struct ebt_limit_info)), | ||
97 | .me = THIS_MODULE, | 94 | .me = THIS_MODULE, |
98 | }; | 95 | }; |
99 | 96 | ||
100 | static int __init ebt_limit_init(void) | 97 | static int __init ebt_limit_init(void) |
101 | { | 98 | { |
102 | return ebt_register_match(&ebt_limit_reg); | 99 | return xt_register_match(&ebt_limit_mt_reg); |
103 | } | 100 | } |
104 | 101 | ||
105 | static void __exit ebt_limit_fini(void) | 102 | static void __exit ebt_limit_fini(void) |
106 | { | 103 | { |
107 | ebt_unregister_match(&ebt_limit_reg); | 104 | xt_unregister_match(&ebt_limit_mt_reg); |
108 | } | 105 | } |
109 | 106 | ||
110 | module_init(ebt_limit_init); | 107 | module_init(ebt_limit_init); |
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 2f430d4ae911..3d33c608906a 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -8,10 +8,6 @@ | |||
8 | * April, 2002 | 8 | * April, 2002 |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
12 | #include <linux/netfilter_bridge/ebtables.h> | ||
13 | #include <linux/netfilter_bridge/ebt_log.h> | ||
14 | #include <linux/netfilter.h> | ||
15 | #include <linux/module.h> | 11 | #include <linux/module.h> |
16 | #include <linux/ip.h> | 12 | #include <linux/ip.h> |
17 | #include <linux/in.h> | 13 | #include <linux/in.h> |
@@ -21,22 +17,23 @@ | |||
21 | #include <linux/ipv6.h> | 17 | #include <linux/ipv6.h> |
22 | #include <net/ipv6.h> | 18 | #include <net/ipv6.h> |
23 | #include <linux/in6.h> | 19 | #include <linux/in6.h> |
20 | #include <linux/netfilter/x_tables.h> | ||
21 | #include <linux/netfilter_bridge/ebtables.h> | ||
22 | #include <linux/netfilter_bridge/ebt_log.h> | ||
23 | #include <linux/netfilter.h> | ||
24 | 24 | ||
25 | static DEFINE_SPINLOCK(ebt_log_lock); | 25 | static DEFINE_SPINLOCK(ebt_log_lock); |
26 | 26 | ||
27 | static int ebt_log_check(const char *tablename, unsigned int hookmask, | 27 | static bool ebt_log_tg_check(const struct xt_tgchk_param *par) |
28 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
29 | { | 28 | { |
30 | struct ebt_log_info *info = data; | 29 | struct ebt_log_info *info = par->targinfo; |
31 | 30 | ||
32 | if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info))) | ||
33 | return -EINVAL; | ||
34 | if (info->bitmask & ~EBT_LOG_MASK) | 31 | if (info->bitmask & ~EBT_LOG_MASK) |
35 | return -EINVAL; | 32 | return false; |
36 | if (info->loglevel >= 8) | 33 | if (info->loglevel >= 8) |
37 | return -EINVAL; | 34 | return false; |
38 | info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0'; | 35 | info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0'; |
39 | return 0; | 36 | return true; |
40 | } | 37 | } |
41 | 38 | ||
42 | struct tcpudphdr | 39 | struct tcpudphdr |
@@ -84,7 +81,7 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset) | |||
84 | 81 | ||
85 | #define myNIPQUAD(a) a[0], a[1], a[2], a[3] | 82 | #define myNIPQUAD(a) a[0], a[1], a[2], a[3] |
86 | static void | 83 | static void |
87 | ebt_log_packet(unsigned int pf, unsigned int hooknum, | 84 | ebt_log_packet(u_int8_t pf, unsigned int hooknum, |
88 | const struct sk_buff *skb, const struct net_device *in, | 85 | const struct sk_buff *skb, const struct net_device *in, |
89 | const struct net_device *out, const struct nf_loginfo *loginfo, | 86 | const struct net_device *out, const struct nf_loginfo *loginfo, |
90 | const char *prefix) | 87 | const char *prefix) |
@@ -194,11 +191,10 @@ out: | |||
194 | 191 | ||
195 | } | 192 | } |
196 | 193 | ||
197 | static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | 194 | static unsigned int |
198 | const struct net_device *in, const struct net_device *out, | 195 | ebt_log_tg(struct sk_buff *skb, const struct xt_target_param *par) |
199 | const void *data, unsigned int datalen) | ||
200 | { | 196 | { |
201 | const struct ebt_log_info *info = data; | 197 | const struct ebt_log_info *info = par->targinfo; |
202 | struct nf_loginfo li; | 198 | struct nf_loginfo li; |
203 | 199 | ||
204 | li.type = NF_LOG_TYPE_LOG; | 200 | li.type = NF_LOG_TYPE_LOG; |
@@ -206,18 +202,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
206 | li.u.log.logflags = info->bitmask; | 202 | li.u.log.logflags = info->bitmask; |
207 | 203 | ||
208 | if (info->bitmask & EBT_LOG_NFLOG) | 204 | if (info->bitmask & EBT_LOG_NFLOG) |
209 | nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, | 205 | nf_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in, |
210 | "%s", info->prefix); | 206 | par->out, &li, "%s", info->prefix); |
211 | else | 207 | else |
212 | ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, | 208 | ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in, |
213 | info->prefix); | 209 | par->out, &li, info->prefix); |
210 | return EBT_CONTINUE; | ||
214 | } | 211 | } |
215 | 212 | ||
216 | static struct ebt_watcher log = | 213 | static struct xt_target ebt_log_tg_reg __read_mostly = { |
217 | { | 214 | .name = "log", |
218 | .name = EBT_LOG_WATCHER, | 215 | .revision = 0, |
219 | .watcher = ebt_log, | 216 | .family = NFPROTO_BRIDGE, |
220 | .check = ebt_log_check, | 217 | .target = ebt_log_tg, |
218 | .checkentry = ebt_log_tg_check, | ||
219 | .targetsize = XT_ALIGN(sizeof(struct ebt_log_info)), | ||
221 | .me = THIS_MODULE, | 220 | .me = THIS_MODULE, |
222 | }; | 221 | }; |
223 | 222 | ||
@@ -231,17 +230,17 @@ static int __init ebt_log_init(void) | |||
231 | { | 230 | { |
232 | int ret; | 231 | int ret; |
233 | 232 | ||
234 | ret = ebt_register_watcher(&log); | 233 | ret = xt_register_target(&ebt_log_tg_reg); |
235 | if (ret < 0) | 234 | if (ret < 0) |
236 | return ret; | 235 | return ret; |
237 | nf_log_register(PF_BRIDGE, &ebt_log_logger); | 236 | nf_log_register(NFPROTO_BRIDGE, &ebt_log_logger); |
238 | return 0; | 237 | return 0; |
239 | } | 238 | } |
240 | 239 | ||
241 | static void __exit ebt_log_fini(void) | 240 | static void __exit ebt_log_fini(void) |
242 | { | 241 | { |
243 | nf_log_unregister(&ebt_log_logger); | 242 | nf_log_unregister(&ebt_log_logger); |
244 | ebt_unregister_watcher(&log); | 243 | xt_unregister_target(&ebt_log_tg_reg); |
245 | } | 244 | } |
246 | 245 | ||
247 | module_init(ebt_log_init); | 246 | module_init(ebt_log_init); |
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c index 36723f47db0a..2fee7e8e2e93 100644 --- a/net/bridge/netfilter/ebt_mark.c +++ b/net/bridge/netfilter/ebt_mark.c | |||
@@ -13,15 +13,15 @@ | |||
13 | * Marking a frame doesn't really change anything in the frame anyway. | 13 | * Marking a frame doesn't really change anything in the frame anyway. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/netfilter/x_tables.h> | ||
16 | #include <linux/netfilter_bridge/ebtables.h> | 18 | #include <linux/netfilter_bridge/ebtables.h> |
17 | #include <linux/netfilter_bridge/ebt_mark_t.h> | 19 | #include <linux/netfilter_bridge/ebt_mark_t.h> |
18 | #include <linux/module.h> | ||
19 | 20 | ||
20 | static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr, | 21 | static unsigned int |
21 | const struct net_device *in, const struct net_device *out, | 22 | ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par) |
22 | const void *data, unsigned int datalen) | ||
23 | { | 23 | { |
24 | const struct ebt_mark_t_info *info = data; | 24 | const struct ebt_mark_t_info *info = par->targinfo; |
25 | int action = info->target & -16; | 25 | int action = info->target & -16; |
26 | 26 | ||
27 | if (action == MARK_SET_VALUE) | 27 | if (action == MARK_SET_VALUE) |
@@ -36,42 +36,41 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr, | |||
36 | return info->target | ~EBT_VERDICT_BITS; | 36 | return info->target | ~EBT_VERDICT_BITS; |
37 | } | 37 | } |
38 | 38 | ||
39 | static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, | 39 | static bool ebt_mark_tg_check(const struct xt_tgchk_param *par) |
40 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
41 | { | 40 | { |
42 | const struct ebt_mark_t_info *info = data; | 41 | const struct ebt_mark_t_info *info = par->targinfo; |
43 | int tmp; | 42 | int tmp; |
44 | 43 | ||
45 | if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info))) | ||
46 | return -EINVAL; | ||
47 | tmp = info->target | ~EBT_VERDICT_BITS; | 44 | tmp = info->target | ~EBT_VERDICT_BITS; |
48 | if (BASE_CHAIN && tmp == EBT_RETURN) | 45 | if (BASE_CHAIN && tmp == EBT_RETURN) |
49 | return -EINVAL; | 46 | return false; |
50 | CLEAR_BASE_CHAIN_BIT; | ||
51 | if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) | 47 | if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) |
52 | return -EINVAL; | 48 | return false; |
53 | tmp = info->target & ~EBT_VERDICT_BITS; | 49 | tmp = info->target & ~EBT_VERDICT_BITS; |
54 | if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && | 50 | if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && |
55 | tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) | 51 | tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) |
56 | return -EINVAL; | 52 | return false; |
57 | return 0; | 53 | return true; |
58 | } | 54 | } |
59 | 55 | ||
60 | static struct ebt_target mark_target __read_mostly = { | 56 | static struct xt_target ebt_mark_tg_reg __read_mostly = { |
61 | .name = EBT_MARK_TARGET, | 57 | .name = "mark", |
62 | .target = ebt_target_mark, | 58 | .revision = 0, |
63 | .check = ebt_target_mark_check, | 59 | .family = NFPROTO_BRIDGE, |
60 | .target = ebt_mark_tg, | ||
61 | .checkentry = ebt_mark_tg_check, | ||
62 | .targetsize = XT_ALIGN(sizeof(struct ebt_mark_t_info)), | ||
64 | .me = THIS_MODULE, | 63 | .me = THIS_MODULE, |
65 | }; | 64 | }; |
66 | 65 | ||
67 | static int __init ebt_mark_init(void) | 66 | static int __init ebt_mark_init(void) |
68 | { | 67 | { |
69 | return ebt_register_target(&mark_target); | 68 | return xt_register_target(&ebt_mark_tg_reg); |
70 | } | 69 | } |
71 | 70 | ||
72 | static void __exit ebt_mark_fini(void) | 71 | static void __exit ebt_mark_fini(void) |
73 | { | 72 | { |
74 | ebt_unregister_target(&mark_target); | 73 | xt_unregister_target(&ebt_mark_tg_reg); |
75 | } | 74 | } |
76 | 75 | ||
77 | module_init(ebt_mark_init); | 76 | module_init(ebt_mark_init); |
diff --git a/net/bridge/netfilter/ebt_mark_m.c b/net/bridge/netfilter/ebt_mark_m.c index 9b0a4543861f..ea570f214b1d 100644 --- a/net/bridge/netfilter/ebt_mark_m.c +++ b/net/bridge/netfilter/ebt_mark_m.c | |||
@@ -7,53 +7,52 @@ | |||
7 | * July, 2002 | 7 | * July, 2002 |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | #include <linux/module.h> | |
11 | #include <linux/netfilter/x_tables.h> | ||
11 | #include <linux/netfilter_bridge/ebtables.h> | 12 | #include <linux/netfilter_bridge/ebtables.h> |
12 | #include <linux/netfilter_bridge/ebt_mark_m.h> | 13 | #include <linux/netfilter_bridge/ebt_mark_m.h> |
13 | #include <linux/module.h> | ||
14 | 14 | ||
15 | static int ebt_filter_mark(const struct sk_buff *skb, | 15 | static bool |
16 | const struct net_device *in, const struct net_device *out, const void *data, | 16 | ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
17 | unsigned int datalen) | ||
18 | { | 17 | { |
19 | const struct ebt_mark_m_info *info = data; | 18 | const struct ebt_mark_m_info *info = par->matchinfo; |
20 | 19 | ||
21 | if (info->bitmask & EBT_MARK_OR) | 20 | if (info->bitmask & EBT_MARK_OR) |
22 | return !(!!(skb->mark & info->mask) ^ info->invert); | 21 | return !!(skb->mark & info->mask) ^ info->invert; |
23 | return !(((skb->mark & info->mask) == info->mark) ^ info->invert); | 22 | return ((skb->mark & info->mask) == info->mark) ^ info->invert; |
24 | } | 23 | } |
25 | 24 | ||
26 | static int ebt_mark_check(const char *tablename, unsigned int hookmask, | 25 | static bool ebt_mark_mt_check(const struct xt_mtchk_param *par) |
27 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
28 | { | 26 | { |
29 | const struct ebt_mark_m_info *info = data; | 27 | const struct ebt_mark_m_info *info = par->matchinfo; |
30 | 28 | ||
31 | if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info))) | ||
32 | return -EINVAL; | ||
33 | if (info->bitmask & ~EBT_MARK_MASK) | 29 | if (info->bitmask & ~EBT_MARK_MASK) |
34 | return -EINVAL; | 30 | return false; |
35 | if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND)) | 31 | if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND)) |
36 | return -EINVAL; | 32 | return false; |
37 | if (!info->bitmask) | 33 | if (!info->bitmask) |
38 | return -EINVAL; | 34 | return false; |
39 | return 0; | 35 | return true; |
40 | } | 36 | } |
41 | 37 | ||
42 | static struct ebt_match filter_mark __read_mostly = { | 38 | static struct xt_match ebt_mark_mt_reg __read_mostly = { |
43 | .name = EBT_MARK_MATCH, | 39 | .name = "mark_m", |
44 | .match = ebt_filter_mark, | 40 | .revision = 0, |
45 | .check = ebt_mark_check, | 41 | .family = NFPROTO_BRIDGE, |
42 | .match = ebt_mark_mt, | ||
43 | .checkentry = ebt_mark_mt_check, | ||
44 | .matchsize = XT_ALIGN(sizeof(struct ebt_mark_m_info)), | ||
46 | .me = THIS_MODULE, | 45 | .me = THIS_MODULE, |
47 | }; | 46 | }; |
48 | 47 | ||
49 | static int __init ebt_mark_m_init(void) | 48 | static int __init ebt_mark_m_init(void) |
50 | { | 49 | { |
51 | return ebt_register_match(&filter_mark); | 50 | return xt_register_match(&ebt_mark_mt_reg); |
52 | } | 51 | } |
53 | 52 | ||
54 | static void __exit ebt_mark_m_fini(void) | 53 | static void __exit ebt_mark_m_fini(void) |
55 | { | 54 | { |
56 | ebt_unregister_match(&filter_mark); | 55 | xt_unregister_match(&ebt_mark_mt_reg); |
57 | } | 56 | } |
58 | 57 | ||
59 | module_init(ebt_mark_m_init); | 58 | module_init(ebt_mark_m_init); |
diff --git a/net/bridge/netfilter/ebt_nflog.c b/net/bridge/netfilter/ebt_nflog.c index 8e799aa9e560..2a63d996dd4e 100644 --- a/net/bridge/netfilter/ebt_nflog.c +++ b/net/bridge/netfilter/ebt_nflog.c | |||
@@ -14,17 +14,15 @@ | |||
14 | 14 | ||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/netfilter/x_tables.h> | ||
17 | #include <linux/netfilter_bridge/ebtables.h> | 18 | #include <linux/netfilter_bridge/ebtables.h> |
18 | #include <linux/netfilter_bridge/ebt_nflog.h> | 19 | #include <linux/netfilter_bridge/ebt_nflog.h> |
19 | #include <net/netfilter/nf_log.h> | 20 | #include <net/netfilter/nf_log.h> |
20 | 21 | ||
21 | static void ebt_nflog(const struct sk_buff *skb, | 22 | static unsigned int |
22 | unsigned int hooknr, | 23 | ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par) |
23 | const struct net_device *in, | ||
24 | const struct net_device *out, | ||
25 | const void *data, unsigned int datalen) | ||
26 | { | 24 | { |
27 | struct ebt_nflog_info *info = (struct ebt_nflog_info *)data; | 25 | const struct ebt_nflog_info *info = par->targinfo; |
28 | struct nf_loginfo li; | 26 | struct nf_loginfo li; |
29 | 27 | ||
30 | li.type = NF_LOG_TYPE_ULOG; | 28 | li.type = NF_LOG_TYPE_ULOG; |
@@ -32,39 +30,39 @@ static void ebt_nflog(const struct sk_buff *skb, | |||
32 | li.u.ulog.group = info->group; | 30 | li.u.ulog.group = info->group; |
33 | li.u.ulog.qthreshold = info->threshold; | 31 | li.u.ulog.qthreshold = info->threshold; |
34 | 32 | ||
35 | nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, "%s", info->prefix); | 33 | nf_log_packet(PF_BRIDGE, par->hooknum, skb, par->in, par->out, |
34 | &li, "%s", info->prefix); | ||
35 | return EBT_CONTINUE; | ||
36 | } | 36 | } |
37 | 37 | ||
38 | static int ebt_nflog_check(const char *tablename, | 38 | static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par) |
39 | unsigned int hookmask, | ||
40 | const struct ebt_entry *e, | ||
41 | void *data, unsigned int datalen) | ||
42 | { | 39 | { |
43 | struct ebt_nflog_info *info = (struct ebt_nflog_info *)data; | 40 | struct ebt_nflog_info *info = par->targinfo; |
44 | 41 | ||
45 | if (datalen != EBT_ALIGN(sizeof(struct ebt_nflog_info))) | ||
46 | return -EINVAL; | ||
47 | if (info->flags & ~EBT_NFLOG_MASK) | 42 | if (info->flags & ~EBT_NFLOG_MASK) |
48 | return -EINVAL; | 43 | return false; |
49 | info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0'; | 44 | info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0'; |
50 | return 0; | 45 | return true; |
51 | } | 46 | } |
52 | 47 | ||
53 | static struct ebt_watcher nflog __read_mostly = { | 48 | static struct xt_target ebt_nflog_tg_reg __read_mostly = { |
54 | .name = EBT_NFLOG_WATCHER, | 49 | .name = "nflog", |
55 | .watcher = ebt_nflog, | 50 | .revision = 0, |
56 | .check = ebt_nflog_check, | 51 | .family = NFPROTO_BRIDGE, |
57 | .me = THIS_MODULE, | 52 | .target = ebt_nflog_tg, |
53 | .checkentry = ebt_nflog_tg_check, | ||
54 | .targetsize = XT_ALIGN(sizeof(struct ebt_nflog_info)), | ||
55 | .me = THIS_MODULE, | ||
58 | }; | 56 | }; |
59 | 57 | ||
60 | static int __init ebt_nflog_init(void) | 58 | static int __init ebt_nflog_init(void) |
61 | { | 59 | { |
62 | return ebt_register_watcher(&nflog); | 60 | return xt_register_target(&ebt_nflog_tg_reg); |
63 | } | 61 | } |
64 | 62 | ||
65 | static void __exit ebt_nflog_fini(void) | 63 | static void __exit ebt_nflog_fini(void) |
66 | { | 64 | { |
67 | ebt_unregister_watcher(&nflog); | 65 | xt_unregister_target(&ebt_nflog_tg_reg); |
68 | } | 66 | } |
69 | 67 | ||
70 | module_init(ebt_nflog_init); | 68 | module_init(ebt_nflog_init); |
diff --git a/net/bridge/netfilter/ebt_pkttype.c b/net/bridge/netfilter/ebt_pkttype.c index 676db32df3d1..883e96e2a542 100644 --- a/net/bridge/netfilter/ebt_pkttype.c +++ b/net/bridge/netfilter/ebt_pkttype.c | |||
@@ -7,50 +7,47 @@ | |||
7 | * April, 2003 | 7 | * April, 2003 |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | #include <linux/module.h> | |
11 | #include <linux/netfilter/x_tables.h> | ||
11 | #include <linux/netfilter_bridge/ebtables.h> | 12 | #include <linux/netfilter_bridge/ebtables.h> |
12 | #include <linux/netfilter_bridge/ebt_pkttype.h> | 13 | #include <linux/netfilter_bridge/ebt_pkttype.h> |
13 | #include <linux/module.h> | ||
14 | 14 | ||
15 | static int ebt_filter_pkttype(const struct sk_buff *skb, | 15 | static bool |
16 | const struct net_device *in, | 16 | ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
17 | const struct net_device *out, | ||
18 | const void *data, | ||
19 | unsigned int datalen) | ||
20 | { | 17 | { |
21 | const struct ebt_pkttype_info *info = data; | 18 | const struct ebt_pkttype_info *info = par->matchinfo; |
22 | 19 | ||
23 | return (skb->pkt_type != info->pkt_type) ^ info->invert; | 20 | return (skb->pkt_type == info->pkt_type) ^ info->invert; |
24 | } | 21 | } |
25 | 22 | ||
26 | static int ebt_pkttype_check(const char *tablename, unsigned int hookmask, | 23 | static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par) |
27 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
28 | { | 24 | { |
29 | const struct ebt_pkttype_info *info = data; | 25 | const struct ebt_pkttype_info *info = par->matchinfo; |
30 | 26 | ||
31 | if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info))) | ||
32 | return -EINVAL; | ||
33 | if (info->invert != 0 && info->invert != 1) | 27 | if (info->invert != 0 && info->invert != 1) |
34 | return -EINVAL; | 28 | return false; |
35 | /* Allow any pkt_type value */ | 29 | /* Allow any pkt_type value */ |
36 | return 0; | 30 | return true; |
37 | } | 31 | } |
38 | 32 | ||
39 | static struct ebt_match filter_pkttype __read_mostly = { | 33 | static struct xt_match ebt_pkttype_mt_reg __read_mostly = { |
40 | .name = EBT_PKTTYPE_MATCH, | 34 | .name = "pkttype", |
41 | .match = ebt_filter_pkttype, | 35 | .revision = 0, |
42 | .check = ebt_pkttype_check, | 36 | .family = NFPROTO_BRIDGE, |
37 | .match = ebt_pkttype_mt, | ||
38 | .checkentry = ebt_pkttype_mt_check, | ||
39 | .matchsize = XT_ALIGN(sizeof(struct ebt_pkttype_info)), | ||
43 | .me = THIS_MODULE, | 40 | .me = THIS_MODULE, |
44 | }; | 41 | }; |
45 | 42 | ||
46 | static int __init ebt_pkttype_init(void) | 43 | static int __init ebt_pkttype_init(void) |
47 | { | 44 | { |
48 | return ebt_register_match(&filter_pkttype); | 45 | return xt_register_match(&ebt_pkttype_mt_reg); |
49 | } | 46 | } |
50 | 47 | ||
51 | static void __exit ebt_pkttype_fini(void) | 48 | static void __exit ebt_pkttype_fini(void) |
52 | { | 49 | { |
53 | ebt_unregister_match(&filter_pkttype); | 50 | xt_unregister_match(&ebt_pkttype_mt_reg); |
54 | } | 51 | } |
55 | 52 | ||
56 | module_init(ebt_pkttype_init); | 53 | module_init(ebt_pkttype_init); |
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c index b8afe850cf1e..c8a49f7a57ba 100644 --- a/net/bridge/netfilter/ebt_redirect.c +++ b/net/bridge/netfilter/ebt_redirect.c | |||
@@ -7,65 +7,70 @@ | |||
7 | * April, 2002 | 7 | * April, 2002 |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | |||
11 | #include <linux/netfilter.h> | ||
12 | #include <linux/netfilter_bridge/ebtables.h> | ||
13 | #include <linux/netfilter_bridge/ebt_redirect.h> | ||
14 | #include <linux/module.h> | 10 | #include <linux/module.h> |
15 | #include <net/sock.h> | 11 | #include <net/sock.h> |
16 | #include "../br_private.h" | 12 | #include "../br_private.h" |
13 | #include <linux/netfilter.h> | ||
14 | #include <linux/netfilter/x_tables.h> | ||
15 | #include <linux/netfilter_bridge/ebtables.h> | ||
16 | #include <linux/netfilter_bridge/ebt_redirect.h> | ||
17 | 17 | ||
18 | static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr, | 18 | static unsigned int |
19 | const struct net_device *in, const struct net_device *out, | 19 | ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par) |
20 | const void *data, unsigned int datalen) | ||
21 | { | 20 | { |
22 | const struct ebt_redirect_info *info = data; | 21 | const struct ebt_redirect_info *info = par->targinfo; |
23 | 22 | ||
24 | if (!skb_make_writable(skb, 0)) | 23 | if (!skb_make_writable(skb, 0)) |
25 | return EBT_DROP; | 24 | return EBT_DROP; |
26 | 25 | ||
27 | if (hooknr != NF_BR_BROUTING) | 26 | if (par->hooknum != NF_BR_BROUTING) |
28 | memcpy(eth_hdr(skb)->h_dest, | 27 | memcpy(eth_hdr(skb)->h_dest, |
29 | in->br_port->br->dev->dev_addr, ETH_ALEN); | 28 | par->in->br_port->br->dev->dev_addr, ETH_ALEN); |
30 | else | 29 | else |
31 | memcpy(eth_hdr(skb)->h_dest, in->dev_addr, ETH_ALEN); | 30 | memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN); |
32 | skb->pkt_type = PACKET_HOST; | 31 | skb->pkt_type = PACKET_HOST; |
33 | return info->target; | 32 | return info->target; |
34 | } | 33 | } |
35 | 34 | ||
36 | static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask, | 35 | static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par) |
37 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
38 | { | 36 | { |
39 | const struct ebt_redirect_info *info = data; | 37 | const struct ebt_redirect_info *info = par->targinfo; |
38 | unsigned int hook_mask; | ||
40 | 39 | ||
41 | if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info))) | ||
42 | return -EINVAL; | ||
43 | if (BASE_CHAIN && info->target == EBT_RETURN) | 40 | if (BASE_CHAIN && info->target == EBT_RETURN) |
44 | return -EINVAL; | 41 | return false; |
45 | CLEAR_BASE_CHAIN_BIT; | 42 | |
46 | if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) && | 43 | hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS); |
47 | (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) | 44 | if ((strcmp(par->table, "nat") != 0 || |
48 | return -EINVAL; | 45 | hook_mask & ~(1 << NF_BR_PRE_ROUTING)) && |
46 | (strcmp(par->table, "broute") != 0 || | ||
47 | hook_mask & ~(1 << NF_BR_BROUTING))) | ||
48 | return false; | ||
49 | if (INVALID_TARGET) | 49 | if (INVALID_TARGET) |
50 | return -EINVAL; | 50 | return false; |
51 | return 0; | 51 | return true; |
52 | } | 52 | } |
53 | 53 | ||
54 | static struct ebt_target redirect_target __read_mostly = { | 54 | static struct xt_target ebt_redirect_tg_reg __read_mostly = { |
55 | .name = EBT_REDIRECT_TARGET, | 55 | .name = "redirect", |
56 | .target = ebt_target_redirect, | 56 | .revision = 0, |
57 | .check = ebt_target_redirect_check, | 57 | .family = NFPROTO_BRIDGE, |
58 | .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) | | ||
59 | (1 << NF_BR_BROUTING), | ||
60 | .target = ebt_redirect_tg, | ||
61 | .checkentry = ebt_redirect_tg_check, | ||
62 | .targetsize = XT_ALIGN(sizeof(struct ebt_redirect_info)), | ||
58 | .me = THIS_MODULE, | 63 | .me = THIS_MODULE, |
59 | }; | 64 | }; |
60 | 65 | ||
61 | static int __init ebt_redirect_init(void) | 66 | static int __init ebt_redirect_init(void) |
62 | { | 67 | { |
63 | return ebt_register_target(&redirect_target); | 68 | return xt_register_target(&ebt_redirect_tg_reg); |
64 | } | 69 | } |
65 | 70 | ||
66 | static void __exit ebt_redirect_fini(void) | 71 | static void __exit ebt_redirect_fini(void) |
67 | { | 72 | { |
68 | ebt_unregister_target(&redirect_target); | 73 | xt_unregister_target(&ebt_redirect_tg_reg); |
69 | } | 74 | } |
70 | 75 | ||
71 | module_init(ebt_redirect_init); | 76 | module_init(ebt_redirect_init); |
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c index 5425333dda03..8d04d4c302bd 100644 --- a/net/bridge/netfilter/ebt_snat.c +++ b/net/bridge/netfilter/ebt_snat.c | |||
@@ -7,20 +7,19 @@ | |||
7 | * June, 2002 | 7 | * June, 2002 |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | |||
11 | #include <linux/netfilter.h> | ||
12 | #include <linux/netfilter_bridge/ebtables.h> | ||
13 | #include <linux/netfilter_bridge/ebt_nat.h> | ||
14 | #include <linux/module.h> | 10 | #include <linux/module.h> |
15 | #include <net/sock.h> | 11 | #include <net/sock.h> |
16 | #include <linux/if_arp.h> | 12 | #include <linux/if_arp.h> |
17 | #include <net/arp.h> | 13 | #include <net/arp.h> |
14 | #include <linux/netfilter.h> | ||
15 | #include <linux/netfilter/x_tables.h> | ||
16 | #include <linux/netfilter_bridge/ebtables.h> | ||
17 | #include <linux/netfilter_bridge/ebt_nat.h> | ||
18 | 18 | ||
19 | static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, | 19 | static unsigned int |
20 | const struct net_device *in, const struct net_device *out, | 20 | ebt_snat_tg(struct sk_buff *skb, const struct xt_target_param *par) |
21 | const void *data, unsigned int datalen) | ||
22 | { | 21 | { |
23 | const struct ebt_nat_info *info = data; | 22 | const struct ebt_nat_info *info = par->targinfo; |
24 | 23 | ||
25 | if (!skb_make_writable(skb, 0)) | 24 | if (!skb_make_writable(skb, 0)) |
26 | return EBT_DROP; | 25 | return EBT_DROP; |
@@ -43,46 +42,43 @@ out: | |||
43 | return info->target | ~EBT_VERDICT_BITS; | 42 | return info->target | ~EBT_VERDICT_BITS; |
44 | } | 43 | } |
45 | 44 | ||
46 | static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, | 45 | static bool ebt_snat_tg_check(const struct xt_tgchk_param *par) |
47 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
48 | { | 46 | { |
49 | const struct ebt_nat_info *info = data; | 47 | const struct ebt_nat_info *info = par->targinfo; |
50 | int tmp; | 48 | int tmp; |
51 | 49 | ||
52 | if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) | ||
53 | return -EINVAL; | ||
54 | tmp = info->target | ~EBT_VERDICT_BITS; | 50 | tmp = info->target | ~EBT_VERDICT_BITS; |
55 | if (BASE_CHAIN && tmp == EBT_RETURN) | 51 | if (BASE_CHAIN && tmp == EBT_RETURN) |
56 | return -EINVAL; | 52 | return false; |
57 | CLEAR_BASE_CHAIN_BIT; | ||
58 | if (strcmp(tablename, "nat")) | ||
59 | return -EINVAL; | ||
60 | if (hookmask & ~(1 << NF_BR_POST_ROUTING)) | ||
61 | return -EINVAL; | ||
62 | 53 | ||
63 | if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) | 54 | if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) |
64 | return -EINVAL; | 55 | return false; |
65 | tmp = info->target | EBT_VERDICT_BITS; | 56 | tmp = info->target | EBT_VERDICT_BITS; |
66 | if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT) | 57 | if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT) |
67 | return -EINVAL; | 58 | return false; |
68 | return 0; | 59 | return true; |
69 | } | 60 | } |
70 | 61 | ||
71 | static struct ebt_target snat __read_mostly = { | 62 | static struct xt_target ebt_snat_tg_reg __read_mostly = { |
72 | .name = EBT_SNAT_TARGET, | 63 | .name = "snat", |
73 | .target = ebt_target_snat, | 64 | .revision = 0, |
74 | .check = ebt_target_snat_check, | 65 | .family = NFPROTO_BRIDGE, |
66 | .table = "nat", | ||
67 | .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_POST_ROUTING), | ||
68 | .target = ebt_snat_tg, | ||
69 | .checkentry = ebt_snat_tg_check, | ||
70 | .targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)), | ||
75 | .me = THIS_MODULE, | 71 | .me = THIS_MODULE, |
76 | }; | 72 | }; |
77 | 73 | ||
78 | static int __init ebt_snat_init(void) | 74 | static int __init ebt_snat_init(void) |
79 | { | 75 | { |
80 | return ebt_register_target(&snat); | 76 | return xt_register_target(&ebt_snat_tg_reg); |
81 | } | 77 | } |
82 | 78 | ||
83 | static void __exit ebt_snat_fini(void) | 79 | static void __exit ebt_snat_fini(void) |
84 | { | 80 | { |
85 | ebt_unregister_target(&snat); | 81 | xt_unregister_target(&ebt_snat_tg_reg); |
86 | } | 82 | } |
87 | 83 | ||
88 | module_init(ebt_snat_init); | 84 | module_init(ebt_snat_init); |
diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c index 40f36d37607d..48527e621626 100644 --- a/net/bridge/netfilter/ebt_stp.c +++ b/net/bridge/netfilter/ebt_stp.c | |||
@@ -7,11 +7,11 @@ | |||
7 | * | 7 | * |
8 | * July, 2003 | 8 | * July, 2003 |
9 | */ | 9 | */ |
10 | |||
11 | #include <linux/netfilter_bridge/ebtables.h> | ||
12 | #include <linux/netfilter_bridge/ebt_stp.h> | ||
13 | #include <linux/etherdevice.h> | 10 | #include <linux/etherdevice.h> |
14 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/netfilter/x_tables.h> | ||
13 | #include <linux/netfilter_bridge/ebtables.h> | ||
14 | #include <linux/netfilter_bridge/ebt_stp.h> | ||
15 | 15 | ||
16 | #define BPDU_TYPE_CONFIG 0 | 16 | #define BPDU_TYPE_CONFIG 0 |
17 | #define BPDU_TYPE_TCN 0x80 | 17 | #define BPDU_TYPE_TCN 0x80 |
@@ -40,7 +40,7 @@ struct stp_config_pdu { | |||
40 | #define NR16(p) (p[0] << 8 | p[1]) | 40 | #define NR16(p) (p[0] << 8 | p[1]) |
41 | #define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]) | 41 | #define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]) |
42 | 42 | ||
43 | static int ebt_filter_config(const struct ebt_stp_info *info, | 43 | static bool ebt_filter_config(const struct ebt_stp_info *info, |
44 | const struct stp_config_pdu *stpc) | 44 | const struct stp_config_pdu *stpc) |
45 | { | 45 | { |
46 | const struct ebt_stp_config_info *c; | 46 | const struct ebt_stp_config_info *c; |
@@ -51,12 +51,12 @@ static int ebt_filter_config(const struct ebt_stp_info *info, | |||
51 | c = &info->config; | 51 | c = &info->config; |
52 | if ((info->bitmask & EBT_STP_FLAGS) && | 52 | if ((info->bitmask & EBT_STP_FLAGS) && |
53 | FWINV(c->flags != stpc->flags, EBT_STP_FLAGS)) | 53 | FWINV(c->flags != stpc->flags, EBT_STP_FLAGS)) |
54 | return EBT_NOMATCH; | 54 | return false; |
55 | if (info->bitmask & EBT_STP_ROOTPRIO) { | 55 | if (info->bitmask & EBT_STP_ROOTPRIO) { |
56 | v16 = NR16(stpc->root); | 56 | v16 = NR16(stpc->root); |
57 | if (FWINV(v16 < c->root_priol || | 57 | if (FWINV(v16 < c->root_priol || |
58 | v16 > c->root_priou, EBT_STP_ROOTPRIO)) | 58 | v16 > c->root_priou, EBT_STP_ROOTPRIO)) |
59 | return EBT_NOMATCH; | 59 | return false; |
60 | } | 60 | } |
61 | if (info->bitmask & EBT_STP_ROOTADDR) { | 61 | if (info->bitmask & EBT_STP_ROOTADDR) { |
62 | verdict = 0; | 62 | verdict = 0; |
@@ -64,19 +64,19 @@ static int ebt_filter_config(const struct ebt_stp_info *info, | |||
64 | verdict |= (stpc->root[2+i] ^ c->root_addr[i]) & | 64 | verdict |= (stpc->root[2+i] ^ c->root_addr[i]) & |
65 | c->root_addrmsk[i]; | 65 | c->root_addrmsk[i]; |
66 | if (FWINV(verdict != 0, EBT_STP_ROOTADDR)) | 66 | if (FWINV(verdict != 0, EBT_STP_ROOTADDR)) |
67 | return EBT_NOMATCH; | 67 | return false; |
68 | } | 68 | } |
69 | if (info->bitmask & EBT_STP_ROOTCOST) { | 69 | if (info->bitmask & EBT_STP_ROOTCOST) { |
70 | v32 = NR32(stpc->root_cost); | 70 | v32 = NR32(stpc->root_cost); |
71 | if (FWINV(v32 < c->root_costl || | 71 | if (FWINV(v32 < c->root_costl || |
72 | v32 > c->root_costu, EBT_STP_ROOTCOST)) | 72 | v32 > c->root_costu, EBT_STP_ROOTCOST)) |
73 | return EBT_NOMATCH; | 73 | return false; |
74 | } | 74 | } |
75 | if (info->bitmask & EBT_STP_SENDERPRIO) { | 75 | if (info->bitmask & EBT_STP_SENDERPRIO) { |
76 | v16 = NR16(stpc->sender); | 76 | v16 = NR16(stpc->sender); |
77 | if (FWINV(v16 < c->sender_priol || | 77 | if (FWINV(v16 < c->sender_priol || |
78 | v16 > c->sender_priou, EBT_STP_SENDERPRIO)) | 78 | v16 > c->sender_priou, EBT_STP_SENDERPRIO)) |
79 | return EBT_NOMATCH; | 79 | return false; |
80 | } | 80 | } |
81 | if (info->bitmask & EBT_STP_SENDERADDR) { | 81 | if (info->bitmask & EBT_STP_SENDERADDR) { |
82 | verdict = 0; | 82 | verdict = 0; |
@@ -84,60 +84,60 @@ static int ebt_filter_config(const struct ebt_stp_info *info, | |||
84 | verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) & | 84 | verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) & |
85 | c->sender_addrmsk[i]; | 85 | c->sender_addrmsk[i]; |
86 | if (FWINV(verdict != 0, EBT_STP_SENDERADDR)) | 86 | if (FWINV(verdict != 0, EBT_STP_SENDERADDR)) |
87 | return EBT_NOMATCH; | 87 | return false; |
88 | } | 88 | } |
89 | if (info->bitmask & EBT_STP_PORT) { | 89 | if (info->bitmask & EBT_STP_PORT) { |
90 | v16 = NR16(stpc->port); | 90 | v16 = NR16(stpc->port); |
91 | if (FWINV(v16 < c->portl || | 91 | if (FWINV(v16 < c->portl || |
92 | v16 > c->portu, EBT_STP_PORT)) | 92 | v16 > c->portu, EBT_STP_PORT)) |
93 | return EBT_NOMATCH; | 93 | return false; |
94 | } | 94 | } |
95 | if (info->bitmask & EBT_STP_MSGAGE) { | 95 | if (info->bitmask & EBT_STP_MSGAGE) { |
96 | v16 = NR16(stpc->msg_age); | 96 | v16 = NR16(stpc->msg_age); |
97 | if (FWINV(v16 < c->msg_agel || | 97 | if (FWINV(v16 < c->msg_agel || |
98 | v16 > c->msg_ageu, EBT_STP_MSGAGE)) | 98 | v16 > c->msg_ageu, EBT_STP_MSGAGE)) |
99 | return EBT_NOMATCH; | 99 | return false; |
100 | } | 100 | } |
101 | if (info->bitmask & EBT_STP_MAXAGE) { | 101 | if (info->bitmask & EBT_STP_MAXAGE) { |
102 | v16 = NR16(stpc->max_age); | 102 | v16 = NR16(stpc->max_age); |
103 | if (FWINV(v16 < c->max_agel || | 103 | if (FWINV(v16 < c->max_agel || |
104 | v16 > c->max_ageu, EBT_STP_MAXAGE)) | 104 | v16 > c->max_ageu, EBT_STP_MAXAGE)) |
105 | return EBT_NOMATCH; | 105 | return false; |
106 | } | 106 | } |
107 | if (info->bitmask & EBT_STP_HELLOTIME) { | 107 | if (info->bitmask & EBT_STP_HELLOTIME) { |
108 | v16 = NR16(stpc->hello_time); | 108 | v16 = NR16(stpc->hello_time); |
109 | if (FWINV(v16 < c->hello_timel || | 109 | if (FWINV(v16 < c->hello_timel || |
110 | v16 > c->hello_timeu, EBT_STP_HELLOTIME)) | 110 | v16 > c->hello_timeu, EBT_STP_HELLOTIME)) |
111 | return EBT_NOMATCH; | 111 | return false; |
112 | } | 112 | } |
113 | if (info->bitmask & EBT_STP_FWDD) { | 113 | if (info->bitmask & EBT_STP_FWDD) { |
114 | v16 = NR16(stpc->forward_delay); | 114 | v16 = NR16(stpc->forward_delay); |
115 | if (FWINV(v16 < c->forward_delayl || | 115 | if (FWINV(v16 < c->forward_delayl || |
116 | v16 > c->forward_delayu, EBT_STP_FWDD)) | 116 | v16 > c->forward_delayu, EBT_STP_FWDD)) |
117 | return EBT_NOMATCH; | 117 | return false; |
118 | } | 118 | } |
119 | return EBT_MATCH; | 119 | return true; |
120 | } | 120 | } |
121 | 121 | ||
122 | static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in, | 122 | static bool |
123 | const struct net_device *out, const void *data, unsigned int datalen) | 123 | ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
124 | { | 124 | { |
125 | const struct ebt_stp_info *info = data; | 125 | const struct ebt_stp_info *info = par->matchinfo; |
126 | const struct stp_header *sp; | 126 | const struct stp_header *sp; |
127 | struct stp_header _stph; | 127 | struct stp_header _stph; |
128 | const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; | 128 | const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; |
129 | 129 | ||
130 | sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph); | 130 | sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph); |
131 | if (sp == NULL) | 131 | if (sp == NULL) |
132 | return EBT_NOMATCH; | 132 | return false; |
133 | 133 | ||
134 | /* The stp code only considers these */ | 134 | /* The stp code only considers these */ |
135 | if (memcmp(sp, header, sizeof(header))) | 135 | if (memcmp(sp, header, sizeof(header))) |
136 | return EBT_NOMATCH; | 136 | return false; |
137 | 137 | ||
138 | if (info->bitmask & EBT_STP_TYPE | 138 | if (info->bitmask & EBT_STP_TYPE |
139 | && FWINV(info->type != sp->type, EBT_STP_TYPE)) | 139 | && FWINV(info->type != sp->type, EBT_STP_TYPE)) |
140 | return EBT_NOMATCH; | 140 | return false; |
141 | 141 | ||
142 | if (sp->type == BPDU_TYPE_CONFIG && | 142 | if (sp->type == BPDU_TYPE_CONFIG && |
143 | info->bitmask & EBT_STP_CONFIG_MASK) { | 143 | info->bitmask & EBT_STP_CONFIG_MASK) { |
@@ -147,48 +147,48 @@ static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in | |||
147 | st = skb_header_pointer(skb, sizeof(_stph), | 147 | st = skb_header_pointer(skb, sizeof(_stph), |
148 | sizeof(_stpc), &_stpc); | 148 | sizeof(_stpc), &_stpc); |
149 | if (st == NULL) | 149 | if (st == NULL) |
150 | return EBT_NOMATCH; | 150 | return false; |
151 | return ebt_filter_config(info, st); | 151 | return ebt_filter_config(info, st); |
152 | } | 152 | } |
153 | return EBT_MATCH; | 153 | return true; |
154 | } | 154 | } |
155 | 155 | ||
156 | static int ebt_stp_check(const char *tablename, unsigned int hookmask, | 156 | static bool ebt_stp_mt_check(const struct xt_mtchk_param *par) |
157 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
158 | { | 157 | { |
159 | const struct ebt_stp_info *info = data; | 158 | const struct ebt_stp_info *info = par->matchinfo; |
160 | const unsigned int len = EBT_ALIGN(sizeof(struct ebt_stp_info)); | ||
161 | const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; | 159 | const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; |
162 | const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 160 | const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
161 | const struct ebt_entry *e = par->entryinfo; | ||
163 | 162 | ||
164 | if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || | 163 | if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || |
165 | !(info->bitmask & EBT_STP_MASK)) | 164 | !(info->bitmask & EBT_STP_MASK)) |
166 | return -EINVAL; | 165 | return false; |
167 | if (datalen != len) | ||
168 | return -EINVAL; | ||
169 | /* Make sure the match only receives stp frames */ | 166 | /* Make sure the match only receives stp frames */ |
170 | if (compare_ether_addr(e->destmac, bridge_ula) || | 167 | if (compare_ether_addr(e->destmac, bridge_ula) || |
171 | compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) | 168 | compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) |
172 | return -EINVAL; | 169 | return false; |
173 | 170 | ||
174 | return 0; | 171 | return true; |
175 | } | 172 | } |
176 | 173 | ||
177 | static struct ebt_match filter_stp __read_mostly = { | 174 | static struct xt_match ebt_stp_mt_reg __read_mostly = { |
178 | .name = EBT_STP_MATCH, | 175 | .name = "stp", |
179 | .match = ebt_filter_stp, | 176 | .revision = 0, |
180 | .check = ebt_stp_check, | 177 | .family = NFPROTO_BRIDGE, |
178 | .match = ebt_stp_mt, | ||
179 | .checkentry = ebt_stp_mt_check, | ||
180 | .matchsize = XT_ALIGN(sizeof(struct ebt_stp_info)), | ||
181 | .me = THIS_MODULE, | 181 | .me = THIS_MODULE, |
182 | }; | 182 | }; |
183 | 183 | ||
184 | static int __init ebt_stp_init(void) | 184 | static int __init ebt_stp_init(void) |
185 | { | 185 | { |
186 | return ebt_register_match(&filter_stp); | 186 | return xt_register_match(&ebt_stp_mt_reg); |
187 | } | 187 | } |
188 | 188 | ||
189 | static void __exit ebt_stp_fini(void) | 189 | static void __exit ebt_stp_fini(void) |
190 | { | 190 | { |
191 | ebt_unregister_match(&filter_stp); | 191 | xt_unregister_match(&ebt_stp_mt_reg); |
192 | } | 192 | } |
193 | 193 | ||
194 | module_init(ebt_stp_init); | 194 | module_init(ebt_stp_init); |
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 2d4c9ef909fc..2c6d6823e703 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/timer.h> | 36 | #include <linux/timer.h> |
37 | #include <linux/netlink.h> | 37 | #include <linux/netlink.h> |
38 | #include <linux/netdevice.h> | 38 | #include <linux/netdevice.h> |
39 | #include <linux/netfilter/x_tables.h> | ||
39 | #include <linux/netfilter_bridge/ebtables.h> | 40 | #include <linux/netfilter_bridge/ebtables.h> |
40 | #include <linux/netfilter_bridge/ebt_ulog.h> | 41 | #include <linux/netfilter_bridge/ebt_ulog.h> |
41 | #include <net/netfilter/nf_log.h> | 42 | #include <net/netfilter/nf_log.h> |
@@ -223,7 +224,7 @@ alloc_failure: | |||
223 | } | 224 | } |
224 | 225 | ||
225 | /* this function is registered with the netfilter core */ | 226 | /* this function is registered with the netfilter core */ |
226 | static void ebt_log_packet(unsigned int pf, unsigned int hooknum, | 227 | static void ebt_log_packet(u_int8_t pf, unsigned int hooknum, |
227 | const struct sk_buff *skb, const struct net_device *in, | 228 | const struct sk_buff *skb, const struct net_device *in, |
228 | const struct net_device *out, const struct nf_loginfo *li, | 229 | const struct net_device *out, const struct nf_loginfo *li, |
229 | const char *prefix) | 230 | const char *prefix) |
@@ -245,24 +246,20 @@ static void ebt_log_packet(unsigned int pf, unsigned int hooknum, | |||
245 | ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | 246 | ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); |
246 | } | 247 | } |
247 | 248 | ||
248 | static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, | 249 | static unsigned int |
249 | const struct net_device *in, const struct net_device *out, | 250 | ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par) |
250 | const void *data, unsigned int datalen) | ||
251 | { | 251 | { |
252 | const struct ebt_ulog_info *uloginfo = data; | 252 | ebt_ulog_packet(par->hooknum, skb, par->in, par->out, |
253 | 253 | par->targinfo, NULL); | |
254 | ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL); | 254 | return EBT_CONTINUE; |
255 | } | 255 | } |
256 | 256 | ||
257 | 257 | static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par) | |
258 | static int ebt_ulog_check(const char *tablename, unsigned int hookmask, | ||
259 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
260 | { | 258 | { |
261 | struct ebt_ulog_info *uloginfo = data; | 259 | struct ebt_ulog_info *uloginfo = par->targinfo; |
262 | 260 | ||
263 | if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) || | 261 | if (uloginfo->nlgroup > 31) |
264 | uloginfo->nlgroup > 31) | 262 | return false; |
265 | return -EINVAL; | ||
266 | 263 | ||
267 | uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0'; | 264 | uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0'; |
268 | 265 | ||
@@ -272,27 +269,31 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask, | |||
272 | return 0; | 269 | return 0; |
273 | } | 270 | } |
274 | 271 | ||
275 | static struct ebt_watcher ulog __read_mostly = { | 272 | static struct xt_target ebt_ulog_tg_reg __read_mostly = { |
276 | .name = EBT_ULOG_WATCHER, | 273 | .name = "ulog", |
277 | .watcher = ebt_ulog, | 274 | .revision = 0, |
278 | .check = ebt_ulog_check, | 275 | .family = NFPROTO_BRIDGE, |
276 | .target = ebt_ulog_tg, | ||
277 | .checkentry = ebt_ulog_tg_check, | ||
278 | .targetsize = XT_ALIGN(sizeof(struct ebt_ulog_info)), | ||
279 | .me = THIS_MODULE, | 279 | .me = THIS_MODULE, |
280 | }; | 280 | }; |
281 | 281 | ||
282 | static const struct nf_logger ebt_ulog_logger = { | 282 | static const struct nf_logger ebt_ulog_logger = { |
283 | .name = EBT_ULOG_WATCHER, | 283 | .name = "ulog", |
284 | .logfn = &ebt_log_packet, | 284 | .logfn = &ebt_log_packet, |
285 | .me = THIS_MODULE, | 285 | .me = THIS_MODULE, |
286 | }; | 286 | }; |
287 | 287 | ||
288 | static int __init ebt_ulog_init(void) | 288 | static int __init ebt_ulog_init(void) |
289 | { | 289 | { |
290 | int i, ret = 0; | 290 | bool ret = true; |
291 | int i; | ||
291 | 292 | ||
292 | if (nlbufsiz >= 128*1024) { | 293 | if (nlbufsiz >= 128*1024) { |
293 | printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB," | 294 | printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB," |
294 | " please try a smaller nlbufsiz parameter.\n"); | 295 | " please try a smaller nlbufsiz parameter.\n"); |
295 | return -EINVAL; | 296 | return false; |
296 | } | 297 | } |
297 | 298 | ||
298 | /* initialize ulog_buffers */ | 299 | /* initialize ulog_buffers */ |
@@ -304,13 +305,16 @@ static int __init ebt_ulog_init(void) | |||
304 | ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, | 305 | ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, |
305 | EBT_ULOG_MAXNLGROUPS, NULL, NULL, | 306 | EBT_ULOG_MAXNLGROUPS, NULL, NULL, |
306 | THIS_MODULE); | 307 | THIS_MODULE); |
307 | if (!ebtulognl) | 308 | if (!ebtulognl) { |
308 | ret = -ENOMEM; | 309 | printk(KERN_WARNING KBUILD_MODNAME ": out of memory trying to " |
309 | else if ((ret = ebt_register_watcher(&ulog))) | 310 | "call netlink_kernel_create\n"); |
311 | ret = false; | ||
312 | } else if (xt_register_target(&ebt_ulog_tg_reg) != 0) { | ||
310 | netlink_kernel_release(ebtulognl); | 313 | netlink_kernel_release(ebtulognl); |
314 | } | ||
311 | 315 | ||
312 | if (ret == 0) | 316 | if (ret) |
313 | nf_log_register(PF_BRIDGE, &ebt_ulog_logger); | 317 | nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger); |
314 | 318 | ||
315 | return ret; | 319 | return ret; |
316 | } | 320 | } |
@@ -321,7 +325,7 @@ static void __exit ebt_ulog_fini(void) | |||
321 | int i; | 325 | int i; |
322 | 326 | ||
323 | nf_log_unregister(&ebt_ulog_logger); | 327 | nf_log_unregister(&ebt_ulog_logger); |
324 | ebt_unregister_watcher(&ulog); | 328 | xt_unregister_target(&ebt_ulog_tg_reg); |
325 | for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { | 329 | for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { |
326 | ub = &ulog_buffers[i]; | 330 | ub = &ulog_buffers[i]; |
327 | if (timer_pending(&ub->timer)) | 331 | if (timer_pending(&ub->timer)) |
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c index ab60b0dade80..3dddd489328e 100644 --- a/net/bridge/netfilter/ebt_vlan.c +++ b/net/bridge/netfilter/ebt_vlan.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/if_vlan.h> | 22 | #include <linux/if_vlan.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
25 | #include <linux/netfilter/x_tables.h> | ||
25 | #include <linux/netfilter_bridge/ebtables.h> | 26 | #include <linux/netfilter_bridge/ebtables.h> |
26 | #include <linux/netfilter_bridge/ebt_vlan.h> | 27 | #include <linux/netfilter_bridge/ebt_vlan.h> |
27 | 28 | ||
@@ -37,15 +38,12 @@ MODULE_LICENSE("GPL"); | |||
37 | 38 | ||
38 | #define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args) | 39 | #define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args) |
39 | #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ | 40 | #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ |
40 | #define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;} | 41 | #define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; } |
41 | 42 | ||
42 | static int | 43 | static bool |
43 | ebt_filter_vlan(const struct sk_buff *skb, | 44 | ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
44 | const struct net_device *in, | ||
45 | const struct net_device *out, | ||
46 | const void *data, unsigned int datalen) | ||
47 | { | 45 | { |
48 | const struct ebt_vlan_info *info = data; | 46 | const struct ebt_vlan_info *info = par->matchinfo; |
49 | const struct vlan_hdr *fp; | 47 | const struct vlan_hdr *fp; |
50 | struct vlan_hdr _frame; | 48 | struct vlan_hdr _frame; |
51 | 49 | ||
@@ -57,7 +55,7 @@ ebt_filter_vlan(const struct sk_buff *skb, | |||
57 | 55 | ||
58 | fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); | 56 | fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); |
59 | if (fp == NULL) | 57 | if (fp == NULL) |
60 | return EBT_NOMATCH; | 58 | return false; |
61 | 59 | ||
62 | /* Tag Control Information (TCI) consists of the following elements: | 60 | /* Tag Control Information (TCI) consists of the following elements: |
63 | * - User_priority. The user_priority field is three bits in length, | 61 | * - User_priority. The user_priority field is three bits in length, |
@@ -83,30 +81,20 @@ ebt_filter_vlan(const struct sk_buff *skb, | |||
83 | if (GET_BITMASK(EBT_VLAN_ENCAP)) | 81 | if (GET_BITMASK(EBT_VLAN_ENCAP)) |
84 | EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP); | 82 | EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP); |
85 | 83 | ||
86 | return EBT_MATCH; | 84 | return true; |
87 | } | 85 | } |
88 | 86 | ||
89 | static int | 87 | static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par) |
90 | ebt_check_vlan(const char *tablename, | ||
91 | unsigned int hooknr, | ||
92 | const struct ebt_entry *e, void *data, unsigned int datalen) | ||
93 | { | 88 | { |
94 | struct ebt_vlan_info *info = data; | 89 | struct ebt_vlan_info *info = par->matchinfo; |
95 | 90 | const struct ebt_entry *e = par->entryinfo; | |
96 | /* Parameters buffer overflow check */ | ||
97 | if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) { | ||
98 | DEBUG_MSG | ||
99 | ("passed size %d is not eq to ebt_vlan_info (%Zd)\n", | ||
100 | datalen, sizeof(struct ebt_vlan_info)); | ||
101 | return -EINVAL; | ||
102 | } | ||
103 | 91 | ||
104 | /* Is it 802.1Q frame checked? */ | 92 | /* Is it 802.1Q frame checked? */ |
105 | if (e->ethproto != htons(ETH_P_8021Q)) { | 93 | if (e->ethproto != htons(ETH_P_8021Q)) { |
106 | DEBUG_MSG | 94 | DEBUG_MSG |
107 | ("passed entry proto %2.4X is not 802.1Q (8100)\n", | 95 | ("passed entry proto %2.4X is not 802.1Q (8100)\n", |
108 | (unsigned short) ntohs(e->ethproto)); | 96 | (unsigned short) ntohs(e->ethproto)); |
109 | return -EINVAL; | 97 | return false; |
110 | } | 98 | } |
111 | 99 | ||
112 | /* Check for bitmask range | 100 | /* Check for bitmask range |
@@ -114,14 +102,14 @@ ebt_check_vlan(const char *tablename, | |||
114 | if (info->bitmask & ~EBT_VLAN_MASK) { | 102 | if (info->bitmask & ~EBT_VLAN_MASK) { |
115 | DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", | 103 | DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", |
116 | info->bitmask, EBT_VLAN_MASK); | 104 | info->bitmask, EBT_VLAN_MASK); |
117 | return -EINVAL; | 105 | return false; |
118 | } | 106 | } |
119 | 107 | ||
120 | /* Check for inversion flags range */ | 108 | /* Check for inversion flags range */ |
121 | if (info->invflags & ~EBT_VLAN_MASK) { | 109 | if (info->invflags & ~EBT_VLAN_MASK) { |
122 | DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", | 110 | DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", |
123 | info->invflags, EBT_VLAN_MASK); | 111 | info->invflags, EBT_VLAN_MASK); |
124 | return -EINVAL; | 112 | return false; |
125 | } | 113 | } |
126 | 114 | ||
127 | /* Reserved VLAN ID (VID) values | 115 | /* Reserved VLAN ID (VID) values |
@@ -136,7 +124,7 @@ ebt_check_vlan(const char *tablename, | |||
136 | DEBUG_MSG | 124 | DEBUG_MSG |
137 | ("id %d is out of range (1-4096)\n", | 125 | ("id %d is out of range (1-4096)\n", |
138 | info->id); | 126 | info->id); |
139 | return -EINVAL; | 127 | return false; |
140 | } | 128 | } |
141 | /* Note: This is valid VLAN-tagged frame point. | 129 | /* Note: This is valid VLAN-tagged frame point. |
142 | * Any value of user_priority are acceptable, | 130 | * Any value of user_priority are acceptable, |
@@ -151,7 +139,7 @@ ebt_check_vlan(const char *tablename, | |||
151 | if ((unsigned char) info->prio > 7) { | 139 | if ((unsigned char) info->prio > 7) { |
152 | DEBUG_MSG("prio %d is out of range (0-7)\n", | 140 | DEBUG_MSG("prio %d is out of range (0-7)\n", |
153 | info->prio); | 141 | info->prio); |
154 | return -EINVAL; | 142 | return false; |
155 | } | 143 | } |
156 | } | 144 | } |
157 | /* Check for encapsulated proto range - it is possible to be | 145 | /* Check for encapsulated proto range - it is possible to be |
@@ -162,17 +150,20 @@ ebt_check_vlan(const char *tablename, | |||
162 | DEBUG_MSG | 150 | DEBUG_MSG |
163 | ("encap frame length %d is less than minimal\n", | 151 | ("encap frame length %d is less than minimal\n", |
164 | ntohs(info->encap)); | 152 | ntohs(info->encap)); |
165 | return -EINVAL; | 153 | return false; |
166 | } | 154 | } |
167 | } | 155 | } |
168 | 156 | ||
169 | return 0; | 157 | return true; |
170 | } | 158 | } |
171 | 159 | ||
172 | static struct ebt_match filter_vlan __read_mostly = { | 160 | static struct xt_match ebt_vlan_mt_reg __read_mostly = { |
173 | .name = EBT_VLAN_MATCH, | 161 | .name = "vlan", |
174 | .match = ebt_filter_vlan, | 162 | .revision = 0, |
175 | .check = ebt_check_vlan, | 163 | .family = NFPROTO_BRIDGE, |
164 | .match = ebt_vlan_mt, | ||
165 | .checkentry = ebt_vlan_mt_check, | ||
166 | .matchsize = XT_ALIGN(sizeof(struct ebt_vlan_info)), | ||
176 | .me = THIS_MODULE, | 167 | .me = THIS_MODULE, |
177 | }; | 168 | }; |
178 | 169 | ||
@@ -181,12 +172,12 @@ static int __init ebt_vlan_init(void) | |||
181 | DEBUG_MSG("ebtables 802.1Q extension module v" | 172 | DEBUG_MSG("ebtables 802.1Q extension module v" |
182 | MODULE_VERS "\n"); | 173 | MODULE_VERS "\n"); |
183 | DEBUG_MSG("module debug=%d\n", !!debug); | 174 | DEBUG_MSG("module debug=%d\n", !!debug); |
184 | return ebt_register_match(&filter_vlan); | 175 | return xt_register_match(&ebt_vlan_mt_reg); |
185 | } | 176 | } |
186 | 177 | ||
187 | static void __exit ebt_vlan_fini(void) | 178 | static void __exit ebt_vlan_fini(void) |
188 | { | 179 | { |
189 | ebt_unregister_match(&filter_vlan); | 180 | xt_unregister_match(&ebt_vlan_mt_reg); |
190 | } | 181 | } |
191 | 182 | ||
192 | module_init(ebt_vlan_init); | 183 | module_init(ebt_vlan_init); |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 32afff859e4a..0fa208e86405 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/kmod.h> | 19 | #include <linux/kmod.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
22 | #include <linux/netfilter/x_tables.h> | ||
22 | #include <linux/netfilter_bridge/ebtables.h> | 23 | #include <linux/netfilter_bridge/ebtables.h> |
23 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
@@ -55,29 +56,31 @@ | |||
55 | 56 | ||
56 | static DEFINE_MUTEX(ebt_mutex); | 57 | static DEFINE_MUTEX(ebt_mutex); |
57 | static LIST_HEAD(ebt_tables); | 58 | static LIST_HEAD(ebt_tables); |
58 | static LIST_HEAD(ebt_targets); | ||
59 | static LIST_HEAD(ebt_matches); | ||
60 | static LIST_HEAD(ebt_watchers); | ||
61 | 59 | ||
62 | static struct ebt_target ebt_standard_target = | 60 | static struct xt_target ebt_standard_target = { |
63 | { {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL}; | 61 | .name = "standard", |
62 | .revision = 0, | ||
63 | .family = NFPROTO_BRIDGE, | ||
64 | .targetsize = sizeof(int), | ||
65 | }; | ||
64 | 66 | ||
65 | static inline int ebt_do_watcher (struct ebt_entry_watcher *w, | 67 | static inline int |
66 | const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, | 68 | ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb, |
67 | const struct net_device *out) | 69 | struct xt_target_param *par) |
68 | { | 70 | { |
69 | w->u.watcher->watcher(skb, hooknr, in, out, w->data, | 71 | par->target = w->u.watcher; |
70 | w->watcher_size); | 72 | par->targinfo = w->data; |
73 | w->u.watcher->target(skb, par); | ||
71 | /* watchers don't give a verdict */ | 74 | /* watchers don't give a verdict */ |
72 | return 0; | 75 | return 0; |
73 | } | 76 | } |
74 | 77 | ||
75 | static inline int ebt_do_match (struct ebt_entry_match *m, | 78 | static inline int ebt_do_match (struct ebt_entry_match *m, |
76 | const struct sk_buff *skb, const struct net_device *in, | 79 | const struct sk_buff *skb, struct xt_match_param *par) |
77 | const struct net_device *out) | ||
78 | { | 80 | { |
79 | return m->u.match->match(skb, in, out, m->data, | 81 | par->match = m->u.match; |
80 | m->match_size); | 82 | par->matchinfo = m->data; |
83 | return m->u.match->match(skb, par); | ||
81 | } | 84 | } |
82 | 85 | ||
83 | static inline int ebt_dev_check(char *entry, const struct net_device *device) | 86 | static inline int ebt_dev_check(char *entry, const struct net_device *device) |
@@ -153,6 +156,15 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, | |||
153 | struct ebt_entries *chaininfo; | 156 | struct ebt_entries *chaininfo; |
154 | char *base; | 157 | char *base; |
155 | struct ebt_table_info *private; | 158 | struct ebt_table_info *private; |
159 | bool hotdrop = false; | ||
160 | struct xt_match_param mtpar; | ||
161 | struct xt_target_param tgpar; | ||
162 | |||
163 | mtpar.family = tgpar.family = NFPROTO_BRIDGE; | ||
164 | mtpar.in = tgpar.in = in; | ||
165 | mtpar.out = tgpar.out = out; | ||
166 | mtpar.hotdrop = &hotdrop; | ||
167 | tgpar.hooknum = hook; | ||
156 | 168 | ||
157 | read_lock_bh(&table->lock); | 169 | read_lock_bh(&table->lock); |
158 | private = table->private; | 170 | private = table->private; |
@@ -173,8 +185,12 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, | |||
173 | if (ebt_basic_match(point, eth_hdr(skb), in, out)) | 185 | if (ebt_basic_match(point, eth_hdr(skb), in, out)) |
174 | goto letscontinue; | 186 | goto letscontinue; |
175 | 187 | ||
176 | if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0) | 188 | if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &mtpar) != 0) |
177 | goto letscontinue; | 189 | goto letscontinue; |
190 | if (hotdrop) { | ||
191 | read_unlock_bh(&table->lock); | ||
192 | return NF_DROP; | ||
193 | } | ||
178 | 194 | ||
179 | /* increase counter */ | 195 | /* increase counter */ |
180 | (*(counter_base + i)).pcnt++; | 196 | (*(counter_base + i)).pcnt++; |
@@ -182,17 +198,18 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, | |||
182 | 198 | ||
183 | /* these should only watch: not modify, nor tell us | 199 | /* these should only watch: not modify, nor tell us |
184 | what to do with the packet */ | 200 | what to do with the packet */ |
185 | EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in, | 201 | EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &tgpar); |
186 | out); | ||
187 | 202 | ||
188 | t = (struct ebt_entry_target *) | 203 | t = (struct ebt_entry_target *) |
189 | (((char *)point) + point->target_offset); | 204 | (((char *)point) + point->target_offset); |
190 | /* standard target */ | 205 | /* standard target */ |
191 | if (!t->u.target->target) | 206 | if (!t->u.target->target) |
192 | verdict = ((struct ebt_standard_target *)t)->verdict; | 207 | verdict = ((struct ebt_standard_target *)t)->verdict; |
193 | else | 208 | else { |
194 | verdict = t->u.target->target(skb, hook, | 209 | tgpar.target = t->u.target; |
195 | in, out, t->data, t->target_size); | 210 | tgpar.targinfo = t->data; |
211 | verdict = t->u.target->target(skb, &tgpar); | ||
212 | } | ||
196 | if (verdict == EBT_ACCEPT) { | 213 | if (verdict == EBT_ACCEPT) { |
197 | read_unlock_bh(&table->lock); | 214 | read_unlock_bh(&table->lock); |
198 | return NF_ACCEPT; | 215 | return NF_ACCEPT; |
@@ -288,23 +305,14 @@ find_inlist_lock_noload(struct list_head *head, const char *name, int *error, | |||
288 | return NULL; | 305 | return NULL; |
289 | } | 306 | } |
290 | 307 | ||
291 | #ifndef CONFIG_KMOD | ||
292 | #define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m)) | ||
293 | #else | ||
294 | static void * | 308 | static void * |
295 | find_inlist_lock(struct list_head *head, const char *name, const char *prefix, | 309 | find_inlist_lock(struct list_head *head, const char *name, const char *prefix, |
296 | int *error, struct mutex *mutex) | 310 | int *error, struct mutex *mutex) |
297 | { | 311 | { |
298 | void *ret; | 312 | return try_then_request_module( |
299 | 313 | find_inlist_lock_noload(head, name, error, mutex), | |
300 | ret = find_inlist_lock_noload(head, name, error, mutex); | 314 | "%s%s", prefix, name); |
301 | if (!ret) { | ||
302 | request_module("%s%s", prefix, name); | ||
303 | ret = find_inlist_lock_noload(head, name, error, mutex); | ||
304 | } | ||
305 | return ret; | ||
306 | } | 315 | } |
307 | #endif | ||
308 | 316 | ||
309 | static inline struct ebt_table * | 317 | static inline struct ebt_table * |
310 | find_table_lock(const char *name, int *error, struct mutex *mutex) | 318 | find_table_lock(const char *name, int *error, struct mutex *mutex) |
@@ -312,80 +320,71 @@ find_table_lock(const char *name, int *error, struct mutex *mutex) | |||
312 | return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); | 320 | return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); |
313 | } | 321 | } |
314 | 322 | ||
315 | static inline struct ebt_match * | ||
316 | find_match_lock(const char *name, int *error, struct mutex *mutex) | ||
317 | { | ||
318 | return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex); | ||
319 | } | ||
320 | |||
321 | static inline struct ebt_watcher * | ||
322 | find_watcher_lock(const char *name, int *error, struct mutex *mutex) | ||
323 | { | ||
324 | return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex); | ||
325 | } | ||
326 | |||
327 | static inline struct ebt_target * | ||
328 | find_target_lock(const char *name, int *error, struct mutex *mutex) | ||
329 | { | ||
330 | return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex); | ||
331 | } | ||
332 | |||
333 | static inline int | 323 | static inline int |
334 | ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, | 324 | ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, |
335 | const char *name, unsigned int hookmask, unsigned int *cnt) | 325 | unsigned int *cnt) |
336 | { | 326 | { |
337 | struct ebt_match *match; | 327 | const struct ebt_entry *e = par->entryinfo; |
328 | struct xt_match *match; | ||
338 | size_t left = ((char *)e + e->watchers_offset) - (char *)m; | 329 | size_t left = ((char *)e + e->watchers_offset) - (char *)m; |
339 | int ret; | 330 | int ret; |
340 | 331 | ||
341 | if (left < sizeof(struct ebt_entry_match) || | 332 | if (left < sizeof(struct ebt_entry_match) || |
342 | left - sizeof(struct ebt_entry_match) < m->match_size) | 333 | left - sizeof(struct ebt_entry_match) < m->match_size) |
343 | return -EINVAL; | 334 | return -EINVAL; |
344 | match = find_match_lock(m->u.name, &ret, &ebt_mutex); | 335 | |
345 | if (!match) | 336 | match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE, |
346 | return ret; | 337 | m->u.name, 0), "ebt_%s", m->u.name); |
347 | m->u.match = match; | 338 | if (IS_ERR(match)) |
348 | if (!try_module_get(match->me)) { | 339 | return PTR_ERR(match); |
349 | mutex_unlock(&ebt_mutex); | 340 | if (match == NULL) |
350 | return -ENOENT; | 341 | return -ENOENT; |
351 | } | 342 | m->u.match = match; |
352 | mutex_unlock(&ebt_mutex); | 343 | |
353 | if (match->check && | 344 | par->match = match; |
354 | match->check(name, hookmask, e, m->data, m->match_size) != 0) { | 345 | par->matchinfo = m->data; |
355 | BUGPRINT("match->check failed\n"); | 346 | ret = xt_check_match(par, m->match_size, |
347 | e->ethproto, e->invflags & EBT_IPROTO); | ||
348 | if (ret < 0) { | ||
356 | module_put(match->me); | 349 | module_put(match->me); |
357 | return -EINVAL; | 350 | return ret; |
358 | } | 351 | } |
352 | |||
359 | (*cnt)++; | 353 | (*cnt)++; |
360 | return 0; | 354 | return 0; |
361 | } | 355 | } |
362 | 356 | ||
363 | static inline int | 357 | static inline int |
364 | ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, | 358 | ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par, |
365 | const char *name, unsigned int hookmask, unsigned int *cnt) | 359 | unsigned int *cnt) |
366 | { | 360 | { |
367 | struct ebt_watcher *watcher; | 361 | const struct ebt_entry *e = par->entryinfo; |
362 | struct xt_target *watcher; | ||
368 | size_t left = ((char *)e + e->target_offset) - (char *)w; | 363 | size_t left = ((char *)e + e->target_offset) - (char *)w; |
369 | int ret; | 364 | int ret; |
370 | 365 | ||
371 | if (left < sizeof(struct ebt_entry_watcher) || | 366 | if (left < sizeof(struct ebt_entry_watcher) || |
372 | left - sizeof(struct ebt_entry_watcher) < w->watcher_size) | 367 | left - sizeof(struct ebt_entry_watcher) < w->watcher_size) |
373 | return -EINVAL; | 368 | return -EINVAL; |
374 | watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); | 369 | |
375 | if (!watcher) | 370 | watcher = try_then_request_module( |
376 | return ret; | 371 | xt_find_target(NFPROTO_BRIDGE, w->u.name, 0), |
377 | w->u.watcher = watcher; | 372 | "ebt_%s", w->u.name); |
378 | if (!try_module_get(watcher->me)) { | 373 | if (IS_ERR(watcher)) |
379 | mutex_unlock(&ebt_mutex); | 374 | return PTR_ERR(watcher); |
375 | if (watcher == NULL) | ||
380 | return -ENOENT; | 376 | return -ENOENT; |
381 | } | 377 | w->u.watcher = watcher; |
382 | mutex_unlock(&ebt_mutex); | 378 | |
383 | if (watcher->check && | 379 | par->target = watcher; |
384 | watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) { | 380 | par->targinfo = w->data; |
385 | BUGPRINT("watcher->check failed\n"); | 381 | ret = xt_check_target(par, w->watcher_size, |
382 | e->ethproto, e->invflags & EBT_IPROTO); | ||
383 | if (ret < 0) { | ||
386 | module_put(watcher->me); | 384 | module_put(watcher->me); |
387 | return -EINVAL; | 385 | return ret; |
388 | } | 386 | } |
387 | |||
389 | (*cnt)++; | 388 | (*cnt)++; |
390 | return 0; | 389 | return 0; |
391 | } | 390 | } |
@@ -558,30 +557,41 @@ ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
558 | static inline int | 557 | static inline int |
559 | ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) | 558 | ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) |
560 | { | 559 | { |
560 | struct xt_mtdtor_param par; | ||
561 | |||
561 | if (i && (*i)-- == 0) | 562 | if (i && (*i)-- == 0) |
562 | return 1; | 563 | return 1; |
563 | if (m->u.match->destroy) | ||
564 | m->u.match->destroy(m->data, m->match_size); | ||
565 | module_put(m->u.match->me); | ||
566 | 564 | ||
565 | par.match = m->u.match; | ||
566 | par.matchinfo = m->data; | ||
567 | par.family = NFPROTO_BRIDGE; | ||
568 | if (par.match->destroy != NULL) | ||
569 | par.match->destroy(&par); | ||
570 | module_put(par.match->me); | ||
567 | return 0; | 571 | return 0; |
568 | } | 572 | } |
569 | 573 | ||
570 | static inline int | 574 | static inline int |
571 | ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) | 575 | ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) |
572 | { | 576 | { |
577 | struct xt_tgdtor_param par; | ||
578 | |||
573 | if (i && (*i)-- == 0) | 579 | if (i && (*i)-- == 0) |
574 | return 1; | 580 | return 1; |
575 | if (w->u.watcher->destroy) | ||
576 | w->u.watcher->destroy(w->data, w->watcher_size); | ||
577 | module_put(w->u.watcher->me); | ||
578 | 581 | ||
582 | par.target = w->u.watcher; | ||
583 | par.targinfo = w->data; | ||
584 | par.family = NFPROTO_BRIDGE; | ||
585 | if (par.target->destroy != NULL) | ||
586 | par.target->destroy(&par); | ||
587 | module_put(par.target->me); | ||
579 | return 0; | 588 | return 0; |
580 | } | 589 | } |
581 | 590 | ||
582 | static inline int | 591 | static inline int |
583 | ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) | 592 | ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) |
584 | { | 593 | { |
594 | struct xt_tgdtor_param par; | ||
585 | struct ebt_entry_target *t; | 595 | struct ebt_entry_target *t; |
586 | 596 | ||
587 | if (e->bitmask == 0) | 597 | if (e->bitmask == 0) |
@@ -592,10 +602,13 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) | |||
592 | EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); | 602 | EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); |
593 | EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); | 603 | EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); |
594 | t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); | 604 | t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); |
595 | if (t->u.target->destroy) | ||
596 | t->u.target->destroy(t->data, t->target_size); | ||
597 | module_put(t->u.target->me); | ||
598 | 605 | ||
606 | par.target = t->u.target; | ||
607 | par.targinfo = t->data; | ||
608 | par.family = NFPROTO_BRIDGE; | ||
609 | if (par.target->destroy != NULL) | ||
610 | par.target->destroy(&par); | ||
611 | module_put(par.target->me); | ||
599 | return 0; | 612 | return 0; |
600 | } | 613 | } |
601 | 614 | ||
@@ -605,10 +618,12 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
605 | struct ebt_cl_stack *cl_s, unsigned int udc_cnt) | 618 | struct ebt_cl_stack *cl_s, unsigned int udc_cnt) |
606 | { | 619 | { |
607 | struct ebt_entry_target *t; | 620 | struct ebt_entry_target *t; |
608 | struct ebt_target *target; | 621 | struct xt_target *target; |
609 | unsigned int i, j, hook = 0, hookmask = 0; | 622 | unsigned int i, j, hook = 0, hookmask = 0; |
610 | size_t gap; | 623 | size_t gap; |
611 | int ret; | 624 | int ret; |
625 | struct xt_mtchk_param mtpar; | ||
626 | struct xt_tgchk_param tgpar; | ||
612 | 627 | ||
613 | /* don't mess with the struct ebt_entries */ | 628 | /* don't mess with the struct ebt_entries */ |
614 | if (e->bitmask == 0) | 629 | if (e->bitmask == 0) |
@@ -649,24 +664,31 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
649 | hookmask = cl_s[i - 1].hookmask; | 664 | hookmask = cl_s[i - 1].hookmask; |
650 | } | 665 | } |
651 | i = 0; | 666 | i = 0; |
652 | ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i); | 667 | |
668 | mtpar.table = tgpar.table = name; | ||
669 | mtpar.entryinfo = tgpar.entryinfo = e; | ||
670 | mtpar.hook_mask = tgpar.hook_mask = hookmask; | ||
671 | mtpar.family = tgpar.family = NFPROTO_BRIDGE; | ||
672 | ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i); | ||
653 | if (ret != 0) | 673 | if (ret != 0) |
654 | goto cleanup_matches; | 674 | goto cleanup_matches; |
655 | j = 0; | 675 | j = 0; |
656 | ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j); | 676 | ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, &tgpar, &j); |
657 | if (ret != 0) | 677 | if (ret != 0) |
658 | goto cleanup_watchers; | 678 | goto cleanup_watchers; |
659 | t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); | 679 | t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); |
660 | gap = e->next_offset - e->target_offset; | 680 | gap = e->next_offset - e->target_offset; |
661 | target = find_target_lock(t->u.name, &ret, &ebt_mutex); | 681 | |
662 | if (!target) | 682 | target = try_then_request_module( |
683 | xt_find_target(NFPROTO_BRIDGE, t->u.name, 0), | ||
684 | "ebt_%s", t->u.name); | ||
685 | if (IS_ERR(target)) { | ||
686 | ret = PTR_ERR(target); | ||
663 | goto cleanup_watchers; | 687 | goto cleanup_watchers; |
664 | if (!try_module_get(target->me)) { | 688 | } else if (target == NULL) { |
665 | mutex_unlock(&ebt_mutex); | ||
666 | ret = -ENOENT; | 689 | ret = -ENOENT; |
667 | goto cleanup_watchers; | 690 | goto cleanup_watchers; |
668 | } | 691 | } |
669 | mutex_unlock(&ebt_mutex); | ||
670 | 692 | ||
671 | t->u.target = target; | 693 | t->u.target = target; |
672 | if (t->u.target == &ebt_standard_target) { | 694 | if (t->u.target == &ebt_standard_target) { |
@@ -681,13 +703,20 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
681 | ret = -EFAULT; | 703 | ret = -EFAULT; |
682 | goto cleanup_watchers; | 704 | goto cleanup_watchers; |
683 | } | 705 | } |
684 | } else if (t->target_size > gap - sizeof(struct ebt_entry_target) || | 706 | } else if (t->target_size > gap - sizeof(struct ebt_entry_target)) { |
685 | (t->u.target->check && | ||
686 | t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){ | ||
687 | module_put(t->u.target->me); | 707 | module_put(t->u.target->me); |
688 | ret = -EFAULT; | 708 | ret = -EFAULT; |
689 | goto cleanup_watchers; | 709 | goto cleanup_watchers; |
690 | } | 710 | } |
711 | |||
712 | tgpar.target = target; | ||
713 | tgpar.targinfo = t->data; | ||
714 | ret = xt_check_target(&tgpar, t->target_size, | ||
715 | e->ethproto, e->invflags & EBT_IPROTO); | ||
716 | if (ret < 0) { | ||
717 | module_put(target->me); | ||
718 | goto cleanup_watchers; | ||
719 | } | ||
691 | (*cnt)++; | 720 | (*cnt)++; |
692 | return 0; | 721 | return 0; |
693 | cleanup_watchers: | 722 | cleanup_watchers: |
@@ -1068,87 +1097,6 @@ free_newinfo: | |||
1068 | return ret; | 1097 | return ret; |
1069 | } | 1098 | } |
1070 | 1099 | ||
1071 | int ebt_register_target(struct ebt_target *target) | ||
1072 | { | ||
1073 | struct ebt_target *t; | ||
1074 | int ret; | ||
1075 | |||
1076 | ret = mutex_lock_interruptible(&ebt_mutex); | ||
1077 | if (ret != 0) | ||
1078 | return ret; | ||
1079 | list_for_each_entry(t, &ebt_targets, list) { | ||
1080 | if (strcmp(t->name, target->name) == 0) { | ||
1081 | mutex_unlock(&ebt_mutex); | ||
1082 | return -EEXIST; | ||
1083 | } | ||
1084 | } | ||
1085 | list_add(&target->list, &ebt_targets); | ||
1086 | mutex_unlock(&ebt_mutex); | ||
1087 | |||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | void ebt_unregister_target(struct ebt_target *target) | ||
1092 | { | ||
1093 | mutex_lock(&ebt_mutex); | ||
1094 | list_del(&target->list); | ||
1095 | mutex_unlock(&ebt_mutex); | ||
1096 | } | ||
1097 | |||
1098 | int ebt_register_match(struct ebt_match *match) | ||
1099 | { | ||
1100 | struct ebt_match *m; | ||
1101 | int ret; | ||
1102 | |||
1103 | ret = mutex_lock_interruptible(&ebt_mutex); | ||
1104 | if (ret != 0) | ||
1105 | return ret; | ||
1106 | list_for_each_entry(m, &ebt_matches, list) { | ||
1107 | if (strcmp(m->name, match->name) == 0) { | ||
1108 | mutex_unlock(&ebt_mutex); | ||
1109 | return -EEXIST; | ||
1110 | } | ||
1111 | } | ||
1112 | list_add(&match->list, &ebt_matches); | ||
1113 | mutex_unlock(&ebt_mutex); | ||
1114 | |||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | void ebt_unregister_match(struct ebt_match *match) | ||
1119 | { | ||
1120 | mutex_lock(&ebt_mutex); | ||
1121 | list_del(&match->list); | ||
1122 | mutex_unlock(&ebt_mutex); | ||
1123 | } | ||
1124 | |||
1125 | int ebt_register_watcher(struct ebt_watcher *watcher) | ||
1126 | { | ||
1127 | struct ebt_watcher *w; | ||
1128 | int ret; | ||
1129 | |||
1130 | ret = mutex_lock_interruptible(&ebt_mutex); | ||
1131 | if (ret != 0) | ||
1132 | return ret; | ||
1133 | list_for_each_entry(w, &ebt_watchers, list) { | ||
1134 | if (strcmp(w->name, watcher->name) == 0) { | ||
1135 | mutex_unlock(&ebt_mutex); | ||
1136 | return -EEXIST; | ||
1137 | } | ||
1138 | } | ||
1139 | list_add(&watcher->list, &ebt_watchers); | ||
1140 | mutex_unlock(&ebt_mutex); | ||
1141 | |||
1142 | return 0; | ||
1143 | } | ||
1144 | |||
1145 | void ebt_unregister_watcher(struct ebt_watcher *watcher) | ||
1146 | { | ||
1147 | mutex_lock(&ebt_mutex); | ||
1148 | list_del(&watcher->list); | ||
1149 | mutex_unlock(&ebt_mutex); | ||
1150 | } | ||
1151 | |||
1152 | int ebt_register_table(struct ebt_table *table) | 1100 | int ebt_register_table(struct ebt_table *table) |
1153 | { | 1101 | { |
1154 | struct ebt_table_info *newinfo; | 1102 | struct ebt_table_info *newinfo; |
@@ -1518,11 +1466,14 @@ static int __init ebtables_init(void) | |||
1518 | { | 1466 | { |
1519 | int ret; | 1467 | int ret; |
1520 | 1468 | ||
1521 | mutex_lock(&ebt_mutex); | 1469 | ret = xt_register_target(&ebt_standard_target); |
1522 | list_add(&ebt_standard_target.list, &ebt_targets); | 1470 | if (ret < 0) |
1523 | mutex_unlock(&ebt_mutex); | 1471 | return ret; |
1524 | if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) | 1472 | ret = nf_register_sockopt(&ebt_sockopts); |
1473 | if (ret < 0) { | ||
1474 | xt_unregister_target(&ebt_standard_target); | ||
1525 | return ret; | 1475 | return ret; |
1476 | } | ||
1526 | 1477 | ||
1527 | printk(KERN_INFO "Ebtables v2.0 registered\n"); | 1478 | printk(KERN_INFO "Ebtables v2.0 registered\n"); |
1528 | return 0; | 1479 | return 0; |
@@ -1531,17 +1482,12 @@ static int __init ebtables_init(void) | |||
1531 | static void __exit ebtables_fini(void) | 1482 | static void __exit ebtables_fini(void) |
1532 | { | 1483 | { |
1533 | nf_unregister_sockopt(&ebt_sockopts); | 1484 | nf_unregister_sockopt(&ebt_sockopts); |
1485 | xt_unregister_target(&ebt_standard_target); | ||
1534 | printk(KERN_INFO "Ebtables v2.0 unregistered\n"); | 1486 | printk(KERN_INFO "Ebtables v2.0 unregistered\n"); |
1535 | } | 1487 | } |
1536 | 1488 | ||
1537 | EXPORT_SYMBOL(ebt_register_table); | 1489 | EXPORT_SYMBOL(ebt_register_table); |
1538 | EXPORT_SYMBOL(ebt_unregister_table); | 1490 | EXPORT_SYMBOL(ebt_unregister_table); |
1539 | EXPORT_SYMBOL(ebt_register_match); | ||
1540 | EXPORT_SYMBOL(ebt_unregister_match); | ||
1541 | EXPORT_SYMBOL(ebt_register_watcher); | ||
1542 | EXPORT_SYMBOL(ebt_unregister_watcher); | ||
1543 | EXPORT_SYMBOL(ebt_register_target); | ||
1544 | EXPORT_SYMBOL(ebt_unregister_target); | ||
1545 | EXPORT_SYMBOL(ebt_do_table); | 1491 | EXPORT_SYMBOL(ebt_do_table); |
1546 | module_init(ebtables_init); | 1492 | module_init(ebtables_init); |
1547 | module_exit(ebtables_fini); | 1493 | module_exit(ebtables_fini); |