aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br.c22
-rw-r--r--net/bridge/br_device.c3
-rw-r--r--net/bridge/br_if.c15
-rw-r--r--net/bridge/br_ioctl.c20
-rw-r--r--net/bridge/br_netfilter.c4
-rw-r--r--net/bridge/br_netlink.c15
-rw-r--r--net/bridge/br_notify.c3
-rw-r--r--net/bridge/br_private.h6
-rw-r--r--net/bridge/br_stp_bpdu.c3
-rw-r--r--net/bridge/netfilter/Kconfig31
-rw-r--r--net/bridge/netfilter/ebt_802_3.c47
-rw-r--r--net/bridge/netfilter/ebt_among.c85
-rw-r--r--net/bridge/netfilter/ebt_arp.c73
-rw-r--r--net/bridge/netfilter/ebt_arpreply.c49
-rw-r--r--net/bridge/netfilter/ebt_dnat.c57
-rw-r--r--net/bridge/netfilter/ebt_ip.c72
-rw-r--r--net/bridge/netfilter/ebt_ip6.c76
-rw-r--r--net/bridge/netfilter/ebt_limit.c45
-rw-r--r--net/bridge/netfilter/ebt_log.c57
-rw-r--r--net/bridge/netfilter/ebt_mark.c41
-rw-r--r--net/bridge/netfilter/ebt_mark_m.c45
-rw-r--r--net/bridge/netfilter/ebt_nflog.c44
-rw-r--r--net/bridge/netfilter/ebt_pkttype.c41
-rw-r--r--net/bridge/netfilter/ebt_redirect.c63
-rw-r--r--net/bridge/netfilter/ebt_snat.c52
-rw-r--r--net/bridge/netfilter/ebt_stp.c78
-rw-r--r--net/bridge/netfilter/ebt_ulog.c58
-rw-r--r--net/bridge/netfilter/ebt_vlan.c61
-rw-r--r--net/bridge/netfilter/ebtables.c328
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
31static struct pernet_operations br_net_ops = {
32 .exit = br_net_exit,
33};
34
31static int __init br_init(void) 35static 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;
64err_out3: 72err_out4:
65 unregister_netdevice_notifier(&br_device_notifier); 73 unregister_netdevice_notifier(&br_device_notifier);
66err_out2: 74err_out3:
67 br_netfilter_fini(); 75 br_netfilter_fini();
76err_out2:
77 unregister_pernet_subsys(&br_net_ops);
68err_out1: 78err_out1:
69 br_fdb_fini(); 79 br_fdb_fini();
70err_out: 80err_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
171static struct net_device *new_bridge_dev(const char *name) 171static 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
265int br_add_bridge(const char *name) 266int 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
297int br_del_bridge(const char *name) 298int 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
448void __exit br_cleanup_bridges(void) 449void 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();
453restart: 454restart:
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 */
24static int get_bridge_ifindices(int *indices, int num) 24static 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
318static int old_deviceless(void __user *uarg) 318static 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 */
83void br_ifinfo_notify(int event, struct net_bridge_port *port) 83void 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);
101errout: 102errout:
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 */
180extern void br_port_carrier_check(struct net_bridge_port *p); 180extern void br_port_carrier_check(struct net_bridge_port *p);
181extern int br_add_bridge(const char *name); 181extern int br_add_bridge(struct net *net, const char *name);
182extern int br_del_bridge(const char *name); 182extern int br_del_bridge(struct net *net, const char *name);
183extern void br_cleanup_bridges(void); 183extern void br_net_exit(struct net *net);
184extern int br_add_if(struct net_bridge *br, 184extern int br_add_if(struct net_bridge *br,
185 struct net_device *dev); 185 struct net_device *dev);
186extern int br_del_if(struct net_bridge *br, 186extern 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
5menu "Bridge: Netfilter Configuration" 5menuconfig BRIDGE_NF_EBTABLES
6 depends on BRIDGE && BRIDGE_NETFILTER
7
8config 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
14if BRIDGE_NF_EBTABLES
15
14# 16#
15# tables 17# tables
16# 18#
17config BRIDGE_EBT_BROUTE 19config 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
28config BRIDGE_EBT_T_FILTER 29config 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
38config BRIDGE_EBT_T_NAT 38config 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#
50config BRIDGE_EBT_802_3 49config 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
58config BRIDGE_EBT_AMONG 56config 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
68config BRIDGE_EBT_ARP 65config 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
77config BRIDGE_EBT_IP 73config 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
95config BRIDGE_EBT_LIMIT 90config 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
106config BRIDGE_EBT_MARK 100config 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
117config BRIDGE_EBT_PKTTYPE 110config 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
128config BRIDGE_EBT_STP 120config 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
137config BRIDGE_EBT_VLAN 128config 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
157config BRIDGE_EBT_DNAT 147config 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
166config BRIDGE_EBT_MARK_T 155config 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
177config BRIDGE_EBT_REDIRECT 165config 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
186config BRIDGE_EBT_SNAT 173config 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#
197config BRIDGE_EBT_LOG 183config 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
207config BRIDGE_EBT_ULOG 192config 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
224config BRIDGE_EBT_NFLOG 208config 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
238endmenu 221endif # 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
15static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, 15static bool
16 const struct net_device *out, const void *data, unsigned int datalen) 16ebt_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
39static struct ebt_match filter_802_3; 39static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
40static 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
53static struct ebt_match filter_802_3 __read_mostly = { 49static 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
60static int __init ebt_802_3_init(void) 59static 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
65static void __exit ebt_802_3_fini(void) 64static 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
70module_init(ebt_802_3_init); 69module_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
17static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, 17static 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
55static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash 51static 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
134static int ebt_filter_among(const struct sk_buff *skb, 130static bool
135 const struct net_device *in, 131ebt_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
180static int ebt_among_check(const char *tablename, unsigned int hookmask, 174static 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
215static struct ebt_match filter_among __read_mostly = { 209static 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
222static int __init ebt_among_init(void) 219static 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
227static void __exit ebt_among_fini(void) 224static 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
232module_init(ebt_among_init); 229module_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
18static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in, 18static bool
19 const struct net_device *out, const void *data, unsigned int datalen) 19ebt_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
103static int ebt_arp_check(const char *tablename, unsigned int hookmask, 103static 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
119static struct ebt_match filter_arp __read_mostly = { 117static 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
126static int __init ebt_arp_init(void) 127static 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
131static void __exit ebt_arp_fini(void) 132static 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
136module_init(ebt_arp_init); 137module_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
18static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr, 18static unsigned int
19 const struct net_device *in, const struct net_device *out, 19ebt_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
61static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, 60static 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
79static struct ebt_target reply_target __read_mostly = { 73static 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
86static int __init ebt_arpreply_init(void) 85static 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
91static void __exit ebt_arpreply_fini(void) 90static 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
96module_init(ebt_arpreply_init); 95module_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
17static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, 17static unsigned int
18 const struct net_device *in, const struct net_device *out, 18ebt_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
30static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, 29static 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
49static struct ebt_target dnat __read_mostly = { 49static 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
56static int __init ebt_dnat_init(void) 61static 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
61static void __exit ebt_dnat_fini(void) 66static 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
66module_init(ebt_dnat_init); 71module_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
22struct tcpudphdr { 22struct tcpudphdr {
23 __be16 src; 23 __be16 src;
24 __be16 dst; 24 __be16 dst;
25}; 25};
26 26
27static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, 27static bool
28 const struct net_device *out, const void *data, 28ebt_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
81static int ebt_ip_check(const char *tablename, unsigned int hookmask, 80static 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
110static struct ebt_match filter_ip __read_mostly = { 107static 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
117static int __init ebt_ip_init(void) 117static 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
122static void __exit ebt_ip_fini(void) 122static 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
127module_init(ebt_ip_init); 127module_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
25struct tcpudphdr { 25struct tcpudphdr {
26 __be16 src; 26 __be16 src;
27 __be16 dst; 27 __be16 dst;
28}; 28};
29 29
30static int ebt_filter_ip6(const struct sk_buff *skb, 30static bool
31 const struct net_device *in, 31ebt_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
95static int ebt_ip6_check(const char *tablename, unsigned int hookmask, 93static 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
123static struct ebt_match filter_ip6 = 119static 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
131static int __init ebt_ip6_init(void) 129static 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
136static void __exit ebt_ip6_fini(void) 134static 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
141module_init(ebt_ip6_init); 139module_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
21static DEFINE_SPINLOCK(limit_lock); 20static 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
34static int ebt_limit_match(const struct sk_buff *skb, 33static bool
35 const struct net_device *in, const struct net_device *out, 34ebt_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
69static int ebt_limit_check(const char *tablename, unsigned int hookmask, 67static 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
93static struct ebt_match ebt_limit_reg __read_mostly = { 87static 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
100static int __init ebt_limit_init(void) 97static 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
105static void __exit ebt_limit_fini(void) 102static 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
110module_init(ebt_limit_init); 107module_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
25static DEFINE_SPINLOCK(ebt_log_lock); 25static DEFINE_SPINLOCK(ebt_log_lock);
26 26
27static int ebt_log_check(const char *tablename, unsigned int hookmask, 27static 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
42struct tcpudphdr 39struct 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]
86static void 83static void
87ebt_log_packet(unsigned int pf, unsigned int hooknum, 84ebt_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
197static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, 194static unsigned int
198 const struct net_device *in, const struct net_device *out, 195ebt_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
216static struct ebt_watcher log = 213static 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
241static void __exit ebt_log_fini(void) 240static 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
247module_init(ebt_log_init); 246module_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
20static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr, 21static unsigned int
21 const struct net_device *in, const struct net_device *out, 22ebt_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
39static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, 39static 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
60static struct ebt_target mark_target __read_mostly = { 56static 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
67static int __init ebt_mark_init(void) 66static 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
72static void __exit ebt_mark_fini(void) 71static 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
77module_init(ebt_mark_init); 76module_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
15static int ebt_filter_mark(const struct sk_buff *skb, 15static bool
16 const struct net_device *in, const struct net_device *out, const void *data, 16ebt_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
26static int ebt_mark_check(const char *tablename, unsigned int hookmask, 25static 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
42static struct ebt_match filter_mark __read_mostly = { 38static 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
49static int __init ebt_mark_m_init(void) 48static 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
54static void __exit ebt_mark_m_fini(void) 53static 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
59module_init(ebt_mark_m_init); 58module_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
21static void ebt_nflog(const struct sk_buff *skb, 22static unsigned int
22 unsigned int hooknr, 23ebt_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
38static int ebt_nflog_check(const char *tablename, 38static 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
53static struct ebt_watcher nflog __read_mostly = { 48static 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
60static int __init ebt_nflog_init(void) 58static 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
65static void __exit ebt_nflog_fini(void) 63static 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
70module_init(ebt_nflog_init); 68module_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
15static int ebt_filter_pkttype(const struct sk_buff *skb, 15static bool
16 const struct net_device *in, 16ebt_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
26static int ebt_pkttype_check(const char *tablename, unsigned int hookmask, 23static 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
39static struct ebt_match filter_pkttype __read_mostly = { 33static 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
46static int __init ebt_pkttype_init(void) 43static 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
51static void __exit ebt_pkttype_fini(void) 48static 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
56module_init(ebt_pkttype_init); 53module_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
18static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr, 18static unsigned int
19 const struct net_device *in, const struct net_device *out, 19ebt_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
36static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask, 35static 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
54static struct ebt_target redirect_target __read_mostly = { 54static 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
61static int __init ebt_redirect_init(void) 66static 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
66static void __exit ebt_redirect_fini(void) 71static 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
71module_init(ebt_redirect_init); 76module_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
19static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, 19static unsigned int
20 const struct net_device *in, const struct net_device *out, 20ebt_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
46static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, 45static 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
71static struct ebt_target snat __read_mostly = { 62static 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
78static int __init ebt_snat_init(void) 74static 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
83static void __exit ebt_snat_fini(void) 79static 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
88module_init(ebt_snat_init); 84module_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
43static int ebt_filter_config(const struct ebt_stp_info *info, 43static 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
122static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in, 122static bool
123 const struct net_device *out, const void *data, unsigned int datalen) 123ebt_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
156static int ebt_stp_check(const char *tablename, unsigned int hookmask, 156static 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
177static struct ebt_match filter_stp __read_mostly = { 174static 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
184static int __init ebt_stp_init(void) 184static 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
189static void __exit ebt_stp_fini(void) 189static 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
194module_init(ebt_stp_init); 194module_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 */
226static void ebt_log_packet(unsigned int pf, unsigned int hooknum, 227static 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
248static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, 249static unsigned int
249 const struct net_device *in, const struct net_device *out, 250ebt_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 257static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
258static 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
275static struct ebt_watcher ulog __read_mostly = { 272static 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
282static const struct nf_logger ebt_ulog_logger = { 282static 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
288static int __init ebt_ulog_init(void) 288static 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
42static int 43static bool
43ebt_filter_vlan(const struct sk_buff *skb, 44ebt_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
89static int 87static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
90ebt_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
172static struct ebt_match filter_vlan __read_mostly = { 160static 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
187static void __exit ebt_vlan_fini(void) 178static 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
192module_init(ebt_vlan_init); 183module_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
56static DEFINE_MUTEX(ebt_mutex); 57static DEFINE_MUTEX(ebt_mutex);
57static LIST_HEAD(ebt_tables); 58static LIST_HEAD(ebt_tables);
58static LIST_HEAD(ebt_targets);
59static LIST_HEAD(ebt_matches);
60static LIST_HEAD(ebt_watchers);
61 59
62static struct ebt_target ebt_standard_target = 60static 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
65static inline int ebt_do_watcher (struct ebt_entry_watcher *w, 67static inline int
66 const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, 68ebt_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
75static inline int ebt_do_match (struct ebt_entry_match *m, 78static 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
83static inline int ebt_dev_check(char *entry, const struct net_device *device) 86static 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
294static void * 308static void *
295find_inlist_lock(struct list_head *head, const char *name, const char *prefix, 309find_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
309static inline struct ebt_table * 317static inline struct ebt_table *
310find_table_lock(const char *name, int *error, struct mutex *mutex) 318find_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
315static inline struct ebt_match *
316find_match_lock(const char *name, int *error, struct mutex *mutex)
317{
318 return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
319}
320
321static inline struct ebt_watcher *
322find_watcher_lock(const char *name, int *error, struct mutex *mutex)
323{
324 return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
325}
326
327static inline struct ebt_target *
328find_target_lock(const char *name, int *error, struct mutex *mutex)
329{
330 return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
331}
332
333static inline int 323static inline int
334ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, 324ebt_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
363static inline int 357static inline int
364ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, 358ebt_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,
558static inline int 557static inline int
559ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) 558ebt_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
570static inline int 574static inline int
571ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) 575ebt_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
582static inline int 591static inline int
583ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) 592ebt_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;
693cleanup_watchers: 722cleanup_watchers:
@@ -1068,87 +1097,6 @@ free_newinfo:
1068 return ret; 1097 return ret;
1069} 1098}
1070 1099
1071int 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
1091void 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
1098int 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
1118void 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
1125int 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
1145void 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
1152int ebt_register_table(struct ebt_table *table) 1100int 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)
1531static void __exit ebtables_fini(void) 1482static 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
1537EXPORT_SYMBOL(ebt_register_table); 1489EXPORT_SYMBOL(ebt_register_table);
1538EXPORT_SYMBOL(ebt_unregister_table); 1490EXPORT_SYMBOL(ebt_unregister_table);
1539EXPORT_SYMBOL(ebt_register_match);
1540EXPORT_SYMBOL(ebt_unregister_match);
1541EXPORT_SYMBOL(ebt_register_watcher);
1542EXPORT_SYMBOL(ebt_unregister_watcher);
1543EXPORT_SYMBOL(ebt_register_target);
1544EXPORT_SYMBOL(ebt_unregister_target);
1545EXPORT_SYMBOL(ebt_do_table); 1491EXPORT_SYMBOL(ebt_do_table);
1546module_init(ebtables_init); 1492module_init(ebtables_init);
1547module_exit(ebtables_fini); 1493module_exit(ebtables_fini);