Эх сурвалжийг харах

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6

David S. Miller 16 жил өмнө
parent
commit
364ae953a4
100 өөрчлөгдсөн 2162 нэмэгдсэн , 1979 устгасан
  1. 3 0
      Documentation/feature-removal-schedule.txt
  2. 85 0
      Documentation/networking/tproxy.txt
  3. 28 69
      include/linux/netfilter.h
  4. 1 0
      include/linux/netfilter/Kbuild
  5. 1 1
      include/linux/netfilter/nf_conntrack_proto_gre.h
  6. 116 45
      include/linux/netfilter/x_tables.h
  7. 14 0
      include/linux/netfilter/xt_TPROXY.h
  8. 26 0
      include/linux/netfilter/xt_recent.h
  9. 42 34
      include/linux/netfilter_bridge/ebtables.h
  10. 11 17
      include/linux/netfilter_ipv4/ipt_recent.h
  11. 6 0
      include/net/net_namespace.h
  12. 6 0
      include/net/netfilter/ipv4/nf_defrag_ipv4.h
  13. 23 11
      include/net/netfilter/nf_conntrack.h
  14. 5 5
      include/net/netfilter/nf_conntrack_acct.h
  15. 5 6
      include/net/netfilter/nf_conntrack_core.h
  16. 17 9
      include/net/netfilter/nf_conntrack_ecache.h
  17. 15 7
      include/net/netfilter/nf_conntrack_expect.h
  18. 10 11
      include/net/netfilter/nf_conntrack_l4proto.h
  19. 4 4
      include/net/netfilter/nf_log.h
  20. 3 3
      include/net/netfilter/nf_queue.h
  21. 32 0
      include/net/netfilter/nf_tproxy_core.h
  22. 30 0
      include/net/netns/conntrack.h
  23. 3 0
      include/net/netns/ipv4.h
  24. 2 2
      net/bridge/br_netfilter.c
  25. 6 24
      net/bridge/netfilter/Kconfig
  26. 23 24
      net/bridge/netfilter/ebt_802_3.c
  27. 41 44
      net/bridge/netfilter/ebt_among.c
  28. 37 36
      net/bridge/netfilter/ebt_arp.c
  29. 24 25
      net/bridge/netfilter/ebt_arpreply.c
  30. 31 26
      net/bridge/netfilter/ebt_dnat.c
  31. 36 36
      net/bridge/netfilter/ebt_ip.c
  32. 37 39
      net/bridge/netfilter/ebt_ip6.c
  33. 21 24
      net/bridge/netfilter/ebt_limit.c
  34. 28 29
      net/bridge/netfilter/ebt_log.c
  35. 20 21
      net/bridge/netfilter/ebt_mark.c
  36. 22 23
      net/bridge/netfilter/ebt_mark_m.c
  37. 21 23
      net/bridge/netfilter/ebt_nflog.c
  38. 19 22
      net/bridge/netfilter/ebt_pkttype.c
  39. 34 29
      net/bridge/netfilter/ebt_redirect.c
  40. 24 28
      net/bridge/netfilter/ebt_snat.c
  41. 39 39
      net/bridge/netfilter/ebt_stp.c
  42. 31 27
      net/bridge/netfilter/ebt_ulog.c
  43. 26 35
      net/bridge/netfilter/ebt_vlan.c
  44. 134 179
      net/bridge/netfilter/ebtables.c
  45. 1 0
      net/core/net_namespace.c
  46. 4 3
      net/ipv4/netfilter.c
  47. 58 70
      net/ipv4/netfilter/Kconfig
  48. 3 1
      net/ipv4/netfilter/Makefile
  49. 62 54
      net/ipv4/netfilter/arp_tables.c
  50. 5 10
      net/ipv4/netfilter/arpt_mangle.c
  51. 4 4
      net/ipv4/netfilter/arptable_filter.c
  52. 88 89
      net/ipv4/netfilter/ip_tables.c
  53. 12 17
      net/ipv4/netfilter/ipt_CLUSTERIP.c
  54. 6 11
      net/ipv4/netfilter/ipt_ECN.c
  55. 8 13
      net/ipv4/netfilter/ipt_LOG.c
  56. 12 18
      net/ipv4/netfilter/ipt_MASQUERADE.c
  57. 11 15
      net/ipv4/netfilter/ipt_NETMAP.c
  58. 8 13
      net/ipv4/netfilter/ipt_REDIRECT.c
  59. 7 12
      net/ipv4/netfilter/ipt_REJECT.c
  60. 5 10
      net/ipv4/netfilter/ipt_TTL.c
  61. 8 15
      net/ipv4/netfilter/ipt_ULOG.c
  62. 14 21
      net/ipv4/netfilter/ipt_addrtype.c
  63. 8 16
      net/ipv4/netfilter/ipt_ah.c
  64. 7 13
      net/ipv4/netfilter/ipt_ecn.c
  65. 3 6
      net/ipv4/netfilter/ipt_ttl.c
  66. 3 3
      net/ipv4/netfilter/iptable_filter.c
  67. 5 5
      net/ipv4/netfilter/iptable_mangle.c
  68. 2 2
      net/ipv4/netfilter/iptable_raw.c
  69. 3 3
      net/ipv4/netfilter/iptable_security.c
  70. 9 59
      net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
  71. 49 24
      net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
  72. 11 11
      net/ipv4/netfilter/nf_conntrack_proto_icmp.c
  73. 96 0
      net/ipv4/netfilter/nf_defrag_ipv4.c
  74. 45 27
      net/ipv4/netfilter/nf_nat_core.c
  75. 1 1
      net/ipv4/netfilter/nf_nat_helper.c
  76. 2 1
      net/ipv4/netfilter/nf_nat_pptp.c
  77. 47 45
      net/ipv4/netfilter/nf_nat_rule.c
  78. 1 1
      net/ipv6/netfilter.c
  79. 34 43
      net/ipv6/netfilter/Kconfig
  80. 86 87
      net/ipv6/netfilter/ip6_tables.c
  81. 5 10
      net/ipv6/netfilter/ip6t_HL.c
  82. 9 13
      net/ipv6/netfilter/ip6t_LOG.c
  83. 18 21
      net/ipv6/netfilter/ip6t_REJECT.c
  84. 7 14
      net/ipv6/netfilter/ip6t_ah.c
  85. 4 7
      net/ipv6/netfilter/ip6t_eui64.c
  86. 7 14
      net/ipv6/netfilter/ip6t_frag.c
  87. 9 16
      net/ipv6/netfilter/ip6t_hbh.c
  88. 3 6
      net/ipv6/netfilter/ip6t_hl.c
  89. 5 11
      net/ipv6/netfilter/ip6t_ipv6header.c
  90. 9 16
      net/ipv6/netfilter/ip6t_mh.c
  91. 7 14
      net/ipv6/netfilter/ip6t_rt.c
  92. 3 3
      net/ipv6/netfilter/ip6table_filter.c
  93. 22 9
      net/ipv6/netfilter/ip6table_mangle.c
  94. 16 4
      net/ipv6/netfilter/ip6table_raw.c
  95. 3 3
      net/ipv6/netfilter/ip6table_security.c
  96. 16 8
      net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
  97. 10 9
      net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
  98. 128 108
      net/netfilter/Kconfig
  99. 6 0
      net/netfilter/Makefile
  100. 5 13
      net/netfilter/core.c

+ 3 - 0
Documentation/feature-removal-schedule.txt

@@ -250,6 +250,9 @@ What (Why):
 	- xt_mark match revision 0
 	- xt_mark match revision 0
 	  (superseded by xt_mark match revision 1)
 	  (superseded by xt_mark match revision 1)
 
 
+	- xt_recent: the old ipt_recent proc dir
+	  (superseded by /proc/net/xt_recent)
+
 When:	January 2009 or Linux 2.7.0, whichever comes first
 When:	January 2009 or Linux 2.7.0, whichever comes first
 Why:	Superseded by newer revisions or modules
 Why:	Superseded by newer revisions or modules
 Who:	Jan Engelhardt <jengelh@computergmbh.de>
 Who:	Jan Engelhardt <jengelh@computergmbh.de>

+ 85 - 0
Documentation/networking/tproxy.txt

@@ -0,0 +1,85 @@
+Transparent proxy support
+=========================
+
+This feature adds Linux 2.2-like transparent proxy support to current kernels.
+To use it, enable NETFILTER_TPROXY, the socket match and the TPROXY target in
+your kernel config. You will need policy routing too, so be sure to enable that
+as well.
+
+
+1. Making non-local sockets work
+================================
+
+The idea is that you identify packets with destination address matching a local
+socket on your box, set the packet mark to a certain value, and then match on that
+value using policy routing to have those packets delivered locally:
+
+# iptables -t mangle -N DIVERT
+# iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
+# iptables -t mangle -A DIVERT -j MARK --set-mark 1
+# iptables -t mangle -A DIVERT -j ACCEPT
+
+# ip rule add fwmark 1 lookup 100
+# ip route add local 0.0.0.0/0 dev lo table 100
+
+Because of certain restrictions in the IPv4 routing output code you'll have to
+modify your application to allow it to send datagrams _from_ non-local IP
+addresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket
+option before calling bind:
+
+fd = socket(AF_INET, SOCK_STREAM, 0);
+/* - 8< -*/
+int value = 1;
+setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
+/* - 8< -*/
+name.sin_family = AF_INET;
+name.sin_port = htons(0xCAFE);
+name.sin_addr.s_addr = htonl(0xDEADBEEF);
+bind(fd, &name, sizeof(name));
+
+A trivial patch for netcat is available here:
+http://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
+
+
+2. Redirecting traffic
+======================
+
+Transparent proxying often involves "intercepting" traffic on a router. This is
+usually done with the iptables REDIRECT target; however, there are serious
+limitations of that method. One of the major issues is that it actually
+modifies the packets to change the destination address -- which might not be
+acceptable in certain situations. (Think of proxying UDP for example: you won't
+be able to find out the original destination address. Even in case of TCP
+getting the original destination address is racy.)
+
+The 'TPROXY' target provides similar functionality without relying on NAT. Simply
+add rules like this to the iptables ruleset above:
+
+# iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
+  --tproxy-mark 0x1/0x1 --on-port 50080
+
+Note that for this to work you'll have to modify the proxy to enable (SOL_IP,
+IP_TRANSPARENT) for the listening socket.
+
+
+3. Iptables extensions
+======================
+
+To use tproxy you'll need to have the 'socket' and 'TPROXY' modules
+compiled for iptables. A patched version of iptables is available
+here: http://git.balabit.hu/?p=bazsi/iptables-tproxy.git
+
+
+4. Application support
+======================
+
+4.1. Squid
+----------
+
+Squid 3.HEAD has support built-in. To use it, pass
+'--enable-linux-netfilter' to configure and set the 'tproxy' option on
+the HTTP listener you redirect traffic to with the TPROXY iptables
+target.
+
+For more information please consult the following page on the Squid
+wiki: http://wiki.squid-cache.org/Features/Tproxy4

+ 28 - 69
include/linux/netfilter.h

@@ -5,13 +5,11 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/skbuff.h>
 #include <linux/net.h>
 #include <linux/net.h>
-#include <linux/netdevice.h>
 #include <linux/if.h>
 #include <linux/if.h>
 #include <linux/in.h>
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/in6.h>
 #include <linux/wait.h>
 #include <linux/wait.h>
 #include <linux/list.h>
 #include <linux/list.h>
-#include <net/net_namespace.h>
 #endif
 #endif
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <linux/compiler.h>
@@ -52,6 +50,16 @@ enum nf_inet_hooks {
 	NF_INET_NUMHOOKS
 	NF_INET_NUMHOOKS
 };
 };
 
 
+enum {
+	NFPROTO_UNSPEC =  0,
+	NFPROTO_IPV4   =  2,
+	NFPROTO_ARP    =  3,
+	NFPROTO_BRIDGE =  7,
+	NFPROTO_IPV6   = 10,
+	NFPROTO_DECNET = 12,
+	NFPROTO_NUMPROTO,
+};
+
 union nf_inet_addr {
 union nf_inet_addr {
 	__u32		all[4];
 	__u32		all[4];
 	__be32		ip;
 	__be32		ip;
@@ -92,8 +100,8 @@ struct nf_hook_ops
 	/* User fills in from here down. */
 	/* User fills in from here down. */
 	nf_hookfn *hook;
 	nf_hookfn *hook;
 	struct module *owner;
 	struct module *owner;
-	int pf;
-	int hooknum;
+	u_int8_t pf;
+	unsigned int hooknum;
 	/* Hooks are ordered in ascending priority. */
 	/* Hooks are ordered in ascending priority. */
 	int priority;
 	int priority;
 };
 };
@@ -102,7 +110,7 @@ struct nf_sockopt_ops
 {
 {
 	struct list_head list;
 	struct list_head list;
 
 
-	int pf;
+	u_int8_t pf;
 
 
 	/* Non-inclusive ranges: use 0/0/NULL to never get called. */
 	/* Non-inclusive ranges: use 0/0/NULL to never get called. */
 	int set_optmin;
 	int set_optmin;
@@ -138,9 +146,9 @@ extern struct ctl_path nf_net_netfilter_sysctl_path[];
 extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[];
 extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[];
 #endif /* CONFIG_SYSCTL */
 #endif /* CONFIG_SYSCTL */
 
 
-extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
+extern struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
 
 
-int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
+int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
 		 struct net_device *indev, struct net_device *outdev,
 		 struct net_device *indev, struct net_device *outdev,
 		 int (*okfn)(struct sk_buff *), int thresh);
 		 int (*okfn)(struct sk_buff *), int thresh);
 
 
@@ -151,7 +159,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
  *	okfn must be invoked by the caller in this case.  Any other return
  *	okfn must be invoked by the caller in this case.  Any other return
  *	value indicates the packet has been consumed by the hook.
  *	value indicates the packet has been consumed by the hook.
  */
  */
-static inline int nf_hook_thresh(int pf, unsigned int hook,
+static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
 				 struct sk_buff *skb,
 				 struct sk_buff *skb,
 				 struct net_device *indev,
 				 struct net_device *indev,
 				 struct net_device *outdev,
 				 struct net_device *outdev,
@@ -167,7 +175,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook,
 	return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh);
 	return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh);
 }
 }
 
 
-static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
+static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
 			  struct net_device *indev, struct net_device *outdev,
 			  struct net_device *indev, struct net_device *outdev,
 			  int (*okfn)(struct sk_buff *))
 			  int (*okfn)(struct sk_buff *))
 {
 {
@@ -212,14 +220,14 @@ __ret;})
 	NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
 	NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
 
 
 /* Call setsockopt() */
 /* Call setsockopt() */
-int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt, 
+int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
 		  int len);
 		  int len);
-int nf_getsockopt(struct sock *sk, int pf, int optval, char __user *opt,
+int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
 		  int *len);
 		  int *len);
 
 
-int compat_nf_setsockopt(struct sock *sk, int pf, int optval,
+int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval,
 		char __user *opt, int len);
 		char __user *opt, int len);
-int compat_nf_getsockopt(struct sock *sk, int pf, int optval,
+int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval,
 		char __user *opt, int *len);
 		char __user *opt, int *len);
 
 
 /* Call this before modifying an existing packet: ensures it is
 /* Call this before modifying an existing packet: ensures it is
@@ -247,7 +255,7 @@ struct nf_afinfo {
 	int		route_key_size;
 	int		route_key_size;
 };
 };
 
 
-extern const struct nf_afinfo *nf_afinfo[NPROTO];
+extern const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO];
 static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family)
 static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family)
 {
 {
 	return rcu_dereference(nf_afinfo[family]);
 	return rcu_dereference(nf_afinfo[family]);
@@ -292,7 +300,7 @@ extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo);
 extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
 extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
 
 
 static inline void
 static inline void
-nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
+nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
 {
 {
 #ifdef CONFIG_NF_NAT_NEEDED
 #ifdef CONFIG_NF_NAT_NEEDED
 	void (*decodefn)(struct sk_buff *, struct flowi *);
 	void (*decodefn)(struct sk_buff *, struct flowi *);
@@ -315,7 +323,7 @@ extern struct proc_dir_entry *proc_net_netfilter;
 #else /* !CONFIG_NETFILTER */
 #else /* !CONFIG_NETFILTER */
 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
 #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
 #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
-static inline int nf_hook_thresh(int pf, unsigned int hook,
+static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
 				 struct sk_buff *skb,
 				 struct sk_buff *skb,
 				 struct net_device *indev,
 				 struct net_device *indev,
 				 struct net_device *outdev,
 				 struct net_device *outdev,
@@ -324,7 +332,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook,
 {
 {
 	return okfn(skb);
 	return okfn(skb);
 }
 }
-static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
+static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
 			  struct net_device *indev, struct net_device *outdev,
 			  struct net_device *indev, struct net_device *outdev,
 			  int (*okfn)(struct sk_buff *))
 			  int (*okfn)(struct sk_buff *))
 {
 {
@@ -332,7 +340,9 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
 }
 }
 struct flowi;
 struct flowi;
 static inline void
 static inline void
-nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) {}
+nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
+{
+}
 #endif /*CONFIG_NETFILTER*/
 #endif /*CONFIG_NETFILTER*/
 
 
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@@ -343,56 +353,5 @@ extern void (*nf_ct_destroy)(struct nf_conntrack *);
 static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
 static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
 #endif
 #endif
 
 
-static inline struct net *nf_pre_routing_net(const struct net_device *in,
-					     const struct net_device *out)
-{
-#ifdef CONFIG_NET_NS
-	return in->nd_net;
-#else
-	return &init_net;
-#endif
-}
-
-static inline struct net *nf_local_in_net(const struct net_device *in,
-					  const struct net_device *out)
-{
-#ifdef CONFIG_NET_NS
-	return in->nd_net;
-#else
-	return &init_net;
-#endif
-}
-
-static inline struct net *nf_forward_net(const struct net_device *in,
-					 const struct net_device *out)
-{
-#ifdef CONFIG_NET_NS
-	BUG_ON(in->nd_net != out->nd_net);
-	return in->nd_net;
-#else
-	return &init_net;
-#endif
-}
-
-static inline struct net *nf_local_out_net(const struct net_device *in,
-					   const struct net_device *out)
-{
-#ifdef CONFIG_NET_NS
-	return out->nd_net;
-#else
-	return &init_net;
-#endif
-}
-
-static inline struct net *nf_post_routing_net(const struct net_device *in,
-					      const struct net_device *out)
-{
-#ifdef CONFIG_NET_NS
-	return out->nd_net;
-#else
-	return &init_net;
-#endif
-}
-
 #endif /*__KERNEL__*/
 #endif /*__KERNEL__*/
 #endif /*__LINUX_NETFILTER_H*/
 #endif /*__LINUX_NETFILTER_H*/

+ 1 - 0
include/linux/netfilter/Kbuild

@@ -32,6 +32,7 @@ header-y += xt_owner.h
 header-y += xt_pkttype.h
 header-y += xt_pkttype.h
 header-y += xt_rateest.h
 header-y += xt_rateest.h
 header-y += xt_realm.h
 header-y += xt_realm.h
+header-y += xt_recent.h
 header-y += xt_sctp.h
 header-y += xt_sctp.h
 header-y += xt_state.h
 header-y += xt_state.h
 header-y += xt_statistic.h
 header-y += xt_statistic.h

+ 1 - 1
include/linux/netfilter/nf_conntrack_proto_gre.h

@@ -87,7 +87,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
 /* delete keymap entries */
 /* delete keymap entries */
 void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
 void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
 
 
-extern void nf_ct_gre_keymap_flush(void);
+extern void nf_ct_gre_keymap_flush(struct net *net);
 extern void nf_nat_need_gre(void);
 extern void nf_nat_need_gre(void);
 
 
 #endif /* __KERNEL__ */
 #endif /* __KERNEL__ */

+ 116 - 45
include/linux/netfilter/x_tables.h

@@ -173,6 +173,98 @@ struct xt_counters_info
 
 
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>
 
 
+/**
+ * struct xt_match_param - parameters for match extensions' match functions
+ *
+ * @in:		input netdevice
+ * @out:	output netdevice
+ * @match:	struct xt_match through which this function was invoked
+ * @matchinfo:	per-match data
+ * @fragoff:	packet is a fragment, this is the data offset
+ * @thoff:	position of transport header relative to skb->data
+ * @hotdrop:	drop packet if we had inspection problems
+ * @family:	Actual NFPROTO_* through which the function is invoked
+ * 		(helpful when match->family == NFPROTO_UNSPEC)
+ */
+struct xt_match_param {
+	const struct net_device *in, *out;
+	const struct xt_match *match;
+	const void *matchinfo;
+	int fragoff;
+	unsigned int thoff;
+	bool *hotdrop;
+	u_int8_t family;
+};
+
+/**
+ * struct xt_mtchk_param - parameters for match extensions'
+ * checkentry functions
+ *
+ * @table:	table the rule is tried to be inserted into
+ * @entryinfo:	the family-specific rule data
+ * 		(struct ipt_ip, ip6t_ip, ebt_entry)
+ * @match:	struct xt_match through which this function was invoked
+ * @matchinfo:	per-match data
+ * @hook_mask:	via which hooks the new rule is reachable
+ */
+struct xt_mtchk_param {
+	const char *table;
+	const void *entryinfo;
+	const struct xt_match *match;
+	void *matchinfo;
+	unsigned int hook_mask;
+	u_int8_t family;
+};
+
+/* Match destructor parameters */
+struct xt_mtdtor_param {
+	const struct xt_match *match;
+	void *matchinfo;
+	u_int8_t family;
+};
+
+/**
+ * struct xt_target_param - parameters for target extensions' target functions
+ *
+ * @hooknum:	hook through which this target was invoked
+ * @target:	struct xt_target through which this function was invoked
+ * @targinfo:	per-target data
+ *
+ * Other fields see above.
+ */
+struct xt_target_param {
+	const struct net_device *in, *out;
+	unsigned int hooknum;
+	const struct xt_target *target;
+	const void *targinfo;
+	u_int8_t family;
+};
+
+/**
+ * struct xt_tgchk_param - parameters for target extensions'
+ * checkentry functions
+ *
+ * @entryinfo:	the family-specific rule data
+ * 		(struct ipt_entry, ip6t_entry, arpt_entry, ebt_entry)
+ *
+ * Other fields see above.
+ */
+struct xt_tgchk_param {
+	const char *table;
+	void *entryinfo;
+	const struct xt_target *target;
+	void *targinfo;
+	unsigned int hook_mask;
+	u_int8_t family;
+};
+
+/* Target destructor parameters */
+struct xt_tgdtor_param {
+	const struct xt_target *target;
+	void *targinfo;
+	u_int8_t family;
+};
+
 struct xt_match
 struct xt_match
 {
 {
 	struct list_head list;
 	struct list_head list;
@@ -185,24 +277,13 @@ struct xt_match
 	   non-linear skb, using skb_header_pointer and
 	   non-linear skb, using skb_header_pointer and
 	   skb_ip_make_writable. */
 	   skb_ip_make_writable. */
 	bool (*match)(const struct sk_buff *skb,
 	bool (*match)(const struct sk_buff *skb,
-		      const struct net_device *in,
-		      const struct net_device *out,
-		      const struct xt_match *match,
-		      const void *matchinfo,
-		      int offset,
-		      unsigned int protoff,
-		      bool *hotdrop);
+		      const struct xt_match_param *);
 
 
 	/* Called when user tries to insert an entry of this type. */
 	/* Called when user tries to insert an entry of this type. */
-	/* Should return true or false. */
-	bool (*checkentry)(const char *tablename,
-			   const void *ip,
-			   const struct xt_match *match,
-			   void *matchinfo,
-			   unsigned int hook_mask);
+	bool (*checkentry)(const struct xt_mtchk_param *);
 
 
 	/* Called when entry of this type deleted. */
 	/* Called when entry of this type deleted. */
-	void (*destroy)(const struct xt_match *match, void *matchinfo);
+	void (*destroy)(const struct xt_mtdtor_param *);
 
 
 	/* Called when userspace align differs from kernel space one */
 	/* Called when userspace align differs from kernel space one */
 	void (*compat_from_user)(void *dst, void *src);
 	void (*compat_from_user)(void *dst, void *src);
@@ -235,24 +316,16 @@ struct xt_target
 	   must now handle non-linear skbs, using skb_copy_bits and
 	   must now handle non-linear skbs, using skb_copy_bits and
 	   skb_ip_make_writable. */
 	   skb_ip_make_writable. */
 	unsigned int (*target)(struct sk_buff *skb,
 	unsigned int (*target)(struct sk_buff *skb,
-			       const struct net_device *in,
-			       const struct net_device *out,
-			       unsigned int hooknum,
-			       const struct xt_target *target,
-			       const void *targinfo);
+			       const struct xt_target_param *);
 
 
 	/* Called when user tries to insert an entry of this type:
 	/* Called when user tries to insert an entry of this type:
            hook_mask is a bitmask of hooks from which it can be
            hook_mask is a bitmask of hooks from which it can be
            called. */
            called. */
 	/* Should return true or false. */
 	/* Should return true or false. */
-	bool (*checkentry)(const char *tablename,
-			   const void *entry,
-			   const struct xt_target *target,
-			   void *targinfo,
-			   unsigned int hook_mask);
+	bool (*checkentry)(const struct xt_tgchk_param *);
 
 
 	/* Called when entry of this type deleted. */
 	/* Called when entry of this type deleted. */
-	void (*destroy)(const struct xt_target *target, void *targinfo);
+	void (*destroy)(const struct xt_tgdtor_param *);
 
 
 	/* Called when userspace align differs from kernel space one */
 	/* Called when userspace align differs from kernel space one */
 	void (*compat_from_user)(void *dst, void *src);
 	void (*compat_from_user)(void *dst, void *src);
@@ -292,7 +365,7 @@ struct xt_table
 	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
 	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
 	struct module *me;
 	struct module *me;
 
 
-	int af;		/* address/protocol family */
+	u_int8_t af;		/* address/protocol family */
 };
 };
 
 
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv4.h>
@@ -328,12 +401,10 @@ extern void xt_unregister_match(struct xt_match *target);
 extern int xt_register_matches(struct xt_match *match, unsigned int n);
 extern int xt_register_matches(struct xt_match *match, unsigned int n);
 extern void xt_unregister_matches(struct xt_match *match, unsigned int n);
 extern void xt_unregister_matches(struct xt_match *match, unsigned int n);
 
 
-extern int xt_check_match(const struct xt_match *match, unsigned short family,
-			  unsigned int size, const char *table, unsigned int hook,
-			  unsigned short proto, int inv_proto);
-extern int xt_check_target(const struct xt_target *target, unsigned short family,
-			   unsigned int size, const char *table, unsigned int hook,
-			   unsigned short proto, int inv_proto);
+extern int xt_check_match(struct xt_mtchk_param *,
+			  unsigned int size, u_int8_t proto, bool inv_proto);
+extern int xt_check_target(struct xt_tgchk_param *,
+			   unsigned int size, u_int8_t proto, bool inv_proto);
 
 
 extern struct xt_table *xt_register_table(struct net *net,
 extern struct xt_table *xt_register_table(struct net *net,
 					  struct xt_table *table,
 					  struct xt_table *table,
@@ -346,19 +417,19 @@ extern struct xt_table_info *xt_replace_table(struct xt_table *table,
 					      struct xt_table_info *newinfo,
 					      struct xt_table_info *newinfo,
 					      int *error);
 					      int *error);
 
 
-extern struct xt_match *xt_find_match(int af, const char *name, u8 revision);
-extern struct xt_target *xt_find_target(int af, const char *name, u8 revision);
-extern struct xt_target *xt_request_find_target(int af, const char *name, 
+extern struct xt_match *xt_find_match(u8 af, const char *name, u8 revision);
+extern struct xt_target *xt_find_target(u8 af, const char *name, u8 revision);
+extern struct xt_target *xt_request_find_target(u8 af, const char *name,
 						u8 revision);
 						u8 revision);
-extern int xt_find_revision(int af, const char *name, u8 revision, int target,
-			    int *err);
+extern int xt_find_revision(u8 af, const char *name, u8 revision,
+			    int target, int *err);
 
 
-extern struct xt_table *xt_find_table_lock(struct net *net, int af,
+extern struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
 					   const char *name);
 					   const char *name);
 extern void xt_table_unlock(struct xt_table *t);
 extern void xt_table_unlock(struct xt_table *t);
 
 
-extern int xt_proto_init(struct net *net, int af);
-extern void xt_proto_fini(struct net *net, int af);
+extern int xt_proto_init(struct net *net, u_int8_t af);
+extern void xt_proto_fini(struct net *net, u_int8_t af);
 
 
 extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
 extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
 extern void xt_free_table_info(struct xt_table_info *info);
 extern void xt_free_table_info(struct xt_table_info *info);
@@ -423,12 +494,12 @@ struct compat_xt_counters_info
 #define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \
 #define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \
 		& ~(__alignof__(struct compat_xt_counters)-1))
 		& ~(__alignof__(struct compat_xt_counters)-1))
 
 
-extern void xt_compat_lock(int af);
-extern void xt_compat_unlock(int af);
+extern void xt_compat_lock(u_int8_t af);
+extern void xt_compat_unlock(u_int8_t af);
 
 
-extern int xt_compat_add_offset(int af, unsigned int offset, short delta);
-extern void xt_compat_flush_offsets(int af);
-extern short xt_compat_calc_jump(int af, unsigned int offset);
+extern int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta);
+extern void xt_compat_flush_offsets(u_int8_t af);
+extern short xt_compat_calc_jump(u_int8_t af, unsigned int offset);
 
 
 extern int xt_compat_match_offset(const struct xt_match *match);
 extern int xt_compat_match_offset(const struct xt_match *match);
 extern int xt_compat_match_from_user(struct xt_entry_match *m,
 extern int xt_compat_match_from_user(struct xt_entry_match *m,

+ 14 - 0
include/linux/netfilter/xt_TPROXY.h

@@ -0,0 +1,14 @@
+#ifndef _XT_TPROXY_H_target
+#define _XT_TPROXY_H_target
+
+/* TPROXY target is capable of marking the packet to perform
+ * redirection. We can get rid of that whenever we get support for
+ * mutliple targets in the same rule. */
+struct xt_tproxy_target_info {
+	u_int32_t mark_mask;
+	u_int32_t mark_value;
+	__be32 laddr;
+	__be16 lport;
+};
+
+#endif /* _XT_TPROXY_H_target */

+ 26 - 0
include/linux/netfilter/xt_recent.h

@@ -0,0 +1,26 @@
+#ifndef _LINUX_NETFILTER_XT_RECENT_H
+#define _LINUX_NETFILTER_XT_RECENT_H 1
+
+enum {
+	XT_RECENT_CHECK    = 1 << 0,
+	XT_RECENT_SET      = 1 << 1,
+	XT_RECENT_UPDATE   = 1 << 2,
+	XT_RECENT_REMOVE   = 1 << 3,
+	XT_RECENT_TTL      = 1 << 4,
+
+	XT_RECENT_SOURCE   = 0,
+	XT_RECENT_DEST     = 1,
+
+	XT_RECENT_NAME_LEN = 200,
+};
+
+struct xt_recent_mtinfo {
+	u_int32_t seconds;
+	u_int32_t hit_count;
+	u_int8_t check_set;
+	u_int8_t invert;
+	char name[XT_RECENT_NAME_LEN];
+	u_int8_t side;
+};
+
+#endif /* _LINUX_NETFILTER_XT_RECENT_H */

+ 42 - 34
include/linux/netfilter_bridge/ebtables.h

@@ -31,6 +31,9 @@
  * The 4 lsb are more than enough to store the verdict. */
  * The 4 lsb are more than enough to store the verdict. */
 #define EBT_VERDICT_BITS 0x0000000F
 #define EBT_VERDICT_BITS 0x0000000F
 
 
+struct xt_match;
+struct xt_target;
+
 struct ebt_counter
 struct ebt_counter
 {
 {
 	uint64_t pcnt;
 	uint64_t pcnt;
@@ -121,7 +124,7 @@ struct ebt_entry_match
 {
 {
 	union {
 	union {
 		char name[EBT_FUNCTION_MAXNAMELEN];
 		char name[EBT_FUNCTION_MAXNAMELEN];
-		struct ebt_match *match;
+		struct xt_match *match;
 	} u;
 	} u;
 	/* size of data */
 	/* size of data */
 	unsigned int match_size;
 	unsigned int match_size;
@@ -132,7 +135,7 @@ struct ebt_entry_watcher
 {
 {
 	union {
 	union {
 		char name[EBT_FUNCTION_MAXNAMELEN];
 		char name[EBT_FUNCTION_MAXNAMELEN];
-		struct ebt_watcher *watcher;
+		struct xt_target *watcher;
 	} u;
 	} u;
 	/* size of data */
 	/* size of data */
 	unsigned int watcher_size;
 	unsigned int watcher_size;
@@ -143,7 +146,7 @@ struct ebt_entry_target
 {
 {
 	union {
 	union {
 		char name[EBT_FUNCTION_MAXNAMELEN];
 		char name[EBT_FUNCTION_MAXNAMELEN];
-		struct ebt_target *target;
+		struct xt_target *target;
 	} u;
 	} u;
 	/* size of data */
 	/* size of data */
 	unsigned int target_size;
 	unsigned int target_size;
@@ -207,14 +210,17 @@ struct ebt_match
 {
 {
 	struct list_head list;
 	struct list_head list;
 	const char name[EBT_FUNCTION_MAXNAMELEN];
 	const char name[EBT_FUNCTION_MAXNAMELEN];
-	/* 0 == it matches */
-	int (*match)(const struct sk_buff *skb, const struct net_device *in,
-	   const struct net_device *out, const void *matchdata,
-	   unsigned int datalen);
-	/* 0 == let it in */
-	int (*check)(const char *tablename, unsigned int hookmask,
-	   const struct ebt_entry *e, void *matchdata, unsigned int datalen);
-	void (*destroy)(void *matchdata, unsigned int datalen);
+	bool (*match)(const struct sk_buff *skb, const struct net_device *in,
+		const struct net_device *out, const struct xt_match *match,
+		const void *matchinfo, int offset, unsigned int protoff,
+		bool *hotdrop);
+	bool (*checkentry)(const char *table, const void *entry,
+		const struct xt_match *match, void *matchinfo,
+		unsigned int hook_mask);
+	void (*destroy)(const struct xt_match *match, void *matchinfo);
+	unsigned int matchsize;
+	u_int8_t revision;
+	u_int8_t family;
 	struct module *me;
 	struct module *me;
 };
 };
 
 
@@ -222,13 +228,17 @@ struct ebt_watcher
 {
 {
 	struct list_head list;
 	struct list_head list;
 	const char name[EBT_FUNCTION_MAXNAMELEN];
 	const char name[EBT_FUNCTION_MAXNAMELEN];
-	void (*watcher)(const struct sk_buff *skb, unsigned int hooknr,
-	   const struct net_device *in, const struct net_device *out,
-	   const void *watcherdata, unsigned int datalen);
-	/* 0 == let it in */
-	int (*check)(const char *tablename, unsigned int hookmask,
-	   const struct ebt_entry *e, void *watcherdata, unsigned int datalen);
-	void (*destroy)(void *watcherdata, unsigned int datalen);
+	unsigned int (*target)(struct sk_buff *skb,
+		const struct net_device *in, const struct net_device *out,
+		unsigned int hook_num, const struct xt_target *target,
+		const void *targinfo);
+	bool (*checkentry)(const char *table, const void *entry,
+		const struct xt_target *target, void *targinfo,
+		unsigned int hook_mask);
+	void (*destroy)(const struct xt_target *target, void *targinfo);
+	unsigned int targetsize;
+	u_int8_t revision;
+	u_int8_t family;
 	struct module *me;
 	struct module *me;
 };
 };
 
 
@@ -236,14 +246,18 @@ struct ebt_target
 {
 {
 	struct list_head list;
 	struct list_head list;
 	const char name[EBT_FUNCTION_MAXNAMELEN];
 	const char name[EBT_FUNCTION_MAXNAMELEN];
-	/* returns one of the standard verdicts */
-	int (*target)(struct sk_buff *skb, unsigned int hooknr,
-	   const struct net_device *in, const struct net_device *out,
-	   const void *targetdata, unsigned int datalen);
-	/* 0 == let it in */
-	int (*check)(const char *tablename, unsigned int hookmask,
-	   const struct ebt_entry *e, void *targetdata, unsigned int datalen);
-	void (*destroy)(void *targetdata, unsigned int datalen);
+	/* returns one of the standard EBT_* verdicts */
+	unsigned int (*target)(struct sk_buff *skb,
+		const struct net_device *in, const struct net_device *out,
+		unsigned int hook_num, const struct xt_target *target,
+		const void *targinfo);
+	bool (*checkentry)(const char *table, const void *entry,
+		const struct xt_target *target, void *targinfo,
+		unsigned int hook_mask);
+	void (*destroy)(const struct xt_target *target, void *targinfo);
+	unsigned int targetsize;
+	u_int8_t revision;
+	u_int8_t family;
 	struct module *me;
 	struct module *me;
 };
 };
 
 
@@ -288,12 +302,6 @@ struct ebt_table
 		     ~(__alignof__(struct ebt_replace)-1))
 		     ~(__alignof__(struct ebt_replace)-1))
 extern int ebt_register_table(struct ebt_table *table);
 extern int ebt_register_table(struct ebt_table *table);
 extern void ebt_unregister_table(struct ebt_table *table);
 extern void ebt_unregister_table(struct ebt_table *table);
-extern int ebt_register_match(struct ebt_match *match);
-extern void ebt_unregister_match(struct ebt_match *match);
-extern int ebt_register_watcher(struct ebt_watcher *watcher);
-extern void ebt_unregister_watcher(struct ebt_watcher *watcher);
-extern int ebt_register_target(struct ebt_target *target);
-extern void ebt_unregister_target(struct ebt_target *target);
 extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
 extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
    const struct net_device *in, const struct net_device *out,
    struct ebt_table *table);
    struct ebt_table *table);
@@ -302,9 +310,9 @@ extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
 #define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
 #define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
 /* True if the hook mask denotes that the rule is in a base chain,
 /* True if the hook mask denotes that the rule is in a base chain,
  * used in the check() functions */
  * used in the check() functions */
-#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS))
+#define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS))
 /* Clear the bit in the hook mask that tells if the rule is on a base chain */
 /* Clear the bit in the hook mask that tells if the rule is on a base chain */
-#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS))
+#define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS))
 /* True if the target is not a standard target */
 /* True if the target is not a standard target */
 #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
 #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
 
 

+ 11 - 17
include/linux/netfilter_ipv4/ipt_recent.h

@@ -1,27 +1,21 @@
 #ifndef _IPT_RECENT_H
 #ifndef _IPT_RECENT_H
 #define _IPT_RECENT_H
 #define _IPT_RECENT_H
 
 
-#define RECENT_NAME	"ipt_recent"
-#define RECENT_VER	"v0.3.1"
+#include <linux/netfilter/xt_recent.h>
 
 
-#define IPT_RECENT_CHECK  1
-#define IPT_RECENT_SET    2
-#define IPT_RECENT_UPDATE 4
-#define IPT_RECENT_REMOVE 8
-#define IPT_RECENT_TTL   16
+#define ipt_recent_info xt_recent_mtinfo
 
 
-#define IPT_RECENT_SOURCE 0
-#define IPT_RECENT_DEST   1
+enum {
+	IPT_RECENT_CHECK    = XT_RECENT_CHECK,
+	IPT_RECENT_SET      = XT_RECENT_SET,
+	IPT_RECENT_UPDATE   = XT_RECENT_UPDATE,
+	IPT_RECENT_REMOVE   = XT_RECENT_REMOVE,
+	IPT_RECENT_TTL      = XT_RECENT_TTL,
 
 
-#define IPT_RECENT_NAME_LEN 200
+	IPT_RECENT_SOURCE   = XT_RECENT_SOURCE,
+	IPT_RECENT_DEST     = XT_RECENT_DEST,
 
 
-struct ipt_recent_info {
-	u_int32_t   seconds;
-	u_int32_t   hit_count;
-	u_int8_t    check_set;
-	u_int8_t    invert;
-	char        name[IPT_RECENT_NAME_LEN];
-	u_int8_t    side;
+	IPT_RECENT_NAME_LEN = XT_RECENT_NAME_LEN,
 };
 };
 
 
 #endif /*_IPT_RECENT_H*/
 #endif /*_IPT_RECENT_H*/

+ 6 - 0
include/net/net_namespace.h

@@ -16,6 +16,9 @@
 #include <net/netns/ipv6.h>
 #include <net/netns/ipv6.h>
 #include <net/netns/dccp.h>
 #include <net/netns/dccp.h>
 #include <net/netns/x_tables.h>
 #include <net/netns/x_tables.h>
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#include <net/netns/conntrack.h>
+#endif
 
 
 struct proc_dir_entry;
 struct proc_dir_entry;
 struct net_device;
 struct net_device;
@@ -67,6 +70,9 @@ struct net {
 #endif
 #endif
 #ifdef CONFIG_NETFILTER
 #ifdef CONFIG_NETFILTER
 	struct netns_xt		xt;
 	struct netns_xt		xt;
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	struct netns_ct		ct;
+#endif
 #endif
 #endif
 	struct net_generic	*gen;
 	struct net_generic	*gen;
 };
 };

+ 6 - 0
include/net/netfilter/ipv4/nf_defrag_ipv4.h

@@ -0,0 +1,6 @@
+#ifndef _NF_DEFRAG_IPV4_H
+#define _NF_DEFRAG_IPV4_H
+
+extern void nf_defrag_ipv4_enable(void);
+
+#endif /* _NF_DEFRAG_IPV4_H */

+ 23 - 11
include/net/netfilter/nf_conntrack.h

@@ -123,7 +123,9 @@ struct nf_conn
 
 
 	/* Extensions */
 	/* Extensions */
 	struct nf_ct_ext *ext;
 	struct nf_ct_ext *ext;
-
+#ifdef CONFIG_NET_NS
+	struct net *ct_net;
+#endif
 	struct rcu_head rcu;
 	struct rcu_head rcu;
 };
 };
 
 
@@ -147,6 +149,17 @@ static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
 /* get master conntrack via master expectation */
 /* get master conntrack via master expectation */
 #define master_ct(conntr) (conntr->master)
 #define master_ct(conntr) (conntr->master)
 
 
+extern struct net init_net;
+
+static inline struct net *nf_ct_net(const struct nf_conn *ct)
+{
+#ifdef CONFIG_NET_NS
+	return ct->ct_net;
+#else
+	return &init_net;
+#endif
+}
+
 /* Alter reply tuple (maybe alter helper). */
 /* Alter reply tuple (maybe alter helper). */
 extern void
 extern void
 nf_conntrack_alter_reply(struct nf_conn *ct,
 nf_conntrack_alter_reply(struct nf_conn *ct,
@@ -182,11 +195,11 @@ extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
 				 unsigned int size);
 				 unsigned int size);
 
 
 extern struct nf_conntrack_tuple_hash *
 extern struct nf_conntrack_tuple_hash *
-__nf_conntrack_find(const struct nf_conntrack_tuple *tuple);
+__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple);
 
 
 extern void nf_conntrack_hash_insert(struct nf_conn *ct);
 extern void nf_conntrack_hash_insert(struct nf_conn *ct);
 
 
-extern void nf_conntrack_flush(void);
+extern void nf_conntrack_flush(struct net *net);
 
 
 extern bool nf_ct_get_tuplepr(const struct sk_buff *skb,
 extern bool nf_ct_get_tuplepr(const struct sk_buff *skb,
 			      unsigned int nhoff, u_int16_t l3num,
 			      unsigned int nhoff, u_int16_t l3num,
@@ -248,10 +261,11 @@ extern struct nf_conn nf_conntrack_untracked;
 
 
 /* Iterate over all conntracks: if iter returns true, it's deleted. */
 /* Iterate over all conntracks: if iter returns true, it's deleted. */
 extern void
 extern void
-nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
+nf_ct_iterate_cleanup(struct net *net, int (*iter)(struct nf_conn *i, void *data), void *data);
 extern void nf_conntrack_free(struct nf_conn *ct);
 extern void nf_conntrack_free(struct nf_conn *ct);
 extern struct nf_conn *
 extern struct nf_conn *
-nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
+nf_conntrack_alloc(struct net *net,
+		   const struct nf_conntrack_tuple *orig,
 		   const struct nf_conntrack_tuple *repl,
 		   const struct nf_conntrack_tuple *repl,
 		   gfp_t gfp);
 		   gfp_t gfp);
 
 
@@ -273,16 +287,14 @@ static inline int nf_ct_is_untracked(const struct sk_buff *skb)
 
 
 extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
 extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
 extern unsigned int nf_conntrack_htable_size;
 extern unsigned int nf_conntrack_htable_size;
-extern int nf_conntrack_checksum;
-extern atomic_t nf_conntrack_count;
 extern int nf_conntrack_max;
 extern int nf_conntrack_max;
 
 
-DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
-#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++)
-#define NF_CT_STAT_INC_ATOMIC(count)			\
+#define NF_CT_STAT_INC(net, count)	\
+	(per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++)
+#define NF_CT_STAT_INC_ATOMIC(net, count)		\
 do {							\
 do {							\
 	local_bh_disable();				\
 	local_bh_disable();				\
-	__get_cpu_var(nf_conntrack_stat).count++;	\
+	per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++;	\
 	local_bh_enable();				\
 	local_bh_enable();				\
 } while (0)
 } while (0)
 
 

+ 5 - 5
include/net/netfilter/nf_conntrack_acct.h

@@ -8,6 +8,7 @@
 
 
 #ifndef _NF_CONNTRACK_ACCT_H
 #ifndef _NF_CONNTRACK_ACCT_H
 #define _NF_CONNTRACK_ACCT_H
 #define _NF_CONNTRACK_ACCT_H
+#include <net/net_namespace.h>
 #include <linux/netfilter/nf_conntrack_common.h>
 #include <linux/netfilter/nf_conntrack_common.h>
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack.h>
@@ -18,8 +19,6 @@ struct nf_conn_counter {
 	u_int64_t bytes;
 	u_int64_t bytes;
 };
 };
 
 
-extern int nf_ct_acct;
-
 static inline
 static inline
 struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct)
 struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct)
 {
 {
@@ -29,9 +28,10 @@ struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct)
 static inline
 static inline
 struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
 struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
 {
 {
+	struct net *net = nf_ct_net(ct);
 	struct nf_conn_counter *acct;
 	struct nf_conn_counter *acct;
 
 
-	if (!nf_ct_acct)
+	if (!net->ct.sysctl_acct)
 		return NULL;
 		return NULL;
 
 
 	acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp);
 	acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp);
@@ -45,7 +45,7 @@ struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
 extern unsigned int
 extern unsigned int
 seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir);
 seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir);
 
 
-extern int nf_conntrack_acct_init(void);
-extern void nf_conntrack_acct_fini(void);
+extern int nf_conntrack_acct_init(struct net *net);
+extern void nf_conntrack_acct_fini(struct net *net);
 
 
 #endif /* _NF_CONNTRACK_ACCT_H */
 #endif /* _NF_CONNTRACK_ACCT_H */

+ 5 - 6
include/net/netfilter/nf_conntrack_core.h

@@ -20,12 +20,13 @@
 /* This header is used to share core functionality between the
 /* This header is used to share core functionality between the
    standalone connection tracking module, and the compatibility layer's use
    standalone connection tracking module, and the compatibility layer's use
    of connection tracking. */
    of connection tracking. */
-extern unsigned int nf_conntrack_in(int pf,
+extern unsigned int nf_conntrack_in(struct net *net,
+				    u_int8_t pf,
 				    unsigned int hooknum,
 				    unsigned int hooknum,
 				    struct sk_buff *skb);
 				    struct sk_buff *skb);
 
 
-extern int nf_conntrack_init(void);
-extern void nf_conntrack_cleanup(void);
+extern int nf_conntrack_init(struct net *net);
+extern void nf_conntrack_cleanup(struct net *net);
 
 
 extern int nf_conntrack_proto_init(void);
 extern int nf_conntrack_proto_init(void);
 extern void nf_conntrack_proto_fini(void);
 extern void nf_conntrack_proto_fini(void);
@@ -48,7 +49,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
 
 
 /* Find a connection corresponding to a tuple. */
 /* Find a connection corresponding to a tuple. */
 extern struct nf_conntrack_tuple_hash *
 extern struct nf_conntrack_tuple_hash *
-nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple);
+nf_conntrack_find_get(struct net *net, const struct nf_conntrack_tuple *tuple);
 
 
 extern int __nf_conntrack_confirm(struct sk_buff *skb);
 extern int __nf_conntrack_confirm(struct sk_buff *skb);
 
 
@@ -71,8 +72,6 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
             const struct nf_conntrack_l3proto *l3proto,
             const struct nf_conntrack_l3proto *l3proto,
             const struct nf_conntrack_l4proto *proto);
             const struct nf_conntrack_l4proto *proto);
 
 
-extern struct hlist_head *nf_conntrack_hash;
 extern spinlock_t nf_conntrack_lock ;
 extern spinlock_t nf_conntrack_lock ;
-extern struct hlist_head unconfirmed;
 
 
 #endif /* _NF_CONNTRACK_CORE_H */
 #endif /* _NF_CONNTRACK_CORE_H */

+ 17 - 9
include/net/netfilter/nf_conntrack_ecache.h

@@ -8,6 +8,7 @@
 
 
 #include <linux/notifier.h>
 #include <linux/notifier.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
+#include <net/net_namespace.h>
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <net/netfilter/nf_conntrack_expect.h>
 
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
@@ -15,9 +16,6 @@ struct nf_conntrack_ecache {
 	struct nf_conn *ct;
 	struct nf_conn *ct;
 	unsigned int events;
 	unsigned int events;
 };
 };
-DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
-
-#define CONNTRACK_ECACHE(x)	(__get_cpu_var(nf_conntrack_ecache).x)
 
 
 extern struct atomic_notifier_head nf_conntrack_chain;
 extern struct atomic_notifier_head nf_conntrack_chain;
 extern int nf_conntrack_register_notifier(struct notifier_block *nb);
 extern int nf_conntrack_register_notifier(struct notifier_block *nb);
@@ -25,17 +23,16 @@ extern int nf_conntrack_unregister_notifier(struct notifier_block *nb);
 
 
 extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
 extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
 extern void __nf_ct_event_cache_init(struct nf_conn *ct);
 extern void __nf_ct_event_cache_init(struct nf_conn *ct);
-extern void nf_ct_event_cache_flush(void);
+extern void nf_ct_event_cache_flush(struct net *net);
 
 
 static inline void
 static inline void
-nf_conntrack_event_cache(enum ip_conntrack_events event,
-			 const struct sk_buff *skb)
+nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
 {
 {
-	struct nf_conn *ct = (struct nf_conn *)skb->nfct;
+	struct net *net = nf_ct_net(ct);
 	struct nf_conntrack_ecache *ecache;
 	struct nf_conntrack_ecache *ecache;
 
 
 	local_bh_disable();
 	local_bh_disable();
-	ecache = &__get_cpu_var(nf_conntrack_ecache);
+	ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
 	if (ct != ecache->ct)
 	if (ct != ecache->ct)
 		__nf_ct_event_cache_init(ct);
 		__nf_ct_event_cache_init(ct);
 	ecache->events |= event;
 	ecache->events |= event;
@@ -60,6 +57,9 @@ nf_ct_expect_event(enum ip_conntrack_expect_events event,
 	atomic_notifier_call_chain(&nf_ct_expect_chain, event, exp);
 	atomic_notifier_call_chain(&nf_ct_expect_chain, event, exp);
 }
 }
 
 
+extern int nf_conntrack_ecache_init(struct net *net);
+extern void nf_conntrack_ecache_fini(struct net *net);
+
 #else /* CONFIG_NF_CONNTRACK_EVENTS */
 #else /* CONFIG_NF_CONNTRACK_EVENTS */
 
 
 static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
 static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
@@ -69,7 +69,15 @@ static inline void nf_conntrack_event(enum ip_conntrack_events event,
 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
 static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
 static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
 				      struct nf_conntrack_expect *exp) {}
 				      struct nf_conntrack_expect *exp) {}
-static inline void nf_ct_event_cache_flush(void) {}
+static inline void nf_ct_event_cache_flush(struct net *net) {}
+
+static inline int nf_conntrack_ecache_init(struct net *net)
+{
+	return 0;
+
+static inline void nf_conntrack_ecache_fini(struct net *net)
+{
+}
 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
 
 
 #endif /*_NF_CONNTRACK_ECACHE_H*/
 #endif /*_NF_CONNTRACK_ECACHE_H*/

+ 15 - 7
include/net/netfilter/nf_conntrack_expect.h

@@ -6,7 +6,6 @@
 #define _NF_CONNTRACK_EXPECT_H
 #define _NF_CONNTRACK_EXPECT_H
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack.h>
 
 
-extern struct hlist_head *nf_ct_expect_hash;
 extern unsigned int nf_ct_expect_hsize;
 extern unsigned int nf_ct_expect_hsize;
 extern unsigned int nf_ct_expect_max;
 extern unsigned int nf_ct_expect_max;
 
 
@@ -56,6 +55,15 @@ struct nf_conntrack_expect
 	struct rcu_head rcu;
 	struct rcu_head rcu;
 };
 };
 
 
+static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp)
+{
+#ifdef CONFIG_NET_NS
+	return exp->master->ct_net;	/* by definition */
+#else
+	return &init_net;
+#endif
+}
+
 struct nf_conntrack_expect_policy
 struct nf_conntrack_expect_policy
 {
 {
 	unsigned int	max_expected;
 	unsigned int	max_expected;
@@ -67,17 +75,17 @@ struct nf_conntrack_expect_policy
 #define NF_CT_EXPECT_PERMANENT	0x1
 #define NF_CT_EXPECT_PERMANENT	0x1
 #define NF_CT_EXPECT_INACTIVE	0x2
 #define NF_CT_EXPECT_INACTIVE	0x2
 
 
-int nf_conntrack_expect_init(void);
-void nf_conntrack_expect_fini(void);
+int nf_conntrack_expect_init(struct net *net);
+void nf_conntrack_expect_fini(struct net *net);
 
 
 struct nf_conntrack_expect *
 struct nf_conntrack_expect *
-__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple);
+__nf_ct_expect_find(struct net *net, const struct nf_conntrack_tuple *tuple);
 
 
 struct nf_conntrack_expect *
 struct nf_conntrack_expect *
-nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple);
+nf_ct_expect_find_get(struct net *net, const struct nf_conntrack_tuple *tuple);
 
 
 struct nf_conntrack_expect *
 struct nf_conntrack_expect *
-nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple);
+nf_ct_find_expectation(struct net *net, const struct nf_conntrack_tuple *tuple);
 
 
 void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
 void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
 void nf_ct_remove_expectations(struct nf_conn *ct);
 void nf_ct_remove_expectations(struct nf_conn *ct);
@@ -86,7 +94,7 @@ void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
 /* Allocate space for an expectation: this is mandatory before calling
 /* Allocate space for an expectation: this is mandatory before calling
    nf_ct_expect_related.  You will have to call put afterwards. */
    nf_ct_expect_related.  You will have to call put afterwards. */
 struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me);
 struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me);
-void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, int,
+void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t,
 		       const union nf_inet_addr *,
 		       const union nf_inet_addr *,
 		       const union nf_inet_addr *,
 		       const union nf_inet_addr *,
 		       u_int8_t, const __be16 *, const __be16 *);
 		       u_int8_t, const __be16 *, const __be16 *);

+ 10 - 11
include/net/netfilter/nf_conntrack_l4proto.h

@@ -39,7 +39,7 @@ struct nf_conntrack_l4proto
 		      const struct sk_buff *skb,
 		      const struct sk_buff *skb,
 		      unsigned int dataoff,
 		      unsigned int dataoff,
 		      enum ip_conntrack_info ctinfo,
 		      enum ip_conntrack_info ctinfo,
-		      int pf,
+		      u_int8_t pf,
 		      unsigned int hooknum);
 		      unsigned int hooknum);
 
 
 	/* Called when a new connection for this protocol found;
 	/* Called when a new connection for this protocol found;
@@ -50,9 +50,9 @@ struct nf_conntrack_l4proto
 	/* Called when a conntrack entry is destroyed */
 	/* Called when a conntrack entry is destroyed */
 	void (*destroy)(struct nf_conn *ct);
 	void (*destroy)(struct nf_conn *ct);
 
 
-	int (*error)(struct sk_buff *skb, unsigned int dataoff,
+	int (*error)(struct net *net, struct sk_buff *skb, unsigned int dataoff,
 		     enum ip_conntrack_info *ctinfo,
 		     enum ip_conntrack_info *ctinfo,
-		     int pf, unsigned int hooknum);
+		     u_int8_t pf, unsigned int hooknum);
 
 
 	/* Print out the per-protocol part of the tuple. Return like seq_* */
 	/* Print out the per-protocol part of the tuple. Return like seq_* */
 	int (*print_tuple)(struct seq_file *s,
 	int (*print_tuple)(struct seq_file *s,
@@ -117,20 +117,19 @@ extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
 				      struct nf_conntrack_tuple *t);
 				      struct nf_conntrack_tuple *t);
 extern const struct nla_policy nf_ct_port_nla_policy[];
 extern const struct nla_policy nf_ct_port_nla_policy[];
 
 
-/* Log invalid packets */
-extern unsigned int nf_ct_log_invalid;
-
 #ifdef CONFIG_SYSCTL
 #ifdef CONFIG_SYSCTL
 #ifdef DEBUG_INVALID_PACKETS
 #ifdef DEBUG_INVALID_PACKETS
-#define LOG_INVALID(proto) \
-	(nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW)
+#define LOG_INVALID(net, proto)				\
+	((net)->ct.sysctl_log_invalid == (proto) ||	\
+	 (net)->ct.sysctl_log_invalid == IPPROTO_RAW)
 #else
 #else
-#define LOG_INVALID(proto) \
-	((nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) \
+#define LOG_INVALID(net, proto)				\
+	(((net)->ct.sysctl_log_invalid == (proto) ||	\
+	  (net)->ct.sysctl_log_invalid == IPPROTO_RAW)	\
 	 && net_ratelimit())
 	 && net_ratelimit())
 #endif
 #endif
 #else
 #else
-#define LOG_INVALID(proto) 0
+#define LOG_INVALID(net, proto) 0
 #endif /* CONFIG_SYSCTL */
 #endif /* CONFIG_SYSCTL */
 
 
 #endif /*_NF_CONNTRACK_PROTOCOL_H*/
 #endif /*_NF_CONNTRACK_PROTOCOL_H*/

+ 4 - 4
include/net/netfilter/nf_log.h

@@ -28,7 +28,7 @@ struct nf_loginfo {
 	} u;
 	} u;
 };
 };
 
 
-typedef void nf_logfn(unsigned int pf,
+typedef void nf_logfn(u_int8_t pf,
 		      unsigned int hooknum,
 		      unsigned int hooknum,
 		      const struct sk_buff *skb,
 		      const struct sk_buff *skb,
 		      const struct net_device *in,
 		      const struct net_device *in,
@@ -43,12 +43,12 @@ struct nf_logger {
 };
 };
 
 
 /* Function to register/unregister log function. */
 /* Function to register/unregister log function. */
-int nf_log_register(int pf, const struct nf_logger *logger);
+int nf_log_register(u_int8_t pf, const struct nf_logger *logger);
 void nf_log_unregister(const struct nf_logger *logger);
 void nf_log_unregister(const struct nf_logger *logger);
-void nf_log_unregister_pf(int pf);
+void nf_log_unregister_pf(u_int8_t pf);
 
 
 /* Calls the registered backend logging function */
 /* Calls the registered backend logging function */
-void nf_log_packet(int pf,
+void nf_log_packet(u_int8_t pf,
 		   unsigned int hooknum,
 		   unsigned int hooknum,
 		   const struct sk_buff *skb,
 		   const struct sk_buff *skb,
 		   const struct net_device *in,
 		   const struct net_device *in,

+ 3 - 3
include/net/netfilter/nf_queue.h

@@ -8,7 +8,7 @@ struct nf_queue_entry {
 	unsigned int		id;
 	unsigned int		id;
 
 
 	struct nf_hook_ops	*elem;
 	struct nf_hook_ops	*elem;
-	int			pf;
+	u_int8_t		pf;
 	unsigned int		hook;
 	unsigned int		hook;
 	struct net_device	*indev;
 	struct net_device	*indev;
 	struct net_device	*outdev;
 	struct net_device	*outdev;
@@ -24,9 +24,9 @@ struct nf_queue_handler {
 	char			*name;
 	char			*name;
 };
 };
 
 
-extern int nf_register_queue_handler(int pf,
+extern int nf_register_queue_handler(u_int8_t pf,
 				     const struct nf_queue_handler *qh);
 				     const struct nf_queue_handler *qh);
-extern int nf_unregister_queue_handler(int pf,
+extern int nf_unregister_queue_handler(u_int8_t pf,
 				       const struct nf_queue_handler *qh);
 				       const struct nf_queue_handler *qh);
 extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
 extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
 extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
 extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);

+ 32 - 0
include/net/netfilter/nf_tproxy_core.h

@@ -0,0 +1,32 @@
+#ifndef _NF_TPROXY_CORE_H
+#define _NF_TPROXY_CORE_H
+
+#include <linux/types.h>
+#include <linux/in.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/inet_sock.h>
+#include <net/tcp.h>
+
+/* look up and get a reference to a matching socket */
+extern struct sock *
+nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
+		      const __be32 saddr, const __be32 daddr,
+		      const __be16 sport, const __be16 dport,
+		      const struct net_device *in, bool listening);
+
+static inline void
+nf_tproxy_put_sock(struct sock *sk)
+{
+	/* TIME_WAIT inet sockets have to be handled differently */
+	if ((sk->sk_protocol == IPPROTO_TCP) && (sk->sk_state == TCP_TIME_WAIT))
+		inet_twsk_put(inet_twsk(sk));
+	else
+		sock_put(sk);
+}
+
+/* assign a socket to the skb -- consumes sk */
+int
+nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk);
+
+#endif

+ 30 - 0
include/net/netns/conntrack.h

@@ -0,0 +1,30 @@
+#ifndef __NETNS_CONNTRACK_H
+#define __NETNS_CONNTRACK_H
+
+#include <linux/list.h>
+#include <asm/atomic.h>
+
+struct ctl_table_header;
+struct nf_conntrack_ecache;
+
+struct netns_ct {
+	atomic_t		count;
+	unsigned int		expect_count;
+	struct hlist_head	*hash;
+	struct hlist_head	*expect_hash;
+	struct hlist_head	unconfirmed;
+	struct ip_conntrack_stat *stat;
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+	struct nf_conntrack_ecache *ecache;
+#endif
+	int			sysctl_acct;
+	int			sysctl_checksum;
+	unsigned int		sysctl_log_invalid; /* Log invalid packets */
+#ifdef CONFIG_SYSCTL
+	struct ctl_table_header	*sysctl_header;
+	struct ctl_table_header	*acct_sysctl_header;
+#endif
+	int			hash_vmalloc;
+	int			expect_vmalloc;
+};
+#endif

+ 3 - 0
include/net/netns/ipv4.h

@@ -38,6 +38,9 @@ struct netns_ipv4 {
 	struct xt_table		*iptable_raw;
 	struct xt_table		*iptable_raw;
 	struct xt_table		*arptable_filter;
 	struct xt_table		*arptable_filter;
 	struct xt_table		*iptable_security;
 	struct xt_table		*iptable_security;
+	struct xt_table		*nat_table;
+	struct hlist_head	*nat_bysource;
+	int			nat_vmalloced;
 #endif
 #endif
 
 
 	int sysctl_icmp_echo_ignore_all;
 	int sysctl_icmp_echo_ignore_all;

+ 2 - 2
net/bridge/br_netfilter.c

@@ -657,7 +657,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
 {
 {
 	struct nf_bridge_info *nf_bridge;
 	struct nf_bridge_info *nf_bridge;
 	struct net_device *parent;
 	struct net_device *parent;
-	int pf;
+	u_int8_t pf;
 
 
 	if (!skb->nf_bridge)
 	if (!skb->nf_bridge)
 		return NF_ACCEPT;
 		return NF_ACCEPT;
@@ -791,7 +791,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
 {
 {
 	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
 	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
 	struct net_device *realoutdev = bridge_parent(skb->dev);
 	struct net_device *realoutdev = bridge_parent(skb->dev);
-	int pf;
+	u_int8_t pf;
 
 
 #ifdef CONFIG_NETFILTER_DEBUG
 #ifdef CONFIG_NETFILTER_DEBUG
 	/* Be very paranoid. This probably won't happen anymore, but let's
 	/* Be very paranoid. This probably won't happen anymore, but let's

+ 6 - 24
net/bridge/netfilter/Kconfig

@@ -2,21 +2,21 @@
 # Bridge netfilter configuration
 # Bridge netfilter configuration
 #
 #
 
 
-menu "Bridge: Netfilter Configuration"
-	depends on BRIDGE && BRIDGE_NETFILTER
-
-config BRIDGE_NF_EBTABLES
+menuconfig BRIDGE_NF_EBTABLES
 	tristate "Ethernet Bridge tables (ebtables) support"
 	tristate "Ethernet Bridge tables (ebtables) support"
+	select NETFILTER_XTABLES
 	help
 	help
 	  ebtables is a general, extensible frame/packet identification
 	  ebtables is a general, extensible frame/packet identification
 	  framework. Say 'Y' or 'M' here if you want to do Ethernet
 	  framework. Say 'Y' or 'M' here if you want to do Ethernet
 	  filtering/NAT/brouting on the Ethernet bridge.
 	  filtering/NAT/brouting on the Ethernet bridge.
+
+if BRIDGE_NF_EBTABLES
+
 #
 #
 # tables
 # tables
 #
 #
 config BRIDGE_EBT_BROUTE
 config BRIDGE_EBT_BROUTE
 	tristate "ebt: broute table support"
 	tristate "ebt: broute table support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  The ebtables broute table is used to define rules that decide between
 	  The ebtables broute table is used to define rules that decide between
 	  bridging and routing frames, giving Linux the functionality of a
 	  bridging and routing frames, giving Linux the functionality of a
@@ -27,7 +27,6 @@ config BRIDGE_EBT_BROUTE
 
 
 config BRIDGE_EBT_T_FILTER
 config BRIDGE_EBT_T_FILTER
 	tristate "ebt: filter table support"
 	tristate "ebt: filter table support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  The ebtables filter table is used to define frame filtering rules at
 	  The ebtables filter table is used to define frame filtering rules at
 	  local input, forwarding and local output. See the man page for
 	  local input, forwarding and local output. See the man page for
@@ -37,7 +36,6 @@ config BRIDGE_EBT_T_FILTER
 
 
 config BRIDGE_EBT_T_NAT
 config BRIDGE_EBT_T_NAT
 	tristate "ebt: nat table support"
 	tristate "ebt: nat table support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  The ebtables nat table is used to define rules that alter the MAC
 	  The ebtables nat table is used to define rules that alter the MAC
 	  source address (MAC SNAT) or the MAC destination address (MAC DNAT).
 	  source address (MAC SNAT) or the MAC destination address (MAC DNAT).
@@ -49,7 +47,6 @@ config BRIDGE_EBT_T_NAT
 #
 #
 config BRIDGE_EBT_802_3
 config BRIDGE_EBT_802_3
 	tristate "ebt: 802.3 filter support"
 	tristate "ebt: 802.3 filter support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds matching support for 802.3 Ethernet frames.
 	  This option adds matching support for 802.3 Ethernet frames.
 
 
@@ -57,7 +54,6 @@ config BRIDGE_EBT_802_3
 
 
 config BRIDGE_EBT_AMONG
 config BRIDGE_EBT_AMONG
 	tristate "ebt: among filter support"
 	tristate "ebt: among filter support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the among match, which allows matching the MAC source
 	  This option adds the among match, which allows matching the MAC source
 	  and/or destination address on a list of addresses. Optionally,
 	  and/or destination address on a list of addresses. Optionally,
@@ -67,7 +63,6 @@ config BRIDGE_EBT_AMONG
 
 
 config BRIDGE_EBT_ARP
 config BRIDGE_EBT_ARP
 	tristate "ebt: ARP filter support"
 	tristate "ebt: ARP filter support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the ARP match, which allows ARP and RARP header field
 	  This option adds the ARP match, which allows ARP and RARP header field
 	  filtering.
 	  filtering.
@@ -76,7 +71,6 @@ config BRIDGE_EBT_ARP
 
 
 config BRIDGE_EBT_IP
 config BRIDGE_EBT_IP
 	tristate "ebt: IP filter support"
 	tristate "ebt: IP filter support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the IP match, which allows basic IP header field
 	  This option adds the IP match, which allows basic IP header field
 	  filtering.
 	  filtering.
@@ -94,7 +88,6 @@ config BRIDGE_EBT_IP6
 
 
 config BRIDGE_EBT_LIMIT
 config BRIDGE_EBT_LIMIT
 	tristate "ebt: limit match support"
 	tristate "ebt: limit match support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the limit match, which allows you to control
 	  This option adds the limit match, which allows you to control
 	  the rate at which a rule can be matched. This match is the
 	  the rate at which a rule can be matched. This match is the
@@ -105,7 +98,6 @@ config BRIDGE_EBT_LIMIT
 
 
 config BRIDGE_EBT_MARK
 config BRIDGE_EBT_MARK
 	tristate "ebt: mark filter support"
 	tristate "ebt: mark filter support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the mark match, which allows matching frames based on
 	  This option adds the mark match, which allows matching frames based on
 	  the 'nfmark' value in the frame. This can be set by the mark target.
 	  the 'nfmark' value in the frame. This can be set by the mark target.
@@ -116,7 +108,6 @@ config BRIDGE_EBT_MARK
 
 
 config BRIDGE_EBT_PKTTYPE
 config BRIDGE_EBT_PKTTYPE
 	tristate "ebt: packet type filter support"
 	tristate "ebt: packet type filter support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the packet type match, which allows matching on the
 	  This option adds the packet type match, which allows matching on the
 	  type of packet based on its Ethernet "class" (as determined by
 	  type of packet based on its Ethernet "class" (as determined by
@@ -127,7 +118,6 @@ config BRIDGE_EBT_PKTTYPE
 
 
 config BRIDGE_EBT_STP
 config BRIDGE_EBT_STP
 	tristate "ebt: STP filter support"
 	tristate "ebt: STP filter support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the Spanning Tree Protocol match, which
 	  This option adds the Spanning Tree Protocol match, which
 	  allows STP header field filtering.
 	  allows STP header field filtering.
@@ -136,7 +126,6 @@ config BRIDGE_EBT_STP
 
 
 config BRIDGE_EBT_VLAN
 config BRIDGE_EBT_VLAN
 	tristate "ebt: 802.1Q VLAN filter support"
 	tristate "ebt: 802.1Q VLAN filter support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the 802.1Q vlan match, which allows the filtering of
 	  This option adds the 802.1Q vlan match, which allows the filtering of
 	  802.1Q vlan fields.
 	  802.1Q vlan fields.
@@ -156,7 +145,6 @@ config BRIDGE_EBT_ARPREPLY
 
 
 config BRIDGE_EBT_DNAT
 config BRIDGE_EBT_DNAT
 	tristate "ebt: dnat target support"
 	tristate "ebt: dnat target support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the MAC DNAT target, which allows altering the MAC
 	  This option adds the MAC DNAT target, which allows altering the MAC
 	  destination address of frames.
 	  destination address of frames.
@@ -165,7 +153,6 @@ config BRIDGE_EBT_DNAT
 
 
 config BRIDGE_EBT_MARK_T
 config BRIDGE_EBT_MARK_T
 	tristate "ebt: mark target support"
 	tristate "ebt: mark target support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the mark target, which allows marking frames by
 	  This option adds the mark target, which allows marking frames by
 	  setting the 'nfmark' value in the frame.
 	  setting the 'nfmark' value in the frame.
@@ -176,7 +163,6 @@ config BRIDGE_EBT_MARK_T
 
 
 config BRIDGE_EBT_REDIRECT
 config BRIDGE_EBT_REDIRECT
 	tristate "ebt: redirect target support"
 	tristate "ebt: redirect target support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the MAC redirect target, which allows altering the MAC
 	  This option adds the MAC redirect target, which allows altering the MAC
 	  destination address of a frame to that of the device it arrived on.
 	  destination address of a frame to that of the device it arrived on.
@@ -185,7 +171,6 @@ config BRIDGE_EBT_REDIRECT
 
 
 config BRIDGE_EBT_SNAT
 config BRIDGE_EBT_SNAT
 	tristate "ebt: snat target support"
 	tristate "ebt: snat target support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the MAC SNAT target, which allows altering the MAC
 	  This option adds the MAC SNAT target, which allows altering the MAC
 	  source address of frames.
 	  source address of frames.
@@ -196,7 +181,6 @@ config BRIDGE_EBT_SNAT
 #
 #
 config BRIDGE_EBT_LOG
 config BRIDGE_EBT_LOG
 	tristate "ebt: log support"
 	tristate "ebt: log support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option adds the log watcher, that you can use in any rule
 	  This option adds the log watcher, that you can use in any rule
 	  in any ebtables table. It records info about the frame header
 	  in any ebtables table. It records info about the frame header
@@ -206,7 +190,6 @@ config BRIDGE_EBT_LOG
 
 
 config BRIDGE_EBT_ULOG
 config BRIDGE_EBT_ULOG
 	tristate "ebt: ulog support (OBSOLETE)"
 	tristate "ebt: ulog support (OBSOLETE)"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option enables the old bridge-specific "ebt_ulog" implementation
 	  This option enables the old bridge-specific "ebt_ulog" implementation
 	  which has been obsoleted by the new "nfnetlink_log" code (see
 	  which has been obsoleted by the new "nfnetlink_log" code (see
@@ -223,7 +206,6 @@ config BRIDGE_EBT_ULOG
 
 
 config BRIDGE_EBT_NFLOG
 config BRIDGE_EBT_NFLOG
 	tristate "ebt: nflog support"
 	tristate "ebt: nflog support"
-	depends on BRIDGE_NF_EBTABLES
 	help
 	help
 	  This option enables the nflog watcher, which allows to LOG
 	  This option enables the nflog watcher, which allows to LOG
 	  messages through the netfilter logging API, which can use
 	  messages through the netfilter logging API, which can use
@@ -235,4 +217,4 @@ config BRIDGE_EBT_NFLOG
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-endmenu
+endif # BRIDGE_NF_EBTABLES

+ 23 - 24
net/bridge/netfilter/ebt_802_3.c

@@ -7,64 +7,63 @@
  * May 2003
  * May 2003
  *
  *
  */
  */
-
+#include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_802_3.h>
 #include <linux/netfilter_bridge/ebt_802_3.h>
-#include <linux/module.h>
 
 
-static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out, const void *data, unsigned int datalen)
+static bool
+ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_802_3_info *info = data;
+	const struct ebt_802_3_info *info = par->matchinfo;
 	const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
 	const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
 	__be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type;
 	__be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type;
 
 
 	if (info->bitmask & EBT_802_3_SAP) {
 	if (info->bitmask & EBT_802_3_SAP) {
 		if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP))
 		if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP))
-				return EBT_NOMATCH;
+			return false;
 		if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP))
 		if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP))
-				return EBT_NOMATCH;
+			return false;
 	}
 	}
 
 
 	if (info->bitmask & EBT_802_3_TYPE) {
 	if (info->bitmask & EBT_802_3_TYPE) {
 		if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE))
 		if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE))
-			return EBT_NOMATCH;
+			return false;
 		if (FWINV(info->type != type, EBT_802_3_TYPE))
 		if (FWINV(info->type != type, EBT_802_3_TYPE))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 
 
-	return EBT_MATCH;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_802_3;
-static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ebt_802_3_info *info = data;
+	const struct ebt_802_3_info *info = par->matchinfo;
 
 
-	if (datalen < sizeof(struct ebt_802_3_info))
-		return -EINVAL;
 	if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
 	if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
-		return -EINVAL;
+		return false;
 
 
-	return 0;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_802_3 __read_mostly = {
-	.name		= EBT_802_3_MATCH,
-	.match		= ebt_filter_802_3,
-	.check		= ebt_802_3_check,
+static struct xt_match ebt_802_3_mt_reg __read_mostly = {
+	.name		= "802_3",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_802_3_mt,
+	.checkentry	= ebt_802_3_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_802_3_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_802_3_init(void)
 static int __init ebt_802_3_init(void)
 {
 {
-	return ebt_register_match(&filter_802_3);
+	return xt_register_match(&ebt_802_3_mt_reg);
 }
 }
 
 
 static void __exit ebt_802_3_fini(void)
 static void __exit ebt_802_3_fini(void)
 {
 {
-	ebt_unregister_match(&filter_802_3);
+	xt_unregister_match(&ebt_802_3_mt_reg);
 }
 }
 
 
 module_init(ebt_802_3_init);
 module_init(ebt_802_3_init);

+ 41 - 44
net/bridge/netfilter/ebt_among.c

@@ -7,15 +7,15 @@
  *  August, 2003
  *  August, 2003
  *
  *
  */
  */
-
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_among.h>
 #include <linux/ip.h>
 #include <linux/ip.h>
 #include <linux/if_arp.h>
 #include <linux/if_arp.h>
 #include <linux/module.h>
 #include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_among.h>
 
 
-static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
-				     const char *mac, __be32 ip)
+static bool ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
+				      const char *mac, __be32 ip)
 {
 {
 	/* You may be puzzled as to how this code works.
 	/* You may be puzzled as to how this code works.
 	 * Some tricks were used, refer to
 	 * Some tricks were used, refer to
@@ -33,23 +33,19 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
 	if (ip) {
 	if (ip) {
 		for (i = start; i < limit; i++) {
 		for (i = start; i < limit; i++) {
 			p = &wh->pool[i];
 			p = &wh->pool[i];
-			if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) {
-				if (p->ip == 0 || p->ip == ip) {
-					return 1;
-				}
-			}
+			if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
+				if (p->ip == 0 || p->ip == ip)
+					return true;
 		}
 		}
 	} else {
 	} else {
 		for (i = start; i < limit; i++) {
 		for (i = start; i < limit; i++) {
 			p = &wh->pool[i];
 			p = &wh->pool[i];
-			if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) {
-				if (p->ip == 0) {
-					return 1;
-				}
-			}
+			if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
+				if (p->ip == 0)
+					return true;
 		}
 		}
 	}
 	}
-	return 0;
+	return false;
 }
 }
 
 
 static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash
 static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash
@@ -131,12 +127,10 @@ static int get_ip_src(const struct sk_buff *skb, __be32 *addr)
 	return 0;
 	return 0;
 }
 }
 
 
-static int ebt_filter_among(const struct sk_buff *skb,
-			    const struct net_device *in,
-			    const struct net_device *out, const void *data,
-			    unsigned int datalen)
+static bool
+ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_among_info *info = data;
+	const struct ebt_among_info *info = par->matchinfo;
 	const char *dmac, *smac;
 	const char *dmac, *smac;
 	const struct ebt_mac_wormhash *wh_dst, *wh_src;
 	const struct ebt_mac_wormhash *wh_dst, *wh_src;
 	__be32 dip = 0, sip = 0;
 	__be32 dip = 0, sip = 0;
@@ -147,41 +141,41 @@ static int ebt_filter_among(const struct sk_buff *skb,
 	if (wh_src) {
 	if (wh_src) {
 		smac = eth_hdr(skb)->h_source;
 		smac = eth_hdr(skb)->h_source;
 		if (get_ip_src(skb, &sip))
 		if (get_ip_src(skb, &sip))
-			return EBT_NOMATCH;
+			return false;
 		if (!(info->bitmask & EBT_AMONG_SRC_NEG)) {
 		if (!(info->bitmask & EBT_AMONG_SRC_NEG)) {
 			/* we match only if it contains */
 			/* we match only if it contains */
 			if (!ebt_mac_wormhash_contains(wh_src, smac, sip))
 			if (!ebt_mac_wormhash_contains(wh_src, smac, sip))
-				return EBT_NOMATCH;
+				return false;
 		} else {
 		} else {
 			/* we match only if it DOES NOT contain */
 			/* we match only if it DOES NOT contain */
 			if (ebt_mac_wormhash_contains(wh_src, smac, sip))
 			if (ebt_mac_wormhash_contains(wh_src, smac, sip))
-				return EBT_NOMATCH;
+				return false;
 		}
 		}
 	}
 	}
 
 
 	if (wh_dst) {
 	if (wh_dst) {
 		dmac = eth_hdr(skb)->h_dest;
 		dmac = eth_hdr(skb)->h_dest;
 		if (get_ip_dst(skb, &dip))
 		if (get_ip_dst(skb, &dip))
-			return EBT_NOMATCH;
+			return false;
 		if (!(info->bitmask & EBT_AMONG_DST_NEG)) {
 		if (!(info->bitmask & EBT_AMONG_DST_NEG)) {
 			/* we match only if it contains */
 			/* we match only if it contains */
 			if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip))
 			if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip))
-				return EBT_NOMATCH;
+				return false;
 		} else {
 		} else {
 			/* we match only if it DOES NOT contain */
 			/* we match only if it DOES NOT contain */
 			if (ebt_mac_wormhash_contains(wh_dst, dmac, dip))
 			if (ebt_mac_wormhash_contains(wh_dst, dmac, dip))
-				return EBT_NOMATCH;
+				return false;
 		}
 		}
 	}
 	}
 
 
-	return EBT_MATCH;
+	return true;
 }
 }
 
 
-static int ebt_among_check(const char *tablename, unsigned int hookmask,
-			   const struct ebt_entry *e, void *data,
-			   unsigned int datalen)
+static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ebt_among_info *info = data;
+	const struct ebt_among_info *info = par->matchinfo;
+	const struct ebt_entry_match *em =
+		container_of(par->matchinfo, const struct ebt_entry_match, data);
 	int expected_length = sizeof(struct ebt_among_info);
 	int expected_length = sizeof(struct ebt_among_info);
 	const struct ebt_mac_wormhash *wh_dst, *wh_src;
 	const struct ebt_mac_wormhash *wh_dst, *wh_src;
 	int err;
 	int err;
@@ -191,42 +185,45 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask,
 	expected_length += ebt_mac_wormhash_size(wh_dst);
 	expected_length += ebt_mac_wormhash_size(wh_dst);
 	expected_length += ebt_mac_wormhash_size(wh_src);
 	expected_length += ebt_mac_wormhash_size(wh_src);
 
 
-	if (datalen != EBT_ALIGN(expected_length)) {
+	if (em->match_size != EBT_ALIGN(expected_length)) {
 		printk(KERN_WARNING
 		printk(KERN_WARNING
 		       "ebtables: among: wrong size: %d "
 		       "ebtables: among: wrong size: %d "
 		       "against expected %d, rounded to %Zd\n",
 		       "against expected %d, rounded to %Zd\n",
-		       datalen, expected_length,
+		       em->match_size, expected_length,
 		       EBT_ALIGN(expected_length));
 		       EBT_ALIGN(expected_length));
-		return -EINVAL;
+		return false;
 	}
 	}
 	if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
 	if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
 		printk(KERN_WARNING
 		printk(KERN_WARNING
 		       "ebtables: among: dst integrity fail: %x\n", -err);
 		       "ebtables: among: dst integrity fail: %x\n", -err);
-		return -EINVAL;
+		return false;
 	}
 	}
 	if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
 	if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
 		printk(KERN_WARNING
 		printk(KERN_WARNING
 		       "ebtables: among: src integrity fail: %x\n", -err);
 		       "ebtables: among: src integrity fail: %x\n", -err);
-		return -EINVAL;
+		return false;
 	}
 	}
-	return 0;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_among __read_mostly = {
-	.name		= EBT_AMONG_MATCH,
-	.match		= ebt_filter_among,
-	.check		= ebt_among_check,
+static struct xt_match ebt_among_mt_reg __read_mostly = {
+	.name		= "among",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_among_mt,
+	.checkentry	= ebt_among_mt_check,
+	.matchsize	= -1, /* special case */
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_among_init(void)
 static int __init ebt_among_init(void)
 {
 {
-	return ebt_register_match(&filter_among);
+	return xt_register_match(&ebt_among_mt_reg);
 }
 }
 
 
 static void __exit ebt_among_fini(void)
 static void __exit ebt_among_fini(void)
 {
 {
-	ebt_unregister_match(&filter_among);
+	xt_unregister_match(&ebt_among_mt_reg);
 }
 }
 
 
 module_init(ebt_among_init);
 module_init(ebt_among_init);

+ 37 - 36
net/bridge/netfilter/ebt_arp.c

@@ -8,58 +8,58 @@
  *  April, 2002
  *  April, 2002
  *
  *
  */
  */
-
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_arp.h>
 #include <linux/if_arp.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/if_ether.h>
 #include <linux/module.h>
 #include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_arp.h>
 
 
-static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out, const void *data, unsigned int datalen)
+static bool
+ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_arp_info *info = data;
+	const struct ebt_arp_info *info = par->matchinfo;
 	const struct arphdr *ah;
 	const struct arphdr *ah;
 	struct arphdr _arph;
 	struct arphdr _arph;
 
 
 	ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
 	ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
 	if (ah == NULL)
 	if (ah == NULL)
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode !=
 	if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode !=
 	   ah->ar_op, EBT_ARP_OPCODE))
 	   ah->ar_op, EBT_ARP_OPCODE))
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype !=
 	if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype !=
 	   ah->ar_hrd, EBT_ARP_HTYPE))
 	   ah->ar_hrd, EBT_ARP_HTYPE))
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype !=
 	if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype !=
 	   ah->ar_pro, EBT_ARP_PTYPE))
 	   ah->ar_pro, EBT_ARP_PTYPE))
-		return EBT_NOMATCH;
+		return false;
 
 
 	if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
 	if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
 		const __be32 *sap, *dap;
 		const __be32 *sap, *dap;
 		__be32 saddr, daddr;
 		__be32 saddr, daddr;
 
 
 		if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
 		if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
-			return EBT_NOMATCH;
+			return false;
 		sap = skb_header_pointer(skb, sizeof(struct arphdr) +
 		sap = skb_header_pointer(skb, sizeof(struct arphdr) +
 					ah->ar_hln, sizeof(saddr),
 					ah->ar_hln, sizeof(saddr),
 					&saddr);
 					&saddr);
 		if (sap == NULL)
 		if (sap == NULL)
-			return EBT_NOMATCH;
+			return false;
 		dap = skb_header_pointer(skb, sizeof(struct arphdr) +
 		dap = skb_header_pointer(skb, sizeof(struct arphdr) +
 					2*ah->ar_hln+sizeof(saddr),
 					2*ah->ar_hln+sizeof(saddr),
 					sizeof(daddr), &daddr);
 					sizeof(daddr), &daddr);
 		if (dap == NULL)
 		if (dap == NULL)
-			return EBT_NOMATCH;
+			return false;
 		if (info->bitmask & EBT_ARP_SRC_IP &&
 		if (info->bitmask & EBT_ARP_SRC_IP &&
 		    FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP))
 		    FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP))
-			return EBT_NOMATCH;
+			return false;
 		if (info->bitmask & EBT_ARP_DST_IP &&
 		if (info->bitmask & EBT_ARP_DST_IP &&
 		    FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP))
 		    FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP))
-			return EBT_NOMATCH;
+			return false;
 		if (info->bitmask & EBT_ARP_GRAT &&
 		if (info->bitmask & EBT_ARP_GRAT &&
 		    FWINV(*dap != *sap, EBT_ARP_GRAT))
 		    FWINV(*dap != *sap, EBT_ARP_GRAT))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 
 
 	if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
 	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
 		uint8_t verdict, i;
 		uint8_t verdict, i;
 
 
 		if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
 		if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
-			return EBT_NOMATCH;
+			return false;
 		if (info->bitmask & EBT_ARP_SRC_MAC) {
 		if (info->bitmask & EBT_ARP_SRC_MAC) {
 			mp = skb_header_pointer(skb, sizeof(struct arphdr),
 			mp = skb_header_pointer(skb, sizeof(struct arphdr),
 						sizeof(_mac), &_mac);
 						sizeof(_mac), &_mac);
 			if (mp == NULL)
 			if (mp == NULL)
-				return EBT_NOMATCH;
+				return false;
 			verdict = 0;
 			verdict = 0;
 			for (i = 0; i < 6; i++)
 			for (i = 0; i < 6; i++)
 				verdict |= (mp[i] ^ info->smaddr[i]) &
 				verdict |= (mp[i] ^ info->smaddr[i]) &
 				       info->smmsk[i];
 				       info->smmsk[i];
 			if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
 			if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
-				return EBT_NOMATCH;
+				return false;
 		}
 		}
 
 
 		if (info->bitmask & EBT_ARP_DST_MAC) {
 		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
 						ah->ar_hln + ah->ar_pln,
 						ah->ar_hln + ah->ar_pln,
 						sizeof(_mac), &_mac);
 						sizeof(_mac), &_mac);
 			if (mp == NULL)
 			if (mp == NULL)
-				return EBT_NOMATCH;
+				return false;
 			verdict = 0;
 			verdict = 0;
 			for (i = 0; i < 6; i++)
 			for (i = 0; i < 6; i++)
 				verdict |= (mp[i] ^ info->dmaddr[i]) &
 				verdict |= (mp[i] ^ info->dmaddr[i]) &
 					info->dmmsk[i];
 					info->dmmsk[i];
 			if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
 			if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
-				return EBT_NOMATCH;
+				return false;
 		}
 		}
 	}
 	}
 
 
-	return EBT_MATCH;
+	return true;
 }
 }
 
 
-static int ebt_arp_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ebt_arp_info *info = data;
+	const struct ebt_arp_info *info = par->matchinfo;
+	const struct ebt_entry *e = par->entryinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info)))
-		return -EINVAL;
 	if ((e->ethproto != htons(ETH_P_ARP) &&
 	if ((e->ethproto != htons(ETH_P_ARP) &&
 	   e->ethproto != htons(ETH_P_RARP)) ||
 	   e->ethproto != htons(ETH_P_RARP)) ||
 	   e->invflags & EBT_IPROTO)
 	   e->invflags & EBT_IPROTO)
-		return -EINVAL;
+		return false;
 	if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
 	if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_arp __read_mostly = {
-	.name		= EBT_ARP_MATCH,
-	.match		= ebt_filter_arp,
-	.check		= ebt_arp_check,
+static struct xt_match ebt_arp_mt_reg __read_mostly = {
+	.name		= "arp",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_arp_mt,
+	.checkentry	= ebt_arp_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_arp_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_arp_init(void)
 static int __init ebt_arp_init(void)
 {
 {
-	return ebt_register_match(&filter_arp);
+	return xt_register_match(&ebt_arp_mt_reg);
 }
 }
 
 
 static void __exit ebt_arp_fini(void)
 static void __exit ebt_arp_fini(void)
 {
 {
-	ebt_unregister_match(&filter_arp);
+	xt_unregister_match(&ebt_arp_mt_reg);
 }
 }
 
 
 module_init(ebt_arp_init);
 module_init(ebt_arp_init);

+ 24 - 25
net/bridge/netfilter/ebt_arpreply.c

@@ -8,18 +8,17 @@
  *  August, 2003
  *  August, 2003
  *
  *
  */
  */
-
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_arpreply.h>
 #include <linux/if_arp.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
 #include <net/arp.h>
 #include <linux/module.h>
 #include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_arpreply.h>
 
 
-static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static unsigned int
+ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	struct ebt_arpreply_info *info = (void *)data;
+	const struct ebt_arpreply_info *info = par->targinfo;
 	const __be32 *siptr, *diptr;
 	const __be32 *siptr, *diptr;
 	__be32 _sip, _dip;
 	__be32 _sip, _dip;
 	const struct arphdr *ap;
 	const struct arphdr *ap;
@@ -52,45 +51,45 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
 	if (diptr == NULL)
 	if (diptr == NULL)
 		return EBT_DROP;
 		return EBT_DROP;
 
 
-	arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)in,
+	arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)par->in,
 		 *diptr, shp, info->mac, shp);
 		 *diptr, shp, info->mac, shp);
 
 
 	return info->target;
 	return info->target;
 }
 }
 
 
-static int ebt_target_reply_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ebt_arpreply_info *info = data;
+	const struct ebt_arpreply_info *info = par->targinfo;
+	const struct ebt_entry *e = par->entryinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info)))
-		return -EINVAL;
 	if (BASE_CHAIN && info->target == EBT_RETURN)
 	if (BASE_CHAIN && info->target == EBT_RETURN)
-		return -EINVAL;
+		return false;
 	if (e->ethproto != htons(ETH_P_ARP) ||
 	if (e->ethproto != htons(ETH_P_ARP) ||
 	    e->invflags & EBT_IPROTO)
 	    e->invflags & EBT_IPROTO)
-		return -EINVAL;
-	CLEAR_BASE_CHAIN_BIT;
-	if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING))
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_target reply_target __read_mostly = {
-	.name		= EBT_ARPREPLY_TARGET,
-	.target		= ebt_target_reply,
-	.check		= ebt_target_reply_check,
+static struct xt_target ebt_arpreply_tg_reg __read_mostly = {
+	.name		= "arpreply",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.table		= "nat",
+	.hooks		= (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING),
+	.target		= ebt_arpreply_tg,
+	.checkentry	= ebt_arpreply_tg_check,
+	.targetsize	= XT_ALIGN(sizeof(struct ebt_arpreply_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_arpreply_init(void)
 static int __init ebt_arpreply_init(void)
 {
 {
-	return ebt_register_target(&reply_target);
+	return xt_register_target(&ebt_arpreply_tg_reg);
 }
 }
 
 
 static void __exit ebt_arpreply_fini(void)
 static void __exit ebt_arpreply_fini(void)
 {
 {
-	ebt_unregister_target(&reply_target);
+	xt_unregister_target(&ebt_arpreply_tg_reg);
 }
 }
 
 
 module_init(ebt_arpreply_init);
 module_init(ebt_arpreply_init);

+ 31 - 26
net/bridge/netfilter/ebt_dnat.c

@@ -7,18 +7,17 @@
  *  June, 2002
  *  June, 2002
  *
  *
  */
  */
-
+#include <linux/module.h>
+#include <net/sock.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_nat.h>
 #include <linux/netfilter_bridge/ebt_nat.h>
-#include <linux/module.h>
-#include <net/sock.h>
 
 
-static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static unsigned int
+ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ebt_nat_info *info = data;
+	const struct ebt_nat_info *info = par->targinfo;
 
 
 	if (!skb_make_writable(skb, 0))
 	if (!skb_make_writable(skb, 0))
 		return EBT_DROP;
 		return EBT_DROP;
@@ -27,40 +26,46 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
 	return info->target;
 	return info->target;
 }
 }
 
 
-static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ebt_nat_info *info = data;
+	const struct ebt_nat_info *info = par->targinfo;
+	unsigned int hook_mask;
 
 
 	if (BASE_CHAIN && info->target == EBT_RETURN)
 	if (BASE_CHAIN && info->target == EBT_RETURN)
-		return -EINVAL;
-	CLEAR_BASE_CHAIN_BIT;
-	if ( (strcmp(tablename, "nat") ||
-	   (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) &&
-	   (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
-		return -EINVAL;
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
-		return -EINVAL;
+		return false;
+
+	hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
+	if ((strcmp(par->table, "nat") != 0 ||
+	    (hook_mask & ~((1 << NF_BR_PRE_ROUTING) |
+	    (1 << NF_BR_LOCAL_OUT)))) &&
+	    (strcmp(par->table, "broute") != 0 ||
+	    hook_mask & ~(1 << NF_BR_BROUTING)))
+		return false;
 	if (INVALID_TARGET)
 	if (INVALID_TARGET)
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_target dnat __read_mostly = {
-	.name		= EBT_DNAT_TARGET,
-	.target		= ebt_target_dnat,
-	.check		= ebt_target_dnat_check,
+static struct xt_target ebt_dnat_tg_reg __read_mostly = {
+	.name		= "dnat",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.hooks		= (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
+			  (1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_BROUTING),
+	.target		= ebt_dnat_tg,
+	.checkentry	= ebt_dnat_tg_check,
+	.targetsize	= XT_ALIGN(sizeof(struct ebt_nat_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_dnat_init(void)
 static int __init ebt_dnat_init(void)
 {
 {
-	return ebt_register_target(&dnat);
+	return xt_register_target(&ebt_dnat_tg_reg);
 }
 }
 
 
 static void __exit ebt_dnat_fini(void)
 static void __exit ebt_dnat_fini(void)
 {
 {
-	ebt_unregister_target(&dnat);
+	xt_unregister_target(&ebt_dnat_tg_reg);
 }
 }
 
 
 module_init(ebt_dnat_init);
 module_init(ebt_dnat_init);

+ 36 - 36
net/bridge/netfilter/ebt_ip.c

@@ -11,24 +11,23 @@
  *    Innominate Security Technologies AG <mhopf@innominate.com>
  *    Innominate Security Technologies AG <mhopf@innominate.com>
  *    September, 2002
  *    September, 2002
  */
  */
-
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_ip.h>
 #include <linux/ip.h>
 #include <linux/ip.h>
 #include <net/ip.h>
 #include <net/ip.h>
 #include <linux/in.h>
 #include <linux/in.h>
 #include <linux/module.h>
 #include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_ip.h>
 
 
 struct tcpudphdr {
 struct tcpudphdr {
 	__be16 src;
 	__be16 src;
 	__be16 dst;
 	__be16 dst;
 };
 };
 
 
-static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out, const void *data,
-   unsigned int datalen)
+static bool
+ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_ip_info *info = data;
+	const struct ebt_ip_info *info = par->matchinfo;
 	const struct iphdr *ih;
 	const struct iphdr *ih;
 	struct iphdr _iph;
 	struct iphdr _iph;
 	const struct tcpudphdr *pptr;
 	const struct tcpudphdr *pptr;
@@ -36,92 +35,93 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
 
 
 	ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
 	ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
 	if (ih == NULL)
 	if (ih == NULL)
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_IP_TOS &&
 	if (info->bitmask & EBT_IP_TOS &&
 	   FWINV(info->tos != ih->tos, EBT_IP_TOS))
 	   FWINV(info->tos != ih->tos, EBT_IP_TOS))
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_IP_SOURCE &&
 	if (info->bitmask & EBT_IP_SOURCE &&
 	   FWINV((ih->saddr & info->smsk) !=
 	   FWINV((ih->saddr & info->smsk) !=
 	   info->saddr, EBT_IP_SOURCE))
 	   info->saddr, EBT_IP_SOURCE))
-		return EBT_NOMATCH;
+		return false;
 	if ((info->bitmask & EBT_IP_DEST) &&
 	if ((info->bitmask & EBT_IP_DEST) &&
 	   FWINV((ih->daddr & info->dmsk) !=
 	   FWINV((ih->daddr & info->dmsk) !=
 	   info->daddr, EBT_IP_DEST))
 	   info->daddr, EBT_IP_DEST))
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_IP_PROTO) {
 	if (info->bitmask & EBT_IP_PROTO) {
 		if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO))
 		if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO))
-			return EBT_NOMATCH;
+			return false;
 		if (!(info->bitmask & EBT_IP_DPORT) &&
 		if (!(info->bitmask & EBT_IP_DPORT) &&
 		    !(info->bitmask & EBT_IP_SPORT))
 		    !(info->bitmask & EBT_IP_SPORT))
-			return EBT_MATCH;
+			return true;
 		if (ntohs(ih->frag_off) & IP_OFFSET)
 		if (ntohs(ih->frag_off) & IP_OFFSET)
-			return EBT_NOMATCH;
+			return false;
 		pptr = skb_header_pointer(skb, ih->ihl*4,
 		pptr = skb_header_pointer(skb, ih->ihl*4,
 					  sizeof(_ports), &_ports);
 					  sizeof(_ports), &_ports);
 		if (pptr == NULL)
 		if (pptr == NULL)
-			return EBT_NOMATCH;
+			return false;
 		if (info->bitmask & EBT_IP_DPORT) {
 		if (info->bitmask & EBT_IP_DPORT) {
 			u32 dst = ntohs(pptr->dst);
 			u32 dst = ntohs(pptr->dst);
 			if (FWINV(dst < info->dport[0] ||
 			if (FWINV(dst < info->dport[0] ||
 				  dst > info->dport[1],
 				  dst > info->dport[1],
 				  EBT_IP_DPORT))
 				  EBT_IP_DPORT))
-			return EBT_NOMATCH;
+			return false;
 		}
 		}
 		if (info->bitmask & EBT_IP_SPORT) {
 		if (info->bitmask & EBT_IP_SPORT) {
 			u32 src = ntohs(pptr->src);
 			u32 src = ntohs(pptr->src);
 			if (FWINV(src < info->sport[0] ||
 			if (FWINV(src < info->sport[0] ||
 				  src > info->sport[1],
 				  src > info->sport[1],
 				  EBT_IP_SPORT))
 				  EBT_IP_SPORT))
-			return EBT_NOMATCH;
+			return false;
 		}
 		}
 	}
 	}
-	return EBT_MATCH;
+	return true;
 }
 }
 
 
-static int ebt_ip_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_ip_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ebt_ip_info *info = data;
+	const struct ebt_ip_info *info = par->matchinfo;
+	const struct ebt_entry *e = par->entryinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info)))
-		return -EINVAL;
 	if (e->ethproto != htons(ETH_P_IP) ||
 	if (e->ethproto != htons(ETH_P_IP) ||
 	   e->invflags & EBT_IPROTO)
 	   e->invflags & EBT_IPROTO)
-		return -EINVAL;
+		return false;
 	if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
 	if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
-		return -EINVAL;
+		return false;
 	if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
 	if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
 		if (info->invflags & EBT_IP_PROTO)
 		if (info->invflags & EBT_IP_PROTO)
-			return -EINVAL;
+			return false;
 		if (info->protocol != IPPROTO_TCP &&
 		if (info->protocol != IPPROTO_TCP &&
 		    info->protocol != IPPROTO_UDP &&
 		    info->protocol != IPPROTO_UDP &&
 		    info->protocol != IPPROTO_UDPLITE &&
 		    info->protocol != IPPROTO_UDPLITE &&
 		    info->protocol != IPPROTO_SCTP &&
 		    info->protocol != IPPROTO_SCTP &&
 		    info->protocol != IPPROTO_DCCP)
 		    info->protocol != IPPROTO_DCCP)
-			 return -EINVAL;
+			 return false;
 	}
 	}
 	if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
 	if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
-		return -EINVAL;
+		return false;
 	if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
 	if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_ip __read_mostly = {
-	.name		= EBT_IP_MATCH,
-	.match		= ebt_filter_ip,
-	.check		= ebt_ip_check,
+static struct xt_match ebt_ip_mt_reg __read_mostly = {
+	.name		= "ip",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_ip_mt,
+	.checkentry	= ebt_ip_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_ip_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_ip_init(void)
 static int __init ebt_ip_init(void)
 {
 {
-	return ebt_register_match(&filter_ip);
+	return xt_register_match(&ebt_ip_mt_reg);
 }
 }
 
 
 static void __exit ebt_ip_fini(void)
 static void __exit ebt_ip_fini(void)
 {
 {
-	ebt_unregister_match(&filter_ip);
+	xt_unregister_match(&ebt_ip_mt_reg);
 }
 }
 
 
 module_init(ebt_ip_init);
 module_init(ebt_ip_init);

+ 37 - 39
net/bridge/netfilter/ebt_ip6.c

@@ -13,26 +13,24 @@
  *
  *
  *  Jan, 2008
  *  Jan, 2008
  */
  */
-
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_ip6.h>
 #include <linux/ipv6.h>
 #include <linux/ipv6.h>
 #include <net/ipv6.h>
 #include <net/ipv6.h>
 #include <linux/in.h>
 #include <linux/in.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <net/dsfield.h>
 #include <net/dsfield.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_ip6.h>
 
 
 struct tcpudphdr {
 struct tcpudphdr {
 	__be16 src;
 	__be16 src;
 	__be16 dst;
 	__be16 dst;
 };
 };
 
 
-static int ebt_filter_ip6(const struct sk_buff *skb,
-   const struct net_device *in,
-   const struct net_device *out, const void *data,
-   unsigned int datalen)
+static bool
+ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_ip6_info *info = (struct ebt_ip6_info *)data;
+	const struct ebt_ip6_info *info = par->matchinfo;
 	const struct ipv6hdr *ih6;
 	const struct ipv6hdr *ih6;
 	struct ipv6hdr _ip6h;
 	struct ipv6hdr _ip6h;
 	const struct tcpudphdr *pptr;
 	const struct tcpudphdr *pptr;
@@ -42,100 +40,100 @@ static int ebt_filter_ip6(const struct sk_buff *skb,
 
 
 	ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
 	ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
 	if (ih6 == NULL)
 	if (ih6 == NULL)
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_IP6_TCLASS &&
 	if (info->bitmask & EBT_IP6_TCLASS &&
 	   FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
 	   FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
-		return EBT_NOMATCH;
+		return false;
 	for (i = 0; i < 4; i++)
 	for (i = 0; i < 4; i++)
 		tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
 		tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
 			info->smsk.in6_u.u6_addr32[i];
 			info->smsk.in6_u.u6_addr32[i];
 	if (info->bitmask & EBT_IP6_SOURCE &&
 	if (info->bitmask & EBT_IP6_SOURCE &&
 		FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
 		FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
 			EBT_IP6_SOURCE))
 			EBT_IP6_SOURCE))
-		return EBT_NOMATCH;
+		return false;
 	for (i = 0; i < 4; i++)
 	for (i = 0; i < 4; i++)
 		tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
 		tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
 			info->dmsk.in6_u.u6_addr32[i];
 			info->dmsk.in6_u.u6_addr32[i];
 	if (info->bitmask & EBT_IP6_DEST &&
 	if (info->bitmask & EBT_IP6_DEST &&
 	   FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST))
 	   FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST))
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_IP6_PROTO) {
 	if (info->bitmask & EBT_IP6_PROTO) {
 		uint8_t nexthdr = ih6->nexthdr;
 		uint8_t nexthdr = ih6->nexthdr;
 		int offset_ph;
 		int offset_ph;
 
 
 		offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr);
 		offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr);
 		if (offset_ph == -1)
 		if (offset_ph == -1)
-			return EBT_NOMATCH;
+			return false;
 		if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
 		if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
-			return EBT_NOMATCH;
+			return false;
 		if (!(info->bitmask & EBT_IP6_DPORT) &&
 		if (!(info->bitmask & EBT_IP6_DPORT) &&
 		    !(info->bitmask & EBT_IP6_SPORT))
 		    !(info->bitmask & EBT_IP6_SPORT))
-			return EBT_MATCH;
+			return true;
 		pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),
 		pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),
 					  &_ports);
 					  &_ports);
 		if (pptr == NULL)
 		if (pptr == NULL)
-			return EBT_NOMATCH;
+			return false;
 		if (info->bitmask & EBT_IP6_DPORT) {
 		if (info->bitmask & EBT_IP6_DPORT) {
 			u32 dst = ntohs(pptr->dst);
 			u32 dst = ntohs(pptr->dst);
 			if (FWINV(dst < info->dport[0] ||
 			if (FWINV(dst < info->dport[0] ||
 				  dst > info->dport[1], EBT_IP6_DPORT))
 				  dst > info->dport[1], EBT_IP6_DPORT))
-				return EBT_NOMATCH;
+				return false;
 		}
 		}
 		if (info->bitmask & EBT_IP6_SPORT) {
 		if (info->bitmask & EBT_IP6_SPORT) {
 			u32 src = ntohs(pptr->src);
 			u32 src = ntohs(pptr->src);
 			if (FWINV(src < info->sport[0] ||
 			if (FWINV(src < info->sport[0] ||
 				  src > info->sport[1], EBT_IP6_SPORT))
 				  src > info->sport[1], EBT_IP6_SPORT))
-			return EBT_NOMATCH;
+			return false;
 		}
 		}
-		return EBT_MATCH;
+		return true;
 	}
 	}
-	return EBT_MATCH;
+	return true;
 }
 }
 
 
-static int ebt_ip6_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	struct ebt_ip6_info *info = (struct ebt_ip6_info *)data;
+	const struct ebt_entry *e = par->entryinfo;
+	struct ebt_ip6_info *info = par->matchinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_ip6_info)))
-		return -EINVAL;
 	if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
 	if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
-		return -EINVAL;
+		return false;
 	if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
 	if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
-		return -EINVAL;
+		return false;
 	if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
 	if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
 		if (info->invflags & EBT_IP6_PROTO)
 		if (info->invflags & EBT_IP6_PROTO)
-			return -EINVAL;
+			return false;
 		if (info->protocol != IPPROTO_TCP &&
 		if (info->protocol != IPPROTO_TCP &&
 		    info->protocol != IPPROTO_UDP &&
 		    info->protocol != IPPROTO_UDP &&
 		    info->protocol != IPPROTO_UDPLITE &&
 		    info->protocol != IPPROTO_UDPLITE &&
 		    info->protocol != IPPROTO_SCTP &&
 		    info->protocol != IPPROTO_SCTP &&
 		    info->protocol != IPPROTO_DCCP)
 		    info->protocol != IPPROTO_DCCP)
-			 return -EINVAL;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
 	if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
-		return -EINVAL;
+		return false;
 	if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
 	if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_ip6 =
-{
-	.name		= EBT_IP6_MATCH,
-	.match		= ebt_filter_ip6,
-	.check		= ebt_ip6_check,
+static struct xt_match ebt_ip6_mt_reg __read_mostly = {
+	.name		= "ip6",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_ip6_mt,
+	.checkentry	= ebt_ip6_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_ip6_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_ip6_init(void)
 static int __init ebt_ip6_init(void)
 {
 {
-	return ebt_register_match(&filter_ip6);
+	return xt_register_match(&ebt_ip6_mt_reg);
 }
 }
 
 
 static void __exit ebt_ip6_fini(void)
 static void __exit ebt_ip6_fini(void)
 {
 {
-	ebt_unregister_match(&filter_ip6);
+	xt_unregister_match(&ebt_ip6_mt_reg);
 }
 }
 
 
 module_init(ebt_ip6_init);
 module_init(ebt_ip6_init);

+ 21 - 24
net/bridge/netfilter/ebt_limit.c

@@ -10,13 +10,12 @@
  *  September, 2003
  *  September, 2003
  *
  *
  */
  */
-
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_limit.h>
 #include <linux/module.h>
 #include <linux/module.h>
-
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_limit.h>
 
 
 static DEFINE_SPINLOCK(limit_lock);
 static DEFINE_SPINLOCK(limit_lock);
 
 
@@ -31,11 +30,10 @@ static DEFINE_SPINLOCK(limit_lock);
 
 
 #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
 #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
 
 
-static int ebt_limit_match(const struct sk_buff *skb,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static bool
+ebt_limit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	struct ebt_limit_info *info = (struct ebt_limit_info *)data;
+	struct ebt_limit_info *info = (void *)par->matchinfo;
 	unsigned long now = jiffies;
 	unsigned long now = jiffies;
 
 
 	spin_lock_bh(&limit_lock);
 	spin_lock_bh(&limit_lock);
@@ -47,11 +45,11 @@ static int ebt_limit_match(const struct sk_buff *skb,
 		/* We're not limited. */
 		/* We're not limited. */
 		info->credit -= info->cost;
 		info->credit -= info->cost;
 		spin_unlock_bh(&limit_lock);
 		spin_unlock_bh(&limit_lock);
-		return EBT_MATCH;
+		return true;
 	}
 	}
 
 
 	spin_unlock_bh(&limit_lock);
 	spin_unlock_bh(&limit_lock);
-	return EBT_NOMATCH;
+	return false;
 }
 }
 
 
 /* Precision saver. */
 /* Precision saver. */
@@ -66,20 +64,16 @@ user2credits(u_int32_t user)
 	return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
 	return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
 }
 }
 
 
-static int ebt_limit_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	struct ebt_limit_info *info = data;
-
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info)))
-		return -EINVAL;
+	struct ebt_limit_info *info = par->matchinfo;
 
 
 	/* Check for overflow. */
 	/* Check for overflow. */
 	if (info->burst == 0 ||
 	if (info->burst == 0 ||
 	    user2credits(info->avg * info->burst) < user2credits(info->avg)) {
 	    user2credits(info->avg * info->burst) < user2credits(info->avg)) {
 		printk("Overflow in ebt_limit, try lower: %u/%u\n",
 		printk("Overflow in ebt_limit, try lower: %u/%u\n",
 			info->avg, info->burst);
 			info->avg, info->burst);
-		return -EINVAL;
+		return false;
 	}
 	}
 
 
 	/* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */
 	/* 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,
 	info->credit = user2credits(info->avg * info->burst);
 	info->credit = user2credits(info->avg * info->burst);
 	info->credit_cap = user2credits(info->avg * info->burst);
 	info->credit_cap = user2credits(info->avg * info->burst);
 	info->cost = user2credits(info->avg);
 	info->cost = user2credits(info->avg);
-	return 0;
+	return true;
 }
 }
 
 
-static struct ebt_match ebt_limit_reg __read_mostly = {
-	.name		= EBT_LIMIT_MATCH,
-	.match		= ebt_limit_match,
-	.check		= ebt_limit_check,
+static struct xt_match ebt_limit_mt_reg __read_mostly = {
+	.name		= "limit",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_limit_mt,
+	.checkentry	= ebt_limit_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_limit_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_limit_init(void)
 static int __init ebt_limit_init(void)
 {
 {
-	return ebt_register_match(&ebt_limit_reg);
+	return xt_register_match(&ebt_limit_mt_reg);
 }
 }
 
 
 static void __exit ebt_limit_fini(void)
 static void __exit ebt_limit_fini(void)
 {
 {
-	ebt_unregister_match(&ebt_limit_reg);
+	xt_unregister_match(&ebt_limit_mt_reg);
 }
 }
 
 
 module_init(ebt_limit_init);
 module_init(ebt_limit_init);

+ 28 - 29
net/bridge/netfilter/ebt_log.c

@@ -8,10 +8,6 @@
  *  April, 2002
  *  April, 2002
  *
  *
  */
  */
-
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_log.h>
-#include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/ip.h>
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/in.h>
@@ -21,22 +17,23 @@
 #include <linux/ipv6.h>
 #include <linux/ipv6.h>
 #include <net/ipv6.h>
 #include <net/ipv6.h>
 #include <linux/in6.h>
 #include <linux/in6.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_log.h>
+#include <linux/netfilter.h>
 
 
 static DEFINE_SPINLOCK(ebt_log_lock);
 static DEFINE_SPINLOCK(ebt_log_lock);
 
 
-static int ebt_log_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_log_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	struct ebt_log_info *info = data;
+	struct ebt_log_info *info = par->targinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info)))
-		return -EINVAL;
 	if (info->bitmask & ~EBT_LOG_MASK)
 	if (info->bitmask & ~EBT_LOG_MASK)
-		return -EINVAL;
+		return false;
 	if (info->loglevel >= 8)
 	if (info->loglevel >= 8)
-		return -EINVAL;
+		return false;
 	info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
 	info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
-	return 0;
+	return true;
 }
 }
 
 
 struct tcpudphdr
 struct tcpudphdr
@@ -84,7 +81,7 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
 
 
 #define myNIPQUAD(a) a[0], a[1], a[2], a[3]
 #define myNIPQUAD(a) a[0], a[1], a[2], a[3]
 static void
 static void
-ebt_log_packet(unsigned int pf, unsigned int hooknum,
+ebt_log_packet(u_int8_t pf, unsigned int hooknum,
    const struct sk_buff *skb, const struct net_device *in,
    const struct sk_buff *skb, const struct net_device *in,
    const struct net_device *out, const struct nf_loginfo *loginfo,
    const struct net_device *out, const struct nf_loginfo *loginfo,
    const char *prefix)
    const char *prefix)
@@ -194,11 +191,10 @@ out:
 
 
 }
 }
 
 
-static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static unsigned int
+ebt_log_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ebt_log_info *info = data;
+	const struct ebt_log_info *info = par->targinfo;
 	struct nf_loginfo li;
 	struct nf_loginfo li;
 
 
 	li.type = NF_LOG_TYPE_LOG;
 	li.type = NF_LOG_TYPE_LOG;
@@ -206,18 +202,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
 	li.u.log.logflags = info->bitmask;
 	li.u.log.logflags = info->bitmask;
 
 
 	if (info->bitmask & EBT_LOG_NFLOG)
 	if (info->bitmask & EBT_LOG_NFLOG)
-		nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li,
-			      "%s", info->prefix);
+		nf_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
+		              par->out, &li, "%s", info->prefix);
 	else
 	else
-		ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li,
-			       info->prefix);
+		ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
+		               par->out, &li, info->prefix);
+	return EBT_CONTINUE;
 }
 }
 
 
-static struct ebt_watcher log =
-{
-	.name		= EBT_LOG_WATCHER,
-	.watcher	= ebt_log,
-	.check		= ebt_log_check,
+static struct xt_target ebt_log_tg_reg __read_mostly = {
+	.name		= "log",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.target		= ebt_log_tg,
+	.checkentry	= ebt_log_tg_check,
+	.targetsize	= XT_ALIGN(sizeof(struct ebt_log_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -231,17 +230,17 @@ static int __init ebt_log_init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	ret = ebt_register_watcher(&log);
+	ret = xt_register_target(&ebt_log_tg_reg);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
-	nf_log_register(PF_BRIDGE, &ebt_log_logger);
+	nf_log_register(NFPROTO_BRIDGE, &ebt_log_logger);
 	return 0;
 	return 0;
 }
 }
 
 
 static void __exit ebt_log_fini(void)
 static void __exit ebt_log_fini(void)
 {
 {
 	nf_log_unregister(&ebt_log_logger);
 	nf_log_unregister(&ebt_log_logger);
-	ebt_unregister_watcher(&log);
+	xt_unregister_target(&ebt_log_tg_reg);
 }
 }
 
 
 module_init(ebt_log_init);
 module_init(ebt_log_init);

+ 20 - 21
net/bridge/netfilter/ebt_mark.c

@@ -13,15 +13,15 @@
  * Marking a frame doesn't really change anything in the frame anyway.
  * Marking a frame doesn't really change anything in the frame anyway.
  */
  */
 
 
+#include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_mark_t.h>
 #include <linux/netfilter_bridge/ebt_mark_t.h>
-#include <linux/module.h>
 
 
-static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static unsigned int
+ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ebt_mark_t_info *info = data;
+	const struct ebt_mark_t_info *info = par->targinfo;
 	int action = info->target & -16;
 	int action = info->target & -16;
 
 
 	if (action == MARK_SET_VALUE)
 	if (action == MARK_SET_VALUE)
@@ -36,42 +36,41 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
 	return info->target | ~EBT_VERDICT_BITS;
 	return info->target | ~EBT_VERDICT_BITS;
 }
 }
 
 
-static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_mark_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ebt_mark_t_info *info = data;
+	const struct ebt_mark_t_info *info = par->targinfo;
 	int tmp;
 	int tmp;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
-		return -EINVAL;
 	tmp = info->target | ~EBT_VERDICT_BITS;
 	tmp = info->target | ~EBT_VERDICT_BITS;
 	if (BASE_CHAIN && tmp == EBT_RETURN)
 	if (BASE_CHAIN && tmp == EBT_RETURN)
-		return -EINVAL;
-	CLEAR_BASE_CHAIN_BIT;
+		return false;
 	if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
 	if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
-		return -EINVAL;
+		return false;
 	tmp = info->target & ~EBT_VERDICT_BITS;
 	tmp = info->target & ~EBT_VERDICT_BITS;
 	if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
 	if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
 	    tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
 	    tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_target mark_target __read_mostly = {
-	.name		= EBT_MARK_TARGET,
-	.target		= ebt_target_mark,
-	.check		= ebt_target_mark_check,
+static struct xt_target ebt_mark_tg_reg __read_mostly = {
+	.name		= "mark",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.target		= ebt_mark_tg,
+	.checkentry	= ebt_mark_tg_check,
+	.targetsize	= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_mark_init(void)
 static int __init ebt_mark_init(void)
 {
 {
-	return ebt_register_target(&mark_target);
+	return xt_register_target(&ebt_mark_tg_reg);
 }
 }
 
 
 static void __exit ebt_mark_fini(void)
 static void __exit ebt_mark_fini(void)
 {
 {
-	ebt_unregister_target(&mark_target);
+	xt_unregister_target(&ebt_mark_tg_reg);
 }
 }
 
 
 module_init(ebt_mark_init);
 module_init(ebt_mark_init);

+ 22 - 23
net/bridge/netfilter/ebt_mark_m.c

@@ -7,53 +7,52 @@
  *  July, 2002
  *  July, 2002
  *
  *
  */
  */
-
+#include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_mark_m.h>
 #include <linux/netfilter_bridge/ebt_mark_m.h>
-#include <linux/module.h>
 
 
-static int ebt_filter_mark(const struct sk_buff *skb,
-   const struct net_device *in, const struct net_device *out, const void *data,
-   unsigned int datalen)
+static bool
+ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_mark_m_info *info = data;
+	const struct ebt_mark_m_info *info = par->matchinfo;
 
 
 	if (info->bitmask & EBT_MARK_OR)
 	if (info->bitmask & EBT_MARK_OR)
-		return !(!!(skb->mark & info->mask) ^ info->invert);
-	return !(((skb->mark & info->mask) == info->mark) ^ info->invert);
+		return !!(skb->mark & info->mask) ^ info->invert;
+	return ((skb->mark & info->mask) == info->mark) ^ info->invert;
 }
 }
 
 
-static int ebt_mark_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_mark_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ebt_mark_m_info *info = data;
+	const struct ebt_mark_m_info *info = par->matchinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info)))
-		return -EINVAL;
 	if (info->bitmask & ~EBT_MARK_MASK)
 	if (info->bitmask & ~EBT_MARK_MASK)
-		return -EINVAL;
+		return false;
 	if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
 	if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
-		return -EINVAL;
+		return false;
 	if (!info->bitmask)
 	if (!info->bitmask)
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_mark __read_mostly = {
-	.name		= EBT_MARK_MATCH,
-	.match		= ebt_filter_mark,
-	.check		= ebt_mark_check,
+static struct xt_match ebt_mark_mt_reg __read_mostly = {
+	.name		= "mark_m",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_mark_mt,
+	.checkentry	= ebt_mark_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_mark_m_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_mark_m_init(void)
 static int __init ebt_mark_m_init(void)
 {
 {
-	return ebt_register_match(&filter_mark);
+	return xt_register_match(&ebt_mark_mt_reg);
 }
 }
 
 
 static void __exit ebt_mark_m_fini(void)
 static void __exit ebt_mark_m_fini(void)
 {
 {
-	ebt_unregister_match(&filter_mark);
+	xt_unregister_match(&ebt_mark_mt_reg);
 }
 }
 
 
 module_init(ebt_mark_m_init);
 module_init(ebt_mark_m_init);

+ 21 - 23
net/bridge/netfilter/ebt_nflog.c

@@ -14,17 +14,15 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_nflog.h>
 #include <linux/netfilter_bridge/ebt_nflog.h>
 #include <net/netfilter/nf_log.h>
 #include <net/netfilter/nf_log.h>
 
 
-static void ebt_nflog(const struct sk_buff *skb,
-		      unsigned int hooknr,
-		      const struct net_device *in,
-		      const struct net_device *out,
-		      const void *data, unsigned int datalen)
+static unsigned int
+ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	struct ebt_nflog_info *info = (struct ebt_nflog_info *)data;
+	const struct ebt_nflog_info *info = par->targinfo;
 	struct nf_loginfo li;
 	struct nf_loginfo li;
 
 
 	li.type = NF_LOG_TYPE_ULOG;
 	li.type = NF_LOG_TYPE_ULOG;
@@ -32,39 +30,39 @@ static void ebt_nflog(const struct sk_buff *skb,
 	li.u.ulog.group = info->group;
 	li.u.ulog.group = info->group;
 	li.u.ulog.qthreshold = info->threshold;
 	li.u.ulog.qthreshold = info->threshold;
 
 
-	nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, "%s", info->prefix);
+	nf_log_packet(PF_BRIDGE, par->hooknum, skb, par->in, par->out,
+	              &li, "%s", info->prefix);
+	return EBT_CONTINUE;
 }
 }
 
 
-static int ebt_nflog_check(const char *tablename,
-			   unsigned int hookmask,
-			   const struct ebt_entry *e,
-			   void *data, unsigned int datalen)
+static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	struct ebt_nflog_info *info = (struct ebt_nflog_info *)data;
+	struct ebt_nflog_info *info = par->targinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_nflog_info)))
-		return -EINVAL;
 	if (info->flags & ~EBT_NFLOG_MASK)
 	if (info->flags & ~EBT_NFLOG_MASK)
-		return -EINVAL;
+		return false;
 	info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
 	info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
-	return 0;
+	return true;
 }
 }
 
 
-static struct ebt_watcher nflog __read_mostly = {
-	.name = EBT_NFLOG_WATCHER,
-	.watcher = ebt_nflog,
-	.check = ebt_nflog_check,
-	.me = THIS_MODULE,
+static struct xt_target ebt_nflog_tg_reg __read_mostly = {
+	.name       = "nflog",
+	.revision   = 0,
+	.family     = NFPROTO_BRIDGE,
+	.target     = ebt_nflog_tg,
+	.checkentry = ebt_nflog_tg_check,
+	.targetsize = XT_ALIGN(sizeof(struct ebt_nflog_info)),
+	.me         = THIS_MODULE,
 };
 };
 
 
 static int __init ebt_nflog_init(void)
 static int __init ebt_nflog_init(void)
 {
 {
-	return ebt_register_watcher(&nflog);
+	return xt_register_target(&ebt_nflog_tg_reg);
 }
 }
 
 
 static void __exit ebt_nflog_fini(void)
 static void __exit ebt_nflog_fini(void)
 {
 {
-	ebt_unregister_watcher(&nflog);
+	xt_unregister_target(&ebt_nflog_tg_reg);
 }
 }
 
 
 module_init(ebt_nflog_init);
 module_init(ebt_nflog_init);

+ 19 - 22
net/bridge/netfilter/ebt_pkttype.c

@@ -7,50 +7,47 @@
  *  April, 2003
  *  April, 2003
  *
  *
  */
  */
-
+#include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_pkttype.h>
 #include <linux/netfilter_bridge/ebt_pkttype.h>
-#include <linux/module.h>
 
 
-static int ebt_filter_pkttype(const struct sk_buff *skb,
-   const struct net_device *in,
-   const struct net_device *out,
-   const void *data,
-   unsigned int datalen)
+static bool
+ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_pkttype_info *info = data;
+	const struct ebt_pkttype_info *info = par->matchinfo;
 
 
-	return (skb->pkt_type != info->pkt_type) ^ info->invert;
+	return (skb->pkt_type == info->pkt_type) ^ info->invert;
 }
 }
 
 
-static int ebt_pkttype_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ebt_pkttype_info *info = data;
+	const struct ebt_pkttype_info *info = par->matchinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info)))
-		return -EINVAL;
 	if (info->invert != 0 && info->invert != 1)
 	if (info->invert != 0 && info->invert != 1)
-		return -EINVAL;
+		return false;
 	/* Allow any pkt_type value */
 	/* Allow any pkt_type value */
-	return 0;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_pkttype __read_mostly = {
-	.name		= EBT_PKTTYPE_MATCH,
-	.match		= ebt_filter_pkttype,
-	.check		= ebt_pkttype_check,
+static struct xt_match ebt_pkttype_mt_reg __read_mostly = {
+	.name		= "pkttype",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_pkttype_mt,
+	.checkentry	= ebt_pkttype_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_pkttype_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_pkttype_init(void)
 static int __init ebt_pkttype_init(void)
 {
 {
-	return ebt_register_match(&filter_pkttype);
+	return xt_register_match(&ebt_pkttype_mt_reg);
 }
 }
 
 
 static void __exit ebt_pkttype_fini(void)
 static void __exit ebt_pkttype_fini(void)
 {
 {
-	ebt_unregister_match(&filter_pkttype);
+	xt_unregister_match(&ebt_pkttype_mt_reg);
 }
 }
 
 
 module_init(ebt_pkttype_init);
 module_init(ebt_pkttype_init);

+ 34 - 29
net/bridge/netfilter/ebt_redirect.c

@@ -7,65 +7,70 @@
  *  April, 2002
  *  April, 2002
  *
  *
  */
  */
-
-#include <linux/netfilter.h>
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_redirect.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <net/sock.h>
 #include <net/sock.h>
 #include "../br_private.h"
 #include "../br_private.h"
+#include <linux/netfilter.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_redirect.h>
 
 
-static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static unsigned int
+ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ebt_redirect_info *info = data;
+	const struct ebt_redirect_info *info = par->targinfo;
 
 
 	if (!skb_make_writable(skb, 0))
 	if (!skb_make_writable(skb, 0))
 		return EBT_DROP;
 		return EBT_DROP;
 
 
-	if (hooknr != NF_BR_BROUTING)
+	if (par->hooknum != NF_BR_BROUTING)
 		memcpy(eth_hdr(skb)->h_dest,
 		memcpy(eth_hdr(skb)->h_dest,
-		       in->br_port->br->dev->dev_addr, ETH_ALEN);
+		       par->in->br_port->br->dev->dev_addr, ETH_ALEN);
 	else
 	else
-		memcpy(eth_hdr(skb)->h_dest, in->dev_addr, ETH_ALEN);
+		memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN);
 	skb->pkt_type = PACKET_HOST;
 	skb->pkt_type = PACKET_HOST;
 	return info->target;
 	return info->target;
 }
 }
 
 
-static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ebt_redirect_info *info = data;
+	const struct ebt_redirect_info *info = par->targinfo;
+	unsigned int hook_mask;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info)))
-		return -EINVAL;
 	if (BASE_CHAIN && info->target == EBT_RETURN)
 	if (BASE_CHAIN && info->target == EBT_RETURN)
-		return -EINVAL;
-	CLEAR_BASE_CHAIN_BIT;
-	if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) &&
-	     (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
-		return -EINVAL;
+		return false;
+
+	hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
+	if ((strcmp(par->table, "nat") != 0 ||
+	    hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
+	    (strcmp(par->table, "broute") != 0 ||
+	    hook_mask & ~(1 << NF_BR_BROUTING)))
+		return false;
 	if (INVALID_TARGET)
 	if (INVALID_TARGET)
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_target redirect_target __read_mostly = {
-	.name		= EBT_REDIRECT_TARGET,
-	.target		= ebt_target_redirect,
-	.check		= ebt_target_redirect_check,
+static struct xt_target ebt_redirect_tg_reg __read_mostly = {
+	.name		= "redirect",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.hooks		= (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
+			  (1 << NF_BR_BROUTING),
+	.target		= ebt_redirect_tg,
+	.checkentry	= ebt_redirect_tg_check,
+	.targetsize	= XT_ALIGN(sizeof(struct ebt_redirect_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_redirect_init(void)
 static int __init ebt_redirect_init(void)
 {
 {
-	return ebt_register_target(&redirect_target);
+	return xt_register_target(&ebt_redirect_tg_reg);
 }
 }
 
 
 static void __exit ebt_redirect_fini(void)
 static void __exit ebt_redirect_fini(void)
 {
 {
-	ebt_unregister_target(&redirect_target);
+	xt_unregister_target(&ebt_redirect_tg_reg);
 }
 }
 
 
 module_init(ebt_redirect_init);
 module_init(ebt_redirect_init);

+ 24 - 28
net/bridge/netfilter/ebt_snat.c

@@ -7,20 +7,19 @@
  *  June, 2002
  *  June, 2002
  *
  *
  */
  */
-
-#include <linux/netfilter.h>
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_nat.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <net/sock.h>
 #include <net/sock.h>
 #include <linux/if_arp.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
 #include <net/arp.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_nat.h>
 
 
-static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static unsigned int
+ebt_snat_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ebt_nat_info *info = data;
+	const struct ebt_nat_info *info = par->targinfo;
 
 
 	if (!skb_make_writable(skb, 0))
 	if (!skb_make_writable(skb, 0))
 		return EBT_DROP;
 		return EBT_DROP;
@@ -43,46 +42,43 @@ out:
 	return info->target | ~EBT_VERDICT_BITS;
 	return info->target | ~EBT_VERDICT_BITS;
 }
 }
 
 
-static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_snat_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ebt_nat_info *info = data;
+	const struct ebt_nat_info *info = par->targinfo;
 	int tmp;
 	int tmp;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
-		return -EINVAL;
 	tmp = info->target | ~EBT_VERDICT_BITS;
 	tmp = info->target | ~EBT_VERDICT_BITS;
 	if (BASE_CHAIN && tmp == EBT_RETURN)
 	if (BASE_CHAIN && tmp == EBT_RETURN)
-		return -EINVAL;
-	CLEAR_BASE_CHAIN_BIT;
-	if (strcmp(tablename, "nat"))
-		return -EINVAL;
-	if (hookmask & ~(1 << NF_BR_POST_ROUTING))
-		return -EINVAL;
+		return false;
 
 
 	if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
 	if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
-		return -EINVAL;
+		return false;
 	tmp = info->target | EBT_VERDICT_BITS;
 	tmp = info->target | EBT_VERDICT_BITS;
 	if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
 	if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
-		return -EINVAL;
-	return 0;
+		return false;
+	return true;
 }
 }
 
 
-static struct ebt_target snat __read_mostly = {
-	.name		= EBT_SNAT_TARGET,
-	.target		= ebt_target_snat,
-	.check		= ebt_target_snat_check,
+static struct xt_target ebt_snat_tg_reg __read_mostly = {
+	.name		= "snat",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.table		= "nat",
+	.hooks		= (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_POST_ROUTING),
+	.target		= ebt_snat_tg,
+	.checkentry	= ebt_snat_tg_check,
+	.targetsize	= XT_ALIGN(sizeof(struct ebt_nat_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_snat_init(void)
 static int __init ebt_snat_init(void)
 {
 {
-	return ebt_register_target(&snat);
+	return xt_register_target(&ebt_snat_tg_reg);
 }
 }
 
 
 static void __exit ebt_snat_fini(void)
 static void __exit ebt_snat_fini(void)
 {
 {
-	ebt_unregister_target(&snat);
+	xt_unregister_target(&ebt_snat_tg_reg);
 }
 }
 
 
 module_init(ebt_snat_init);
 module_init(ebt_snat_init);

+ 39 - 39
net/bridge/netfilter/ebt_stp.c

@@ -7,11 +7,11 @@
  *
  *
  *  July, 2003
  *  July, 2003
  */
  */
-
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter_bridge/ebt_stp.h>
 #include <linux/etherdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/module.h>
 #include <linux/module.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_stp.h>
 
 
 #define BPDU_TYPE_CONFIG 0
 #define BPDU_TYPE_CONFIG 0
 #define BPDU_TYPE_TCN 0x80
 #define BPDU_TYPE_TCN 0x80
@@ -40,7 +40,7 @@ struct stp_config_pdu {
 #define NR16(p) (p[0] << 8 | p[1])
 #define NR16(p) (p[0] << 8 | p[1])
 #define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])
 #define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])
 
 
-static int ebt_filter_config(const struct ebt_stp_info *info,
+static bool ebt_filter_config(const struct ebt_stp_info *info,
    const struct stp_config_pdu *stpc)
    const struct stp_config_pdu *stpc)
 {
 {
 	const struct ebt_stp_config_info *c;
 	const struct ebt_stp_config_info *c;
@@ -51,12 +51,12 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
 	c = &info->config;
 	c = &info->config;
 	if ((info->bitmask & EBT_STP_FLAGS) &&
 	if ((info->bitmask & EBT_STP_FLAGS) &&
 	    FWINV(c->flags != stpc->flags, EBT_STP_FLAGS))
 	    FWINV(c->flags != stpc->flags, EBT_STP_FLAGS))
-		return EBT_NOMATCH;
+		return false;
 	if (info->bitmask & EBT_STP_ROOTPRIO) {
 	if (info->bitmask & EBT_STP_ROOTPRIO) {
 		v16 = NR16(stpc->root);
 		v16 = NR16(stpc->root);
 		if (FWINV(v16 < c->root_priol ||
 		if (FWINV(v16 < c->root_priol ||
 		    v16 > c->root_priou, EBT_STP_ROOTPRIO))
 		    v16 > c->root_priou, EBT_STP_ROOTPRIO))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_ROOTADDR) {
 	if (info->bitmask & EBT_STP_ROOTADDR) {
 		verdict = 0;
 		verdict = 0;
@@ -64,19 +64,19 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
 			verdict |= (stpc->root[2+i] ^ c->root_addr[i]) &
 			verdict |= (stpc->root[2+i] ^ c->root_addr[i]) &
 				   c->root_addrmsk[i];
 				   c->root_addrmsk[i];
 		if (FWINV(verdict != 0, EBT_STP_ROOTADDR))
 		if (FWINV(verdict != 0, EBT_STP_ROOTADDR))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_ROOTCOST) {
 	if (info->bitmask & EBT_STP_ROOTCOST) {
 		v32 = NR32(stpc->root_cost);
 		v32 = NR32(stpc->root_cost);
 		if (FWINV(v32 < c->root_costl ||
 		if (FWINV(v32 < c->root_costl ||
 		    v32 > c->root_costu, EBT_STP_ROOTCOST))
 		    v32 > c->root_costu, EBT_STP_ROOTCOST))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_SENDERPRIO) {
 	if (info->bitmask & EBT_STP_SENDERPRIO) {
 		v16 = NR16(stpc->sender);
 		v16 = NR16(stpc->sender);
 		if (FWINV(v16 < c->sender_priol ||
 		if (FWINV(v16 < c->sender_priol ||
 		    v16 > c->sender_priou, EBT_STP_SENDERPRIO))
 		    v16 > c->sender_priou, EBT_STP_SENDERPRIO))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_SENDERADDR) {
 	if (info->bitmask & EBT_STP_SENDERADDR) {
 		verdict = 0;
 		verdict = 0;
@@ -84,60 +84,60 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
 			verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) &
 			verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) &
 				   c->sender_addrmsk[i];
 				   c->sender_addrmsk[i];
 		if (FWINV(verdict != 0, EBT_STP_SENDERADDR))
 		if (FWINV(verdict != 0, EBT_STP_SENDERADDR))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_PORT) {
 	if (info->bitmask & EBT_STP_PORT) {
 		v16 = NR16(stpc->port);
 		v16 = NR16(stpc->port);
 		if (FWINV(v16 < c->portl ||
 		if (FWINV(v16 < c->portl ||
 		    v16 > c->portu, EBT_STP_PORT))
 		    v16 > c->portu, EBT_STP_PORT))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_MSGAGE) {
 	if (info->bitmask & EBT_STP_MSGAGE) {
 		v16 = NR16(stpc->msg_age);
 		v16 = NR16(stpc->msg_age);
 		if (FWINV(v16 < c->msg_agel ||
 		if (FWINV(v16 < c->msg_agel ||
 		    v16 > c->msg_ageu, EBT_STP_MSGAGE))
 		    v16 > c->msg_ageu, EBT_STP_MSGAGE))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_MAXAGE) {
 	if (info->bitmask & EBT_STP_MAXAGE) {
 		v16 = NR16(stpc->max_age);
 		v16 = NR16(stpc->max_age);
 		if (FWINV(v16 < c->max_agel ||
 		if (FWINV(v16 < c->max_agel ||
 		    v16 > c->max_ageu, EBT_STP_MAXAGE))
 		    v16 > c->max_ageu, EBT_STP_MAXAGE))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_HELLOTIME) {
 	if (info->bitmask & EBT_STP_HELLOTIME) {
 		v16 = NR16(stpc->hello_time);
 		v16 = NR16(stpc->hello_time);
 		if (FWINV(v16 < c->hello_timel ||
 		if (FWINV(v16 < c->hello_timel ||
 		    v16 > c->hello_timeu, EBT_STP_HELLOTIME))
 		    v16 > c->hello_timeu, EBT_STP_HELLOTIME))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
 	if (info->bitmask & EBT_STP_FWDD) {
 	if (info->bitmask & EBT_STP_FWDD) {
 		v16 = NR16(stpc->forward_delay);
 		v16 = NR16(stpc->forward_delay);
 		if (FWINV(v16 < c->forward_delayl ||
 		if (FWINV(v16 < c->forward_delayl ||
 		    v16 > c->forward_delayu, EBT_STP_FWDD))
 		    v16 > c->forward_delayu, EBT_STP_FWDD))
-			return EBT_NOMATCH;
+			return false;
 	}
 	}
-	return EBT_MATCH;
+	return true;
 }
 }
 
 
-static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out, const void *data, unsigned int datalen)
+static bool
+ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_stp_info *info = data;
+	const struct ebt_stp_info *info = par->matchinfo;
 	const struct stp_header *sp;
 	const struct stp_header *sp;
 	struct stp_header _stph;
 	struct stp_header _stph;
 	const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
 	const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
 
 
 	sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph);
 	sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph);
 	if (sp == NULL)
 	if (sp == NULL)
-		return EBT_NOMATCH;
+		return false;
 
 
 	/* The stp code only considers these */
 	/* The stp code only considers these */
 	if (memcmp(sp, header, sizeof(header)))
 	if (memcmp(sp, header, sizeof(header)))
-		return EBT_NOMATCH;
+		return false;
 
 
 	if (info->bitmask & EBT_STP_TYPE
 	if (info->bitmask & EBT_STP_TYPE
 	    && FWINV(info->type != sp->type, EBT_STP_TYPE))
 	    && FWINV(info->type != sp->type, EBT_STP_TYPE))
-		return EBT_NOMATCH;
+		return false;
 
 
 	if (sp->type == BPDU_TYPE_CONFIG &&
 	if (sp->type == BPDU_TYPE_CONFIG &&
 	    info->bitmask & EBT_STP_CONFIG_MASK) {
 	    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
 		st = skb_header_pointer(skb, sizeof(_stph),
 		st = skb_header_pointer(skb, sizeof(_stph),
 					sizeof(_stpc), &_stpc);
 					sizeof(_stpc), &_stpc);
 		if (st == NULL)
 		if (st == NULL)
-			return EBT_NOMATCH;
+			return false;
 		return ebt_filter_config(info, st);
 		return ebt_filter_config(info, st);
 	}
 	}
-	return EBT_MATCH;
+	return true;
 }
 }
 
 
-static int ebt_stp_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ebt_stp_info *info = data;
-	const unsigned int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
+	const struct ebt_stp_info *info = par->matchinfo;
 	const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
 	const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
 	const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 	const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+	const struct ebt_entry *e = par->entryinfo;
 
 
 	if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
 	if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
 	    !(info->bitmask & EBT_STP_MASK))
 	    !(info->bitmask & EBT_STP_MASK))
-		return -EINVAL;
-	if (datalen != len)
-		return -EINVAL;
+		return false;
 	/* Make sure the match only receives stp frames */
 	/* Make sure the match only receives stp frames */
 	if (compare_ether_addr(e->destmac, bridge_ula) ||
 	if (compare_ether_addr(e->destmac, bridge_ula) ||
 	    compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC))
 	    compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC))
-		return -EINVAL;
+		return false;
 
 
-	return 0;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_stp __read_mostly = {
-	.name		= EBT_STP_MATCH,
-	.match		= ebt_filter_stp,
-	.check		= ebt_stp_check,
+static struct xt_match ebt_stp_mt_reg __read_mostly = {
+	.name		= "stp",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_stp_mt,
+	.checkentry	= ebt_stp_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_stp_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_stp_init(void)
 static int __init ebt_stp_init(void)
 {
 {
-	return ebt_register_match(&filter_stp);
+	return xt_register_match(&ebt_stp_mt_reg);
 }
 }
 
 
 static void __exit ebt_stp_fini(void)
 static void __exit ebt_stp_fini(void)
 {
 {
-	ebt_unregister_match(&filter_stp);
+	xt_unregister_match(&ebt_stp_mt_reg);
 }
 }
 
 
 module_init(ebt_stp_init);
 module_init(ebt_stp_init);

+ 31 - 27
net/bridge/netfilter/ebt_ulog.c

@@ -36,6 +36,7 @@
 #include <linux/timer.h>
 #include <linux/timer.h>
 #include <linux/netlink.h>
 #include <linux/netlink.h>
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_ulog.h>
 #include <linux/netfilter_bridge/ebt_ulog.h>
 #include <net/netfilter/nf_log.h>
 #include <net/netfilter/nf_log.h>
@@ -223,7 +224,7 @@ alloc_failure:
 }
 }
 
 
 /* this function is registered with the netfilter core */
 /* this function is registered with the netfilter core */
-static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
+static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
    const struct sk_buff *skb, const struct net_device *in,
    const struct sk_buff *skb, const struct net_device *in,
    const struct net_device *out, const struct nf_loginfo *li,
    const struct net_device *out, const struct nf_loginfo *li,
    const char *prefix)
    const char *prefix)
@@ -245,24 +246,20 @@ static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
 	ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
 	ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
 }
 }
 
 
-static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static unsigned int
+ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ebt_ulog_info *uloginfo = data;
-
-	ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
+	ebt_ulog_packet(par->hooknum, skb, par->in, par->out,
+	                par->targinfo, NULL);
+	return EBT_CONTINUE;
 }
 }
 
 
-
-static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
-   const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	struct ebt_ulog_info *uloginfo = data;
+	struct ebt_ulog_info *uloginfo = par->targinfo;
 
 
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) ||
-	    uloginfo->nlgroup > 31)
-		return -EINVAL;
+	if (uloginfo->nlgroup > 31)
+		return false;
 
 
 	uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
 	uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
 
 
@@ -272,27 +269,31 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
 	return 0;
 	return 0;
 }
 }
 
 
-static struct ebt_watcher ulog __read_mostly = {
-	.name		= EBT_ULOG_WATCHER,
-	.watcher	= ebt_ulog,
-	.check		= ebt_ulog_check,
+static struct xt_target ebt_ulog_tg_reg __read_mostly = {
+	.name		= "ulog",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.target		= ebt_ulog_tg,
+	.checkentry	= ebt_ulog_tg_check,
+	.targetsize	= XT_ALIGN(sizeof(struct ebt_ulog_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static const struct nf_logger ebt_ulog_logger = {
 static const struct nf_logger ebt_ulog_logger = {
-	.name		= EBT_ULOG_WATCHER,
+	.name		= "ulog",
 	.logfn		= &ebt_log_packet,
 	.logfn		= &ebt_log_packet,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
 static int __init ebt_ulog_init(void)
 static int __init ebt_ulog_init(void)
 {
 {
-	int i, ret = 0;
+	bool ret = true;
+	int i;
 
 
 	if (nlbufsiz >= 128*1024) {
 	if (nlbufsiz >= 128*1024) {
 		printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB,"
 		printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB,"
 		       " please try a smaller nlbufsiz parameter.\n");
 		       " please try a smaller nlbufsiz parameter.\n");
-		return -EINVAL;
+		return false;
 	}
 	}
 
 
 	/* initialize ulog_buffers */
 	/* initialize ulog_buffers */
@@ -304,13 +305,16 @@ static int __init ebt_ulog_init(void)
 	ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
 	ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
 					  EBT_ULOG_MAXNLGROUPS, NULL, NULL,
 					  EBT_ULOG_MAXNLGROUPS, NULL, NULL,
 					  THIS_MODULE);
 					  THIS_MODULE);
-	if (!ebtulognl)
-		ret = -ENOMEM;
-	else if ((ret = ebt_register_watcher(&ulog)))
+	if (!ebtulognl) {
+		printk(KERN_WARNING KBUILD_MODNAME ": out of memory trying to "
+		       "call netlink_kernel_create\n");
+		ret = false;
+	} else if (xt_register_target(&ebt_ulog_tg_reg) != 0) {
 		netlink_kernel_release(ebtulognl);
 		netlink_kernel_release(ebtulognl);
+	}
 
 
-	if (ret == 0)
-		nf_log_register(PF_BRIDGE, &ebt_ulog_logger);
+	if (ret)
+		nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -321,7 +325,7 @@ static void __exit ebt_ulog_fini(void)
 	int i;
 	int i;
 
 
 	nf_log_unregister(&ebt_ulog_logger);
 	nf_log_unregister(&ebt_ulog_logger);
-	ebt_unregister_watcher(&ulog);
+	xt_unregister_target(&ebt_ulog_tg_reg);
 	for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
 	for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
 		ub = &ulog_buffers[i];
 		ub = &ulog_buffers[i];
 		if (timer_pending(&ub->timer))
 		if (timer_pending(&ub->timer))

+ 26 - 35
net/bridge/netfilter/ebt_vlan.c

@@ -22,6 +22,7 @@
 #include <linux/if_vlan.h>
 #include <linux/if_vlan.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_vlan.h>
 #include <linux/netfilter_bridge/ebt_vlan.h>
 
 
@@ -37,15 +38,12 @@ MODULE_LICENSE("GPL");
 
 
 #define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
 #define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
 #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
 #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
-#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;}
+#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; }
 
 
-static int
-ebt_filter_vlan(const struct sk_buff *skb,
-		const struct net_device *in,
-		const struct net_device *out,
-		const void *data, unsigned int datalen)
+static bool
+ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ebt_vlan_info *info = data;
+	const struct ebt_vlan_info *info = par->matchinfo;
 	const struct vlan_hdr *fp;
 	const struct vlan_hdr *fp;
 	struct vlan_hdr _frame;
 	struct vlan_hdr _frame;
 
 
@@ -57,7 +55,7 @@ ebt_filter_vlan(const struct sk_buff *skb,
 
 
 	fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
 	fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
 	if (fp == NULL)
 	if (fp == NULL)
-		return EBT_NOMATCH;
+		return false;
 
 
 	/* Tag Control Information (TCI) consists of the following elements:
 	/* Tag Control Information (TCI) consists of the following elements:
 	 * - User_priority. The user_priority field is three bits in length,
 	 * - User_priority. The user_priority field is three bits in length,
@@ -83,30 +81,20 @@ ebt_filter_vlan(const struct sk_buff *skb,
 	if (GET_BITMASK(EBT_VLAN_ENCAP))
 	if (GET_BITMASK(EBT_VLAN_ENCAP))
 		EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);
 		EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);
 
 
-	return EBT_MATCH;
+	return true;
 }
 }
 
 
-static int
-ebt_check_vlan(const char *tablename,
-	       unsigned int hooknr,
-	       const struct ebt_entry *e, void *data, unsigned int datalen)
+static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	struct ebt_vlan_info *info = data;
-
-	/* Parameters buffer overflow check */
-	if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) {
-		DEBUG_MSG
-		    ("passed size %d is not eq to ebt_vlan_info (%Zd)\n",
-		     datalen, sizeof(struct ebt_vlan_info));
-		return -EINVAL;
-	}
+	struct ebt_vlan_info *info = par->matchinfo;
+	const struct ebt_entry *e = par->entryinfo;
 
 
 	/* Is it 802.1Q frame checked? */
 	/* Is it 802.1Q frame checked? */
 	if (e->ethproto != htons(ETH_P_8021Q)) {
 	if (e->ethproto != htons(ETH_P_8021Q)) {
 		DEBUG_MSG
 		DEBUG_MSG
 		    ("passed entry proto %2.4X is not 802.1Q (8100)\n",
 		    ("passed entry proto %2.4X is not 802.1Q (8100)\n",
 		     (unsigned short) ntohs(e->ethproto));
 		     (unsigned short) ntohs(e->ethproto));
-		return -EINVAL;
+		return false;
 	}
 	}
 
 
 	/* Check for bitmask range
 	/* Check for bitmask range
@@ -114,14 +102,14 @@ ebt_check_vlan(const char *tablename,
 	if (info->bitmask & ~EBT_VLAN_MASK) {
 	if (info->bitmask & ~EBT_VLAN_MASK) {
 		DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
 		DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
 			  info->bitmask, EBT_VLAN_MASK);
 			  info->bitmask, EBT_VLAN_MASK);
-		return -EINVAL;
+		return false;
 	}
 	}
 
 
 	/* Check for inversion flags range */
 	/* Check for inversion flags range */
 	if (info->invflags & ~EBT_VLAN_MASK) {
 	if (info->invflags & ~EBT_VLAN_MASK) {
 		DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
 		DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
 			  info->invflags, EBT_VLAN_MASK);
 			  info->invflags, EBT_VLAN_MASK);
-		return -EINVAL;
+		return false;
 	}
 	}
 
 
 	/* Reserved VLAN ID (VID) values
 	/* Reserved VLAN ID (VID) values
@@ -136,7 +124,7 @@ ebt_check_vlan(const char *tablename,
 				DEBUG_MSG
 				DEBUG_MSG
 				    ("id %d is out of range (1-4096)\n",
 				    ("id %d is out of range (1-4096)\n",
 				     info->id);
 				     info->id);
-				return -EINVAL;
+				return false;
 			}
 			}
 			/* Note: This is valid VLAN-tagged frame point.
 			/* Note: This is valid VLAN-tagged frame point.
 			 * Any value of user_priority are acceptable,
 			 * Any value of user_priority are acceptable,
@@ -151,7 +139,7 @@ ebt_check_vlan(const char *tablename,
 		if ((unsigned char) info->prio > 7) {
 		if ((unsigned char) info->prio > 7) {
 			DEBUG_MSG("prio %d is out of range (0-7)\n",
 			DEBUG_MSG("prio %d is out of range (0-7)\n",
 			     info->prio);
 			     info->prio);
-			return -EINVAL;
+			return false;
 		}
 		}
 	}
 	}
 	/* Check for encapsulated proto range - it is possible to be
 	/* Check for encapsulated proto range - it is possible to be
@@ -162,17 +150,20 @@ ebt_check_vlan(const char *tablename,
 			DEBUG_MSG
 			DEBUG_MSG
 			    ("encap frame length %d is less than minimal\n",
 			    ("encap frame length %d is less than minimal\n",
 			     ntohs(info->encap));
 			     ntohs(info->encap));
-			return -EINVAL;
+			return false;
 		}
 		}
 	}
 	}
 
 
-	return 0;
+	return true;
 }
 }
 
 
-static struct ebt_match filter_vlan __read_mostly = {
-	.name		= EBT_VLAN_MATCH,
-	.match		= ebt_filter_vlan,
-	.check		= ebt_check_vlan,
+static struct xt_match ebt_vlan_mt_reg __read_mostly = {
+	.name		= "vlan",
+	.revision	= 0,
+	.family		= NFPROTO_BRIDGE,
+	.match		= ebt_vlan_mt,
+	.checkentry	= ebt_vlan_mt_check,
+	.matchsize	= XT_ALIGN(sizeof(struct ebt_vlan_info)),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 };
 };
 
 
@@ -181,12 +172,12 @@ static int __init ebt_vlan_init(void)
 	DEBUG_MSG("ebtables 802.1Q extension module v"
 	DEBUG_MSG("ebtables 802.1Q extension module v"
 		  MODULE_VERS "\n");
 		  MODULE_VERS "\n");
 	DEBUG_MSG("module debug=%d\n", !!debug);
 	DEBUG_MSG("module debug=%d\n", !!debug);
-	return ebt_register_match(&filter_vlan);
+	return xt_register_match(&ebt_vlan_mt_reg);
 }
 }
 
 
 static void __exit ebt_vlan_fini(void)
 static void __exit ebt_vlan_fini(void)
 {
 {
-	ebt_unregister_match(&filter_vlan);
+	xt_unregister_match(&ebt_vlan_mt_reg);
 }
 }
 
 
 module_init(ebt_vlan_init);
 module_init(ebt_vlan_init);

+ 134 - 179
net/bridge/netfilter/ebtables.c

@@ -19,6 +19,7 @@
 #include <linux/kmod.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
@@ -55,29 +56,31 @@
 
 
 static DEFINE_MUTEX(ebt_mutex);
 static DEFINE_MUTEX(ebt_mutex);
 static LIST_HEAD(ebt_tables);
 static LIST_HEAD(ebt_tables);
-static LIST_HEAD(ebt_targets);
-static LIST_HEAD(ebt_matches);
-static LIST_HEAD(ebt_watchers);
 
 
-static struct ebt_target ebt_standard_target =
-{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL};
+static struct xt_target ebt_standard_target = {
+	.name       = "standard",
+	.revision   = 0,
+	.family     = NFPROTO_BRIDGE,
+	.targetsize = sizeof(int),
+};
 
 
-static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
-   const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in,
-   const struct net_device *out)
+static inline int
+ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
+	       struct xt_target_param *par)
 {
 {
-	w->u.watcher->watcher(skb, hooknr, in, out, w->data,
-	   w->watcher_size);
+	par->target   = w->u.watcher;
+	par->targinfo = w->data;
+	w->u.watcher->target(skb, par);
 	/* watchers don't give a verdict */
 	/* watchers don't give a verdict */
 	return 0;
 	return 0;
 }
 }
 
 
 static inline int ebt_do_match (struct ebt_entry_match *m,
 static inline int ebt_do_match (struct ebt_entry_match *m,
-   const struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out)
+   const struct sk_buff *skb, struct xt_match_param *par)
 {
 {
-	return m->u.match->match(skb, in, out, m->data,
-	   m->match_size);
+	par->match     = m->u.match;
+	par->matchinfo = m->data;
+	return m->u.match->match(skb, par);
 }
 }
 
 
 static inline int ebt_dev_check(char *entry, const struct net_device *device)
 static inline int ebt_dev_check(char *entry, const struct net_device *device)
@@ -153,6 +156,15 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
 	struct ebt_entries *chaininfo;
 	struct ebt_entries *chaininfo;
 	char *base;
 	char *base;
 	struct ebt_table_info *private;
 	struct ebt_table_info *private;
+	bool hotdrop = false;
+	struct xt_match_param mtpar;
+	struct xt_target_param tgpar;
+
+	mtpar.family  = tgpar.family = NFPROTO_BRIDGE;
+	mtpar.in      = tgpar.in  = in;
+	mtpar.out     = tgpar.out = out;
+	mtpar.hotdrop = &hotdrop;
+	tgpar.hooknum = hook;
 
 
 	read_lock_bh(&table->lock);
 	read_lock_bh(&table->lock);
 	private = table->private;
 	private = table->private;
@@ -173,8 +185,12 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
 		if (ebt_basic_match(point, eth_hdr(skb), in, out))
 		if (ebt_basic_match(point, eth_hdr(skb), in, out))
 			goto letscontinue;
 			goto letscontinue;
 
 
-		if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0)
+		if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &mtpar) != 0)
 			goto letscontinue;
 			goto letscontinue;
+		if (hotdrop) {
+			read_unlock_bh(&table->lock);
+			return NF_DROP;
+		}
 
 
 		/* increase counter */
 		/* increase counter */
 		(*(counter_base + i)).pcnt++;
 		(*(counter_base + i)).pcnt++;
@@ -182,17 +198,18 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
 
 
 		/* these should only watch: not modify, nor tell us
 		/* these should only watch: not modify, nor tell us
 		   what to do with the packet */
 		   what to do with the packet */
-		EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in,
-		   out);
+		EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &tgpar);
 
 
 		t = (struct ebt_entry_target *)
 		t = (struct ebt_entry_target *)
 		   (((char *)point) + point->target_offset);
 		   (((char *)point) + point->target_offset);
 		/* standard target */
 		/* standard target */
 		if (!t->u.target->target)
 		if (!t->u.target->target)
 			verdict = ((struct ebt_standard_target *)t)->verdict;
 			verdict = ((struct ebt_standard_target *)t)->verdict;
-		else
-			verdict = t->u.target->target(skb, hook,
-			   in, out, t->data, t->target_size);
+		else {
+			tgpar.target   = t->u.target;
+			tgpar.targinfo = t->data;
+			verdict = t->u.target->target(skb, &tgpar);
+		}
 		if (verdict == EBT_ACCEPT) {
 		if (verdict == EBT_ACCEPT) {
 			read_unlock_bh(&table->lock);
 			read_unlock_bh(&table->lock);
 			return NF_ACCEPT;
 			return NF_ACCEPT;
@@ -312,80 +329,71 @@ find_table_lock(const char *name, int *error, struct mutex *mutex)
 	return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
 	return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
 }
 }
 
 
-static inline struct ebt_match *
-find_match_lock(const char *name, int *error, struct mutex *mutex)
-{
-	return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
-}
-
-static inline struct ebt_watcher *
-find_watcher_lock(const char *name, int *error, struct mutex *mutex)
-{
-	return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
-}
-
-static inline struct ebt_target *
-find_target_lock(const char *name, int *error, struct mutex *mutex)
-{
-	return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
-}
-
 static inline int
 static inline int
-ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
-   const char *name, unsigned int hookmask, unsigned int *cnt)
+ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
+		unsigned int *cnt)
 {
 {
-	struct ebt_match *match;
+	const struct ebt_entry *e = par->entryinfo;
+	struct xt_match *match;
 	size_t left = ((char *)e + e->watchers_offset) - (char *)m;
 	size_t left = ((char *)e + e->watchers_offset) - (char *)m;
 	int ret;
 	int ret;
 
 
 	if (left < sizeof(struct ebt_entry_match) ||
 	if (left < sizeof(struct ebt_entry_match) ||
 	    left - sizeof(struct ebt_entry_match) < m->match_size)
 	    left - sizeof(struct ebt_entry_match) < m->match_size)
 		return -EINVAL;
 		return -EINVAL;
-	match = find_match_lock(m->u.name, &ret, &ebt_mutex);
-	if (!match)
-		return ret;
-	m->u.match = match;
-	if (!try_module_get(match->me)) {
-		mutex_unlock(&ebt_mutex);
+
+	match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE,
+		m->u.name, 0), "ebt_%s", m->u.name);
+	if (IS_ERR(match))
+		return PTR_ERR(match);
+	if (match == NULL)
 		return -ENOENT;
 		return -ENOENT;
-	}
-	mutex_unlock(&ebt_mutex);
-	if (match->check &&
-	   match->check(name, hookmask, e, m->data, m->match_size) != 0) {
-		BUGPRINT("match->check failed\n");
+	m->u.match = match;
+
+	par->match     = match;
+	par->matchinfo = m->data;
+	ret = xt_check_match(par, m->match_size,
+	      e->ethproto, e->invflags & EBT_IPROTO);
+	if (ret < 0) {
 		module_put(match->me);
 		module_put(match->me);
-		return -EINVAL;
+		return ret;
 	}
 	}
+
 	(*cnt)++;
 	(*cnt)++;
 	return 0;
 	return 0;
 }
 }
 
 
 static inline int
 static inline int
-ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
-   const char *name, unsigned int hookmask, unsigned int *cnt)
+ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
+		  unsigned int *cnt)
 {
 {
-	struct ebt_watcher *watcher;
+	const struct ebt_entry *e = par->entryinfo;
+	struct xt_target *watcher;
 	size_t left = ((char *)e + e->target_offset) - (char *)w;
 	size_t left = ((char *)e + e->target_offset) - (char *)w;
 	int ret;
 	int ret;
 
 
 	if (left < sizeof(struct ebt_entry_watcher) ||
 	if (left < sizeof(struct ebt_entry_watcher) ||
 	   left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
 	   left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
 		return -EINVAL;
 		return -EINVAL;
-	watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
-	if (!watcher)
-		return ret;
-	w->u.watcher = watcher;
-	if (!try_module_get(watcher->me)) {
-		mutex_unlock(&ebt_mutex);
+
+	watcher = try_then_request_module(
+		  xt_find_target(NFPROTO_BRIDGE, w->u.name, 0),
+		  "ebt_%s", w->u.name);
+	if (IS_ERR(watcher))
+		return PTR_ERR(watcher);
+	if (watcher == NULL)
 		return -ENOENT;
 		return -ENOENT;
-	}
-	mutex_unlock(&ebt_mutex);
-	if (watcher->check &&
-	   watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
-		BUGPRINT("watcher->check failed\n");
+	w->u.watcher = watcher;
+
+	par->target   = watcher;
+	par->targinfo = w->data;
+	ret = xt_check_target(par, w->watcher_size,
+	      e->ethproto, e->invflags & EBT_IPROTO);
+	if (ret < 0) {
 		module_put(watcher->me);
 		module_put(watcher->me);
-		return -EINVAL;
+		return ret;
 	}
 	}
+
 	(*cnt)++;
 	(*cnt)++;
 	return 0;
 	return 0;
 }
 }
@@ -558,30 +566,41 @@ ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
 static inline int
 static inline int
 ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
 ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
 {
 {
+	struct xt_mtdtor_param par;
+
 	if (i && (*i)-- == 0)
 	if (i && (*i)-- == 0)
 		return 1;
 		return 1;
-	if (m->u.match->destroy)
-		m->u.match->destroy(m->data, m->match_size);
-	module_put(m->u.match->me);
 
 
+	par.match     = m->u.match;
+	par.matchinfo = m->data;
+	par.family    = NFPROTO_BRIDGE;
+	if (par.match->destroy != NULL)
+		par.match->destroy(&par);
+	module_put(par.match->me);
 	return 0;
 	return 0;
 }
 }
 
 
 static inline int
 static inline int
 ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
 ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
 {
 {
+	struct xt_tgdtor_param par;
+
 	if (i && (*i)-- == 0)
 	if (i && (*i)-- == 0)
 		return 1;
 		return 1;
-	if (w->u.watcher->destroy)
-		w->u.watcher->destroy(w->data, w->watcher_size);
-	module_put(w->u.watcher->me);
 
 
+	par.target   = w->u.watcher;
+	par.targinfo = w->data;
+	par.family   = NFPROTO_BRIDGE;
+	if (par.target->destroy != NULL)
+		par.target->destroy(&par);
+	module_put(par.target->me);
 	return 0;
 	return 0;
 }
 }
 
 
 static inline int
 static inline int
 ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
 ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
 {
 {
+	struct xt_tgdtor_param par;
 	struct ebt_entry_target *t;
 	struct ebt_entry_target *t;
 
 
 	if (e->bitmask == 0)
 	if (e->bitmask == 0)
@@ -592,10 +611,13 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
 	EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
 	EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
 	EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
 	EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
 	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
 	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
-	if (t->u.target->destroy)
-		t->u.target->destroy(t->data, t->target_size);
-	module_put(t->u.target->me);
 
 
+	par.target   = t->u.target;
+	par.targinfo = t->data;
+	par.family   = NFPROTO_BRIDGE;
+	if (par.target->destroy != NULL)
+		par.target->destroy(&par);
+	module_put(par.target->me);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -605,10 +627,12 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
    struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
    struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
 {
 {
 	struct ebt_entry_target *t;
 	struct ebt_entry_target *t;
-	struct ebt_target *target;
+	struct xt_target *target;
 	unsigned int i, j, hook = 0, hookmask = 0;
 	unsigned int i, j, hook = 0, hookmask = 0;
 	size_t gap;
 	size_t gap;
 	int ret;
 	int ret;
+	struct xt_mtchk_param mtpar;
+	struct xt_tgchk_param tgpar;
 
 
 	/* don't mess with the struct ebt_entries */
 	/* don't mess with the struct ebt_entries */
 	if (e->bitmask == 0)
 	if (e->bitmask == 0)
@@ -649,24 +673,31 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
 			hookmask = cl_s[i - 1].hookmask;
 			hookmask = cl_s[i - 1].hookmask;
 	}
 	}
 	i = 0;
 	i = 0;
-	ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
+
+	mtpar.table     = tgpar.table     = name;
+	mtpar.entryinfo = tgpar.entryinfo = e;
+	mtpar.hook_mask = tgpar.hook_mask = hookmask;
+	mtpar.family    = tgpar.family    = NFPROTO_BRIDGE;
+	ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
 	if (ret != 0)
 	if (ret != 0)
 		goto cleanup_matches;
 		goto cleanup_matches;
 	j = 0;
 	j = 0;
-	ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
+	ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, &tgpar, &j);
 	if (ret != 0)
 	if (ret != 0)
 		goto cleanup_watchers;
 		goto cleanup_watchers;
 	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
 	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
 	gap = e->next_offset - e->target_offset;
 	gap = e->next_offset - e->target_offset;
-	target = find_target_lock(t->u.name, &ret, &ebt_mutex);
-	if (!target)
+
+	target = try_then_request_module(
+		 xt_find_target(NFPROTO_BRIDGE, t->u.name, 0),
+		 "ebt_%s", t->u.name);
+	if (IS_ERR(target)) {
+		ret = PTR_ERR(target);
 		goto cleanup_watchers;
 		goto cleanup_watchers;
-	if (!try_module_get(target->me)) {
-		mutex_unlock(&ebt_mutex);
+	} else if (target == NULL) {
 		ret = -ENOENT;
 		ret = -ENOENT;
 		goto cleanup_watchers;
 		goto cleanup_watchers;
 	}
 	}
-	mutex_unlock(&ebt_mutex);
 
 
 	t->u.target = target;
 	t->u.target = target;
 	if (t->u.target == &ebt_standard_target) {
 	if (t->u.target == &ebt_standard_target) {
@@ -681,13 +712,20 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
 			ret = -EFAULT;
 			ret = -EFAULT;
 			goto cleanup_watchers;
 			goto cleanup_watchers;
 		}
 		}
-	} else if (t->target_size > gap - sizeof(struct ebt_entry_target) ||
-	   (t->u.target->check &&
-	   t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
+	} else if (t->target_size > gap - sizeof(struct ebt_entry_target)) {
 		module_put(t->u.target->me);
 		module_put(t->u.target->me);
 		ret = -EFAULT;
 		ret = -EFAULT;
 		goto cleanup_watchers;
 		goto cleanup_watchers;
 	}
 	}
+
+	tgpar.target   = target;
+	tgpar.targinfo = t->data;
+	ret = xt_check_target(&tgpar, t->target_size,
+	      e->ethproto, e->invflags & EBT_IPROTO);
+	if (ret < 0) {
+		module_put(target->me);
+		goto cleanup_watchers;
+	}
 	(*cnt)++;
 	(*cnt)++;
 	return 0;
 	return 0;
 cleanup_watchers:
 cleanup_watchers:
@@ -1068,87 +1106,6 @@ free_newinfo:
 	return ret;
 	return ret;
 }
 }
 
 
-int ebt_register_target(struct ebt_target *target)
-{
-	struct ebt_target *t;
-	int ret;
-
-	ret = mutex_lock_interruptible(&ebt_mutex);
-	if (ret != 0)
-		return ret;
-	list_for_each_entry(t, &ebt_targets, list) {
-		if (strcmp(t->name, target->name) == 0) {
-			mutex_unlock(&ebt_mutex);
-			return -EEXIST;
-		}
-	}
-	list_add(&target->list, &ebt_targets);
-	mutex_unlock(&ebt_mutex);
-
-	return 0;
-}
-
-void ebt_unregister_target(struct ebt_target *target)
-{
-	mutex_lock(&ebt_mutex);
-	list_del(&target->list);
-	mutex_unlock(&ebt_mutex);
-}
-
-int ebt_register_match(struct ebt_match *match)
-{
-	struct ebt_match *m;
-	int ret;
-
-	ret = mutex_lock_interruptible(&ebt_mutex);
-	if (ret != 0)
-		return ret;
-	list_for_each_entry(m, &ebt_matches, list) {
-		if (strcmp(m->name, match->name) == 0) {
-			mutex_unlock(&ebt_mutex);
-			return -EEXIST;
-		}
-	}
-	list_add(&match->list, &ebt_matches);
-	mutex_unlock(&ebt_mutex);
-
-	return 0;
-}
-
-void ebt_unregister_match(struct ebt_match *match)
-{
-	mutex_lock(&ebt_mutex);
-	list_del(&match->list);
-	mutex_unlock(&ebt_mutex);
-}
-
-int ebt_register_watcher(struct ebt_watcher *watcher)
-{
-	struct ebt_watcher *w;
-	int ret;
-
-	ret = mutex_lock_interruptible(&ebt_mutex);
-	if (ret != 0)
-		return ret;
-	list_for_each_entry(w, &ebt_watchers, list) {
-		if (strcmp(w->name, watcher->name) == 0) {
-			mutex_unlock(&ebt_mutex);
-			return -EEXIST;
-		}
-	}
-	list_add(&watcher->list, &ebt_watchers);
-	mutex_unlock(&ebt_mutex);
-
-	return 0;
-}
-
-void ebt_unregister_watcher(struct ebt_watcher *watcher)
-{
-	mutex_lock(&ebt_mutex);
-	list_del(&watcher->list);
-	mutex_unlock(&ebt_mutex);
-}
-
 int ebt_register_table(struct ebt_table *table)
 int ebt_register_table(struct ebt_table *table)
 {
 {
 	struct ebt_table_info *newinfo;
 	struct ebt_table_info *newinfo;
@@ -1518,11 +1475,14 @@ static int __init ebtables_init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	mutex_lock(&ebt_mutex);
-	list_add(&ebt_standard_target.list, &ebt_targets);
-	mutex_unlock(&ebt_mutex);
-	if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
+	ret = xt_register_target(&ebt_standard_target);
+	if (ret < 0)
+		return ret;
+	ret = nf_register_sockopt(&ebt_sockopts);
+	if (ret < 0) {
+		xt_unregister_target(&ebt_standard_target);
 		return ret;
 		return ret;
+	}
 
 
 	printk(KERN_INFO "Ebtables v2.0 registered\n");
 	printk(KERN_INFO "Ebtables v2.0 registered\n");
 	return 0;
 	return 0;
@@ -1531,17 +1491,12 @@ static int __init ebtables_init(void)
 static void __exit ebtables_fini(void)
 static void __exit ebtables_fini(void)
 {
 {
 	nf_unregister_sockopt(&ebt_sockopts);
 	nf_unregister_sockopt(&ebt_sockopts);
+	xt_unregister_target(&ebt_standard_target);
 	printk(KERN_INFO "Ebtables v2.0 unregistered\n");
 	printk(KERN_INFO "Ebtables v2.0 unregistered\n");
 }
 }
 
 
 EXPORT_SYMBOL(ebt_register_table);
 EXPORT_SYMBOL(ebt_register_table);
 EXPORT_SYMBOL(ebt_unregister_table);
 EXPORT_SYMBOL(ebt_unregister_table);
-EXPORT_SYMBOL(ebt_register_match);
-EXPORT_SYMBOL(ebt_unregister_match);
-EXPORT_SYMBOL(ebt_register_watcher);
-EXPORT_SYMBOL(ebt_unregister_watcher);
-EXPORT_SYMBOL(ebt_register_target);
-EXPORT_SYMBOL(ebt_unregister_target);
 EXPORT_SYMBOL(ebt_do_table);
 EXPORT_SYMBOL(ebt_do_table);
 module_init(ebtables_init);
 module_init(ebtables_init);
 module_exit(ebtables_fini);
 module_exit(ebtables_fini);

+ 1 - 0
net/core/net_namespace.c

@@ -18,6 +18,7 @@ static struct list_head *first_device = &pernet_list;
 static DEFINE_MUTEX(net_mutex);
 static DEFINE_MUTEX(net_mutex);
 
 
 LIST_HEAD(net_namespace_list);
 LIST_HEAD(net_namespace_list);
+EXPORT_SYMBOL_GPL(net_namespace_list);
 
 
 struct net init_net;
 struct net init_net;
 EXPORT_SYMBOL(init_net);
 EXPORT_SYMBOL(init_net);

+ 4 - 3
net/ipv4/netfilter.c

@@ -12,6 +12,7 @@
 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
 int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 {
 {
+	struct net *net = dev_net(skb->dst->dev);
 	const struct iphdr *iph = ip_hdr(skb);
 	const struct iphdr *iph = ip_hdr(skb);
 	struct rtable *rt;
 	struct rtable *rt;
 	struct flowi fl = {};
 	struct flowi fl = {};
@@ -19,7 +20,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 	unsigned int hh_len;
 	unsigned int hh_len;
 	unsigned int type;
 	unsigned int type;
 
 
-	type = inet_addr_type(&init_net, iph->saddr);
+	type = inet_addr_type(net, iph->saddr);
 	if (skb->sk && inet_sk(skb->sk)->transparent)
 	if (skb->sk && inet_sk(skb->sk)->transparent)
 		type = RTN_LOCAL;
 		type = RTN_LOCAL;
 	if (addr_type == RTN_UNSPEC)
 	if (addr_type == RTN_UNSPEC)
@@ -36,7 +37,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 		fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
 		fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
 		fl.mark = skb->mark;
 		fl.mark = skb->mark;
 		fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
 		fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
-		if (ip_route_output_key(&init_net, &rt, &fl) != 0)
+		if (ip_route_output_key(net, &rt, &fl) != 0)
 			return -1;
 			return -1;
 
 
 		/* Drop old route. */
 		/* Drop old route. */
@@ -46,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 		/* non-local src, find valid iif to satisfy
 		/* non-local src, find valid iif to satisfy
 		 * rp-filter when calling ip_route_input. */
 		 * rp-filter when calling ip_route_input. */
 		fl.nl_u.ip4_u.daddr = iph->saddr;
 		fl.nl_u.ip4_u.daddr = iph->saddr;
-		if (ip_route_output_key(&init_net, &rt, &fl) != 0)
+		if (ip_route_output_key(net, &rt, &fl) != 0)
 			return -1;
 			return -1;
 
 
 		odst = skb->dst;
 		odst = skb->dst;

+ 58 - 70
net/ipv4/netfilter/Kconfig

@@ -5,10 +5,15 @@
 menu "IP: Netfilter Configuration"
 menu "IP: Netfilter Configuration"
 	depends on INET && NETFILTER
 	depends on INET && NETFILTER
 
 
+config NF_DEFRAG_IPV4
+	tristate
+	default n
+
 config NF_CONNTRACK_IPV4
 config NF_CONNTRACK_IPV4
 	tristate "IPv4 connection tracking support (required for NAT)"
 	tristate "IPv4 connection tracking support (required for NAT)"
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
+	select NF_DEFRAG_IPV4
 	---help---
 	---help---
 	  Connection tracking keeps a record of what packets have passed
 	  Connection tracking keeps a record of what packets have passed
 	  through your machine, in order to figure out how they are related
 	  through your machine, in order to figure out how they are related
@@ -56,23 +61,30 @@ config IP_NF_IPTABLES
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+if IP_NF_IPTABLES
+
 # The matches.
 # The matches.
-config IP_NF_MATCH_RECENT
-	tristate '"recent" match support'
-	depends on IP_NF_IPTABLES
+config IP_NF_MATCH_ADDRTYPE
+	tristate '"addrtype" address type match support'
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
-	  This match is used for creating one or many lists of recently
-	  used addresses and then matching against that/those list(s).
+	  This option allows you to match what routing thinks of an address,
+	  eg. UNICAST, LOCAL, BROADCAST, ...
 
 
-	  Short options are available by using 'iptables -m recent -h'
-	  Official Website: <http://snowman.net/projects/ipt_recent/>
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
+
+config IP_NF_MATCH_AH
+	tristate '"ah" match support'
+	depends on NETFILTER_ADVANCED
+	help
+	  This match extension allows you to match a range of SPIs
+	  inside AH header of IPSec packets.
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
 config IP_NF_MATCH_ECN
 config IP_NF_MATCH_ECN
 	tristate '"ecn" match support'
 	tristate '"ecn" match support'
-	depends on IP_NF_IPTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `ECN' match, which allows you to match against
 	  This option adds a `ECN' match, which allows you to match against
@@ -80,19 +92,8 @@ config IP_NF_MATCH_ECN
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP_NF_MATCH_AH
-	tristate '"ah" match support'
-	depends on IP_NF_IPTABLES
-	depends on NETFILTER_ADVANCED
-	help
-	  This match extension allows you to match a range of SPIs
-	  inside AH header of IPSec packets.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config IP_NF_MATCH_TTL
 config IP_NF_MATCH_TTL
 	tristate '"ttl" match support'
 	tristate '"ttl" match support'
-	depends on IP_NF_IPTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
 	  This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
@@ -100,21 +101,9 @@ config IP_NF_MATCH_TTL
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP_NF_MATCH_ADDRTYPE
-	tristate '"addrtype" address type match support'
-	depends on IP_NF_IPTABLES
-	depends on NETFILTER_ADVANCED
-	help
-	  This option allows you to match what routing thinks of an address,
-	  eg. UNICAST, LOCAL, BROADCAST, ...
-
-	  If you want to compile it as a module, say M here and read
-	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
-
 # `filter', generic and specific targets
 # `filter', generic and specific targets
 config IP_NF_FILTER
 config IP_NF_FILTER
 	tristate "Packet filtering"
 	tristate "Packet filtering"
-	depends on IP_NF_IPTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  Packet filtering defines a table `filter', which has a series of
 	  Packet filtering defines a table `filter', which has a series of
@@ -136,7 +125,6 @@ config IP_NF_TARGET_REJECT
 
 
 config IP_NF_TARGET_LOG
 config IP_NF_TARGET_LOG
 	tristate "LOG target support"
 	tristate "LOG target support"
-	depends on IP_NF_IPTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  This option adds a `LOG' target, which allows you to create rules in
 	  This option adds a `LOG' target, which allows you to create rules in
@@ -146,7 +134,6 @@ config IP_NF_TARGET_LOG
 
 
 config IP_NF_TARGET_ULOG
 config IP_NF_TARGET_ULOG
 	tristate "ULOG target support"
 	tristate "ULOG target support"
-	depends on IP_NF_IPTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	---help---
 	---help---
 
 
@@ -167,7 +154,7 @@ config IP_NF_TARGET_ULOG
 # NAT + specific targets: nf_conntrack
 # NAT + specific targets: nf_conntrack
 config NF_NAT
 config NF_NAT
 	tristate "Full NAT"
 	tristate "Full NAT"
-	depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4
+	depends on NF_CONNTRACK_IPV4
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  The Full NAT option allows masquerading, port forwarding and other
 	  The Full NAT option allows masquerading, port forwarding and other
@@ -194,26 +181,26 @@ config IP_NF_TARGET_MASQUERADE
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP_NF_TARGET_REDIRECT
-	tristate "REDIRECT target support"
+config IP_NF_TARGET_NETMAP
+	tristate "NETMAP target support"
 	depends on NF_NAT
 	depends on NF_NAT
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
-	  REDIRECT is a special case of NAT: all incoming connections are
-	  mapped onto the incoming interface's address, causing the packets to
-	  come to the local machine instead of passing through.  This is
-	  useful for transparent proxies.
+	  NETMAP is an implementation of static 1:1 NAT mapping of network
+	  addresses. It maps the network address part, while keeping the host
+	  address part intact.
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP_NF_TARGET_NETMAP
-	tristate "NETMAP target support"
+config IP_NF_TARGET_REDIRECT
+	tristate "REDIRECT target support"
 	depends on NF_NAT
 	depends on NF_NAT
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
-	  NETMAP is an implementation of static 1:1 NAT mapping of network
-	  addresses. It maps the network address part, while keeping the host
-	  address part intact.
+	  REDIRECT is a special case of NAT: all incoming connections are
+	  mapped onto the incoming interface's address, causing the packets to
+	  come to the local machine instead of passing through.  This is
+	  useful for transparent proxies.
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
@@ -262,44 +249,43 @@ config NF_NAT_PROTO_SCTP
 
 
 config NF_NAT_FTP
 config NF_NAT_FTP
 	tristate
 	tristate
-	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	depends on NF_CONNTRACK && NF_NAT
 	default NF_NAT && NF_CONNTRACK_FTP
 	default NF_NAT && NF_CONNTRACK_FTP
 
 
 config NF_NAT_IRC
 config NF_NAT_IRC
 	tristate
 	tristate
-	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	depends on NF_CONNTRACK && NF_NAT
 	default NF_NAT && NF_CONNTRACK_IRC
 	default NF_NAT && NF_CONNTRACK_IRC
 
 
 config NF_NAT_TFTP
 config NF_NAT_TFTP
 	tristate
 	tristate
-	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	depends on NF_CONNTRACK && NF_NAT
 	default NF_NAT && NF_CONNTRACK_TFTP
 	default NF_NAT && NF_CONNTRACK_TFTP
 
 
 config NF_NAT_AMANDA
 config NF_NAT_AMANDA
 	tristate
 	tristate
-	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	depends on NF_CONNTRACK && NF_NAT
 	default NF_NAT && NF_CONNTRACK_AMANDA
 	default NF_NAT && NF_CONNTRACK_AMANDA
 
 
 config NF_NAT_PPTP
 config NF_NAT_PPTP
 	tristate
 	tristate
-	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	depends on NF_CONNTRACK && NF_NAT
 	default NF_NAT && NF_CONNTRACK_PPTP
 	default NF_NAT && NF_CONNTRACK_PPTP
 	select NF_NAT_PROTO_GRE
 	select NF_NAT_PROTO_GRE
 
 
 config NF_NAT_H323
 config NF_NAT_H323
 	tristate
 	tristate
-	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	depends on NF_CONNTRACK && NF_NAT
 	default NF_NAT && NF_CONNTRACK_H323
 	default NF_NAT && NF_CONNTRACK_H323
 
 
 config NF_NAT_SIP
 config NF_NAT_SIP
 	tristate
 	tristate
-	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	depends on NF_CONNTRACK && NF_NAT
 	default NF_NAT && NF_CONNTRACK_SIP
 	default NF_NAT && NF_CONNTRACK_SIP
 
 
 # mangle + specific targets
 # mangle + specific targets
 config IP_NF_MANGLE
 config IP_NF_MANGLE
 	tristate "Packet mangling"
 	tristate "Packet mangling"
-	depends on IP_NF_IPTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  This option adds a `mangle' table to iptables: see the man page for
 	  This option adds a `mangle' table to iptables: see the man page for
@@ -308,6 +294,19 @@ config IP_NF_MANGLE
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+config IP_NF_TARGET_CLUSTERIP
+	tristate "CLUSTERIP target support (EXPERIMENTAL)"
+	depends on IP_NF_MANGLE && EXPERIMENTAL
+	depends on NF_CONNTRACK_IPV4
+	depends on NETFILTER_ADVANCED
+	select NF_CONNTRACK_MARK
+	help
+	  The CLUSTERIP target allows you to build load-balancing clusters of
+	  network servers without having a dedicated load-balancing
+	  router/server/switch.
+	
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_NF_TARGET_ECN
 config IP_NF_TARGET_ECN
 	tristate "ECN target support"
 	tristate "ECN target support"
 	depends on IP_NF_MANGLE
 	depends on IP_NF_MANGLE
@@ -338,23 +337,9 @@ config IP_NF_TARGET_TTL
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP_NF_TARGET_CLUSTERIP
-	tristate "CLUSTERIP target support (EXPERIMENTAL)"
-	depends on IP_NF_MANGLE && EXPERIMENTAL
-	depends on NF_CONNTRACK_IPV4
-	depends on NETFILTER_ADVANCED
-	select NF_CONNTRACK_MARK
-	help
-	  The CLUSTERIP target allows you to build load-balancing clusters of
-	  network servers without having a dedicated load-balancing
-	  router/server/switch.
-	
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 # raw + specific targets
 # raw + specific targets
 config IP_NF_RAW
 config IP_NF_RAW
 	tristate  'raw table support (required for NOTRACK/TRACE)'
 	tristate  'raw table support (required for NOTRACK/TRACE)'
-	depends on IP_NF_IPTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `raw' table to iptables. This table is the very
 	  This option adds a `raw' table to iptables. This table is the very
@@ -367,7 +352,6 @@ config IP_NF_RAW
 # security table for MAC policy
 # security table for MAC policy
 config IP_NF_SECURITY
 config IP_NF_SECURITY
 	tristate "Security table"
 	tristate "Security table"
-	depends on IP_NF_IPTABLES
 	depends on SECURITY
 	depends on SECURITY
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
@@ -376,6 +360,8 @@ config IP_NF_SECURITY
 	 
 	 
 	  If unsure, say N.
 	  If unsure, say N.
 
 
+endif # IP_NF_IPTABLES
+
 # ARP tables
 # ARP tables
 config IP_NF_ARPTABLES
 config IP_NF_ARPTABLES
 	tristate "ARP tables support"
 	tristate "ARP tables support"
@@ -388,9 +374,10 @@ config IP_NF_ARPTABLES
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+if IP_NF_ARPTABLES
+
 config IP_NF_ARPFILTER
 config IP_NF_ARPFILTER
 	tristate "ARP packet filtering"
 	tristate "ARP packet filtering"
-	depends on IP_NF_ARPTABLES
 	help
 	help
 	  ARP packet filtering defines a table `filter', which has a series of
 	  ARP packet filtering defines a table `filter', which has a series of
 	  rules for simple ARP packet filtering at local input and
 	  rules for simple ARP packet filtering at local input and
@@ -401,10 +388,11 @@ config IP_NF_ARPFILTER
 
 
 config IP_NF_ARP_MANGLE
 config IP_NF_ARP_MANGLE
 	tristate "ARP payload mangling"
 	tristate "ARP payload mangling"
-	depends on IP_NF_ARPTABLES
 	help
 	help
 	  Allows altering the ARP packet payload: source and destination
 	  Allows altering the ARP packet payload: source and destination
 	  hardware and network addresses.
 	  hardware and network addresses.
 
 
+endif # IP_NF_ARPTABLES
+
 endmenu
 endmenu
 
 

+ 3 - 1
net/ipv4/netfilter/Makefile

@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
 
 
 obj-$(CONFIG_NF_NAT) += nf_nat.o
 obj-$(CONFIG_NF_NAT) += nf_nat.o
 
 
+# defrag
+obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
+
 # NAT helpers (nf_conntrack)
 # NAT helpers (nf_conntrack)
 obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
 obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
 obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
 obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
@@ -48,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
-obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
 
 
 # targets
 # targets

+ 62 - 54
net/ipv4/netfilter/arp_tables.c

@@ -200,15 +200,12 @@ static inline int arp_checkentry(const struct arpt_arp *arp)
 	return 1;
 	return 1;
 }
 }
 
 
-static unsigned int arpt_error(struct sk_buff *skb,
-			       const struct net_device *in,
-			       const struct net_device *out,
-			       unsigned int hooknum,
-			       const struct xt_target *target,
-			       const void *targinfo)
+static unsigned int
+arpt_error(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	if (net_ratelimit())
 	if (net_ratelimit())
-		printk("arp_tables: error: '%s'\n", (char *)targinfo);
+		printk("arp_tables: error: '%s'\n",
+		       (const char *)par->targinfo);
 
 
 	return NF_DROP;
 	return NF_DROP;
 }
 }
@@ -232,6 +229,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 	const char *indev, *outdev;
 	const char *indev, *outdev;
 	void *table_base;
 	void *table_base;
 	const struct xt_table_info *private;
 	const struct xt_table_info *private;
+	struct xt_target_param tgpar;
 
 
 	if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
 	if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
 		return NF_DROP;
 		return NF_DROP;
@@ -245,6 +243,11 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 	e = get_entry(table_base, private->hook_entry[hook]);
 	e = get_entry(table_base, private->hook_entry[hook]);
 	back = get_entry(table_base, private->underflow[hook]);
 	back = get_entry(table_base, private->underflow[hook]);
 
 
+	tgpar.in      = in;
+	tgpar.out     = out;
+	tgpar.hooknum = hook;
+	tgpar.family  = NFPROTO_ARP;
+
 	arp = arp_hdr(skb);
 	arp = arp_hdr(skb);
 	do {
 	do {
 		if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
 		if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
@@ -290,11 +293,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 				/* Targets which reenter must return
 				/* Targets which reenter must return
 				 * abs. verdicts
 				 * abs. verdicts
 				 */
 				 */
+				tgpar.target   = t->u.kernel.target;
+				tgpar.targinfo = t->data;
 				verdict = t->u.kernel.target->target(skb,
 				verdict = t->u.kernel.target->target(skb,
-								     in, out,
-								     hook,
-								     t->u.kernel.target,
-								     t->data);
+								     &tgpar);
 
 
 				/* Target might have changed stuff. */
 				/* Target might have changed stuff. */
 				arp = arp_hdr(skb);
 				arp = arp_hdr(skb);
@@ -456,23 +458,24 @@ static inline int check_entry(struct arpt_entry *e, const char *name)
 
 
 static inline int check_target(struct arpt_entry *e, const char *name)
 static inline int check_target(struct arpt_entry *e, const char *name)
 {
 {
-	struct arpt_entry_target *t;
-	struct xt_target *target;
+	struct arpt_entry_target *t = arpt_get_target(e);
 	int ret;
 	int ret;
-
-	t = arpt_get_target(e);
-	target = t->u.kernel.target;
-
-	ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t),
-			      name, e->comefrom, 0, 0);
-	if (!ret && t->u.kernel.target->checkentry
-	    && !t->u.kernel.target->checkentry(name, e, target, t->data,
-					       e->comefrom)) {
+	struct xt_tgchk_param par = {
+		.table     = name,
+		.entryinfo = e,
+		.target    = t->u.kernel.target,
+		.targinfo  = t->data,
+		.hook_mask = e->comefrom,
+		.family    = NFPROTO_ARP,
+	};
+
+	ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
+	if (ret < 0) {
 		duprintf("arp_tables: check failed for `%s'.\n",
 		duprintf("arp_tables: check failed for `%s'.\n",
 			 t->u.kernel.target->name);
 			 t->u.kernel.target->name);
-		ret = -EINVAL;
+		return ret;
 	}
 	}
-	return ret;
+	return 0;
 }
 }
 
 
 static inline int
 static inline int
@@ -488,7 +491,8 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
 		return ret;
 		return ret;
 
 
 	t = arpt_get_target(e);
 	t = arpt_get_target(e);
-	target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
+	target = try_then_request_module(xt_find_target(NFPROTO_ARP,
+							t->u.user.name,
 							t->u.user.revision),
 							t->u.user.revision),
 					 "arpt_%s", t->u.user.name);
 					 "arpt_%s", t->u.user.name);
 	if (IS_ERR(target) || !target) {
 	if (IS_ERR(target) || !target) {
@@ -554,15 +558,19 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
 
 
 static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
 static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
 {
 {
+	struct xt_tgdtor_param par;
 	struct arpt_entry_target *t;
 	struct arpt_entry_target *t;
 
 
 	if (i && (*i)-- == 0)
 	if (i && (*i)-- == 0)
 		return 1;
 		return 1;
 
 
 	t = arpt_get_target(e);
 	t = arpt_get_target(e);
-	if (t->u.kernel.target->destroy)
-		t->u.kernel.target->destroy(t->u.kernel.target, t->data);
-	module_put(t->u.kernel.target->me);
+	par.target   = t->u.kernel.target;
+	par.targinfo = t->data;
+	par.family   = NFPROTO_ARP;
+	if (par.target->destroy != NULL)
+		par.target->destroy(&par);
+	module_put(par.target->me);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -788,7 +796,7 @@ static void compat_standard_from_user(void *dst, void *src)
 	int v = *(compat_int_t *)src;
 	int v = *(compat_int_t *)src;
 
 
 	if (v > 0)
 	if (v > 0)
-		v += xt_compat_calc_jump(NF_ARP, v);
+		v += xt_compat_calc_jump(NFPROTO_ARP, v);
 	memcpy(dst, &v, sizeof(v));
 	memcpy(dst, &v, sizeof(v));
 }
 }
 
 
@@ -797,7 +805,7 @@ static int compat_standard_to_user(void __user *dst, void *src)
 	compat_int_t cv = *(int *)src;
 	compat_int_t cv = *(int *)src;
 
 
 	if (cv > 0)
 	if (cv > 0)
-		cv -= xt_compat_calc_jump(NF_ARP, cv);
+		cv -= xt_compat_calc_jump(NFPROTO_ARP, cv);
 	return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
 	return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
 }
 }
 
 
@@ -815,7 +823,7 @@ static int compat_calc_entry(struct arpt_entry *e,
 	t = arpt_get_target(e);
 	t = arpt_get_target(e);
 	off += xt_compat_target_offset(t->u.kernel.target);
 	off += xt_compat_target_offset(t->u.kernel.target);
 	newinfo->size -= off;
 	newinfo->size -= off;
-	ret = xt_compat_add_offset(NF_ARP, entry_offset, off);
+	ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
@@ -866,9 +874,9 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
 	name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
 	name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
 #ifdef CONFIG_COMPAT
 #ifdef CONFIG_COMPAT
 	if (compat)
 	if (compat)
-		xt_compat_lock(NF_ARP);
+		xt_compat_lock(NFPROTO_ARP);
 #endif
 #endif
-	t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name),
+	t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name),
 				    "arptable_%s", name);
 				    "arptable_%s", name);
 	if (t && !IS_ERR(t)) {
 	if (t && !IS_ERR(t)) {
 		struct arpt_getinfo info;
 		struct arpt_getinfo info;
@@ -878,7 +886,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
 		if (compat) {
 		if (compat) {
 			struct xt_table_info tmp;
 			struct xt_table_info tmp;
 			ret = compat_table_info(private, &tmp);
 			ret = compat_table_info(private, &tmp);
-			xt_compat_flush_offsets(NF_ARP);
+			xt_compat_flush_offsets(NFPROTO_ARP);
 			private = &tmp;
 			private = &tmp;
 		}
 		}
 #endif
 #endif
@@ -901,7 +909,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		ret = t ? PTR_ERR(t) : -ENOENT;
 #ifdef CONFIG_COMPAT
 #ifdef CONFIG_COMPAT
 	if (compat)
 	if (compat)
-		xt_compat_unlock(NF_ARP);
+		xt_compat_unlock(NFPROTO_ARP);
 #endif
 #endif
 	return ret;
 	return ret;
 }
 }
@@ -925,7 +933,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	t = xt_find_table_lock(net, NF_ARP, get.name);
+	t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
 	if (t && !IS_ERR(t)) {
 	if (t && !IS_ERR(t)) {
 		const struct xt_table_info *private = t->private;
 		const struct xt_table_info *private = t->private;
 
 
@@ -967,7 +975,7 @@ static int __do_replace(struct net *net, const char *name,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name),
+	t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name),
 				    "arptable_%s", name);
 				    "arptable_%s", name);
 	if (!t || IS_ERR(t)) {
 	if (!t || IS_ERR(t)) {
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1134,7 +1142,7 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len,
 		goto free;
 		goto free;
 	}
 	}
 
 
-	t = xt_find_table_lock(net, NF_ARP, name);
+	t = xt_find_table_lock(net, NFPROTO_ARP, name);
 	if (!t || IS_ERR(t)) {
 	if (!t || IS_ERR(t)) {
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		goto free;
 		goto free;
@@ -1218,7 +1226,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 	entry_offset = (void *)e - (void *)base;
 	entry_offset = (void *)e - (void *)base;
 
 
 	t = compat_arpt_get_target(e);
 	t = compat_arpt_get_target(e);
-	target = try_then_request_module(xt_find_target(NF_ARP,
+	target = try_then_request_module(xt_find_target(NFPROTO_ARP,
 							t->u.user.name,
 							t->u.user.name,
 							t->u.user.revision),
 							t->u.user.revision),
 					 "arpt_%s", t->u.user.name);
 					 "arpt_%s", t->u.user.name);
@@ -1232,7 +1240,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
 
 
 	off += xt_compat_target_offset(target);
 	off += xt_compat_target_offset(target);
 	*size += off;
 	*size += off;
-	ret = xt_compat_add_offset(NF_ARP, entry_offset, off);
+	ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off);
 	if (ret)
 	if (ret)
 		goto release_target;
 		goto release_target;
 
 
@@ -1333,7 +1341,7 @@ static int translate_compat_table(const char *name,
 
 
 	duprintf("translate_compat_table: size %u\n", info->size);
 	duprintf("translate_compat_table: size %u\n", info->size);
 	j = 0;
 	j = 0;
-	xt_compat_lock(NF_ARP);
+	xt_compat_lock(NFPROTO_ARP);
 	/* Walk through entries, checking offsets. */
 	/* Walk through entries, checking offsets. */
 	ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
 	ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
 					check_compat_entry_size_and_hooks,
 					check_compat_entry_size_and_hooks,
@@ -1383,8 +1391,8 @@ static int translate_compat_table(const char *name,
 	ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
 	ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
 					compat_copy_entry_from_user,
 					compat_copy_entry_from_user,
 					&pos, &size, name, newinfo, entry1);
 					&pos, &size, name, newinfo, entry1);
-	xt_compat_flush_offsets(NF_ARP);
-	xt_compat_unlock(NF_ARP);
+	xt_compat_flush_offsets(NFPROTO_ARP);
+	xt_compat_unlock(NFPROTO_ARP);
 	if (ret)
 	if (ret)
 		goto free_newinfo;
 		goto free_newinfo;
 
 
@@ -1420,8 +1428,8 @@ out:
 	COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
 	COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
 	return ret;
 	return ret;
 out_unlock:
 out_unlock:
-	xt_compat_flush_offsets(NF_ARP);
-	xt_compat_unlock(NF_ARP);
+	xt_compat_flush_offsets(NFPROTO_ARP);
+	xt_compat_unlock(NFPROTO_ARP);
 	goto out;
 	goto out;
 }
 }
 
 
@@ -1607,8 +1615,8 @@ static int compat_get_entries(struct net *net,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	xt_compat_lock(NF_ARP);
-	t = xt_find_table_lock(net, NF_ARP, get.name);
+	xt_compat_lock(NFPROTO_ARP);
+	t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
 	if (t && !IS_ERR(t)) {
 	if (t && !IS_ERR(t)) {
 		const struct xt_table_info *private = t->private;
 		const struct xt_table_info *private = t->private;
 		struct xt_table_info info;
 		struct xt_table_info info;
@@ -1623,13 +1631,13 @@ static int compat_get_entries(struct net *net,
 				 private->size, get.size);
 				 private->size, get.size);
 			ret = -EAGAIN;
 			ret = -EAGAIN;
 		}
 		}
-		xt_compat_flush_offsets(NF_ARP);
+		xt_compat_flush_offsets(NFPROTO_ARP);
 		module_put(t->me);
 		module_put(t->me);
 		xt_table_unlock(t);
 		xt_table_unlock(t);
 	} else
 	} else
 		ret = t ? PTR_ERR(t) : -ENOENT;
 		ret = t ? PTR_ERR(t) : -ENOENT;
 
 
-	xt_compat_unlock(NF_ARP);
+	xt_compat_unlock(NFPROTO_ARP);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1709,7 +1717,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
 			break;
 			break;
 		}
 		}
 
 
-		try_then_request_module(xt_find_revision(NF_ARP, rev.name,
+		try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name,
 							 rev.revision, 1, &ret),
 							 rev.revision, 1, &ret),
 					"arpt_%s", rev.name);
 					"arpt_%s", rev.name);
 		break;
 		break;
@@ -1787,7 +1795,7 @@ void arpt_unregister_table(struct xt_table *table)
 static struct xt_target arpt_standard_target __read_mostly = {
 static struct xt_target arpt_standard_target __read_mostly = {
 	.name		= ARPT_STANDARD_TARGET,
 	.name		= ARPT_STANDARD_TARGET,
 	.targetsize	= sizeof(int),
 	.targetsize	= sizeof(int),
-	.family		= NF_ARP,
+	.family		= NFPROTO_ARP,
 #ifdef CONFIG_COMPAT
 #ifdef CONFIG_COMPAT
 	.compatsize	= sizeof(compat_int_t),
 	.compatsize	= sizeof(compat_int_t),
 	.compat_from_user = compat_standard_from_user,
 	.compat_from_user = compat_standard_from_user,
@@ -1799,7 +1807,7 @@ static struct xt_target arpt_error_target __read_mostly = {
 	.name		= ARPT_ERROR_TARGET,
 	.name		= ARPT_ERROR_TARGET,
 	.target		= arpt_error,
 	.target		= arpt_error,
 	.targetsize	= ARPT_FUNCTION_MAXNAMELEN,
 	.targetsize	= ARPT_FUNCTION_MAXNAMELEN,
-	.family		= NF_ARP,
+	.family		= NFPROTO_ARP,
 };
 };
 
 
 static struct nf_sockopt_ops arpt_sockopts = {
 static struct nf_sockopt_ops arpt_sockopts = {
@@ -1821,12 +1829,12 @@ static struct nf_sockopt_ops arpt_sockopts = {
 
 
 static int __net_init arp_tables_net_init(struct net *net)
 static int __net_init arp_tables_net_init(struct net *net)
 {
 {
-	return xt_proto_init(net, NF_ARP);
+	return xt_proto_init(net, NFPROTO_ARP);
 }
 }
 
 
 static void __net_exit arp_tables_net_exit(struct net *net)
 static void __net_exit arp_tables_net_exit(struct net *net)
 {
 {
-	xt_proto_fini(net, NF_ARP);
+	xt_proto_fini(net, NFPROTO_ARP);
 }
 }
 
 
 static struct pernet_operations arp_tables_net_ops = {
 static struct pernet_operations arp_tables_net_ops = {

+ 5 - 10
net/ipv4/netfilter/arpt_mangle.c

@@ -9,12 +9,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
 MODULE_DESCRIPTION("arptables arp payload mangle target");
 MODULE_DESCRIPTION("arptables arp payload mangle target");
 
 
 static unsigned int
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in, const struct net_device *out,
-       unsigned int hooknum, const struct xt_target *target,
-       const void *targinfo)
+target(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct arpt_mangle *mangle = targinfo;
+	const struct arpt_mangle *mangle = par->targinfo;
 	const struct arphdr *arp;
 	const struct arphdr *arp;
 	unsigned char *arpptr;
 	unsigned char *arpptr;
 	int pln, hln;
 	int pln, hln;
@@ -57,11 +54,9 @@ target(struct sk_buff *skb,
 	return mangle->target;
 	return mangle->target;
 }
 }
 
 
-static bool
-checkentry(const char *tablename, const void *e, const struct xt_target *target,
-	   void *targinfo, unsigned int hook_mask)
+static bool checkentry(const struct xt_tgchk_param *par)
 {
 {
-	const struct arpt_mangle *mangle = targinfo;
+	const struct arpt_mangle *mangle = par->targinfo;
 
 
 	if (mangle->flags & ~ARPT_MANGLE_MASK ||
 	if (mangle->flags & ~ARPT_MANGLE_MASK ||
 	    !(mangle->flags & ARPT_MANGLE_MASK))
 	    !(mangle->flags & ARPT_MANGLE_MASK))
@@ -75,7 +70,7 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target,
 
 
 static struct xt_target arpt_mangle_reg __read_mostly = {
 static struct xt_target arpt_mangle_reg __read_mostly = {
 	.name		= "mangle",
 	.name		= "mangle",
-	.family		= NF_ARP,
+	.family		= NFPROTO_ARP,
 	.target		= target,
 	.target		= target,
 	.targetsize	= sizeof(struct arpt_mangle),
 	.targetsize	= sizeof(struct arpt_mangle),
 	.checkentry	= checkentry,
 	.checkentry	= checkentry,

+ 4 - 4
net/ipv4/netfilter/arptable_filter.c

@@ -51,7 +51,7 @@ static struct xt_table packet_filter = {
 	.lock		= __RW_LOCK_UNLOCKED(packet_filter.lock),
 	.lock		= __RW_LOCK_UNLOCKED(packet_filter.lock),
 	.private	= NULL,
 	.private	= NULL,
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
-	.af		= NF_ARP,
+	.af		= NFPROTO_ARP,
 };
 };
 
 
 /* The work comes in here from netfilter.c */
 /* The work comes in here from netfilter.c */
@@ -89,21 +89,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
 	{
 	{
 		.hook		= arpt_in_hook,
 		.hook		= arpt_in_hook,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
-		.pf		= NF_ARP,
+		.pf		= NFPROTO_ARP,
 		.hooknum	= NF_ARP_IN,
 		.hooknum	= NF_ARP_IN,
 		.priority	= NF_IP_PRI_FILTER,
 		.priority	= NF_IP_PRI_FILTER,
 	},
 	},
 	{
 	{
 		.hook		= arpt_out_hook,
 		.hook		= arpt_out_hook,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
-		.pf		= NF_ARP,
+		.pf		= NFPROTO_ARP,
 		.hooknum	= NF_ARP_OUT,
 		.hooknum	= NF_ARP_OUT,
 		.priority	= NF_IP_PRI_FILTER,
 		.priority	= NF_IP_PRI_FILTER,
 	},
 	},
 	{
 	{
 		.hook		= arpt_forward_hook,
 		.hook		= arpt_forward_hook,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
-		.pf		= NF_ARP,
+		.pf		= NFPROTO_ARP,
 		.hooknum	= NF_ARP_FORWARD,
 		.hooknum	= NF_ARP_FORWARD,
 		.priority	= NF_IP_PRI_FILTER,
 		.priority	= NF_IP_PRI_FILTER,
 	},
 	},

+ 88 - 89
net/ipv4/netfilter/ip_tables.c

@@ -171,31 +171,25 @@ ip_checkentry(const struct ipt_ip *ip)
 }
 }
 
 
 static unsigned int
 static unsigned int
-ipt_error(struct sk_buff *skb,
-	  const struct net_device *in,
-	  const struct net_device *out,
-	  unsigned int hooknum,
-	  const struct xt_target *target,
-	  const void *targinfo)
+ipt_error(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	if (net_ratelimit())
 	if (net_ratelimit())
-		printk("ip_tables: error: `%s'\n", (char *)targinfo);
+		printk("ip_tables: error: `%s'\n",
+		       (const char *)par->targinfo);
 
 
 	return NF_DROP;
 	return NF_DROP;
 }
 }
 
 
 /* Performance critical - called for every packet */
 /* Performance critical - called for every packet */
 static inline bool
 static inline bool
-do_match(struct ipt_entry_match *m,
-	      const struct sk_buff *skb,
-	      const struct net_device *in,
-	      const struct net_device *out,
-	      int offset,
-	      bool *hotdrop)
+do_match(struct ipt_entry_match *m, const struct sk_buff *skb,
+	 struct xt_match_param *par)
 {
 {
+	par->match     = m->u.kernel.match;
+	par->matchinfo = m->data;
+
 	/* Stop iteration if it doesn't match */
 	/* Stop iteration if it doesn't match */
-	if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
-				      offset, ip_hdrlen(skb), hotdrop))
+	if (!m->u.kernel.match->match(skb, par))
 		return true;
 		return true;
 	else
 	else
 		return false;
 		return false;
@@ -326,7 +320,6 @@ ipt_do_table(struct sk_buff *skb,
 	     struct xt_table *table)
 	     struct xt_table *table)
 {
 {
 	static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
 	static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
-	u_int16_t offset;
 	const struct iphdr *ip;
 	const struct iphdr *ip;
 	u_int16_t datalen;
 	u_int16_t datalen;
 	bool hotdrop = false;
 	bool hotdrop = false;
@@ -336,6 +329,8 @@ ipt_do_table(struct sk_buff *skb,
 	void *table_base;
 	void *table_base;
 	struct ipt_entry *e, *back;
 	struct ipt_entry *e, *back;
 	struct xt_table_info *private;
 	struct xt_table_info *private;
+	struct xt_match_param mtpar;
+	struct xt_target_param tgpar;
 
 
 	/* Initialization */
 	/* Initialization */
 	ip = ip_hdr(skb);
 	ip = ip_hdr(skb);
@@ -348,7 +343,13 @@ ipt_do_table(struct sk_buff *skb,
 	 * things we don't know, ie. tcp syn flag or ports).  If the
 	 * things we don't know, ie. tcp syn flag or ports).  If the
 	 * rule is also a fragment-specific rule, non-fragments won't
 	 * rule is also a fragment-specific rule, non-fragments won't
 	 * match it. */
 	 * match it. */
-	offset = ntohs(ip->frag_off) & IP_OFFSET;
+	mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
+	mtpar.thoff   = ip_hdrlen(skb);
+	mtpar.hotdrop = &hotdrop;
+	mtpar.in      = tgpar.in  = in;
+	mtpar.out     = tgpar.out = out;
+	mtpar.family  = tgpar.family = NFPROTO_IPV4;
+	tgpar.hooknum = hook;
 
 
 	read_lock_bh(&table->lock);
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@@ -362,12 +363,11 @@ ipt_do_table(struct sk_buff *skb,
 	do {
 	do {
 		IP_NF_ASSERT(e);
 		IP_NF_ASSERT(e);
 		IP_NF_ASSERT(back);
 		IP_NF_ASSERT(back);
-		if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) {
+		if (ip_packet_match(ip, indev, outdev,
+		    &e->ip, mtpar.fragoff)) {
 			struct ipt_entry_target *t;
 			struct ipt_entry_target *t;
 
 
-			if (IPT_MATCH_ITERATE(e, do_match,
-					      skb, in, out,
-					      offset, &hotdrop) != 0)
+			if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
 				goto no_match;
 				goto no_match;
 
 
 			ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
 			ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
@@ -413,16 +413,14 @@ ipt_do_table(struct sk_buff *skb,
 			} else {
 			} else {
 				/* Targets which reenter must return
 				/* Targets which reenter must return
 				   abs. verdicts */
 				   abs. verdicts */
+				tgpar.target   = t->u.kernel.target;
+				tgpar.targinfo = t->data;
 #ifdef CONFIG_NETFILTER_DEBUG
 #ifdef CONFIG_NETFILTER_DEBUG
 				((struct ipt_entry *)table_base)->comefrom
 				((struct ipt_entry *)table_base)->comefrom
 					= 0xeeeeeeec;
 					= 0xeeeeeeec;
 #endif
 #endif
 				verdict = t->u.kernel.target->target(skb,
 				verdict = t->u.kernel.target->target(skb,
-								     in, out,
-								     hook,
-								     t->u.kernel.target,
-								     t->data);
-
+								     &tgpar);
 #ifdef CONFIG_NETFILTER_DEBUG
 #ifdef CONFIG_NETFILTER_DEBUG
 				if (((struct ipt_entry *)table_base)->comefrom
 				if (((struct ipt_entry *)table_base)->comefrom
 				    != 0xeeeeeeec
 				    != 0xeeeeeeec
@@ -575,12 +573,17 @@ mark_source_chains(struct xt_table_info *newinfo,
 static int
 static int
 cleanup_match(struct ipt_entry_match *m, unsigned int *i)
 cleanup_match(struct ipt_entry_match *m, unsigned int *i)
 {
 {
+	struct xt_mtdtor_param par;
+
 	if (i && (*i)-- == 0)
 	if (i && (*i)-- == 0)
 		return 1;
 		return 1;
 
 
-	if (m->u.kernel.match->destroy)
-		m->u.kernel.match->destroy(m->u.kernel.match, m->data);
-	module_put(m->u.kernel.match->me);
+	par.match     = m->u.kernel.match;
+	par.matchinfo = m->data;
+	par.family    = NFPROTO_IPV4;
+	if (par.match->destroy != NULL)
+		par.match->destroy(&par);
+	module_put(par.match->me);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -606,34 +609,28 @@ check_entry(struct ipt_entry *e, const char *name)
 }
 }
 
 
 static int
 static int
-check_match(struct ipt_entry_match *m, const char *name,
-			      const struct ipt_ip *ip,
-			      unsigned int hookmask, unsigned int *i)
+check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
+	    unsigned int *i)
 {
 {
-	struct xt_match *match;
+	const struct ipt_ip *ip = par->entryinfo;
 	int ret;
 	int ret;
 
 
-	match = m->u.kernel.match;
-	ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
-			     name, hookmask, ip->proto,
-			     ip->invflags & IPT_INV_PROTO);
-	if (!ret && m->u.kernel.match->checkentry
-	    && !m->u.kernel.match->checkentry(name, ip, match, m->data,
-					      hookmask)) {
+	par->match     = m->u.kernel.match;
+	par->matchinfo = m->data;
+
+	ret = xt_check_match(par, m->u.match_size - sizeof(*m),
+	      ip->proto, ip->invflags & IPT_INV_PROTO);
+	if (ret < 0) {
 		duprintf("ip_tables: check failed for `%s'.\n",
 		duprintf("ip_tables: check failed for `%s'.\n",
-			 m->u.kernel.match->name);
-		ret = -EINVAL;
+			 par.match->name);
+		return ret;
 	}
 	}
-	if (!ret)
-		(*i)++;
-	return ret;
+	++*i;
+	return 0;
 }
 }
 
 
 static int
 static int
-find_check_match(struct ipt_entry_match *m,
-		 const char *name,
-		 const struct ipt_ip *ip,
-		 unsigned int hookmask,
+find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
 		 unsigned int *i)
 		 unsigned int *i)
 {
 {
 	struct xt_match *match;
 	struct xt_match *match;
@@ -648,7 +645,7 @@ find_check_match(struct ipt_entry_match *m,
 	}
 	}
 	m->u.kernel.match = match;
 	m->u.kernel.match = match;
 
 
-	ret = check_match(m, name, ip, hookmask, i);
+	ret = check_match(m, par, i);
 	if (ret)
 	if (ret)
 		goto err;
 		goto err;
 
 
@@ -660,23 +657,25 @@ err:
 
 
 static int check_target(struct ipt_entry *e, const char *name)
 static int check_target(struct ipt_entry *e, const char *name)
 {
 {
-	struct ipt_entry_target *t;
-	struct xt_target *target;
+	struct ipt_entry_target *t = ipt_get_target(e);
+	struct xt_tgchk_param par = {
+		.table     = name,
+		.entryinfo = e,
+		.target    = t->u.kernel.target,
+		.targinfo  = t->data,
+		.hook_mask = e->comefrom,
+		.family    = NFPROTO_IPV4,
+	};
 	int ret;
 	int ret;
 
 
-	t = ipt_get_target(e);
-	target = t->u.kernel.target;
-	ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
-			      name, e->comefrom, e->ip.proto,
-			      e->ip.invflags & IPT_INV_PROTO);
-	if (!ret && t->u.kernel.target->checkentry
-	    && !t->u.kernel.target->checkentry(name, e, target, t->data,
-					       e->comefrom)) {
+	ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
+	      e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
+	if (ret < 0) {
 		duprintf("ip_tables: check failed for `%s'.\n",
 		duprintf("ip_tables: check failed for `%s'.\n",
 			 t->u.kernel.target->name);
 			 t->u.kernel.target->name);
-		ret = -EINVAL;
+		return ret;
 	}
 	}
-	return ret;
+	return 0;
 }
 }
 
 
 static int
 static int
@@ -687,14 +686,18 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
 	struct xt_target *target;
 	struct xt_target *target;
 	int ret;
 	int ret;
 	unsigned int j;
 	unsigned int j;
+	struct xt_mtchk_param mtpar;
 
 
 	ret = check_entry(e, name);
 	ret = check_entry(e, name);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
 	j = 0;
 	j = 0;
-	ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip,
-				e->comefrom, &j);
+	mtpar.table     = name;
+	mtpar.entryinfo = &e->ip;
+	mtpar.hook_mask = e->comefrom;
+	mtpar.family    = NFPROTO_IPV4;
+	ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
 	if (ret != 0)
 	if (ret != 0)
 		goto cleanup_matches;
 		goto cleanup_matches;
 
 
@@ -769,6 +772,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
 static int
 static int
 cleanup_entry(struct ipt_entry *e, unsigned int *i)
 cleanup_entry(struct ipt_entry *e, unsigned int *i)
 {
 {
+	struct xt_tgdtor_param par;
 	struct ipt_entry_target *t;
 	struct ipt_entry_target *t;
 
 
 	if (i && (*i)-- == 0)
 	if (i && (*i)-- == 0)
@@ -777,9 +781,13 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)
 	/* Cleanup all matches */
 	/* Cleanup all matches */
 	IPT_MATCH_ITERATE(e, cleanup_match, NULL);
 	IPT_MATCH_ITERATE(e, cleanup_match, NULL);
 	t = ipt_get_target(e);
 	t = ipt_get_target(e);
-	if (t->u.kernel.target->destroy)
-		t->u.kernel.target->destroy(t->u.kernel.target, t->data);
-	module_put(t->u.kernel.target->me);
+
+	par.target   = t->u.kernel.target;
+	par.targinfo = t->data;
+	par.family   = NFPROTO_IPV4;
+	if (par.target->destroy != NULL)
+		par.target->destroy(&par);
+	module_put(par.target->me);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1648,12 +1656,16 @@ static int
 compat_check_entry(struct ipt_entry *e, const char *name,
 compat_check_entry(struct ipt_entry *e, const char *name,
 				     unsigned int *i)
 				     unsigned int *i)
 {
 {
+	struct xt_mtchk_param mtpar;
 	unsigned int j;
 	unsigned int j;
 	int ret;
 	int ret;
 
 
 	j = 0;
 	j = 0;
-	ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip,
-				e->comefrom, &j);
+	mtpar.table     = name;
+	mtpar.entryinfo = &e->ip;
+	mtpar.hook_mask = e->comefrom;
+	mtpar.family    = NFPROTO_IPV4;
+	ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
 	if (ret)
 	if (ret)
 		goto cleanup_matches;
 		goto cleanup_matches;
 
 
@@ -2121,30 +2133,23 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
 }
 }
 
 
 static bool
 static bool
-icmp_match(const struct sk_buff *skb,
-	   const struct net_device *in,
-	   const struct net_device *out,
-	   const struct xt_match *match,
-	   const void *matchinfo,
-	   int offset,
-	   unsigned int protoff,
-	   bool *hotdrop)
+icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	const struct icmphdr *ic;
 	const struct icmphdr *ic;
 	struct icmphdr _icmph;
 	struct icmphdr _icmph;
-	const struct ipt_icmp *icmpinfo = matchinfo;
+	const struct ipt_icmp *icmpinfo = par->matchinfo;
 
 
 	/* Must not be a fragment. */
 	/* Must not be a fragment. */
-	if (offset)
+	if (par->fragoff != 0)
 		return false;
 		return false;
 
 
-	ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph);
+	ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
 	if (ic == NULL) {
 	if (ic == NULL) {
 		/* We've been asked to examine this packet, and we
 		/* We've been asked to examine this packet, and we
 		 * can't.  Hence, no choice but to drop.
 		 * can't.  Hence, no choice but to drop.
 		 */
 		 */
 		duprintf("Dropping evil ICMP tinygram.\n");
 		duprintf("Dropping evil ICMP tinygram.\n");
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -2155,15 +2160,9 @@ icmp_match(const struct sk_buff *skb,
 				    !!(icmpinfo->invflags&IPT_ICMP_INV));
 				    !!(icmpinfo->invflags&IPT_ICMP_INV));
 }
 }
 
 
-/* Called when user tries to insert an entry of this type. */
-static bool
-icmp_checkentry(const char *tablename,
-	   const void *entry,
-	   const struct xt_match *match,
-	   void *matchinfo,
-	   unsigned int hook_mask)
+static bool icmp_checkentry(const struct xt_mtchk_param *par)
 {
 {
-	const struct ipt_icmp *icmpinfo = matchinfo;
+	const struct ipt_icmp *icmpinfo = par->matchinfo;
 
 
 	/* Must specify no unknown invflags */
 	/* Must specify no unknown invflags */
 	return !(icmpinfo->invflags & ~IPT_ICMP_INV);
 	return !(icmpinfo->invflags & ~IPT_ICMP_INV);

+ 12 - 17
net/ipv4/netfilter/ipt_CLUSTERIP.c

@@ -281,11 +281,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
  ***********************************************************************/
  ***********************************************************************/
 
 
 static unsigned int
 static unsigned int
-clusterip_tg(struct sk_buff *skb, const struct net_device *in,
-             const struct net_device *out, unsigned int hooknum,
-             const struct xt_target *target, const void *targinfo)
+clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
+	const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
 	struct nf_conn *ct;
 	struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
 	enum ip_conntrack_info ctinfo;
 	u_int32_t hash;
 	u_int32_t hash;
@@ -349,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in,
 	return XT_CONTINUE;
 	return XT_CONTINUE;
 }
 }
 
 
-static bool
-clusterip_tg_check(const char *tablename, const void *e_void,
-                   const struct xt_target *target, void *targinfo,
-                   unsigned int hook_mask)
+static bool clusterip_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	struct ipt_clusterip_tgt_info *cipinfo = targinfo;
-	const struct ipt_entry *e = e_void;
+	struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
+	const struct ipt_entry *e = par->entryinfo;
 
 
 	struct clusterip_config *config;
 	struct clusterip_config *config;
 
 
@@ -406,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
 	}
 	}
 	cipinfo->config = config;
 	cipinfo->config = config;
 
 
-	if (nf_ct_l3proto_try_module_get(target->family) < 0) {
+	if (nf_ct_l3proto_try_module_get(par->target->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 		printk(KERN_WARNING "can't load conntrack support for "
-				    "proto=%u\n", target->family);
+				    "proto=%u\n", par->target->family);
 		return false;
 		return false;
 	}
 	}
 
 
@@ -416,9 +411,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
 }
 }
 
 
 /* drop reference count of cluster config when rule is deleted */
 /* drop reference count of cluster config when rule is deleted */
-static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
+static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
 {
 {
-	const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
+	const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
 
 
 	/* if no more entries are referencing the config, remove it
 	/* if no more entries are referencing the config, remove it
 	 * from the list and destroy the proc entry */
 	 * from the list and destroy the proc entry */
@@ -426,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
 
 
 	clusterip_config_put(cipinfo->config);
 	clusterip_config_put(cipinfo->config);
 
 
-	nf_ct_l3proto_module_put(target->family);
+	nf_ct_l3proto_module_put(par->target->family);
 }
 }
 
 
 #ifdef CONFIG_COMPAT
 #ifdef CONFIG_COMPAT
@@ -445,7 +440,7 @@ struct compat_ipt_clusterip_tgt_info
 
 
 static struct xt_target clusterip_tg_reg __read_mostly = {
 static struct xt_target clusterip_tg_reg __read_mostly = {
 	.name		= "CLUSTERIP",
 	.name		= "CLUSTERIP",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target		= clusterip_tg,
 	.target		= clusterip_tg,
 	.checkentry	= clusterip_tg_check,
 	.checkentry	= clusterip_tg_check,
 	.destroy	= clusterip_tg_destroy,
 	.destroy	= clusterip_tg_destroy,
@@ -546,7 +541,7 @@ arp_mangle(unsigned int hook,
 
 
 static struct nf_hook_ops cip_arp_ops __read_mostly = {
 static struct nf_hook_ops cip_arp_ops __read_mostly = {
 	.hook = arp_mangle,
 	.hook = arp_mangle,
-	.pf = NF_ARP,
+	.pf = NFPROTO_ARP,
 	.hooknum = NF_ARP_OUT,
 	.hooknum = NF_ARP_OUT,
 	.priority = -1
 	.priority = -1
 };
 };

+ 6 - 11
net/ipv4/netfilter/ipt_ECN.c

@@ -77,11 +77,9 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
 }
 }
 
 
 static unsigned int
 static unsigned int
-ecn_tg(struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, unsigned int hooknum,
-       const struct xt_target *target, const void *targinfo)
+ecn_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ipt_ECN_info *einfo = targinfo;
+	const struct ipt_ECN_info *einfo = par->targinfo;
 
 
 	if (einfo->operation & IPT_ECN_OP_SET_IP)
 	if (einfo->operation & IPT_ECN_OP_SET_IP)
 		if (!set_ect_ip(skb, einfo))
 		if (!set_ect_ip(skb, einfo))
@@ -95,13 +93,10 @@ ecn_tg(struct sk_buff *skb, const struct net_device *in,
 	return XT_CONTINUE;
 	return XT_CONTINUE;
 }
 }
 
 
-static bool
-ecn_tg_check(const char *tablename, const void *e_void,
-             const struct xt_target *target, void *targinfo,
-             unsigned int hook_mask)
+static bool ecn_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ipt_ECN_info *einfo = targinfo;
-	const struct ipt_entry *e = e_void;
+	const struct ipt_ECN_info *einfo = par->targinfo;
+	const struct ipt_entry *e = par->entryinfo;
 
 
 	if (einfo->operation & IPT_ECN_OP_MASK) {
 	if (einfo->operation & IPT_ECN_OP_MASK) {
 		printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
 		printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
@@ -124,7 +119,7 @@ ecn_tg_check(const char *tablename, const void *e_void,
 
 
 static struct xt_target ecn_tg_reg __read_mostly = {
 static struct xt_target ecn_tg_reg __read_mostly = {
 	.name		= "ECN",
 	.name		= "ECN",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target		= ecn_tg,
 	.target		= ecn_tg,
 	.targetsize	= sizeof(struct ipt_ECN_info),
 	.targetsize	= sizeof(struct ipt_ECN_info),
 	.table		= "mangle",
 	.table		= "mangle",

+ 8 - 13
net/ipv4/netfilter/ipt_LOG.c

@@ -375,7 +375,7 @@ static struct nf_loginfo default_loginfo = {
 };
 };
 
 
 static void
 static void
-ipt_log_packet(unsigned int pf,
+ipt_log_packet(u_int8_t pf,
 	       unsigned int hooknum,
 	       unsigned int hooknum,
 	       const struct sk_buff *skb,
 	       const struct sk_buff *skb,
 	       const struct net_device *in,
 	       const struct net_device *in,
@@ -426,28 +426,23 @@ ipt_log_packet(unsigned int pf,
 }
 }
 
 
 static unsigned int
 static unsigned int
-log_tg(struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, unsigned int hooknum,
-       const struct xt_target *target, const void *targinfo)
+log_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ipt_log_info *loginfo = targinfo;
+	const struct ipt_log_info *loginfo = par->targinfo;
 	struct nf_loginfo li;
 	struct nf_loginfo li;
 
 
 	li.type = NF_LOG_TYPE_LOG;
 	li.type = NF_LOG_TYPE_LOG;
 	li.u.log.level = loginfo->level;
 	li.u.log.level = loginfo->level;
 	li.u.log.logflags = loginfo->logflags;
 	li.u.log.logflags = loginfo->logflags;
 
 
-	ipt_log_packet(PF_INET, hooknum, skb, in, out, &li,
+	ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li,
 		       loginfo->prefix);
 		       loginfo->prefix);
 	return XT_CONTINUE;
 	return XT_CONTINUE;
 }
 }
 
 
-static bool
-log_tg_check(const char *tablename, const void *e,
-             const struct xt_target *target, void *targinfo,
-             unsigned int hook_mask)
+static bool log_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ipt_log_info *loginfo = targinfo;
+	const struct ipt_log_info *loginfo = par->targinfo;
 
 
 	if (loginfo->level >= 8) {
 	if (loginfo->level >= 8) {
 		pr_debug("LOG: level %u >= 8\n", loginfo->level);
 		pr_debug("LOG: level %u >= 8\n", loginfo->level);
@@ -463,7 +458,7 @@ log_tg_check(const char *tablename, const void *e,
 
 
 static struct xt_target log_tg_reg __read_mostly = {
 static struct xt_target log_tg_reg __read_mostly = {
 	.name		= "LOG",
 	.name		= "LOG",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target		= log_tg,
 	.target		= log_tg,
 	.targetsize	= sizeof(struct ipt_log_info),
 	.targetsize	= sizeof(struct ipt_log_info),
 	.checkentry	= log_tg_check,
 	.checkentry	= log_tg_check,
@@ -483,7 +478,7 @@ static int __init log_tg_init(void)
 	ret = xt_register_target(&log_tg_reg);
 	ret = xt_register_target(&log_tg_reg);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
-	nf_log_register(PF_INET, &ipt_log_logger);
+	nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
 	return 0;
 	return 0;
 }
 }
 
 

+ 12 - 18
net/ipv4/netfilter/ipt_MASQUERADE.c

@@ -31,12 +31,9 @@ MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
 static DEFINE_RWLOCK(masq_lock);
 static DEFINE_RWLOCK(masq_lock);
 
 
 /* FIXME: Multiple targets. --RR */
 /* FIXME: Multiple targets. --RR */
-static bool
-masquerade_tg_check(const char *tablename, const void *e,
-                    const struct xt_target *target, void *targinfo,
-                    unsigned int hook_mask)
+static bool masquerade_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
 
 	if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
 	if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
 		pr_debug("masquerade_check: bad MAP_IPS.\n");
 		pr_debug("masquerade_check: bad MAP_IPS.\n");
@@ -50,9 +47,7 @@ masquerade_tg_check(const char *tablename, const void *e,
 }
 }
 
 
 static unsigned int
 static unsigned int
-masquerade_tg(struct sk_buff *skb, const struct net_device *in,
-              const struct net_device *out, unsigned int hooknum,
-              const struct xt_target *target, const void *targinfo)
+masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	struct nf_conn *ct;
 	struct nf_conn *ct;
 	struct nf_conn_nat *nat;
 	struct nf_conn_nat *nat;
@@ -62,7 +57,7 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in,
 	const struct rtable *rt;
 	const struct rtable *rt;
 	__be32 newsrc;
 	__be32 newsrc;
 
 
-	NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING);
+	NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);
 
 
 	ct = nf_ct_get(skb, &ctinfo);
 	ct = nf_ct_get(skb, &ctinfo);
 	nat = nfct_nat(ct);
 	nat = nfct_nat(ct);
@@ -76,16 +71,16 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in,
 	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)
 	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)
 		return NF_ACCEPT;
 		return NF_ACCEPT;
 
 
-	mr = targinfo;
+	mr = par->targinfo;
 	rt = skb->rtable;
 	rt = skb->rtable;
-	newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
+	newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
 	if (!newsrc) {
 	if (!newsrc) {
-		printk("MASQUERADE: %s ate my IP address\n", out->name);
+		printk("MASQUERADE: %s ate my IP address\n", par->out->name);
 		return NF_DROP;
 		return NF_DROP;
 	}
 	}
 
 
 	write_lock_bh(&masq_lock);
 	write_lock_bh(&masq_lock);
-	nat->masq_index = out->ifindex;
+	nat->masq_index = par->out->ifindex;
 	write_unlock_bh(&masq_lock);
 	write_unlock_bh(&masq_lock);
 
 
 	/* Transfer from original range. */
 	/* Transfer from original range. */
@@ -119,9 +114,7 @@ static int masq_device_event(struct notifier_block *this,
 			     void *ptr)
 			     void *ptr)
 {
 {
 	const struct net_device *dev = ptr;
 	const struct net_device *dev = ptr;
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return NOTIFY_DONE;
+	struct net *net = dev_net(dev);
 
 
 	if (event == NETDEV_DOWN) {
 	if (event == NETDEV_DOWN) {
 		/* Device was downed.  Search entire table for
 		/* Device was downed.  Search entire table for
@@ -129,7 +122,8 @@ static int masq_device_event(struct notifier_block *this,
 		   and forget them. */
 		   and forget them. */
 		NF_CT_ASSERT(dev->ifindex != 0);
 		NF_CT_ASSERT(dev->ifindex != 0);
 
 
-		nf_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex);
+		nf_ct_iterate_cleanup(net, device_cmp,
+				      (void *)(long)dev->ifindex);
 	}
 	}
 
 
 	return NOTIFY_DONE;
 	return NOTIFY_DONE;
@@ -153,7 +147,7 @@ static struct notifier_block masq_inet_notifier = {
 
 
 static struct xt_target masquerade_tg_reg __read_mostly = {
 static struct xt_target masquerade_tg_reg __read_mostly = {
 	.name		= "MASQUERADE",
 	.name		= "MASQUERADE",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target		= masquerade_tg,
 	.target		= masquerade_tg,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.table		= "nat",
 	.table		= "nat",

+ 11 - 15
net/ipv4/netfilter/ipt_NETMAP.c

@@ -22,12 +22,9 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
 MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
 MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
 MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
 
 
-static bool
-netmap_tg_check(const char *tablename, const void *e,
-                const struct xt_target *target, void *targinfo,
-                unsigned int hook_mask)
+static bool netmap_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
 
 	if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
 	if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
 		pr_debug("NETMAP:check: bad MAP_IPS.\n");
 		pr_debug("NETMAP:check: bad MAP_IPS.\n");
@@ -41,24 +38,23 @@ netmap_tg_check(const char *tablename, const void *e,
 }
 }
 
 
 static unsigned int
 static unsigned int
-netmap_tg(struct sk_buff *skb, const struct net_device *in,
-          const struct net_device *out, unsigned int hooknum,
-          const struct xt_target *target, const void *targinfo)
+netmap_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	struct nf_conn *ct;
 	struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
 	enum ip_conntrack_info ctinfo;
 	__be32 new_ip, netmask;
 	__be32 new_ip, netmask;
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 	struct nf_nat_range newrange;
 	struct nf_nat_range newrange;
 
 
-	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING
-		     || hooknum == NF_INET_POST_ROUTING
-		     || hooknum == NF_INET_LOCAL_OUT);
+	NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
+		     par->hooknum == NF_INET_POST_ROUTING ||
+		     par->hooknum == NF_INET_LOCAL_OUT);
 	ct = nf_ct_get(skb, &ctinfo);
 	ct = nf_ct_get(skb, &ctinfo);
 
 
 	netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
 	netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
 
 
-	if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT)
+	if (par->hooknum == NF_INET_PRE_ROUTING ||
+	    par->hooknum == NF_INET_LOCAL_OUT)
 		new_ip = ip_hdr(skb)->daddr & ~netmask;
 		new_ip = ip_hdr(skb)->daddr & ~netmask;
 	else
 	else
 		new_ip = ip_hdr(skb)->saddr & ~netmask;
 		new_ip = ip_hdr(skb)->saddr & ~netmask;
@@ -70,12 +66,12 @@ netmap_tg(struct sk_buff *skb, const struct net_device *in,
 		  mr->range[0].min, mr->range[0].max });
 		  mr->range[0].min, mr->range[0].max });
 
 
 	/* Hand modified range to generic setup. */
 	/* Hand modified range to generic setup. */
-	return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(hooknum));
+	return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->hooknum));
 }
 }
 
 
 static struct xt_target netmap_tg_reg __read_mostly = {
 static struct xt_target netmap_tg_reg __read_mostly = {
 	.name 		= "NETMAP",
 	.name 		= "NETMAP",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target 	= netmap_tg,
 	.target 	= netmap_tg,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.table		= "nat",
 	.table		= "nat",

+ 8 - 13
net/ipv4/netfilter/ipt_REDIRECT.c

@@ -26,12 +26,9 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
 MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
 
 
 /* FIXME: Take multiple ranges --RR */
 /* FIXME: Take multiple ranges --RR */
-static bool
-redirect_tg_check(const char *tablename, const void *e,
-                  const struct xt_target *target, void *targinfo,
-                  unsigned int hook_mask)
+static bool redirect_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
 
 	if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
 	if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
 		pr_debug("redirect_check: bad MAP_IPS.\n");
 		pr_debug("redirect_check: bad MAP_IPS.\n");
@@ -45,24 +42,22 @@ redirect_tg_check(const char *tablename, const void *e,
 }
 }
 
 
 static unsigned int
 static unsigned int
-redirect_tg(struct sk_buff *skb, const struct net_device *in,
-            const struct net_device *out, unsigned int hooknum,
-            const struct xt_target *target, const void *targinfo)
+redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	struct nf_conn *ct;
 	struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
 	enum ip_conntrack_info ctinfo;
 	__be32 newdst;
 	__be32 newdst;
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 	struct nf_nat_range newrange;
 	struct nf_nat_range newrange;
 
 
-	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING
-		     || hooknum == NF_INET_LOCAL_OUT);
+	NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
+		     par->hooknum == NF_INET_LOCAL_OUT);
 
 
 	ct = nf_ct_get(skb, &ctinfo);
 	ct = nf_ct_get(skb, &ctinfo);
 	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 
 
 	/* Local packets: make them go to loopback */
 	/* Local packets: make them go to loopback */
-	if (hooknum == NF_INET_LOCAL_OUT)
+	if (par->hooknum == NF_INET_LOCAL_OUT)
 		newdst = htonl(0x7F000001);
 		newdst = htonl(0x7F000001);
 	else {
 	else {
 		struct in_device *indev;
 		struct in_device *indev;
@@ -92,7 +87,7 @@ redirect_tg(struct sk_buff *skb, const struct net_device *in,
 
 
 static struct xt_target redirect_tg_reg __read_mostly = {
 static struct xt_target redirect_tg_reg __read_mostly = {
 	.name		= "REDIRECT",
 	.name		= "REDIRECT",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target		= redirect_tg,
 	.target		= redirect_tg,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.table		= "nat",
 	.table		= "nat",

+ 7 - 12
net/ipv4/netfilter/ipt_REJECT.c

@@ -136,11 +136,9 @@ static inline void send_unreach(struct sk_buff *skb_in, int code)
 }
 }
 
 
 static unsigned int
 static unsigned int
-reject_tg(struct sk_buff *skb, const struct net_device *in,
-          const struct net_device *out, unsigned int hooknum,
-          const struct xt_target *target, const void *targinfo)
+reject_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ipt_reject_info *reject = targinfo;
+	const struct ipt_reject_info *reject = par->targinfo;
 
 
 	/* WARNING: This code causes reentry within iptables.
 	/* WARNING: This code causes reentry within iptables.
 	   This means that the iptables jump stack is now crap.  We
 	   This means that the iptables jump stack is now crap.  We
@@ -168,7 +166,7 @@ reject_tg(struct sk_buff *skb, const struct net_device *in,
 		send_unreach(skb, ICMP_PKT_FILTERED);
 		send_unreach(skb, ICMP_PKT_FILTERED);
 		break;
 		break;
 	case IPT_TCP_RESET:
 	case IPT_TCP_RESET:
-		send_reset(skb, hooknum);
+		send_reset(skb, par->hooknum);
 	case IPT_ICMP_ECHOREPLY:
 	case IPT_ICMP_ECHOREPLY:
 		/* Doesn't happen. */
 		/* Doesn't happen. */
 		break;
 		break;
@@ -177,13 +175,10 @@ reject_tg(struct sk_buff *skb, const struct net_device *in,
 	return NF_DROP;
 	return NF_DROP;
 }
 }
 
 
-static bool
-reject_tg_check(const char *tablename, const void *e_void,
-                const struct xt_target *target, void *targinfo,
-                unsigned int hook_mask)
+static bool reject_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ipt_reject_info *rejinfo = targinfo;
-	const struct ipt_entry *e = e_void;
+	const struct ipt_reject_info *rejinfo = par->targinfo;
+	const struct ipt_entry *e = par->entryinfo;
 
 
 	if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
 	if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
 		printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
 		printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
@@ -201,7 +196,7 @@ reject_tg_check(const char *tablename, const void *e_void,
 
 
 static struct xt_target reject_tg_reg __read_mostly = {
 static struct xt_target reject_tg_reg __read_mostly = {
 	.name		= "REJECT",
 	.name		= "REJECT",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target		= reject_tg,
 	.target		= reject_tg,
 	.targetsize	= sizeof(struct ipt_reject_info),
 	.targetsize	= sizeof(struct ipt_reject_info),
 	.table		= "filter",
 	.table		= "filter",

+ 5 - 10
net/ipv4/netfilter/ipt_TTL.c

@@ -20,12 +20,10 @@ MODULE_DESCRIPTION("Xtables: IPv4 TTL field modification target");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
 static unsigned int
 static unsigned int
-ttl_tg(struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, unsigned int hooknum,
-       const struct xt_target *target, const void *targinfo)
+ttl_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	struct iphdr *iph;
 	struct iphdr *iph;
-	const struct ipt_TTL_info *info = targinfo;
+	const struct ipt_TTL_info *info = par->targinfo;
 	int new_ttl;
 	int new_ttl;
 
 
 	if (!skb_make_writable(skb, skb->len))
 	if (!skb_make_writable(skb, skb->len))
@@ -61,12 +59,9 @@ ttl_tg(struct sk_buff *skb, const struct net_device *in,
 	return XT_CONTINUE;
 	return XT_CONTINUE;
 }
 }
 
 
-static bool
-ttl_tg_check(const char *tablename, const void *e,
-             const struct xt_target *target, void *targinfo,
-             unsigned int hook_mask)
+static bool ttl_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ipt_TTL_info *info = targinfo;
+	const struct ipt_TTL_info *info = par->targinfo;
 
 
 	if (info->mode > IPT_TTL_MAXMODE) {
 	if (info->mode > IPT_TTL_MAXMODE) {
 		printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
 		printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
@@ -80,7 +75,7 @@ ttl_tg_check(const char *tablename, const void *e,
 
 
 static struct xt_target ttl_tg_reg __read_mostly = {
 static struct xt_target ttl_tg_reg __read_mostly = {
 	.name 		= "TTL",
 	.name 		= "TTL",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target 	= ttl_tg,
 	.target 	= ttl_tg,
 	.targetsize	= sizeof(struct ipt_TTL_info),
 	.targetsize	= sizeof(struct ipt_TTL_info),
 	.table		= "mangle",
 	.table		= "mangle",

+ 8 - 15
net/ipv4/netfilter/ipt_ULOG.c

@@ -281,18 +281,14 @@ alloc_failure:
 }
 }
 
 
 static unsigned int
 static unsigned int
-ulog_tg(struct sk_buff *skb, const struct net_device *in,
-        const struct net_device *out, unsigned int hooknum,
-        const struct xt_target *target, const void *targinfo)
+ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
-
-	ipt_ulog_packet(hooknum, skb, in, out, loginfo, NULL);
-
+	ipt_ulog_packet(par->hooknum, skb, par->in, par->out,
+	                par->targinfo, NULL);
 	return XT_CONTINUE;
 	return XT_CONTINUE;
 }
 }
 
 
-static void ipt_logfn(unsigned int pf,
+static void ipt_logfn(u_int8_t pf,
 		      unsigned int hooknum,
 		      unsigned int hooknum,
 		      const struct sk_buff *skb,
 		      const struct sk_buff *skb,
 		      const struct net_device *in,
 		      const struct net_device *in,
@@ -317,12 +313,9 @@ static void ipt_logfn(unsigned int pf,
 	ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
 	ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
 }
 }
 
 
-static bool
-ulog_tg_check(const char *tablename, const void *e,
-              const struct xt_target *target, void *targinfo,
-              unsigned int hookmask)
+static bool ulog_tg_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ipt_ulog_info *loginfo = targinfo;
+	const struct ipt_ulog_info *loginfo = par->targinfo;
 
 
 	if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
 	if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
 		pr_debug("ipt_ULOG: prefix term %i\n",
 		pr_debug("ipt_ULOG: prefix term %i\n",
@@ -374,7 +367,7 @@ static int ulog_tg_compat_to_user(void __user *dst, void *src)
 
 
 static struct xt_target ulog_tg_reg __read_mostly = {
 static struct xt_target ulog_tg_reg __read_mostly = {
 	.name		= "ULOG",
 	.name		= "ULOG",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.target		= ulog_tg,
 	.target		= ulog_tg,
 	.targetsize	= sizeof(struct ipt_ulog_info),
 	.targetsize	= sizeof(struct ipt_ulog_info),
 	.checkentry	= ulog_tg_check,
 	.checkentry	= ulog_tg_check,
@@ -419,7 +412,7 @@ static int __init ulog_tg_init(void)
 		return ret;
 		return ret;
 	}
 	}
 	if (nflog)
 	if (nflog)
-		nf_log_register(PF_INET, &ipt_ulog_logger);
+		nf_log_register(NFPROTO_IPV4, &ipt_ulog_logger);
 
 
 	return 0;
 	return 0;
 }
 }

+ 14 - 21
net/ipv4/netfilter/ipt_addrtype.c

@@ -30,12 +30,9 @@ static inline bool match_type(const struct net_device *dev, __be32 addr,
 }
 }
 
 
 static bool
 static bool
-addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
-	       const struct net_device *out, const struct xt_match *match,
-	       const void *matchinfo, int offset, unsigned int protoff,
-	       bool *hotdrop)
+addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ipt_addrtype_info *info = matchinfo;
+	const struct ipt_addrtype_info *info = par->matchinfo;
 	const struct iphdr *iph = ip_hdr(skb);
 	const struct iphdr *iph = ip_hdr(skb);
 	bool ret = true;
 	bool ret = true;
 
 
@@ -50,20 +47,17 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
 }
 }
 
 
 static bool
 static bool
-addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
-	       const struct net_device *out, const struct xt_match *match,
-	       const void *matchinfo, int offset, unsigned int protoff,
-	       bool *hotdrop)
+addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ipt_addrtype_info_v1 *info = matchinfo;
+	const struct ipt_addrtype_info_v1 *info = par->matchinfo;
 	const struct iphdr *iph = ip_hdr(skb);
 	const struct iphdr *iph = ip_hdr(skb);
 	const struct net_device *dev = NULL;
 	const struct net_device *dev = NULL;
 	bool ret = true;
 	bool ret = true;
 
 
 	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
 	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
-		dev = in;
+		dev = par->in;
 	else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
 	else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
-		dev = out;
+		dev = par->out;
 
 
 	if (info->source)
 	if (info->source)
 		ret &= match_type(dev, iph->saddr, info->source) ^
 		ret &= match_type(dev, iph->saddr, info->source) ^
@@ -74,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
 	return ret;
 	return ret;
 }
 }
 
 
-static bool
-addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
-			  const struct xt_match *match, void *matchinfo,
-			  unsigned int hook_mask)
+static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
 {
 {
-	struct ipt_addrtype_info_v1 *info = matchinfo;
+	struct ipt_addrtype_info_v1 *info = par->matchinfo;
 
 
 	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
 	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
 	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
 	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
@@ -88,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
 		return false;
 		return false;
 	}
 	}
 
 
-	if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) &&
+	if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
+	    (1 << NF_INET_LOCAL_IN)) &&
 	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
 	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
 		printk(KERN_ERR "ipt_addrtype: output interface limitation "
 		printk(KERN_ERR "ipt_addrtype: output interface limitation "
 				"not valid in PRE_ROUTING and INPUT\n");
 				"not valid in PRE_ROUTING and INPUT\n");
 		return false;
 		return false;
 	}
 	}
 
 
-	if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) &&
+	if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
+	    (1 << NF_INET_LOCAL_OUT)) &&
 	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
 	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
 		printk(KERN_ERR "ipt_addrtype: input interface limitation "
 		printk(KERN_ERR "ipt_addrtype: input interface limitation "
 				"not valid in POST_ROUTING and OUTPUT\n");
 				"not valid in POST_ROUTING and OUTPUT\n");
@@ -108,14 +101,14 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
 static struct xt_match addrtype_mt_reg[] __read_mostly = {
 static struct xt_match addrtype_mt_reg[] __read_mostly = {
 	{
 	{
 		.name		= "addrtype",
 		.name		= "addrtype",
-		.family		= AF_INET,
+		.family		= NFPROTO_IPV4,
 		.match		= addrtype_mt_v0,
 		.match		= addrtype_mt_v0,
 		.matchsize	= sizeof(struct ipt_addrtype_info),
 		.matchsize	= sizeof(struct ipt_addrtype_info),
 		.me		= THIS_MODULE
 		.me		= THIS_MODULE
 	},
 	},
 	{
 	{
 		.name		= "addrtype",
 		.name		= "addrtype",
-		.family		= AF_INET,
+		.family		= NFPROTO_IPV4,
 		.revision	= 1,
 		.revision	= 1,
 		.match		= addrtype_mt_v1,
 		.match		= addrtype_mt_v1,
 		.checkentry	= addrtype_mt_checkentry_v1,
 		.checkentry	= addrtype_mt_checkentry_v1,

+ 8 - 16
net/ipv4/netfilter/ipt_ah.c

@@ -36,27 +36,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 	return r;
 	return r;
 }
 }
 
 
-static bool
-ah_mt(const struct sk_buff *skb, const struct net_device *in,
-      const struct net_device *out, const struct xt_match *match,
-      const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
+static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	struct ip_auth_hdr _ahdr;
 	struct ip_auth_hdr _ahdr;
 	const struct ip_auth_hdr *ah;
 	const struct ip_auth_hdr *ah;
-	const struct ipt_ah *ahinfo = matchinfo;
+	const struct ipt_ah *ahinfo = par->matchinfo;
 
 
 	/* Must not be a fragment. */
 	/* Must not be a fragment. */
-	if (offset)
+	if (par->fragoff != 0)
 		return false;
 		return false;
 
 
-	ah = skb_header_pointer(skb, protoff,
-				sizeof(_ahdr), &_ahdr);
+	ah = skb_header_pointer(skb, par->thoff, sizeof(_ahdr), &_ahdr);
 	if (ah == NULL) {
 	if (ah == NULL) {
 		/* We've been asked to examine this packet, and we
 		/* We've been asked to examine this packet, and we
 		 * can't.  Hence, no choice but to drop.
 		 * can't.  Hence, no choice but to drop.
 		 */
 		 */
 		duprintf("Dropping evil AH tinygram.\n");
 		duprintf("Dropping evil AH tinygram.\n");
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -65,13 +61,9 @@ ah_mt(const struct sk_buff *skb, const struct net_device *in,
 			 !!(ahinfo->invflags & IPT_AH_INV_SPI));
 			 !!(ahinfo->invflags & IPT_AH_INV_SPI));
 }
 }
 
 
-/* Called when user tries to insert an entry of this type. */
-static bool
-ah_mt_check(const char *tablename, const void *ip_void,
-            const struct xt_match *match, void *matchinfo,
-            unsigned int hook_mask)
+static bool ah_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ipt_ah *ahinfo = matchinfo;
+	const struct ipt_ah *ahinfo = par->matchinfo;
 
 
 	/* Must specify no unknown invflags */
 	/* Must specify no unknown invflags */
 	if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
 	if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
@@ -83,7 +75,7 @@ ah_mt_check(const char *tablename, const void *ip_void,
 
 
 static struct xt_match ah_mt_reg __read_mostly = {
 static struct xt_match ah_mt_reg __read_mostly = {
 	.name		= "ah",
 	.name		= "ah",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.match		= ah_mt,
 	.match		= ah_mt,
 	.matchsize	= sizeof(struct ipt_ah),
 	.matchsize	= sizeof(struct ipt_ah),
 	.proto		= IPPROTO_AH,
 	.proto		= IPPROTO_AH,

+ 7 - 13
net/ipv4/netfilter/ipt_ecn.c

@@ -67,12 +67,9 @@ static inline bool match_tcp(const struct sk_buff *skb,
 	return true;
 	return true;
 }
 }
 
 
-static bool
-ecn_mt(const struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, const struct xt_match *match,
-       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
+static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ipt_ecn_info *info = matchinfo;
+	const struct ipt_ecn_info *info = par->matchinfo;
 
 
 	if (info->operation & IPT_ECN_OP_MATCH_IP)
 	if (info->operation & IPT_ECN_OP_MATCH_IP)
 		if (!match_ip(skb, info))
 		if (!match_ip(skb, info))
@@ -81,20 +78,17 @@ ecn_mt(const struct sk_buff *skb, const struct net_device *in,
 	if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
 	if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
 		if (ip_hdr(skb)->protocol != IPPROTO_TCP)
 		if (ip_hdr(skb)->protocol != IPPROTO_TCP)
 			return false;
 			return false;
-		if (!match_tcp(skb, info, hotdrop))
+		if (!match_tcp(skb, info, par->hotdrop))
 			return false;
 			return false;
 	}
 	}
 
 
 	return true;
 	return true;
 }
 }
 
 
-static bool
-ecn_mt_check(const char *tablename, const void *ip_void,
-             const struct xt_match *match, void *matchinfo,
-             unsigned int hook_mask)
+static bool ecn_mt_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ipt_ecn_info *info = matchinfo;
-	const struct ipt_ip *ip = ip_void;
+	const struct ipt_ecn_info *info = par->matchinfo;
+	const struct ipt_ip *ip = par->entryinfo;
 
 
 	if (info->operation & IPT_ECN_OP_MATCH_MASK)
 	if (info->operation & IPT_ECN_OP_MATCH_MASK)
 		return false;
 		return false;
@@ -114,7 +108,7 @@ ecn_mt_check(const char *tablename, const void *ip_void,
 
 
 static struct xt_match ecn_mt_reg __read_mostly = {
 static struct xt_match ecn_mt_reg __read_mostly = {
 	.name		= "ecn",
 	.name		= "ecn",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.match		= ecn_mt,
 	.match		= ecn_mt,
 	.matchsize	= sizeof(struct ipt_ecn_info),
 	.matchsize	= sizeof(struct ipt_ecn_info),
 	.checkentry	= ecn_mt_check,
 	.checkentry	= ecn_mt_check,

+ 3 - 6
net/ipv4/netfilter/ipt_ttl.c

@@ -18,12 +18,9 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("Xtables: IPv4 TTL field match");
 MODULE_DESCRIPTION("Xtables: IPv4 TTL field match");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
-static bool
-ttl_mt(const struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, const struct xt_match *match,
-       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
+static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ipt_ttl_info *info = matchinfo;
+	const struct ipt_ttl_info *info = par->matchinfo;
 	const u8 ttl = ip_hdr(skb)->ttl;
 	const u8 ttl = ip_hdr(skb)->ttl;
 
 
 	switch (info->mode) {
 	switch (info->mode) {
@@ -46,7 +43,7 @@ ttl_mt(const struct sk_buff *skb, const struct net_device *in,
 
 
 static struct xt_match ttl_mt_reg __read_mostly = {
 static struct xt_match ttl_mt_reg __read_mostly = {
 	.name		= "ttl",
 	.name		= "ttl",
-	.family		= AF_INET,
+	.family		= NFPROTO_IPV4,
 	.match		= ttl_mt,
 	.match		= ttl_mt,
 	.matchsize	= sizeof(struct ipt_ttl_info),
 	.matchsize	= sizeof(struct ipt_ttl_info),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,

+ 3 - 3
net/ipv4/netfilter/iptable_filter.c

@@ -70,7 +70,7 @@ ipt_local_in_hook(unsigned int hook,
 		  int (*okfn)(struct sk_buff *))
 		  int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_local_in_net(in, out)->ipv4.iptable_filter);
+			    dev_net(in)->ipv4.iptable_filter);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -81,7 +81,7 @@ ipt_hook(unsigned int hook,
 	 int (*okfn)(struct sk_buff *))
 	 int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_forward_net(in, out)->ipv4.iptable_filter);
+			    dev_net(in)->ipv4.iptable_filter);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -101,7 +101,7 @@ ipt_local_out_hook(unsigned int hook,
 	}
 	}
 
 
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_local_out_net(in, out)->ipv4.iptable_filter);
+			    dev_net(out)->ipv4.iptable_filter);
 }
 }
 
 
 static struct nf_hook_ops ipt_ops[] __read_mostly = {
 static struct nf_hook_ops ipt_ops[] __read_mostly = {

+ 5 - 5
net/ipv4/netfilter/iptable_mangle.c

@@ -81,7 +81,7 @@ ipt_pre_routing_hook(unsigned int hook,
 		     int (*okfn)(struct sk_buff *))
 		     int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_pre_routing_net(in, out)->ipv4.iptable_mangle);
+			    dev_net(in)->ipv4.iptable_mangle);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -92,7 +92,7 @@ ipt_post_routing_hook(unsigned int hook,
 		      int (*okfn)(struct sk_buff *))
 		      int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_post_routing_net(in, out)->ipv4.iptable_mangle);
+			    dev_net(out)->ipv4.iptable_mangle);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -103,7 +103,7 @@ ipt_local_in_hook(unsigned int hook,
 		  int (*okfn)(struct sk_buff *))
 		  int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_local_in_net(in, out)->ipv4.iptable_mangle);
+			    dev_net(in)->ipv4.iptable_mangle);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -114,7 +114,7 @@ ipt_forward_hook(unsigned int hook,
 	 int (*okfn)(struct sk_buff *))
 	 int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_forward_net(in, out)->ipv4.iptable_mangle);
+			    dev_net(in)->ipv4.iptable_mangle);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -147,7 +147,7 @@ ipt_local_hook(unsigned int hook,
 	tos = iph->tos;
 	tos = iph->tos;
 
 
 	ret = ipt_do_table(skb, hook, in, out,
 	ret = ipt_do_table(skb, hook, in, out,
-			   nf_local_out_net(in, out)->ipv4.iptable_mangle);
+			   dev_net(out)->ipv4.iptable_mangle);
 	/* Reroute for ANY change. */
 	/* Reroute for ANY change. */
 	if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
 	if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
 		iph = ip_hdr(skb);
 		iph = ip_hdr(skb);

+ 2 - 2
net/ipv4/netfilter/iptable_raw.c

@@ -53,7 +53,7 @@ ipt_hook(unsigned int hook,
 	 int (*okfn)(struct sk_buff *))
 	 int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_pre_routing_net(in, out)->ipv4.iptable_raw);
+			    dev_net(in)->ipv4.iptable_raw);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -72,7 +72,7 @@ ipt_local_hook(unsigned int hook,
 		return NF_ACCEPT;
 		return NF_ACCEPT;
 	}
 	}
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_local_out_net(in, out)->ipv4.iptable_raw);
+			    dev_net(out)->ipv4.iptable_raw);
 }
 }
 
 
 /* 'raw' is the very first table. */
 /* 'raw' is the very first table. */

+ 3 - 3
net/ipv4/netfilter/iptable_security.c

@@ -73,7 +73,7 @@ ipt_local_in_hook(unsigned int hook,
 		  int (*okfn)(struct sk_buff *))
 		  int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_local_in_net(in, out)->ipv4.iptable_security);
+			    dev_net(in)->ipv4.iptable_security);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -84,7 +84,7 @@ ipt_forward_hook(unsigned int hook,
 		 int (*okfn)(struct sk_buff *))
 		 int (*okfn)(struct sk_buff *))
 {
 {
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_forward_net(in, out)->ipv4.iptable_security);
+			    dev_net(in)->ipv4.iptable_security);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -103,7 +103,7 @@ ipt_local_out_hook(unsigned int hook,
 		return NF_ACCEPT;
 		return NF_ACCEPT;
 	}
 	}
 	return ipt_do_table(skb, hook, in, out,
 	return ipt_do_table(skb, hook, in, out,
-			    nf_local_out_net(in, out)->ipv4.iptable_security);
+			    dev_net(out)->ipv4.iptable_security);
 }
 }
 
 
 static struct nf_hook_ops ipt_ops[] __read_mostly = {
 static struct nf_hook_ops ipt_ops[] __read_mostly = {

+ 9 - 59
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c

@@ -1,3 +1,4 @@
+
 /* (C) 1999-2001 Paul `Rusty' Russell
 /* (C) 1999-2001 Paul `Rusty' Russell
  * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
  * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
  *
  *
@@ -24,6 +25,7 @@
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 #include <net/netfilter/nf_nat_helper.h>
 #include <net/netfilter/nf_nat_helper.h>
+#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
 
 
 int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
 int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
 			      struct nf_conn *ct,
 			      struct nf_conn *ct,
@@ -63,23 +65,6 @@ static int ipv4_print_tuple(struct seq_file *s,
 			  NIPQUAD(tuple->dst.u3.ip));
 			  NIPQUAD(tuple->dst.u3.ip));
 }
 }
 
 
-/* Returns new sk_buff, or NULL */
-static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
-{
-	int err;
-
-	skb_orphan(skb);
-
-	local_bh_disable();
-	err = ip_defrag(skb, user);
-	local_bh_enable();
-
-	if (!err)
-		ip_send_check(ip_hdr(skb));
-
-	return err;
-}
-
 static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
 static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
 			    unsigned int *dataoff, u_int8_t *protonum)
 			    unsigned int *dataoff, u_int8_t *protonum)
 {
 {
@@ -144,35 +129,13 @@ out:
 	return nf_conntrack_confirm(skb);
 	return nf_conntrack_confirm(skb);
 }
 }
 
 
-static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
-					  struct sk_buff *skb,
-					  const struct net_device *in,
-					  const struct net_device *out,
-					  int (*okfn)(struct sk_buff *))
-{
-	/* Previously seen (loopback)?  Ignore.  Do this before
-	   fragment check. */
-	if (skb->nfct)
-		return NF_ACCEPT;
-
-	/* Gather fragments. */
-	if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-		if (nf_ct_ipv4_gather_frags(skb,
-					    hooknum == NF_INET_PRE_ROUTING ?
-					    IP_DEFRAG_CONNTRACK_IN :
-					    IP_DEFRAG_CONNTRACK_OUT))
-			return NF_STOLEN;
-	}
-	return NF_ACCEPT;
-}
-
 static unsigned int ipv4_conntrack_in(unsigned int hooknum,
 static unsigned int ipv4_conntrack_in(unsigned int hooknum,
 				      struct sk_buff *skb,
 				      struct sk_buff *skb,
 				      const struct net_device *in,
 				      const struct net_device *in,
 				      const struct net_device *out,
 				      const struct net_device *out,
 				      int (*okfn)(struct sk_buff *))
 				      int (*okfn)(struct sk_buff *))
 {
 {
-	return nf_conntrack_in(PF_INET, hooknum, skb);
+	return nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb);
 }
 }
 
 
 static unsigned int ipv4_conntrack_local(unsigned int hooknum,
 static unsigned int ipv4_conntrack_local(unsigned int hooknum,
@@ -188,19 +151,12 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
 			printk("ipt_hook: happy cracking.\n");
 			printk("ipt_hook: happy cracking.\n");
 		return NF_ACCEPT;
 		return NF_ACCEPT;
 	}
 	}
-	return nf_conntrack_in(PF_INET, hooknum, skb);
+	return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb);
 }
 }
 
 
 /* Connection tracking may drop packets, but never alters them, so
 /* Connection tracking may drop packets, but never alters them, so
    make it the first hook. */
    make it the first hook. */
 static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
 static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
-	{
-		.hook		= ipv4_conntrack_defrag,
-		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
-		.hooknum	= NF_INET_PRE_ROUTING,
-		.priority	= NF_IP_PRI_CONNTRACK_DEFRAG,
-	},
 	{
 	{
 		.hook		= ipv4_conntrack_in,
 		.hook		= ipv4_conntrack_in,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
@@ -208,13 +164,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP_PRI_CONNTRACK,
 		.priority	= NF_IP_PRI_CONNTRACK,
 	},
 	},
-	{
-		.hook           = ipv4_conntrack_defrag,
-		.owner          = THIS_MODULE,
-		.pf             = PF_INET,
-		.hooknum        = NF_INET_LOCAL_OUT,
-		.priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
-	},
 	{
 	{
 		.hook		= ipv4_conntrack_local,
 		.hook		= ipv4_conntrack_local,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
@@ -254,7 +203,7 @@ static ctl_table ip_ct_sysctl_table[] = {
 	{
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_COUNT,
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_COUNT,
 		.procname	= "ip_conntrack_count",
 		.procname	= "ip_conntrack_count",
-		.data		= &nf_conntrack_count,
+		.data		= &init_net.ct.count,
 		.maxlen		= sizeof(int),
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
 		.mode		= 0444,
 		.proc_handler	= &proc_dointvec,
 		.proc_handler	= &proc_dointvec,
@@ -270,7 +219,7 @@ static ctl_table ip_ct_sysctl_table[] = {
 	{
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_CHECKSUM,
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_CHECKSUM,
 		.procname	= "ip_conntrack_checksum",
 		.procname	= "ip_conntrack_checksum",
-		.data		= &nf_conntrack_checksum,
+		.data		= &init_net.ct.sysctl_checksum,
 		.maxlen		= sizeof(int),
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 		.proc_handler	= &proc_dointvec,
@@ -278,7 +227,7 @@ static ctl_table ip_ct_sysctl_table[] = {
 	{
 	{
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_LOG_INVALID,
 		.ctl_name	= NET_IPV4_NF_CONNTRACK_LOG_INVALID,
 		.procname	= "ip_conntrack_log_invalid",
 		.procname	= "ip_conntrack_log_invalid",
-		.data		= &nf_ct_log_invalid,
+		.data		= &init_net.ct.sysctl_log_invalid,
 		.maxlen		= sizeof(unsigned int),
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec_minmax,
 		.proc_handler	= &proc_dointvec_minmax,
@@ -323,7 +272,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	h = nf_conntrack_find_get(&tuple);
+	h = nf_conntrack_find_get(sock_net(sk), &tuple);
 	if (h) {
 	if (h) {
 		struct sockaddr_in sin;
 		struct sockaddr_in sin;
 		struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
 		struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
@@ -422,6 +371,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 	int ret = 0;
 	int ret = 0;
 
 
 	need_conntrack();
 	need_conntrack();
+	nf_defrag_ipv4_enable();
 
 
 	ret = nf_register_sockopt(&so_getorigdst);
 	ret = nf_register_sockopt(&so_getorigdst);
 	if (ret < 0) {
 	if (ret < 0) {

+ 49 - 24
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c

@@ -21,18 +21,20 @@
 #include <net/netfilter/nf_conntrack_acct.h>
 #include <net/netfilter/nf_conntrack_acct.h>
 
 
 struct ct_iter_state {
 struct ct_iter_state {
+	struct seq_net_private p;
 	unsigned int bucket;
 	unsigned int bucket;
 };
 };
 
 
 static struct hlist_node *ct_get_first(struct seq_file *seq)
 static struct hlist_node *ct_get_first(struct seq_file *seq)
 {
 {
+	struct net *net = seq_file_net(seq);
 	struct ct_iter_state *st = seq->private;
 	struct ct_iter_state *st = seq->private;
 	struct hlist_node *n;
 	struct hlist_node *n;
 
 
 	for (st->bucket = 0;
 	for (st->bucket = 0;
 	     st->bucket < nf_conntrack_htable_size;
 	     st->bucket < nf_conntrack_htable_size;
 	     st->bucket++) {
 	     st->bucket++) {
-		n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
+		n = rcu_dereference(net->ct.hash[st->bucket].first);
 		if (n)
 		if (n)
 			return n;
 			return n;
 	}
 	}
@@ -42,13 +44,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq)
 static struct hlist_node *ct_get_next(struct seq_file *seq,
 static struct hlist_node *ct_get_next(struct seq_file *seq,
 				      struct hlist_node *head)
 				      struct hlist_node *head)
 {
 {
+	struct net *net = seq_file_net(seq);
 	struct ct_iter_state *st = seq->private;
 	struct ct_iter_state *st = seq->private;
 
 
 	head = rcu_dereference(head->next);
 	head = rcu_dereference(head->next);
 	while (head == NULL) {
 	while (head == NULL) {
 		if (++st->bucket >= nf_conntrack_htable_size)
 		if (++st->bucket >= nf_conntrack_htable_size)
 			return NULL;
 			return NULL;
-		head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
+		head = rcu_dereference(net->ct.hash[st->bucket].first);
 	}
 	}
 	return head;
 	return head;
 }
 }
@@ -158,8 +161,8 @@ static const struct seq_operations ct_seq_ops = {
 
 
 static int ct_open(struct inode *inode, struct file *file)
 static int ct_open(struct inode *inode, struct file *file)
 {
 {
-	return seq_open_private(file, &ct_seq_ops,
-			sizeof(struct ct_iter_state));
+	return seq_open_net(inode, file, &ct_seq_ops,
+			    sizeof(struct ct_iter_state));
 }
 }
 
 
 static const struct file_operations ct_file_ops = {
 static const struct file_operations ct_file_ops = {
@@ -167,21 +170,23 @@ static const struct file_operations ct_file_ops = {
 	.open    = ct_open,
 	.open    = ct_open,
 	.read    = seq_read,
 	.read    = seq_read,
 	.llseek  = seq_lseek,
 	.llseek  = seq_lseek,
-	.release = seq_release_private,
+	.release = seq_release_net,
 };
 };
 
 
 /* expects */
 /* expects */
 struct ct_expect_iter_state {
 struct ct_expect_iter_state {
+	struct seq_net_private p;
 	unsigned int bucket;
 	unsigned int bucket;
 };
 };
 
 
 static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 {
 {
+	struct net *net = seq_file_net(seq);
 	struct ct_expect_iter_state *st = seq->private;
 	struct ct_expect_iter_state *st = seq->private;
 	struct hlist_node *n;
 	struct hlist_node *n;
 
 
 	for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
 	for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
-		n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
+		n = rcu_dereference(net->ct.expect_hash[st->bucket].first);
 		if (n)
 		if (n)
 			return n;
 			return n;
 	}
 	}
@@ -191,13 +196,14 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
 static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
 					     struct hlist_node *head)
 					     struct hlist_node *head)
 {
 {
+	struct net *net = seq_file_net(seq);
 	struct ct_expect_iter_state *st = seq->private;
 	struct ct_expect_iter_state *st = seq->private;
 
 
 	head = rcu_dereference(head->next);
 	head = rcu_dereference(head->next);
 	while (head == NULL) {
 	while (head == NULL) {
 		if (++st->bucket >= nf_ct_expect_hsize)
 		if (++st->bucket >= nf_ct_expect_hsize)
 			return NULL;
 			return NULL;
-		head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
+		head = rcu_dereference(net->ct.expect_hash[st->bucket].first);
 	}
 	}
 	return head;
 	return head;
 }
 }
@@ -265,8 +271,8 @@ static const struct seq_operations exp_seq_ops = {
 
 
 static int exp_open(struct inode *inode, struct file *file)
 static int exp_open(struct inode *inode, struct file *file)
 {
 {
-	return seq_open_private(file, &exp_seq_ops,
-			sizeof(struct ct_expect_iter_state));
+	return seq_open_net(inode, file, &exp_seq_ops,
+			    sizeof(struct ct_expect_iter_state));
 }
 }
 
 
 static const struct file_operations ip_exp_file_ops = {
 static const struct file_operations ip_exp_file_ops = {
@@ -274,11 +280,12 @@ static const struct file_operations ip_exp_file_ops = {
 	.open    = exp_open,
 	.open    = exp_open,
 	.read    = seq_read,
 	.read    = seq_read,
 	.llseek  = seq_lseek,
 	.llseek  = seq_lseek,
-	.release = seq_release_private,
+	.release = seq_release_net,
 };
 };
 
 
 static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
 static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
 {
 {
+	struct net *net = seq_file_net(seq);
 	int cpu;
 	int cpu;
 
 
 	if (*pos == 0)
 	if (*pos == 0)
@@ -288,7 +295,7 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
 		if (!cpu_possible(cpu))
 		if (!cpu_possible(cpu))
 			continue;
 			continue;
 		*pos = cpu+1;
 		*pos = cpu+1;
-		return &per_cpu(nf_conntrack_stat, cpu);
+		return per_cpu_ptr(net->ct.stat, cpu);
 	}
 	}
 
 
 	return NULL;
 	return NULL;
@@ -296,13 +303,14 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
 
 
 static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
 {
+	struct net *net = seq_file_net(seq);
 	int cpu;
 	int cpu;
 
 
 	for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
 	for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
 		if (!cpu_possible(cpu))
 		if (!cpu_possible(cpu))
 			continue;
 			continue;
 		*pos = cpu+1;
 		*pos = cpu+1;
-		return &per_cpu(nf_conntrack_stat, cpu);
+		return per_cpu_ptr(net->ct.stat, cpu);
 	}
 	}
 
 
 	return NULL;
 	return NULL;
@@ -314,7 +322,8 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
 
 
 static int ct_cpu_seq_show(struct seq_file *seq, void *v)
 static int ct_cpu_seq_show(struct seq_file *seq, void *v)
 {
 {
-	unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
+	struct net *net = seq_file_net(seq);
+	unsigned int nr_conntracks = atomic_read(&net->ct.count);
 	const struct ip_conntrack_stat *st = v;
 	const struct ip_conntrack_stat *st = v;
 
 
 	if (v == SEQ_START_TOKEN) {
 	if (v == SEQ_START_TOKEN) {
@@ -354,7 +363,8 @@ static const struct seq_operations ct_cpu_seq_ops = {
 
 
 static int ct_cpu_seq_open(struct inode *inode, struct file *file)
 static int ct_cpu_seq_open(struct inode *inode, struct file *file)
 {
 {
-	return seq_open(file, &ct_cpu_seq_ops);
+	return seq_open_net(inode, file, &ct_cpu_seq_ops,
+			    sizeof(struct seq_net_private));
 }
 }
 
 
 static const struct file_operations ct_cpu_seq_fops = {
 static const struct file_operations ct_cpu_seq_fops = {
@@ -362,39 +372,54 @@ static const struct file_operations ct_cpu_seq_fops = {
 	.open    = ct_cpu_seq_open,
 	.open    = ct_cpu_seq_open,
 	.read    = seq_read,
 	.read    = seq_read,
 	.llseek  = seq_lseek,
 	.llseek  = seq_lseek,
-	.release = seq_release,
+	.release = seq_release_net,
 };
 };
 
 
-int __init nf_conntrack_ipv4_compat_init(void)
+static int __net_init ip_conntrack_net_init(struct net *net)
 {
 {
 	struct proc_dir_entry *proc, *proc_exp, *proc_stat;
 	struct proc_dir_entry *proc, *proc_exp, *proc_stat;
 
 
-	proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops);
+	proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops);
 	if (!proc)
 	if (!proc)
 		goto err1;
 		goto err1;
 
 
-	proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440,
+	proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440,
 					&ip_exp_file_ops);
 					&ip_exp_file_ops);
 	if (!proc_exp)
 	if (!proc_exp)
 		goto err2;
 		goto err2;
 
 
 	proc_stat = proc_create("ip_conntrack", S_IRUGO,
 	proc_stat = proc_create("ip_conntrack", S_IRUGO,
-				init_net.proc_net_stat, &ct_cpu_seq_fops);
+				net->proc_net_stat, &ct_cpu_seq_fops);
 	if (!proc_stat)
 	if (!proc_stat)
 		goto err3;
 		goto err3;
 	return 0;
 	return 0;
 
 
 err3:
 err3:
-	proc_net_remove(&init_net, "ip_conntrack_expect");
+	proc_net_remove(net, "ip_conntrack_expect");
 err2:
 err2:
-	proc_net_remove(&init_net, "ip_conntrack");
+	proc_net_remove(net, "ip_conntrack");
 err1:
 err1:
 	return -ENOMEM;
 	return -ENOMEM;
 }
 }
 
 
+static void __net_exit ip_conntrack_net_exit(struct net *net)
+{
+	remove_proc_entry("ip_conntrack", net->proc_net_stat);
+	proc_net_remove(net, "ip_conntrack_expect");
+	proc_net_remove(net, "ip_conntrack");
+}
+
+static struct pernet_operations ip_conntrack_net_ops = {
+	.init = ip_conntrack_net_init,
+	.exit = ip_conntrack_net_exit,
+};
+
+int __init nf_conntrack_ipv4_compat_init(void)
+{
+	return register_pernet_subsys(&ip_conntrack_net_ops);
+}
+
 void __exit nf_conntrack_ipv4_compat_fini(void)
 void __exit nf_conntrack_ipv4_compat_fini(void)
 {
 {
-	remove_proc_entry("ip_conntrack", init_net.proc_net_stat);
-	proc_net_remove(&init_net, "ip_conntrack_expect");
-	proc_net_remove(&init_net, "ip_conntrack");
+	unregister_pernet_subsys(&ip_conntrack_net_ops);
 }
 }

+ 11 - 11
net/ipv4/netfilter/nf_conntrack_proto_icmp.c

@@ -79,7 +79,7 @@ static int icmp_packet(struct nf_conn *ct,
 		       const struct sk_buff *skb,
 		       const struct sk_buff *skb,
 		       unsigned int dataoff,
 		       unsigned int dataoff,
 		       enum ip_conntrack_info ctinfo,
 		       enum ip_conntrack_info ctinfo,
-		       int pf,
+		       u_int8_t pf,
 		       unsigned int hooknum)
 		       unsigned int hooknum)
 {
 {
 	/* Try to delete connection immediately after all replies:
 	/* Try to delete connection immediately after all replies:
@@ -91,7 +91,7 @@ static int icmp_packet(struct nf_conn *ct,
 			nf_ct_kill_acct(ct, ctinfo, skb);
 			nf_ct_kill_acct(ct, ctinfo, skb);
 	} else {
 	} else {
 		atomic_inc(&ct->proto.icmp.count);
 		atomic_inc(&ct->proto.icmp.count);
-		nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
+		nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
 		nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
 		nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
 	}
 	}
 
 
@@ -123,7 +123,7 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
 
 
 /* Returns conntrack if it dealt with ICMP, and filled in skb fields */
 /* Returns conntrack if it dealt with ICMP, and filled in skb fields */
 static int
 static int
-icmp_error_message(struct sk_buff *skb,
+icmp_error_message(struct net *net, struct sk_buff *skb,
 		 enum ip_conntrack_info *ctinfo,
 		 enum ip_conntrack_info *ctinfo,
 		 unsigned int hooknum)
 		 unsigned int hooknum)
 {
 {
@@ -155,7 +155,7 @@ icmp_error_message(struct sk_buff *skb,
 
 
 	*ctinfo = IP_CT_RELATED;
 	*ctinfo = IP_CT_RELATED;
 
 
-	h = nf_conntrack_find_get(&innertuple);
+	h = nf_conntrack_find_get(net, &innertuple);
 	if (!h) {
 	if (!h) {
 		pr_debug("icmp_error_message: no match\n");
 		pr_debug("icmp_error_message: no match\n");
 		return -NF_ACCEPT;
 		return -NF_ACCEPT;
@@ -172,8 +172,8 @@ icmp_error_message(struct sk_buff *skb,
 
 
 /* Small and modified version of icmp_rcv */
 /* Small and modified version of icmp_rcv */
 static int
 static int
-icmp_error(struct sk_buff *skb, unsigned int dataoff,
-	   enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
+icmp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
+	   enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
 {
 {
 	const struct icmphdr *icmph;
 	const struct icmphdr *icmph;
 	struct icmphdr _ih;
 	struct icmphdr _ih;
@@ -181,16 +181,16 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
 	/* Not enough header? */
 	/* Not enough header? */
 	icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
 	icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
 	if (icmph == NULL) {
 	if (icmph == NULL) {
-		if (LOG_INVALID(IPPROTO_ICMP))
+		if (LOG_INVALID(net, IPPROTO_ICMP))
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
 				      "nf_ct_icmp: short packet ");
 				      "nf_ct_icmp: short packet ");
 		return -NF_ACCEPT;
 		return -NF_ACCEPT;
 	}
 	}
 
 
 	/* See ip_conntrack_proto_tcp.c */
 	/* See ip_conntrack_proto_tcp.c */
-	if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
+	if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
 	    nf_ip_checksum(skb, hooknum, dataoff, 0)) {
 	    nf_ip_checksum(skb, hooknum, dataoff, 0)) {
-		if (LOG_INVALID(IPPROTO_ICMP))
+		if (LOG_INVALID(net, IPPROTO_ICMP))
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
 				      "nf_ct_icmp: bad HW ICMP checksum ");
 				      "nf_ct_icmp: bad HW ICMP checksum ");
 		return -NF_ACCEPT;
 		return -NF_ACCEPT;
@@ -203,7 +203,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
 	 *		  discarded.
 	 *		  discarded.
 	 */
 	 */
 	if (icmph->type > NR_ICMP_TYPES) {
 	if (icmph->type > NR_ICMP_TYPES) {
-		if (LOG_INVALID(IPPROTO_ICMP))
+		if (LOG_INVALID(net, IPPROTO_ICMP))
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
 				      "nf_ct_icmp: invalid ICMP type ");
 				      "nf_ct_icmp: invalid ICMP type ");
 		return -NF_ACCEPT;
 		return -NF_ACCEPT;
@@ -217,7 +217,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
 	    && icmph->type != ICMP_REDIRECT)
 	    && icmph->type != ICMP_REDIRECT)
 		return NF_ACCEPT;
 		return NF_ACCEPT;
 
 
-	return icmp_error_message(skb, ctinfo, hooknum);
+	return icmp_error_message(net, skb, ctinfo, hooknum);
 }
 }
 
 
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)

+ 96 - 0
net/ipv4/netfilter/nf_defrag_ipv4.c

@@ -0,0 +1,96 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/ip.h>
+#include <linux/netfilter.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <net/route.h>
+#include <net/ip.h>
+
+#include <linux/netfilter_ipv4.h>
+#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+
+/* Returns new sk_buff, or NULL */
+static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
+{
+	int err;
+
+	skb_orphan(skb);
+
+	local_bh_disable();
+	err = ip_defrag(skb, user);
+	local_bh_enable();
+
+	if (!err)
+		ip_send_check(ip_hdr(skb));
+
+	return err;
+}
+
+static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
+					  struct sk_buff *skb,
+					  const struct net_device *in,
+					  const struct net_device *out,
+					  int (*okfn)(struct sk_buff *))
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	/* Previously seen (loopback)?  Ignore.  Do this before
+	   fragment check. */
+	if (skb->nfct)
+		return NF_ACCEPT;
+#endif
+
+	/* Gather fragments. */
+	if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
+		if (nf_ct_ipv4_gather_frags(skb,
+					    hooknum == NF_INET_PRE_ROUTING ?
+					    IP_DEFRAG_CONNTRACK_IN :
+					    IP_DEFRAG_CONNTRACK_OUT))
+			return NF_STOLEN;
+	}
+	return NF_ACCEPT;
+}
+
+static struct nf_hook_ops ipv4_defrag_ops[] = {
+	{
+		.hook		= ipv4_conntrack_defrag,
+		.owner		= THIS_MODULE,
+		.pf		= PF_INET,
+		.hooknum	= NF_INET_PRE_ROUTING,
+		.priority	= NF_IP_PRI_CONNTRACK_DEFRAG,
+	},
+	{
+		.hook           = ipv4_conntrack_defrag,
+		.owner          = THIS_MODULE,
+		.pf             = PF_INET,
+		.hooknum        = NF_INET_LOCAL_OUT,
+		.priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
+	},
+};
+
+static int __init nf_defrag_init(void)
+{
+	return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
+}
+
+static void __exit nf_defrag_fini(void)
+{
+	nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
+}
+
+void nf_defrag_ipv4_enable(void)
+{
+}
+EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
+
+module_init(nf_defrag_init);
+module_exit(nf_defrag_fini);
+
+MODULE_LICENSE("GPL");

+ 45 - 27
net/ipv4/netfilter/nf_nat_core.c

@@ -37,9 +37,6 @@ static struct nf_conntrack_l3proto *l3proto __read_mostly;
 
 
 /* Calculated at init based on memory size */
 /* Calculated at init based on memory size */
 static unsigned int nf_nat_htable_size __read_mostly;
 static unsigned int nf_nat_htable_size __read_mostly;
-static int nf_nat_vmalloced;
-
-static struct hlist_head *bysource __read_mostly;
 
 
 #define MAX_IP_NAT_PROTO 256
 #define MAX_IP_NAT_PROTO 256
 static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
 static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
@@ -145,7 +142,8 @@ same_src(const struct nf_conn *ct,
 
 
 /* Only called for SRC manip */
 /* Only called for SRC manip */
 static int
 static int
-find_appropriate_src(const struct nf_conntrack_tuple *tuple,
+find_appropriate_src(struct net *net,
+		     const struct nf_conntrack_tuple *tuple,
 		     struct nf_conntrack_tuple *result,
 		     struct nf_conntrack_tuple *result,
 		     const struct nf_nat_range *range)
 		     const struct nf_nat_range *range)
 {
 {
@@ -155,7 +153,7 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
 	const struct hlist_node *n;
 	const struct hlist_node *n;
 
 
 	rcu_read_lock();
 	rcu_read_lock();
-	hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) {
+	hlist_for_each_entry_rcu(nat, n, &net->ipv4.nat_bysource[h], bysource) {
 		ct = nat->ct;
 		ct = nat->ct;
 		if (same_src(ct, tuple)) {
 		if (same_src(ct, tuple)) {
 			/* Copy source part from reply tuple. */
 			/* Copy source part from reply tuple. */
@@ -231,6 +229,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
 		 struct nf_conn *ct,
 		 struct nf_conn *ct,
 		 enum nf_nat_manip_type maniptype)
 		 enum nf_nat_manip_type maniptype)
 {
 {
+	struct net *net = nf_ct_net(ct);
 	const struct nf_nat_protocol *proto;
 	const struct nf_nat_protocol *proto;
 
 
 	/* 1) If this srcip/proto/src-proto-part is currently mapped,
 	/* 1) If this srcip/proto/src-proto-part is currently mapped,
@@ -242,7 +241,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
 	   manips not an issue.  */
 	   manips not an issue.  */
 	if (maniptype == IP_NAT_MANIP_SRC &&
 	if (maniptype == IP_NAT_MANIP_SRC &&
 	    !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
 	    !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
-		if (find_appropriate_src(orig_tuple, tuple, range)) {
+		if (find_appropriate_src(net, orig_tuple, tuple, range)) {
 			pr_debug("get_unique_tuple: Found current src map\n");
 			pr_debug("get_unique_tuple: Found current src map\n");
 			if (!nf_nat_used_tuple(tuple, ct))
 			if (!nf_nat_used_tuple(tuple, ct))
 				return;
 				return;
@@ -283,6 +282,7 @@ nf_nat_setup_info(struct nf_conn *ct,
 		  const struct nf_nat_range *range,
 		  const struct nf_nat_range *range,
 		  enum nf_nat_manip_type maniptype)
 		  enum nf_nat_manip_type maniptype)
 {
 {
+	struct net *net = nf_ct_net(ct);
 	struct nf_conntrack_tuple curr_tuple, new_tuple;
 	struct nf_conntrack_tuple curr_tuple, new_tuple;
 	struct nf_conn_nat *nat;
 	struct nf_conn_nat *nat;
 	int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
 	int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
@@ -334,7 +334,8 @@ nf_nat_setup_info(struct nf_conn *ct,
 		/* nf_conntrack_alter_reply might re-allocate exntension aera */
 		/* nf_conntrack_alter_reply might re-allocate exntension aera */
 		nat = nfct_nat(ct);
 		nat = nfct_nat(ct);
 		nat->ct = ct;
 		nat->ct = ct;
-		hlist_add_head_rcu(&nat->bysource, &bysource[srchash]);
+		hlist_add_head_rcu(&nat->bysource,
+				   &net->ipv4.nat_bysource[srchash]);
 		spin_unlock_bh(&nf_nat_lock);
 		spin_unlock_bh(&nf_nat_lock);
 	}
 	}
 
 
@@ -583,6 +584,40 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
 	.flags		= NF_CT_EXT_F_PREALLOC,
 	.flags		= NF_CT_EXT_F_PREALLOC,
 };
 };
 
 
+static int __net_init nf_nat_net_init(struct net *net)
+{
+	net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
+						      &net->ipv4.nat_vmalloced);
+	if (!net->ipv4.nat_bysource)
+		return -ENOMEM;
+	return 0;
+}
+
+/* Clear NAT section of all conntracks, in case we're loaded again. */
+static int clean_nat(struct nf_conn *i, void *data)
+{
+	struct nf_conn_nat *nat = nfct_nat(i);
+
+	if (!nat)
+		return 0;
+	memset(nat, 0, sizeof(*nat));
+	i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
+	return 0;
+}
+
+static void __net_exit nf_nat_net_exit(struct net *net)
+{
+	nf_ct_iterate_cleanup(net, &clean_nat, NULL);
+	synchronize_rcu();
+	nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced,
+			     nf_nat_htable_size);
+}
+
+static struct pernet_operations nf_nat_net_ops = {
+	.init = nf_nat_net_init,
+	.exit = nf_nat_net_exit,
+};
+
 static int __init nf_nat_init(void)
 static int __init nf_nat_init(void)
 {
 {
 	size_t i;
 	size_t i;
@@ -599,12 +634,9 @@ static int __init nf_nat_init(void)
 	/* Leave them the same for the moment. */
 	/* Leave them the same for the moment. */
 	nf_nat_htable_size = nf_conntrack_htable_size;
 	nf_nat_htable_size = nf_conntrack_htable_size;
 
 
-	bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
-					 &nf_nat_vmalloced);
-	if (!bysource) {
-		ret = -ENOMEM;
+	ret = register_pernet_subsys(&nf_nat_net_ops);
+	if (ret < 0)
 		goto cleanup_extend;
 		goto cleanup_extend;
-	}
 
 
 	/* Sew in builtin protocols. */
 	/* Sew in builtin protocols. */
 	spin_lock_bh(&nf_nat_lock);
 	spin_lock_bh(&nf_nat_lock);
@@ -629,23 +661,9 @@ static int __init nf_nat_init(void)
 	return ret;
 	return ret;
 }
 }
 
 
-/* Clear NAT section of all conntracks, in case we're loaded again. */
-static int clean_nat(struct nf_conn *i, void *data)
-{
-	struct nf_conn_nat *nat = nfct_nat(i);
-
-	if (!nat)
-		return 0;
-	memset(nat, 0, sizeof(*nat));
-	i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
-	return 0;
-}
-
 static void __exit nf_nat_cleanup(void)
 static void __exit nf_nat_cleanup(void)
 {
 {
-	nf_ct_iterate_cleanup(&clean_nat, NULL);
-	synchronize_rcu();
-	nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
+	unregister_pernet_subsys(&nf_nat_net_ops);
 	nf_ct_l3proto_put(l3proto);
 	nf_ct_l3proto_put(l3proto);
 	nf_ct_extend_unregister(&nat_extend);
 	nf_ct_extend_unregister(&nat_extend);
 	rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
 	rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);

+ 1 - 1
net/ipv4/netfilter/nf_nat_helper.c

@@ -193,7 +193,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
 		nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
 		nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
 					ct, CTINFO2DIR(ctinfo));
 					ct, CTINFO2DIR(ctinfo));
 
 
-		nf_conntrack_event_cache(IPCT_NATSEQADJ, skb);
+		nf_conntrack_event_cache(IPCT_NATSEQADJ, ct);
 	}
 	}
 	return 1;
 	return 1;
 }
 }

+ 2 - 1
net/ipv4/netfilter/nf_nat_pptp.c

@@ -40,6 +40,7 @@ MODULE_ALIAS("ip_nat_pptp");
 static void pptp_nat_expected(struct nf_conn *ct,
 static void pptp_nat_expected(struct nf_conn *ct,
 			      struct nf_conntrack_expect *exp)
 			      struct nf_conntrack_expect *exp)
 {
 {
+	struct net *net = nf_ct_net(ct);
 	const struct nf_conn *master = ct->master;
 	const struct nf_conn *master = ct->master;
 	struct nf_conntrack_expect *other_exp;
 	struct nf_conntrack_expect *other_exp;
 	struct nf_conntrack_tuple t;
 	struct nf_conntrack_tuple t;
@@ -73,7 +74,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
 
 
 	pr_debug("trying to unexpect other dir: ");
 	pr_debug("trying to unexpect other dir: ");
 	nf_ct_dump_tuple_ip(&t);
 	nf_ct_dump_tuple_ip(&t);
-	other_exp = nf_ct_expect_find_get(&t);
+	other_exp = nf_ct_expect_find_get(net, &t);
 	if (other_exp) {
 	if (other_exp) {
 		nf_ct_unexpect_related(other_exp);
 		nf_ct_unexpect_related(other_exp);
 		nf_ct_expect_put(other_exp);
 		nf_ct_expect_put(other_exp);

+ 47 - 45
net/ipv4/netfilter/nf_nat_rule.c

@@ -33,7 +33,7 @@ static struct
 	struct ipt_replace repl;
 	struct ipt_replace repl;
 	struct ipt_standard entries[3];
 	struct ipt_standard entries[3];
 	struct ipt_error term;
 	struct ipt_error term;
-} nat_initial_table __initdata = {
+} nat_initial_table __net_initdata = {
 	.repl = {
 	.repl = {
 		.name = "nat",
 		.name = "nat",
 		.valid_hooks = NAT_VALID_HOOKS,
 		.valid_hooks = NAT_VALID_HOOKS,
@@ -58,47 +58,42 @@ static struct
 	.term = IPT_ERROR_INIT,			/* ERROR */
 	.term = IPT_ERROR_INIT,			/* ERROR */
 };
 };
 
 
-static struct xt_table __nat_table = {
+static struct xt_table nat_table = {
 	.name		= "nat",
 	.name		= "nat",
 	.valid_hooks	= NAT_VALID_HOOKS,
 	.valid_hooks	= NAT_VALID_HOOKS,
 	.lock		= __RW_LOCK_UNLOCKED(__nat_table.lock),
 	.lock		= __RW_LOCK_UNLOCKED(__nat_table.lock),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,
 	.af		= AF_INET,
 	.af		= AF_INET,
 };
 };
-static struct xt_table *nat_table;
 
 
 /* Source NAT */
 /* Source NAT */
-static unsigned int ipt_snat_target(struct sk_buff *skb,
-				    const struct net_device *in,
-				    const struct net_device *out,
-				    unsigned int hooknum,
-				    const struct xt_target *target,
-				    const void *targinfo)
+static unsigned int
+ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	struct nf_conn *ct;
 	struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
 	enum ip_conntrack_info ctinfo;
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
 
-	NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING);
+	NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);
 
 
 	ct = nf_ct_get(skb, &ctinfo);
 	ct = nf_ct_get(skb, &ctinfo);
 
 
 	/* Connection must be valid and new. */
 	/* Connection must be valid and new. */
 	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
 	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
 			    ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
 			    ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
-	NF_CT_ASSERT(out);
+	NF_CT_ASSERT(par->out != NULL);
 
 
 	return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
 	return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
 }
 }
 
 
 /* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
 /* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
-static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
+static void warn_if_extra_mangle(struct net *net, __be32 dstip, __be32 srcip)
 {
 {
 	static int warned = 0;
 	static int warned = 0;
 	struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
 	struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
 	struct rtable *rt;
 	struct rtable *rt;
 
 
-	if (ip_route_output_key(&init_net, &rt, &fl) != 0)
+	if (ip_route_output_key(net, &rt, &fl) != 0)
 		return;
 		return;
 
 
 	if (rt->rt_src != srcip && !warned) {
 	if (rt->rt_src != srcip && !warned) {
@@ -110,40 +105,32 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
 	ip_rt_put(rt);
 	ip_rt_put(rt);
 }
 }
 
 
-static unsigned int ipt_dnat_target(struct sk_buff *skb,
-				    const struct net_device *in,
-				    const struct net_device *out,
-				    unsigned int hooknum,
-				    const struct xt_target *target,
-				    const void *targinfo)
+static unsigned int
+ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	struct nf_conn *ct;
 	struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
 	enum ip_conntrack_info ctinfo;
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
 
-	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
-		     hooknum == NF_INET_LOCAL_OUT);
+	NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
+		     par->hooknum == NF_INET_LOCAL_OUT);
 
 
 	ct = nf_ct_get(skb, &ctinfo);
 	ct = nf_ct_get(skb, &ctinfo);
 
 
 	/* Connection must be valid and new. */
 	/* Connection must be valid and new. */
 	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 
 
-	if (hooknum == NF_INET_LOCAL_OUT &&
+	if (par->hooknum == NF_INET_LOCAL_OUT &&
 	    mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
 	    mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
-		warn_if_extra_mangle(ip_hdr(skb)->daddr,
+		warn_if_extra_mangle(dev_net(par->out), ip_hdr(skb)->daddr,
 				     mr->range[0].min_ip);
 				     mr->range[0].min_ip);
 
 
 	return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
 	return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
 }
 }
 
 
-static bool ipt_snat_checkentry(const char *tablename,
-				const void *entry,
-				const struct xt_target *target,
-				void *targinfo,
-				unsigned int hook_mask)
+static bool ipt_snat_checkentry(const struct xt_tgchk_param *par)
 {
 {
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
 
 	/* Must be a valid range */
 	/* Must be a valid range */
 	if (mr->rangesize != 1) {
 	if (mr->rangesize != 1) {
@@ -153,13 +140,9 @@ static bool ipt_snat_checkentry(const char *tablename,
 	return true;
 	return true;
 }
 }
 
 
-static bool ipt_dnat_checkentry(const char *tablename,
-				const void *entry,
-				const struct xt_target *target,
-				void *targinfo,
-				unsigned int hook_mask)
+static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par)
 {
 {
-	const struct nf_nat_multi_range_compat *mr = targinfo;
+	const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
 
 	/* Must be a valid range */
 	/* Must be a valid range */
 	if (mr->rangesize != 1) {
 	if (mr->rangesize != 1) {
@@ -194,9 +177,10 @@ int nf_nat_rule_find(struct sk_buff *skb,
 		     const struct net_device *out,
 		     const struct net_device *out,
 		     struct nf_conn *ct)
 		     struct nf_conn *ct)
 {
 {
+	struct net *net = nf_ct_net(ct);
 	int ret;
 	int ret;
 
 
-	ret = ipt_do_table(skb, hooknum, in, out, nat_table);
+	ret = ipt_do_table(skb, hooknum, in, out, net->ipv4.nat_table);
 
 
 	if (ret == NF_ACCEPT) {
 	if (ret == NF_ACCEPT) {
 		if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
 		if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
@@ -226,14 +210,32 @@ static struct xt_target ipt_dnat_reg __read_mostly = {
 	.family		= AF_INET,
 	.family		= AF_INET,
 };
 };
 
 
+static int __net_init nf_nat_rule_net_init(struct net *net)
+{
+	net->ipv4.nat_table = ipt_register_table(net, &nat_table,
+						 &nat_initial_table.repl);
+	if (IS_ERR(net->ipv4.nat_table))
+		return PTR_ERR(net->ipv4.nat_table);
+	return 0;
+}
+
+static void __net_exit nf_nat_rule_net_exit(struct net *net)
+{
+	ipt_unregister_table(net->ipv4.nat_table);
+}
+
+static struct pernet_operations nf_nat_rule_net_ops = {
+	.init = nf_nat_rule_net_init,
+	.exit = nf_nat_rule_net_exit,
+};
+
 int __init nf_nat_rule_init(void)
 int __init nf_nat_rule_init(void)
 {
 {
 	int ret;
 	int ret;
 
 
-	nat_table = ipt_register_table(&init_net, &__nat_table,
-				       &nat_initial_table.repl);
-	if (IS_ERR(nat_table))
-		return PTR_ERR(nat_table);
+	ret = register_pernet_subsys(&nf_nat_rule_net_ops);
+	if (ret != 0)
+		goto out;
 	ret = xt_register_target(&ipt_snat_reg);
 	ret = xt_register_target(&ipt_snat_reg);
 	if (ret != 0)
 	if (ret != 0)
 		goto unregister_table;
 		goto unregister_table;
@@ -247,8 +249,8 @@ int __init nf_nat_rule_init(void)
  unregister_snat:
  unregister_snat:
 	xt_unregister_target(&ipt_snat_reg);
 	xt_unregister_target(&ipt_snat_reg);
  unregister_table:
  unregister_table:
-	ipt_unregister_table(nat_table);
-
+	unregister_pernet_subsys(&nf_nat_rule_net_ops);
+ out:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -256,5 +258,5 @@ void nf_nat_rule_cleanup(void)
 {
 {
 	xt_unregister_target(&ipt_dnat_reg);
 	xt_unregister_target(&ipt_dnat_reg);
 	xt_unregister_target(&ipt_snat_reg);
 	xt_unregister_target(&ipt_snat_reg);
-	ipt_unregister_table(nat_table);
+	unregister_pernet_subsys(&nf_nat_rule_net_ops);
 }
 }

+ 1 - 1
net/ipv6/netfilter.c

@@ -23,7 +23,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
 		    .saddr = iph->saddr, } },
 		    .saddr = iph->saddr, } },
 	};
 	};
 
 
-	dst = ip6_route_output(&init_net, skb->sk, &fl);
+	dst = ip6_route_output(dev_net(skb->dst->dev), skb->sk, &fl);
 
 
 #ifdef CONFIG_XFRM
 #ifdef CONFIG_XFRM
 	if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
 	if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&

+ 34 - 43
net/ipv6/netfilter/Kconfig

@@ -55,30 +55,29 @@ config IP6_NF_IPTABLES
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+if IP6_NF_IPTABLES
+
 # The simple matches.
 # The simple matches.
-config IP6_NF_MATCH_RT
-	tristate '"rt" Routing header match support'
-	depends on IP6_NF_IPTABLES
+config IP6_NF_MATCH_AH
+	tristate '"ah" match support'
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
-	  rt matching allows you to match packets based on the routing
-	  header of the packet.
+	  This module allows one to match AH packets.
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP6_NF_MATCH_OPTS
-	tristate '"hopbyhop" and "dst" opts header match support'
-	depends on IP6_NF_IPTABLES
+config IP6_NF_MATCH_EUI64
+	tristate '"eui64" address check'
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
-	  This allows one to match packets based on the hop-by-hop
-	  and destination options headers of a packet.
+	  This module performs checking on the IPv6 source address
+	  Compares the last 64 bits with the EUI64 (delivered
+	  from the MAC address) address
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
 config IP6_NF_MATCH_FRAG
 config IP6_NF_MATCH_FRAG
 	tristate '"frag" Fragmentation header match support'
 	tristate '"frag" Fragmentation header match support'
-	depends on IP6_NF_IPTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  frag matching allows you to match packets based on the fragmentation
 	  frag matching allows you to match packets based on the fragmentation
@@ -86,9 +85,17 @@ config IP6_NF_MATCH_FRAG
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+config IP6_NF_MATCH_OPTS
+	tristate '"hbh" hop-by-hop and "dst" opts header match support'
+	depends on NETFILTER_ADVANCED
+	help
+	  This allows one to match packets based on the hop-by-hop
+	  and destination options headers of a packet.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config IP6_NF_MATCH_HL
 config IP6_NF_MATCH_HL
 	tristate '"hl" match support'
 	tristate '"hl" match support'
-	depends on IP6_NF_IPTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  HL matching allows you to match packets based on the hop
 	  HL matching allows you to match packets based on the hop
@@ -98,7 +105,6 @@ config IP6_NF_MATCH_HL
 
 
 config IP6_NF_MATCH_IPV6HEADER
 config IP6_NF_MATCH_IPV6HEADER
 	tristate '"ipv6header" IPv6 Extension Headers Match'
 	tristate '"ipv6header" IPv6 Extension Headers Match'
-	depends on IP6_NF_IPTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  This module allows one to match packets based upon
 	  This module allows one to match packets based upon
@@ -106,54 +112,40 @@ config IP6_NF_MATCH_IPV6HEADER
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP6_NF_MATCH_AH
-	tristate '"ah" match support'
-	depends on IP6_NF_IPTABLES
-	depends on NETFILTER_ADVANCED
-	help
-	  This module allows one to match AH packets.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config IP6_NF_MATCH_MH
 config IP6_NF_MATCH_MH
 	tristate '"mh" match support'
 	tristate '"mh" match support'
-	depends on IP6_NF_IPTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This module allows one to match MH packets.
 	  This module allows one to match MH packets.
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP6_NF_MATCH_EUI64
-	tristate '"eui64" address check'
-	depends on IP6_NF_IPTABLES
+config IP6_NF_MATCH_RT
+	tristate '"rt" Routing header match support'
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
-	  This module performs checking on the IPv6 source address
-	  Compares the last 64 bits with the EUI64 (delivered
-	  from the MAC address) address
+	  rt matching allows you to match packets based on the routing
+	  header of the packet.
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
 # The targets
 # The targets
-config IP6_NF_FILTER
-	tristate "Packet filtering"
-	depends on IP6_NF_IPTABLES
+config IP6_NF_TARGET_LOG
+	tristate "LOG target support"
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
-	  Packet filtering defines a table `filter', which has a series of
-	  rules for simple packet filtering at local input, forwarding and
-	  local output.  See the man page for iptables(8).
+	  This option adds a `LOG' target, which allows you to create rules in
+	  any iptables table which records the packet header to the syslog.
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config IP6_NF_TARGET_LOG
-	tristate "LOG target support"
-	depends on IP6_NF_FILTER
+config IP6_NF_FILTER
+	tristate "Packet filtering"
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
-	  This option adds a `LOG' target, which allows you to create rules in
-	  any iptables table which records the packet header to the syslog.
+	  Packet filtering defines a table `filter', which has a series of
+	  rules for simple packet filtering at local input, forwarding and
+	  local output.  See the man page for iptables(8).
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
@@ -170,7 +162,6 @@ config IP6_NF_TARGET_REJECT
 
 
 config IP6_NF_MANGLE
 config IP6_NF_MANGLE
 	tristate "Packet mangling"
 	tristate "Packet mangling"
-	depends on IP6_NF_IPTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  This option adds a `mangle' table to iptables: see the man page for
 	  This option adds a `mangle' table to iptables: see the man page for
@@ -198,7 +189,6 @@ config IP6_NF_TARGET_HL
 
 
 config IP6_NF_RAW
 config IP6_NF_RAW
 	tristate  'raw table support (required for TRACE)'
 	tristate  'raw table support (required for TRACE)'
-	depends on IP6_NF_IPTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `raw' table to ip6tables. This table is the very
 	  This option adds a `raw' table to ip6tables. This table is the very
@@ -211,7 +201,6 @@ config IP6_NF_RAW
 # security table for MAC policy
 # security table for MAC policy
 config IP6_NF_SECURITY
 config IP6_NF_SECURITY
        tristate "Security table"
        tristate "Security table"
-       depends on IP6_NF_IPTABLES
        depends on SECURITY
        depends on SECURITY
        depends on NETFILTER_ADVANCED
        depends on NETFILTER_ADVANCED
        help
        help
@@ -220,5 +209,7 @@ config IP6_NF_SECURITY
         
         
          If unsure, say N.
          If unsure, say N.
 
 
+endif # IP6_NF_IPTABLES
+
 endmenu
 endmenu
 
 

+ 86 - 87
net/ipv6/netfilter/ip6_tables.c

@@ -200,32 +200,25 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6)
 }
 }
 
 
 static unsigned int
 static unsigned int
-ip6t_error(struct sk_buff *skb,
-	  const struct net_device *in,
-	  const struct net_device *out,
-	  unsigned int hooknum,
-	  const struct xt_target *target,
-	  const void *targinfo)
+ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	if (net_ratelimit())
 	if (net_ratelimit())
-		printk("ip6_tables: error: `%s'\n", (char *)targinfo);
+		printk("ip6_tables: error: `%s'\n",
+		       (const char *)par->targinfo);
 
 
 	return NF_DROP;
 	return NF_DROP;
 }
 }
 
 
 /* Performance critical - called for every packet */
 /* Performance critical - called for every packet */
 static inline bool
 static inline bool
-do_match(struct ip6t_entry_match *m,
-	      const struct sk_buff *skb,
-	      const struct net_device *in,
-	      const struct net_device *out,
-	      int offset,
-	      unsigned int protoff,
-	      bool *hotdrop)
+do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
+	 struct xt_match_param *par)
 {
 {
+	par->match     = m->u.kernel.match;
+	par->matchinfo = m->data;
+
 	/* Stop iteration if it doesn't match */
 	/* Stop iteration if it doesn't match */
-	if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
-				      offset, protoff, hotdrop))
+	if (!m->u.kernel.match->match(skb, par))
 		return true;
 		return true;
 	else
 	else
 		return false;
 		return false;
@@ -355,8 +348,6 @@ ip6t_do_table(struct sk_buff *skb,
 	      struct xt_table *table)
 	      struct xt_table *table)
 {
 {
 	static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
 	static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
-	int offset = 0;
-	unsigned int protoff = 0;
 	bool hotdrop = false;
 	bool hotdrop = false;
 	/* Initializing verdict to NF_DROP keeps gcc happy. */
 	/* Initializing verdict to NF_DROP keeps gcc happy. */
 	unsigned int verdict = NF_DROP;
 	unsigned int verdict = NF_DROP;
@@ -364,6 +355,8 @@ ip6t_do_table(struct sk_buff *skb,
 	void *table_base;
 	void *table_base;
 	struct ip6t_entry *e, *back;
 	struct ip6t_entry *e, *back;
 	struct xt_table_info *private;
 	struct xt_table_info *private;
+	struct xt_match_param mtpar;
+	struct xt_target_param tgpar;
 
 
 	/* Initialization */
 	/* Initialization */
 	indev = in ? in->name : nulldevname;
 	indev = in ? in->name : nulldevname;
@@ -374,6 +367,11 @@ ip6t_do_table(struct sk_buff *skb,
 	 * things we don't know, ie. tcp syn flag or ports).  If the
 	 * things we don't know, ie. tcp syn flag or ports).  If the
 	 * rule is also a fragment-specific rule, non-fragments won't
 	 * rule is also a fragment-specific rule, non-fragments won't
 	 * match it. */
 	 * match it. */
+	mtpar.hotdrop = &hotdrop;
+	mtpar.in      = tgpar.in  = in;
+	mtpar.out     = tgpar.out = out;
+	mtpar.family  = tgpar.family = NFPROTO_IPV6;
+	tgpar.hooknum = hook;
 
 
 	read_lock_bh(&table->lock);
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@@ -388,12 +386,10 @@ ip6t_do_table(struct sk_buff *skb,
 		IP_NF_ASSERT(e);
 		IP_NF_ASSERT(e);
 		IP_NF_ASSERT(back);
 		IP_NF_ASSERT(back);
 		if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
 		if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
-			&protoff, &offset, &hotdrop)) {
+			&mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
 			struct ip6t_entry_target *t;
 			struct ip6t_entry_target *t;
 
 
-			if (IP6T_MATCH_ITERATE(e, do_match,
-					       skb, in, out,
-					       offset, protoff, &hotdrop) != 0)
+			if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
 				goto no_match;
 				goto no_match;
 
 
 			ADD_COUNTER(e->counters,
 			ADD_COUNTER(e->counters,
@@ -441,15 +437,15 @@ ip6t_do_table(struct sk_buff *skb,
 			} else {
 			} else {
 				/* Targets which reenter must return
 				/* Targets which reenter must return
 				   abs. verdicts */
 				   abs. verdicts */
+				tgpar.target   = t->u.kernel.target;
+				tgpar.targinfo = t->data;
+
 #ifdef CONFIG_NETFILTER_DEBUG
 #ifdef CONFIG_NETFILTER_DEBUG
 				((struct ip6t_entry *)table_base)->comefrom
 				((struct ip6t_entry *)table_base)->comefrom
 					= 0xeeeeeeec;
 					= 0xeeeeeeec;
 #endif
 #endif
 				verdict = t->u.kernel.target->target(skb,
 				verdict = t->u.kernel.target->target(skb,
-								     in, out,
-								     hook,
-								     t->u.kernel.target,
-								     t->data);
+								     &tgpar);
 
 
 #ifdef CONFIG_NETFILTER_DEBUG
 #ifdef CONFIG_NETFILTER_DEBUG
 				if (((struct ip6t_entry *)table_base)->comefrom
 				if (((struct ip6t_entry *)table_base)->comefrom
@@ -602,12 +598,17 @@ mark_source_chains(struct xt_table_info *newinfo,
 static int
 static int
 cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
 cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
 {
 {
+	struct xt_mtdtor_param par;
+
 	if (i && (*i)-- == 0)
 	if (i && (*i)-- == 0)
 		return 1;
 		return 1;
 
 
-	if (m->u.kernel.match->destroy)
-		m->u.kernel.match->destroy(m->u.kernel.match, m->data);
-	module_put(m->u.kernel.match->me);
+	par.match     = m->u.kernel.match;
+	par.matchinfo = m->data;
+	par.family    = NFPROTO_IPV6;
+	if (par.match->destroy != NULL)
+		par.match->destroy(&par);
+	module_put(par.match->me);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -632,34 +633,28 @@ check_entry(struct ip6t_entry *e, const char *name)
 	return 0;
 	return 0;
 }
 }
 
 
-static int check_match(struct ip6t_entry_match *m, const char *name,
-			      const struct ip6t_ip6 *ipv6,
-			      unsigned int hookmask, unsigned int *i)
+static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
+		       unsigned int *i)
 {
 {
-	struct xt_match *match;
+	const struct ip6t_ip6 *ipv6 = par->entryinfo;
 	int ret;
 	int ret;
 
 
-	match = m->u.kernel.match;
-	ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m),
-			     name, hookmask, ipv6->proto,
-			     ipv6->invflags & IP6T_INV_PROTO);
-	if (!ret && m->u.kernel.match->checkentry
-	    && !m->u.kernel.match->checkentry(name, ipv6, match, m->data,
-					      hookmask)) {
+	par->match     = m->u.kernel.match;
+	par->matchinfo = m->data;
+
+	ret = xt_check_match(par, m->u.match_size - sizeof(*m),
+			     ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
+	if (ret < 0) {
 		duprintf("ip_tables: check failed for `%s'.\n",
 		duprintf("ip_tables: check failed for `%s'.\n",
-			 m->u.kernel.match->name);
-		ret = -EINVAL;
+			 par.match->name);
+		return ret;
 	}
 	}
-	if (!ret)
-		(*i)++;
-	return ret;
+	++*i;
+	return 0;
 }
 }
 
 
 static int
 static int
-find_check_match(struct ip6t_entry_match *m,
-		 const char *name,
-		 const struct ip6t_ip6 *ipv6,
-		 unsigned int hookmask,
+find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
 		 unsigned int *i)
 		 unsigned int *i)
 {
 {
 	struct xt_match *match;
 	struct xt_match *match;
@@ -674,7 +669,7 @@ find_check_match(struct ip6t_entry_match *m,
 	}
 	}
 	m->u.kernel.match = match;
 	m->u.kernel.match = match;
 
 
-	ret = check_match(m, name, ipv6, hookmask, i);
+	ret = check_match(m, par, i);
 	if (ret)
 	if (ret)
 		goto err;
 		goto err;
 
 
@@ -686,23 +681,26 @@ err:
 
 
 static int check_target(struct ip6t_entry *e, const char *name)
 static int check_target(struct ip6t_entry *e, const char *name)
 {
 {
-	struct ip6t_entry_target *t;
-	struct xt_target *target;
+	struct ip6t_entry_target *t = ip6t_get_target(e);
+	struct xt_tgchk_param par = {
+		.table     = name,
+		.entryinfo = e,
+		.target    = t->u.kernel.target,
+		.targinfo  = t->data,
+		.hook_mask = e->comefrom,
+		.family    = NFPROTO_IPV6,
+	};
 	int ret;
 	int ret;
 
 
 	t = ip6t_get_target(e);
 	t = ip6t_get_target(e);
-	target = t->u.kernel.target;
-	ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
-			      name, e->comefrom, e->ipv6.proto,
-			      e->ipv6.invflags & IP6T_INV_PROTO);
-	if (!ret && t->u.kernel.target->checkentry
-	    && !t->u.kernel.target->checkentry(name, e, target, t->data,
-					       e->comefrom)) {
+	ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
+	      e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
+	if (ret < 0) {
 		duprintf("ip_tables: check failed for `%s'.\n",
 		duprintf("ip_tables: check failed for `%s'.\n",
 			 t->u.kernel.target->name);
 			 t->u.kernel.target->name);
-		ret = -EINVAL;
+		return ret;
 	}
 	}
-	return ret;
+	return 0;
 }
 }
 
 
 static int
 static int
@@ -713,14 +711,18 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
 	struct xt_target *target;
 	struct xt_target *target;
 	int ret;
 	int ret;
 	unsigned int j;
 	unsigned int j;
+	struct xt_mtchk_param mtpar;
 
 
 	ret = check_entry(e, name);
 	ret = check_entry(e, name);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
 	j = 0;
 	j = 0;
-	ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6,
-				 e->comefrom, &j);
+	mtpar.table     = name;
+	mtpar.entryinfo = &e->ipv6;
+	mtpar.hook_mask = e->comefrom;
+	mtpar.family    = NFPROTO_IPV6;
+	ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
 	if (ret != 0)
 	if (ret != 0)
 		goto cleanup_matches;
 		goto cleanup_matches;
 
 
@@ -795,6 +797,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 static int
 static int
 cleanup_entry(struct ip6t_entry *e, unsigned int *i)
 cleanup_entry(struct ip6t_entry *e, unsigned int *i)
 {
 {
+	struct xt_tgdtor_param par;
 	struct ip6t_entry_target *t;
 	struct ip6t_entry_target *t;
 
 
 	if (i && (*i)-- == 0)
 	if (i && (*i)-- == 0)
@@ -803,9 +806,13 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
 	/* Cleanup all matches */
 	/* Cleanup all matches */
 	IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
 	IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
 	t = ip6t_get_target(e);
 	t = ip6t_get_target(e);
-	if (t->u.kernel.target->destroy)
-		t->u.kernel.target->destroy(t->u.kernel.target, t->data);
-	module_put(t->u.kernel.target->me);
+
+	par.target   = t->u.kernel.target;
+	par.targinfo = t->data;
+	par.family   = NFPROTO_IPV6;
+	if (par.target->destroy != NULL)
+		par.target->destroy(&par);
+	module_put(par.target->me);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1677,10 +1684,14 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
 {
 {
 	unsigned int j;
 	unsigned int j;
 	int ret;
 	int ret;
+	struct xt_mtchk_param mtpar;
 
 
 	j = 0;
 	j = 0;
-	ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6,
-				 e->comefrom, &j);
+	mtpar.table     = name;
+	mtpar.entryinfo = &e->ipv6;
+	mtpar.hook_mask = e->comefrom;
+	mtpar.family    = NFPROTO_IPV6;
+	ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
 	if (ret)
 	if (ret)
 		goto cleanup_matches;
 		goto cleanup_matches;
 
 
@@ -2146,30 +2157,23 @@ icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
 }
 }
 
 
 static bool
 static bool
-icmp6_match(const struct sk_buff *skb,
-	   const struct net_device *in,
-	   const struct net_device *out,
-	   const struct xt_match *match,
-	   const void *matchinfo,
-	   int offset,
-	   unsigned int protoff,
-	   bool *hotdrop)
+icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	const struct icmp6hdr *ic;
 	const struct icmp6hdr *ic;
 	struct icmp6hdr _icmph;
 	struct icmp6hdr _icmph;
-	const struct ip6t_icmp *icmpinfo = matchinfo;
+	const struct ip6t_icmp *icmpinfo = par->matchinfo;
 
 
 	/* Must not be a fragment. */
 	/* Must not be a fragment. */
-	if (offset)
+	if (par->fragoff != 0)
 		return false;
 		return false;
 
 
-	ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph);
+	ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
 	if (ic == NULL) {
 	if (ic == NULL) {
 		/* We've been asked to examine this packet, and we
 		/* We've been asked to examine this packet, and we
 		 * can't.  Hence, no choice but to drop.
 		 * can't.  Hence, no choice but to drop.
 		 */
 		 */
 		duprintf("Dropping evil ICMP tinygram.\n");
 		duprintf("Dropping evil ICMP tinygram.\n");
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -2181,14 +2185,9 @@ icmp6_match(const struct sk_buff *skb,
 }
 }
 
 
 /* Called when user tries to insert an entry of this type. */
 /* Called when user tries to insert an entry of this type. */
-static bool
-icmp6_checkentry(const char *tablename,
-	   const void *entry,
-	   const struct xt_match *match,
-	   void *matchinfo,
-	   unsigned int hook_mask)
+static bool icmp6_checkentry(const struct xt_mtchk_param *par)
 {
 {
-	const struct ip6t_icmp *icmpinfo = matchinfo;
+	const struct ip6t_icmp *icmpinfo = par->matchinfo;
 
 
 	/* Must specify no unknown invflags */
 	/* Must specify no unknown invflags */
 	return !(icmpinfo->invflags & ~IP6T_ICMP_INV);
 	return !(icmpinfo->invflags & ~IP6T_ICMP_INV);

+ 5 - 10
net/ipv6/netfilter/ip6t_HL.c

@@ -19,12 +19,10 @@ MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
 static unsigned int
 static unsigned int
-hl_tg6(struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, unsigned int hooknum,
-       const struct xt_target *target, const void *targinfo)
+hl_tg6(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
 	struct ipv6hdr *ip6h;
 	struct ipv6hdr *ip6h;
-	const struct ip6t_HL_info *info = targinfo;
+	const struct ip6t_HL_info *info = par->targinfo;
 	int new_hl;
 	int new_hl;
 
 
 	if (!skb_make_writable(skb, skb->len))
 	if (!skb_make_writable(skb, skb->len))
@@ -56,12 +54,9 @@ hl_tg6(struct sk_buff *skb, const struct net_device *in,
 	return XT_CONTINUE;
 	return XT_CONTINUE;
 }
 }
 
 
-static bool
-hl_tg6_check(const char *tablename, const void *entry,
-             const struct xt_target *target, void *targinfo,
-             unsigned int hook_mask)
+static bool hl_tg6_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ip6t_HL_info *info = targinfo;
+	const struct ip6t_HL_info *info = par->targinfo;
 
 
 	if (info->mode > IP6T_HL_MAXMODE) {
 	if (info->mode > IP6T_HL_MAXMODE) {
 		printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
 		printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
@@ -78,7 +73,7 @@ hl_tg6_check(const char *tablename, const void *entry,
 
 
 static struct xt_target hl_tg6_reg __read_mostly = {
 static struct xt_target hl_tg6_reg __read_mostly = {
 	.name 		= "HL",
 	.name 		= "HL",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.target		= hl_tg6,
 	.target		= hl_tg6,
 	.targetsize	= sizeof(struct ip6t_HL_info),
 	.targetsize	= sizeof(struct ip6t_HL_info),
 	.table		= "mangle",
 	.table		= "mangle",

+ 9 - 13
net/ipv6/netfilter/ip6t_LOG.c

@@ -385,7 +385,7 @@ static struct nf_loginfo default_loginfo = {
 };
 };
 
 
 static void
 static void
-ip6t_log_packet(unsigned int pf,
+ip6t_log_packet(u_int8_t pf,
 		unsigned int hooknum,
 		unsigned int hooknum,
 		const struct sk_buff *skb,
 		const struct sk_buff *skb,
 		const struct net_device *in,
 		const struct net_device *in,
@@ -438,28 +438,24 @@ ip6t_log_packet(unsigned int pf,
 }
 }
 
 
 static unsigned int
 static unsigned int
-log_tg6(struct sk_buff *skb, const struct net_device *in,
-        const struct net_device *out, unsigned int hooknum,
-        const struct xt_target *target, const void *targinfo)
+log_tg6(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ip6t_log_info *loginfo = targinfo;
+	const struct ip6t_log_info *loginfo = par->targinfo;
 	struct nf_loginfo li;
 	struct nf_loginfo li;
 
 
 	li.type = NF_LOG_TYPE_LOG;
 	li.type = NF_LOG_TYPE_LOG;
 	li.u.log.level = loginfo->level;
 	li.u.log.level = loginfo->level;
 	li.u.log.logflags = loginfo->logflags;
 	li.u.log.logflags = loginfo->logflags;
 
 
-	ip6t_log_packet(PF_INET6, hooknum, skb, in, out, &li, loginfo->prefix);
+	ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, par->out,
+			&li, loginfo->prefix);
 	return XT_CONTINUE;
 	return XT_CONTINUE;
 }
 }
 
 
 
 
-static bool
-log_tg6_check(const char *tablename, const void *entry,
-              const struct xt_target *target, void *targinfo,
-              unsigned int hook_mask)
+static bool log_tg6_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ip6t_log_info *loginfo = targinfo;
+	const struct ip6t_log_info *loginfo = par->targinfo;
 
 
 	if (loginfo->level >= 8) {
 	if (loginfo->level >= 8) {
 		pr_debug("LOG: level %u >= 8\n", loginfo->level);
 		pr_debug("LOG: level %u >= 8\n", loginfo->level);
@@ -475,7 +471,7 @@ log_tg6_check(const char *tablename, const void *entry,
 
 
 static struct xt_target log_tg6_reg __read_mostly = {
 static struct xt_target log_tg6_reg __read_mostly = {
 	.name 		= "LOG",
 	.name 		= "LOG",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.target 	= log_tg6,
 	.target 	= log_tg6,
 	.targetsize	= sizeof(struct ip6t_log_info),
 	.targetsize	= sizeof(struct ip6t_log_info),
 	.checkentry	= log_tg6_check,
 	.checkentry	= log_tg6_check,
@@ -495,7 +491,7 @@ static int __init log_tg6_init(void)
 	ret = xt_register_target(&log_tg6_reg);
 	ret = xt_register_target(&log_tg6_reg);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
-	nf_log_register(PF_INET6, &ip6t_logger);
+	nf_log_register(NFPROTO_IPV6, &ip6t_logger);
 	return 0;
 	return 0;
 }
 }
 
 

+ 18 - 21
net/ipv6/netfilter/ip6t_REJECT.c

@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
 /* Send RST reply */
 /* Send RST reply */
-static void send_reset(struct sk_buff *oldskb)
+static void send_reset(struct net *net, struct sk_buff *oldskb)
 {
 {
 	struct sk_buff *nskb;
 	struct sk_buff *nskb;
 	struct tcphdr otcph, *tcph;
 	struct tcphdr otcph, *tcph;
@@ -94,7 +94,7 @@ static void send_reset(struct sk_buff *oldskb)
 	fl.fl_ip_sport = otcph.dest;
 	fl.fl_ip_sport = otcph.dest;
 	fl.fl_ip_dport = otcph.source;
 	fl.fl_ip_dport = otcph.source;
 	security_skb_classify_flow(oldskb, &fl);
 	security_skb_classify_flow(oldskb, &fl);
-	dst = ip6_route_output(&init_net, NULL, &fl);
+	dst = ip6_route_output(net, NULL, &fl);
 	if (dst == NULL)
 	if (dst == NULL)
 		return;
 		return;
 	if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
 	if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
@@ -163,20 +163,20 @@ static void send_reset(struct sk_buff *oldskb)
 }
 }
 
 
 static inline void
 static inline void
-send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum)
+send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code,
+	     unsigned int hooknum)
 {
 {
 	if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
 	if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
-		skb_in->dev = init_net.loopback_dev;
+		skb_in->dev = net->loopback_dev;
 
 
 	icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
 	icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
 }
 }
 
 
 static unsigned int
 static unsigned int
-reject_tg6(struct sk_buff *skb, const struct net_device *in,
-           const struct net_device *out, unsigned int hooknum,
-           const struct xt_target *target, const void *targinfo)
+reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
 {
 {
-	const struct ip6t_reject_info *reject = targinfo;
+	const struct ip6t_reject_info *reject = par->targinfo;
+	struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
 
 
 	pr_debug("%s: medium point\n", __func__);
 	pr_debug("%s: medium point\n", __func__);
 	/* WARNING: This code causes reentry within ip6tables.
 	/* WARNING: This code causes reentry within ip6tables.
@@ -184,25 +184,25 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
 	   must return an absolute verdict. --RR */
 	   must return an absolute verdict. --RR */
 	switch (reject->with) {
 	switch (reject->with) {
 	case IP6T_ICMP6_NO_ROUTE:
 	case IP6T_ICMP6_NO_ROUTE:
-		send_unreach(skb, ICMPV6_NOROUTE, hooknum);
+		send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum);
 		break;
 		break;
 	case IP6T_ICMP6_ADM_PROHIBITED:
 	case IP6T_ICMP6_ADM_PROHIBITED:
-		send_unreach(skb, ICMPV6_ADM_PROHIBITED, hooknum);
+		send_unreach(net, skb, ICMPV6_ADM_PROHIBITED, par->hooknum);
 		break;
 		break;
 	case IP6T_ICMP6_NOT_NEIGHBOUR:
 	case IP6T_ICMP6_NOT_NEIGHBOUR:
-		send_unreach(skb, ICMPV6_NOT_NEIGHBOUR, hooknum);
+		send_unreach(net, skb, ICMPV6_NOT_NEIGHBOUR, par->hooknum);
 		break;
 		break;
 	case IP6T_ICMP6_ADDR_UNREACH:
 	case IP6T_ICMP6_ADDR_UNREACH:
-		send_unreach(skb, ICMPV6_ADDR_UNREACH, hooknum);
+		send_unreach(net, skb, ICMPV6_ADDR_UNREACH, par->hooknum);
 		break;
 		break;
 	case IP6T_ICMP6_PORT_UNREACH:
 	case IP6T_ICMP6_PORT_UNREACH:
-		send_unreach(skb, ICMPV6_PORT_UNREACH, hooknum);
+		send_unreach(net, skb, ICMPV6_PORT_UNREACH, par->hooknum);
 		break;
 		break;
 	case IP6T_ICMP6_ECHOREPLY:
 	case IP6T_ICMP6_ECHOREPLY:
 		/* Do nothing */
 		/* Do nothing */
 		break;
 		break;
 	case IP6T_TCP_RESET:
 	case IP6T_TCP_RESET:
-		send_reset(skb);
+		send_reset(net, skb);
 		break;
 		break;
 	default:
 	default:
 		if (net_ratelimit())
 		if (net_ratelimit())
@@ -213,13 +213,10 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
 	return NF_DROP;
 	return NF_DROP;
 }
 }
 
 
-static bool
-reject_tg6_check(const char *tablename, const void *entry,
-                 const struct xt_target *target, void *targinfo,
-                 unsigned int hook_mask)
+static bool reject_tg6_check(const struct xt_tgchk_param *par)
 {
 {
-	const struct ip6t_reject_info *rejinfo = targinfo;
-	const struct ip6t_entry *e = entry;
+	const struct ip6t_reject_info *rejinfo = par->targinfo;
+	const struct ip6t_entry *e = par->entryinfo;
 
 
 	if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
 	if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
 		printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
 		printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
@@ -237,7 +234,7 @@ reject_tg6_check(const char *tablename, const void *entry,
 
 
 static struct xt_target reject_tg6_reg __read_mostly = {
 static struct xt_target reject_tg6_reg __read_mostly = {
 	.name		= "REJECT",
 	.name		= "REJECT",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.target		= reject_tg6,
 	.target		= reject_tg6,
 	.targetsize	= sizeof(struct ip6t_reject_info),
 	.targetsize	= sizeof(struct ip6t_reject_info),
 	.table		= "filter",
 	.table		= "filter",

+ 7 - 14
net/ipv6/netfilter/ip6t_ah.c

@@ -36,14 +36,11 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 	return r;
 	return r;
 }
 }
 
 
-static bool
-ah_mt6(const struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, const struct xt_match *match,
-       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
+static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	struct ip_auth_hdr _ah;
 	struct ip_auth_hdr _ah;
 	const struct ip_auth_hdr *ah;
 	const struct ip_auth_hdr *ah;
-	const struct ip6t_ah *ahinfo = matchinfo;
+	const struct ip6t_ah *ahinfo = par->matchinfo;
 	unsigned int ptr;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
 	unsigned int hdrlen = 0;
 	int err;
 	int err;
@@ -51,13 +48,13 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
 	if (err < 0) {
 	if (err < 0) {
 		if (err != -ENOENT)
 		if (err != -ENOENT)
-			*hotdrop = true;
+			*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
 	ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
 	ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
 	if (ah == NULL) {
 	if (ah == NULL) {
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -93,13 +90,9 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
 	       !(ahinfo->hdrres && ah->reserved);
 	       !(ahinfo->hdrres && ah->reserved);
 }
 }
 
 
-/* Called when user tries to insert an entry of this type. */
-static bool
-ah_mt6_check(const char *tablename, const void *entry,
-             const struct xt_match *match, void *matchinfo,
-             unsigned int hook_mask)
+static bool ah_mt6_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ip6t_ah *ahinfo = matchinfo;
+	const struct ip6t_ah *ahinfo = par->matchinfo;
 
 
 	if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
 	if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
 		pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
 		pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
@@ -110,7 +103,7 @@ ah_mt6_check(const char *tablename, const void *entry,
 
 
 static struct xt_match ah_mt6_reg __read_mostly = {
 static struct xt_match ah_mt6_reg __read_mostly = {
 	.name		= "ah",
 	.name		= "ah",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.match		= ah_mt6,
 	.match		= ah_mt6,
 	.matchsize	= sizeof(struct ip6t_ah),
 	.matchsize	= sizeof(struct ip6t_ah),
 	.checkentry	= ah_mt6_check,
 	.checkentry	= ah_mt6_check,

+ 4 - 7
net/ipv6/netfilter/ip6t_eui64.c

@@ -20,18 +20,15 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
 
 static bool
 static bool
-eui64_mt6(const struct sk_buff *skb, const struct net_device *in,
-          const struct net_device *out, const struct xt_match *match,
-          const void *matchinfo, int offset, unsigned int protoff,
-          bool *hotdrop)
+eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	unsigned char eui64[8];
 	unsigned char eui64[8];
 	int i = 0;
 	int i = 0;
 
 
 	if (!(skb_mac_header(skb) >= skb->head &&
 	if (!(skb_mac_header(skb) >= skb->head &&
 	      skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
 	      skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
-	    offset != 0) {
-		*hotdrop = true;
+	    par->fragoff != 0) {
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -60,7 +57,7 @@ eui64_mt6(const struct sk_buff *skb, const struct net_device *in,
 
 
 static struct xt_match eui64_mt6_reg __read_mostly = {
 static struct xt_match eui64_mt6_reg __read_mostly = {
 	.name		= "eui64",
 	.name		= "eui64",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.match		= eui64_mt6,
 	.match		= eui64_mt6,
 	.matchsize	= sizeof(int),
 	.matchsize	= sizeof(int),
 	.hooks		= (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
 	.hooks		= (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |

+ 7 - 14
net/ipv6/netfilter/ip6t_frag.c

@@ -35,27 +35,24 @@ id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 }
 }
 
 
 static bool
 static bool
-frag_mt6(const struct sk_buff *skb, const struct net_device *in,
-         const struct net_device *out, const struct xt_match *match,
-         const void *matchinfo, int offset, unsigned int protoff,
-         bool *hotdrop)
+frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	struct frag_hdr _frag;
 	struct frag_hdr _frag;
 	const struct frag_hdr *fh;
 	const struct frag_hdr *fh;
-	const struct ip6t_frag *fraginfo = matchinfo;
+	const struct ip6t_frag *fraginfo = par->matchinfo;
 	unsigned int ptr;
 	unsigned int ptr;
 	int err;
 	int err;
 
 
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
 	if (err < 0) {
 	if (err < 0) {
 		if (err != -ENOENT)
 		if (err != -ENOENT)
-			*hotdrop = true;
+			*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
 	fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
 	fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
 	if (fh == NULL) {
 	if (fh == NULL) {
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -110,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct net_device *in,
 		 && (ntohs(fh->frag_off) & IP6_MF));
 		 && (ntohs(fh->frag_off) & IP6_MF));
 }
 }
 
 
-/* Called when user tries to insert an entry of this type. */
-static bool
-frag_mt6_check(const char *tablename, const void *ip,
-               const struct xt_match *match, void *matchinfo,
-               unsigned int hook_mask)
+static bool frag_mt6_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ip6t_frag *fraginfo = matchinfo;
+	const struct ip6t_frag *fraginfo = par->matchinfo;
 
 
 	if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
 	if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
 		pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
 		pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
@@ -127,7 +120,7 @@ frag_mt6_check(const char *tablename, const void *ip,
 
 
 static struct xt_match frag_mt6_reg __read_mostly = {
 static struct xt_match frag_mt6_reg __read_mostly = {
 	.name		= "frag",
 	.name		= "frag",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.match		= frag_mt6,
 	.match		= frag_mt6,
 	.matchsize	= sizeof(struct ip6t_frag),
 	.matchsize	= sizeof(struct ip6t_frag),
 	.checkentry	= frag_mt6_check,
 	.checkentry	= frag_mt6_check,

+ 9 - 16
net/ipv6/netfilter/ip6t_hbh.c

@@ -42,14 +42,11 @@ MODULE_ALIAS("ip6t_dst");
  */
  */
 
 
 static bool
 static bool
-hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
-        const struct net_device *out, const struct xt_match *match,
-        const void *matchinfo, int offset, unsigned int protoff,
-        bool *hotdrop)
+hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	struct ipv6_opt_hdr _optsh;
 	struct ipv6_opt_hdr _optsh;
 	const struct ipv6_opt_hdr *oh;
 	const struct ipv6_opt_hdr *oh;
-	const struct ip6t_opts *optinfo = matchinfo;
+	const struct ip6t_opts *optinfo = par->matchinfo;
 	unsigned int temp;
 	unsigned int temp;
 	unsigned int ptr;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
 	unsigned int hdrlen = 0;
@@ -61,16 +58,16 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
 	unsigned int optlen;
 	unsigned int optlen;
 	int err;
 	int err;
 
 
-	err = ipv6_find_hdr(skb, &ptr, match->data, NULL);
+	err = ipv6_find_hdr(skb, &ptr, par->match->data, NULL);
 	if (err < 0) {
 	if (err < 0) {
 		if (err != -ENOENT)
 		if (err != -ENOENT)
-			*hotdrop = true;
+			*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
 	oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
 	oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
 	if (oh == NULL) {
 	if (oh == NULL) {
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -163,13 +160,9 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
 	return false;
 	return false;
 }
 }
 
 
-/* Called when user tries to insert an entry of this type. */
-static bool
-hbh_mt6_check(const char *tablename, const void *entry,
-              const struct xt_match *match, void *matchinfo,
-              unsigned int hook_mask)
+static bool hbh_mt6_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ip6t_opts *optsinfo = matchinfo;
+	const struct ip6t_opts *optsinfo = par->matchinfo;
 
 
 	if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
 	if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
 		pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
 		pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
@@ -187,7 +180,7 @@ hbh_mt6_check(const char *tablename, const void *entry,
 static struct xt_match hbh_mt6_reg[] __read_mostly = {
 static struct xt_match hbh_mt6_reg[] __read_mostly = {
 	{
 	{
 		.name		= "hbh",
 		.name		= "hbh",
-		.family		= AF_INET6,
+		.family		= NFPROTO_IPV6,
 		.match		= hbh_mt6,
 		.match		= hbh_mt6,
 		.matchsize	= sizeof(struct ip6t_opts),
 		.matchsize	= sizeof(struct ip6t_opts),
 		.checkentry	= hbh_mt6_check,
 		.checkentry	= hbh_mt6_check,
@@ -196,7 +189,7 @@ static struct xt_match hbh_mt6_reg[] __read_mostly = {
 	},
 	},
 	{
 	{
 		.name		= "dst",
 		.name		= "dst",
-		.family		= AF_INET6,
+		.family		= NFPROTO_IPV6,
 		.match		= hbh_mt6,
 		.match		= hbh_mt6,
 		.matchsize	= sizeof(struct ip6t_opts),
 		.matchsize	= sizeof(struct ip6t_opts),
 		.checkentry	= hbh_mt6_check,
 		.checkentry	= hbh_mt6_check,

+ 3 - 6
net/ipv6/netfilter/ip6t_hl.c

@@ -19,12 +19,9 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
 MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match");
 MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
-static bool
-hl_mt6(const struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, const struct xt_match *match,
-       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
+static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ip6t_hl_info *info = matchinfo;
+	const struct ip6t_hl_info *info = par->matchinfo;
 	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
 	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
 
 
 	switch (info->mode) {
 	switch (info->mode) {
@@ -51,7 +48,7 @@ hl_mt6(const struct sk_buff *skb, const struct net_device *in,
 
 
 static struct xt_match hl_mt6_reg __read_mostly = {
 static struct xt_match hl_mt6_reg __read_mostly = {
 	.name		= "hl",
 	.name		= "hl",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.match		= hl_mt6,
 	.match		= hl_mt6,
 	.matchsize	= sizeof(struct ip6t_hl_info),
 	.matchsize	= sizeof(struct ip6t_hl_info),
 	.me		= THIS_MODULE,
 	.me		= THIS_MODULE,

+ 5 - 11
net/ipv6/netfilter/ip6t_ipv6header.c

@@ -27,12 +27,9 @@ MODULE_DESCRIPTION("Xtables: IPv6 header types match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
 
 static bool
 static bool
-ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
-               const struct net_device *out, const struct xt_match *match,
-               const void *matchinfo, int offset, unsigned int protoff,
-               bool *hotdrop)
+ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
-	const struct ip6t_ipv6header_info *info = matchinfo;
+	const struct ip6t_ipv6header_info *info = par->matchinfo;
 	unsigned int temp;
 	unsigned int temp;
 	int len;
 	int len;
 	u8 nexthdr;
 	u8 nexthdr;
@@ -121,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
 	}
 	}
 }
 }
 
 
-static bool
-ipv6header_mt6_check(const char *tablename, const void *ip,
-                     const struct xt_match *match, void *matchinfo,
-                     unsigned int hook_mask)
+static bool ipv6header_mt6_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ip6t_ipv6header_info *info = matchinfo;
+	const struct ip6t_ipv6header_info *info = par->matchinfo;
 
 
 	/* invflags is 0 or 0xff in hard mode */
 	/* invflags is 0 or 0xff in hard mode */
 	if ((!info->modeflag) && info->invflags != 0x00 &&
 	if ((!info->modeflag) && info->invflags != 0x00 &&
@@ -138,7 +132,7 @@ ipv6header_mt6_check(const char *tablename, const void *ip,
 
 
 static struct xt_match ipv6header_mt6_reg __read_mostly = {
 static struct xt_match ipv6header_mt6_reg __read_mostly = {
 	.name		= "ipv6header",
 	.name		= "ipv6header",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.match		= ipv6header_mt6,
 	.match		= ipv6header_mt6,
 	.matchsize	= sizeof(struct ip6t_ipv6header_info),
 	.matchsize	= sizeof(struct ip6t_ipv6header_info),
 	.checkentry	= ipv6header_mt6_check,
 	.checkentry	= ipv6header_mt6_check,

+ 9 - 16
net/ipv6/netfilter/ip6t_mh.c

@@ -37,32 +37,29 @@ type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
 	return (type >= min && type <= max) ^ invert;
 	return (type >= min && type <= max) ^ invert;
 }
 }
 
 
-static bool
-mh_mt6(const struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, const struct xt_match *match,
-       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
+static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	struct ip6_mh _mh;
 	struct ip6_mh _mh;
 	const struct ip6_mh *mh;
 	const struct ip6_mh *mh;
-	const struct ip6t_mh *mhinfo = matchinfo;
+	const struct ip6t_mh *mhinfo = par->matchinfo;
 
 
 	/* Must not be a fragment. */
 	/* Must not be a fragment. */
-	if (offset)
+	if (par->fragoff != 0)
 		return false;
 		return false;
 
 
-	mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh);
+	mh = skb_header_pointer(skb, par->thoff, sizeof(_mh), &_mh);
 	if (mh == NULL) {
 	if (mh == NULL) {
 		/* We've been asked to examine this packet, and we
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil MH tinygram.\n");
 		duprintf("Dropping evil MH tinygram.\n");
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
 	if (mh->ip6mh_proto != IPPROTO_NONE) {
 	if (mh->ip6mh_proto != IPPROTO_NONE) {
 		duprintf("Dropping invalid MH Payload Proto: %u\n",
 		duprintf("Dropping invalid MH Payload Proto: %u\n",
 			 mh->ip6mh_proto);
 			 mh->ip6mh_proto);
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -70,13 +67,9 @@ mh_mt6(const struct sk_buff *skb, const struct net_device *in,
 			  !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
 			  !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
 }
 }
 
 
-/* Called when user tries to insert an entry of this type. */
-static bool
-mh_mt6_check(const char *tablename, const void *entry,
-             const struct xt_match *match, void *matchinfo,
-             unsigned int hook_mask)
+static bool mh_mt6_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ip6t_mh *mhinfo = matchinfo;
+	const struct ip6t_mh *mhinfo = par->matchinfo;
 
 
 	/* Must specify no unknown invflags */
 	/* Must specify no unknown invflags */
 	return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
 	return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
@@ -84,7 +77,7 @@ mh_mt6_check(const char *tablename, const void *entry,
 
 
 static struct xt_match mh_mt6_reg __read_mostly = {
 static struct xt_match mh_mt6_reg __read_mostly = {
 	.name		= "mh",
 	.name		= "mh",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.checkentry	= mh_mt6_check,
 	.checkentry	= mh_mt6_check,
 	.match		= mh_mt6,
 	.match		= mh_mt6,
 	.matchsize	= sizeof(struct ip6t_mh),
 	.matchsize	= sizeof(struct ip6t_mh),

+ 7 - 14
net/ipv6/netfilter/ip6t_rt.c

@@ -36,14 +36,11 @@ segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 	return r;
 	return r;
 }
 }
 
 
-static bool
-rt_mt6(const struct sk_buff *skb, const struct net_device *in,
-       const struct net_device *out, const struct xt_match *match,
-       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
+static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 {
 	struct ipv6_rt_hdr _route;
 	struct ipv6_rt_hdr _route;
 	const struct ipv6_rt_hdr *rh;
 	const struct ipv6_rt_hdr *rh;
-	const struct ip6t_rt *rtinfo = matchinfo;
+	const struct ip6t_rt *rtinfo = par->matchinfo;
 	unsigned int temp;
 	unsigned int temp;
 	unsigned int ptr;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
 	unsigned int hdrlen = 0;
@@ -55,13 +52,13 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
 	if (err < 0) {
 	if (err < 0) {
 		if (err != -ENOENT)
 		if (err != -ENOENT)
-			*hotdrop = true;
+			*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
 	rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
 	rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
 	if (rh == NULL) {
 	if (rh == NULL) {
-		*hotdrop = true;
+		*par->hotdrop = true;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -189,13 +186,9 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
 	return false;
 	return false;
 }
 }
 
 
-/* Called when user tries to insert an entry of this type. */
-static bool
-rt_mt6_check(const char *tablename, const void *entry,
-             const struct xt_match *match, void *matchinfo,
-             unsigned int hook_mask)
+static bool rt_mt6_check(const struct xt_mtchk_param *par)
 {
 {
-	const struct ip6t_rt *rtinfo = matchinfo;
+	const struct ip6t_rt *rtinfo = par->matchinfo;
 
 
 	if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
 	if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
 		pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
 		pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
@@ -214,7 +207,7 @@ rt_mt6_check(const char *tablename, const void *entry,
 
 
 static struct xt_match rt_mt6_reg __read_mostly = {
 static struct xt_match rt_mt6_reg __read_mostly = {
 	.name		= "rt",
 	.name		= "rt",
-	.family		= AF_INET6,
+	.family		= NFPROTO_IPV6,
 	.match		= rt_mt6,
 	.match		= rt_mt6,
 	.matchsize	= sizeof(struct ip6t_rt),
 	.matchsize	= sizeof(struct ip6t_rt),
 	.checkentry	= rt_mt6_check,
 	.checkentry	= rt_mt6_check,

+ 3 - 3
net/ipv6/netfilter/ip6table_filter.c

@@ -68,7 +68,7 @@ ip6t_local_in_hook(unsigned int hook,
 		   int (*okfn)(struct sk_buff *))
 		   int (*okfn)(struct sk_buff *))
 {
 {
 	return ip6t_do_table(skb, hook, in, out,
 	return ip6t_do_table(skb, hook, in, out,
-			     nf_local_in_net(in, out)->ipv6.ip6table_filter);
+			     dev_net(in)->ipv6.ip6table_filter);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -79,7 +79,7 @@ ip6t_forward_hook(unsigned int hook,
 		  int (*okfn)(struct sk_buff *))
 		  int (*okfn)(struct sk_buff *))
 {
 {
 	return ip6t_do_table(skb, hook, in, out,
 	return ip6t_do_table(skb, hook, in, out,
-			     nf_forward_net(in, out)->ipv6.ip6table_filter);
+			     dev_net(in)->ipv6.ip6table_filter);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -100,7 +100,7 @@ ip6t_local_out_hook(unsigned int hook,
 #endif
 #endif
 
 
 	return ip6t_do_table(skb, hook, in, out,
 	return ip6t_do_table(skb, hook, in, out,
-			     nf_local_out_net(in, out)->ipv6.ip6table_filter);
+			     dev_net(out)->ipv6.ip6table_filter);
 }
 }
 
 
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {

+ 22 - 9
net/ipv6/netfilter/ip6table_mangle.c

@@ -67,17 +67,29 @@ static struct xt_table packet_mangler = {
 
 
 /* The work comes in here from netfilter.c. */
 /* The work comes in here from netfilter.c. */
 static unsigned int
 static unsigned int
-ip6t_route_hook(unsigned int hook,
+ip6t_in_hook(unsigned int hook,
 	 struct sk_buff *skb,
 	 struct sk_buff *skb,
 	 const struct net_device *in,
 	 const struct net_device *in,
 	 const struct net_device *out,
 	 const struct net_device *out,
 	 int (*okfn)(struct sk_buff *))
 	 int (*okfn)(struct sk_buff *))
 {
 {
-	return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
+	return ip6t_do_table(skb, hook, in, out,
+			     dev_net(in)->ipv6.ip6table_mangle);
 }
 }
 
 
 static unsigned int
 static unsigned int
-ip6t_local_hook(unsigned int hook,
+ip6t_post_routing_hook(unsigned int hook,
+		struct sk_buff *skb,
+		const struct net_device *in,
+		const struct net_device *out,
+		int (*okfn)(struct sk_buff *))
+{
+	return ip6t_do_table(skb, hook, in, out,
+			     dev_net(out)->ipv6.ip6table_mangle);
+}
+
+static unsigned int
+ip6t_local_out_hook(unsigned int hook,
 		   struct sk_buff *skb,
 		   struct sk_buff *skb,
 		   const struct net_device *in,
 		   const struct net_device *in,
 		   const struct net_device *out,
 		   const struct net_device *out,
@@ -108,7 +120,8 @@ ip6t_local_hook(unsigned int hook,
 	/* flowlabel and prio (includes version, which shouldn't change either */
 	/* flowlabel and prio (includes version, which shouldn't change either */
 	flowlabel = *((u_int32_t *)ipv6_hdr(skb));
 	flowlabel = *((u_int32_t *)ipv6_hdr(skb));
 
 
-	ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
+	ret = ip6t_do_table(skb, hook, in, out,
+			    dev_net(out)->ipv6.ip6table_mangle);
 
 
 	if (ret != NF_DROP && ret != NF_STOLEN
 	if (ret != NF_DROP && ret != NF_STOLEN
 		&& (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
 		&& (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@@ -122,35 +135,35 @@ ip6t_local_hook(unsigned int hook,
 
 
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 	{
 	{
-		.hook		= ip6t_route_hook,
+		.hook		= ip6t_in_hook,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
 		.pf		= PF_INET6,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP6_PRI_MANGLE,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	},
 	{
 	{
-		.hook		= ip6t_route_hook,
+		.hook		= ip6t_in_hook,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
 		.pf		= PF_INET6,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP6_PRI_MANGLE,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	},
 	{
 	{
-		.hook		= ip6t_route_hook,
+		.hook		= ip6t_in_hook,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
 		.pf		= PF_INET6,
 		.hooknum	= NF_INET_FORWARD,
 		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP6_PRI_MANGLE,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	},
 	{
 	{
-		.hook		= ip6t_local_hook,
+		.hook		= ip6t_local_out_hook,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
 		.pf		= PF_INET6,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_MANGLE,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	},
 	{
 	{
-		.hook		= ip6t_route_hook,
+		.hook		= ip6t_post_routing_hook,
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
 		.pf		= PF_INET6,
 		.hooknum	= NF_INET_POST_ROUTING,
 		.hooknum	= NF_INET_POST_ROUTING,

+ 16 - 4
net/ipv6/netfilter/ip6table_raw.c

@@ -45,25 +45,37 @@ static struct xt_table packet_raw = {
 
 
 /* The work comes in here from netfilter.c. */
 /* The work comes in here from netfilter.c. */
 static unsigned int
 static unsigned int
-ip6t_hook(unsigned int hook,
+ip6t_pre_routing_hook(unsigned int hook,
 	 struct sk_buff *skb,
 	 struct sk_buff *skb,
 	 const struct net_device *in,
 	 const struct net_device *in,
 	 const struct net_device *out,
 	 const struct net_device *out,
 	 int (*okfn)(struct sk_buff *))
 	 int (*okfn)(struct sk_buff *))
 {
 {
-	return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw);
+	return ip6t_do_table(skb, hook, in, out,
+			     dev_net(in)->ipv6.ip6table_raw);
+}
+
+static unsigned int
+ip6t_local_out_hook(unsigned int hook,
+	 struct sk_buff *skb,
+	 const struct net_device *in,
+	 const struct net_device *out,
+	 int (*okfn)(struct sk_buff *))
+{
+	return ip6t_do_table(skb, hook, in, out,
+			     dev_net(out)->ipv6.ip6table_raw);
 }
 }
 
 
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 	{
 	{
-	  .hook = ip6t_hook,
+	  .hook = ip6t_pre_routing_hook,
 	  .pf = PF_INET6,
 	  .pf = PF_INET6,
 	  .hooknum = NF_INET_PRE_ROUTING,
 	  .hooknum = NF_INET_PRE_ROUTING,
 	  .priority = NF_IP6_PRI_FIRST,
 	  .priority = NF_IP6_PRI_FIRST,
 	  .owner = THIS_MODULE,
 	  .owner = THIS_MODULE,
 	},
 	},
 	{
 	{
-	  .hook = ip6t_hook,
+	  .hook = ip6t_local_out_hook,
 	  .pf = PF_INET6,
 	  .pf = PF_INET6,
 	  .hooknum = NF_INET_LOCAL_OUT,
 	  .hooknum = NF_INET_LOCAL_OUT,
 	  .priority = NF_IP6_PRI_FIRST,
 	  .priority = NF_IP6_PRI_FIRST,

+ 3 - 3
net/ipv6/netfilter/ip6table_security.c

@@ -72,7 +72,7 @@ ip6t_local_in_hook(unsigned int hook,
 		   int (*okfn)(struct sk_buff *))
 		   int (*okfn)(struct sk_buff *))
 {
 {
 	return ip6t_do_table(skb, hook, in, out,
 	return ip6t_do_table(skb, hook, in, out,
-			     nf_local_in_net(in, out)->ipv6.ip6table_security);
+			     dev_net(in)->ipv6.ip6table_security);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -83,7 +83,7 @@ ip6t_forward_hook(unsigned int hook,
 		  int (*okfn)(struct sk_buff *))
 		  int (*okfn)(struct sk_buff *))
 {
 {
 	return ip6t_do_table(skb, hook, in, out,
 	return ip6t_do_table(skb, hook, in, out,
-			     nf_forward_net(in, out)->ipv6.ip6table_security);
+			     dev_net(in)->ipv6.ip6table_security);
 }
 }
 
 
 static unsigned int
 static unsigned int
@@ -95,7 +95,7 @@ ip6t_local_out_hook(unsigned int hook,
 {
 {
 	/* TBD: handle short packets via raw socket */
 	/* TBD: handle short packets via raw socket */
 	return ip6t_do_table(skb, hook, in, out,
 	return ip6t_do_table(skb, hook, in, out,
-			     nf_local_out_net(in, out)->ipv6.ip6table_security);
+			     dev_net(out)->ipv6.ip6table_security);
 }
 }
 
 
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {

+ 16 - 8
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c

@@ -211,11 +211,10 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
 	return NF_STOLEN;
 	return NF_STOLEN;
 }
 }
 
 
-static unsigned int ipv6_conntrack_in(unsigned int hooknum,
-				      struct sk_buff *skb,
-				      const struct net_device *in,
-				      const struct net_device *out,
-				      int (*okfn)(struct sk_buff *))
+static unsigned int __ipv6_conntrack_in(struct net *net,
+					unsigned int hooknum,
+					struct sk_buff *skb,
+					int (*okfn)(struct sk_buff *))
 {
 {
 	struct sk_buff *reasm = skb->nfct_reasm;
 	struct sk_buff *reasm = skb->nfct_reasm;
 
 
@@ -225,7 +224,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
 		if (!reasm->nfct) {
 		if (!reasm->nfct) {
 			unsigned int ret;
 			unsigned int ret;
 
 
-			ret = nf_conntrack_in(PF_INET6, hooknum, reasm);
+			ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
 			if (ret != NF_ACCEPT)
 			if (ret != NF_ACCEPT)
 				return ret;
 				return ret;
 		}
 		}
@@ -235,7 +234,16 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
 		return NF_ACCEPT;
 		return NF_ACCEPT;
 	}
 	}
 
 
-	return nf_conntrack_in(PF_INET6, hooknum, skb);
+	return nf_conntrack_in(net, PF_INET6, hooknum, skb);
+}
+
+static unsigned int ipv6_conntrack_in(unsigned int hooknum,
+				      struct sk_buff *skb,
+				      const struct net_device *in,
+				      const struct net_device *out,
+				      int (*okfn)(struct sk_buff *))
+{
+	return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
 }
 }
 
 
 static unsigned int ipv6_conntrack_local(unsigned int hooknum,
 static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@@ -250,7 +258,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
 			printk("ipv6_conntrack_local: packet too short\n");
 			printk("ipv6_conntrack_local: packet too short\n");
 		return NF_ACCEPT;
 		return NF_ACCEPT;
 	}
 	}
-	return ipv6_conntrack_in(hooknum, skb, in, out, okfn);
+	return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
 }
 }
 
 
 static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
 static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {

+ 10 - 9
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c

@@ -81,7 +81,7 @@ static int icmpv6_packet(struct nf_conn *ct,
 		       const struct sk_buff *skb,
 		       const struct sk_buff *skb,
 		       unsigned int dataoff,
 		       unsigned int dataoff,
 		       enum ip_conntrack_info ctinfo,
 		       enum ip_conntrack_info ctinfo,
-		       int pf,
+		       u_int8_t pf,
 		       unsigned int hooknum)
 		       unsigned int hooknum)
 {
 {
 	/* Try to delete connection immediately after all replies:
 	/* Try to delete connection immediately after all replies:
@@ -93,7 +93,7 @@ static int icmpv6_packet(struct nf_conn *ct,
 			nf_ct_kill_acct(ct, ctinfo, skb);
 			nf_ct_kill_acct(ct, ctinfo, skb);
 	} else {
 	} else {
 		atomic_inc(&ct->proto.icmp.count);
 		atomic_inc(&ct->proto.icmp.count);
-		nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
+		nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
 		nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
 		nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
 	}
 	}
 
 
@@ -122,7 +122,8 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
 }
 }
 
 
 static int
 static int
-icmpv6_error_message(struct sk_buff *skb,
+icmpv6_error_message(struct net *net,
+		     struct sk_buff *skb,
 		     unsigned int icmp6off,
 		     unsigned int icmp6off,
 		     enum ip_conntrack_info *ctinfo,
 		     enum ip_conntrack_info *ctinfo,
 		     unsigned int hooknum)
 		     unsigned int hooknum)
@@ -156,7 +157,7 @@ icmpv6_error_message(struct sk_buff *skb,
 
 
 	*ctinfo = IP_CT_RELATED;
 	*ctinfo = IP_CT_RELATED;
 
 
-	h = nf_conntrack_find_get(&intuple);
+	h = nf_conntrack_find_get(net, &intuple);
 	if (!h) {
 	if (!h) {
 		pr_debug("icmpv6_error: no match\n");
 		pr_debug("icmpv6_error: no match\n");
 		return -NF_ACCEPT;
 		return -NF_ACCEPT;
@@ -172,21 +173,21 @@ icmpv6_error_message(struct sk_buff *skb,
 }
 }
 
 
 static int
 static int
-icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
-	     enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
+icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
+	     enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
 {
 {
 	const struct icmp6hdr *icmp6h;
 	const struct icmp6hdr *icmp6h;
 	struct icmp6hdr _ih;
 	struct icmp6hdr _ih;
 
 
 	icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
 	icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
 	if (icmp6h == NULL) {
 	if (icmp6h == NULL) {
-		if (LOG_INVALID(IPPROTO_ICMPV6))
+		if (LOG_INVALID(net, IPPROTO_ICMPV6))
 		nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
 		nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
 			      "nf_ct_icmpv6: short packet ");
 			      "nf_ct_icmpv6: short packet ");
 		return -NF_ACCEPT;
 		return -NF_ACCEPT;
 	}
 	}
 
 
-	if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
+	if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
 	    nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
 	    nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
 		nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
 		nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
 			      "nf_ct_icmpv6: ICMPv6 checksum failed\n");
 			      "nf_ct_icmpv6: ICMPv6 checksum failed\n");
@@ -197,7 +198,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
 	if (icmp6h->icmp6_type >= 128)
 	if (icmp6h->icmp6_type >= 128)
 		return NF_ACCEPT;
 		return NF_ACCEPT;
 
 
-	return icmpv6_error_message(skb, dataoff, ctinfo, hooknum);
+	return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum);
 }
 }
 
 
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)

+ 128 - 108
net/netfilter/Kconfig

@@ -38,10 +38,11 @@ config NF_CONNTRACK
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+if NF_CONNTRACK
+
 config NF_CT_ACCT
 config NF_CT_ACCT
 	bool "Connection tracking flow accounting"
 	bool "Connection tracking flow accounting"
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
-	depends on NF_CONNTRACK
 	help
 	help
 	  If this option is enabled, the connection tracking code will
 	  If this option is enabled, the connection tracking code will
 	  keep per-flow packet and byte counters.
 	  keep per-flow packet and byte counters.
@@ -63,7 +64,6 @@ config NF_CT_ACCT
 config NF_CONNTRACK_MARK
 config NF_CONNTRACK_MARK
 	bool  'Connection mark tracking support'
 	bool  'Connection mark tracking support'
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
-	depends on NF_CONNTRACK
 	help
 	help
 	  This option enables support for connection marks, used by the
 	  This option enables support for connection marks, used by the
 	  `CONNMARK' target and `connmark' match. Similar to the mark value
 	  `CONNMARK' target and `connmark' match. Similar to the mark value
@@ -72,7 +72,7 @@ config NF_CONNTRACK_MARK
 
 
 config NF_CONNTRACK_SECMARK
 config NF_CONNTRACK_SECMARK
 	bool  'Connection tracking security mark support'
 	bool  'Connection tracking security mark support'
-	depends on NF_CONNTRACK && NETWORK_SECMARK
+	depends on NETWORK_SECMARK
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  This option enables security markings to be applied to
 	  This option enables security markings to be applied to
@@ -85,7 +85,6 @@ config NF_CONNTRACK_SECMARK
 
 
 config NF_CONNTRACK_EVENTS
 config NF_CONNTRACK_EVENTS
 	bool "Connection tracking events"
 	bool "Connection tracking events"
-	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  If this option is enabled, the connection tracking code will
 	  If this option is enabled, the connection tracking code will
@@ -96,7 +95,7 @@ config NF_CONNTRACK_EVENTS
 
 
 config NF_CT_PROTO_DCCP
 config NF_CT_PROTO_DCCP
 	tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
 	tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	depends on EXPERIMENTAL
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	default IP_DCCP
 	default IP_DCCP
 	help
 	help
@@ -107,11 +106,10 @@ config NF_CT_PROTO_DCCP
 
 
 config NF_CT_PROTO_GRE
 config NF_CT_PROTO_GRE
 	tristate
 	tristate
-	depends on NF_CONNTRACK
 
 
 config NF_CT_PROTO_SCTP
 config NF_CT_PROTO_SCTP
 	tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
 	tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	depends on EXPERIMENTAL
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	default IP_SCTP
 	default IP_SCTP
 	help
 	help
@@ -123,7 +121,6 @@ config NF_CT_PROTO_SCTP
 
 
 config NF_CT_PROTO_UDPLITE
 config NF_CT_PROTO_UDPLITE
 	tristate 'UDP-Lite protocol connection tracking support'
 	tristate 'UDP-Lite protocol connection tracking support'
-	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  With this option enabled, the layer 3 independent connection
 	  With this option enabled, the layer 3 independent connection
@@ -134,7 +131,6 @@ config NF_CT_PROTO_UDPLITE
 
 
 config NF_CONNTRACK_AMANDA
 config NF_CONNTRACK_AMANDA
 	tristate "Amanda backup protocol support"
 	tristate "Amanda backup protocol support"
-	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	select TEXTSEARCH
 	select TEXTSEARCH
 	select TEXTSEARCH_KMP
 	select TEXTSEARCH_KMP
@@ -150,7 +146,6 @@ config NF_CONNTRACK_AMANDA
 
 
 config NF_CONNTRACK_FTP
 config NF_CONNTRACK_FTP
 	tristate "FTP protocol support"
 	tristate "FTP protocol support"
-	depends on NF_CONNTRACK
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  Tracking FTP connections is problematic: special helpers are
 	  Tracking FTP connections is problematic: special helpers are
@@ -165,7 +160,7 @@ config NF_CONNTRACK_FTP
 
 
 config NF_CONNTRACK_H323
 config NF_CONNTRACK_H323
 	tristate "H.323 protocol support"
 	tristate "H.323 protocol support"
-	depends on NF_CONNTRACK && (IPV6 || IPV6=n)
+	depends on (IPV6 || IPV6=n)
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most
 	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most
@@ -185,7 +180,6 @@ config NF_CONNTRACK_H323
 
 
 config NF_CONNTRACK_IRC
 config NF_CONNTRACK_IRC
 	tristate "IRC protocol support"
 	tristate "IRC protocol support"
-	depends on NF_CONNTRACK
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  There is a commonly-used extension to IRC called
 	  There is a commonly-used extension to IRC called
@@ -201,7 +195,6 @@ config NF_CONNTRACK_IRC
 
 
 config NF_CONNTRACK_NETBIOS_NS
 config NF_CONNTRACK_NETBIOS_NS
 	tristate "NetBIOS name service protocol support"
 	tristate "NetBIOS name service protocol support"
-	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  NetBIOS name service requests are sent as broadcast messages from an
 	  NetBIOS name service requests are sent as broadcast messages from an
@@ -221,7 +214,6 @@ config NF_CONNTRACK_NETBIOS_NS
 
 
 config NF_CONNTRACK_PPTP
 config NF_CONNTRACK_PPTP
 	tristate "PPtP protocol support"
 	tristate "PPtP protocol support"
-	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	select NF_CT_PROTO_GRE
 	select NF_CT_PROTO_GRE
 	help
 	help
@@ -241,7 +233,7 @@ config NF_CONNTRACK_PPTP
 
 
 config NF_CONNTRACK_SANE
 config NF_CONNTRACK_SANE
 	tristate "SANE protocol support (EXPERIMENTAL)"
 	tristate "SANE protocol support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	depends on EXPERIMENTAL
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  SANE is a protocol for remote access to scanners as implemented
 	  SANE is a protocol for remote access to scanners as implemented
@@ -255,7 +247,6 @@ config NF_CONNTRACK_SANE
 
 
 config NF_CONNTRACK_SIP
 config NF_CONNTRACK_SIP
 	tristate "SIP protocol support"
 	tristate "SIP protocol support"
-	depends on NF_CONNTRACK
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  SIP is an application-layer control protocol that can establish,
 	  SIP is an application-layer control protocol that can establish,
@@ -268,7 +259,6 @@ config NF_CONNTRACK_SIP
 
 
 config NF_CONNTRACK_TFTP
 config NF_CONNTRACK_TFTP
 	tristate "TFTP protocol support"
 	tristate "TFTP protocol support"
-	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  TFTP connection tracking helper, this is required depending
 	  TFTP connection tracking helper, this is required depending
@@ -280,13 +270,29 @@ config NF_CONNTRACK_TFTP
 
 
 config NF_CT_NETLINK
 config NF_CT_NETLINK
 	tristate 'Connection tracking netlink interface'
 	tristate 'Connection tracking netlink interface'
-	depends on NF_CONNTRACK
 	select NETFILTER_NETLINK
 	select NETFILTER_NETLINK
 	depends on NF_NAT=n || NF_NAT
 	depends on NF_NAT=n || NF_NAT
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  This option enables support for a netlink-based userspace interface
 	  This option enables support for a netlink-based userspace interface
 
 
+# transparent proxy support
+config NETFILTER_TPROXY
+	tristate "Transparent proxying support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	depends on IP_NF_MANGLE
+	depends on NETFILTER_ADVANCED
+	help
+	  This option enables transparent proxying support, that is,
+	  support for handling non-locally bound IPv4 TCP and UDP sockets.
+	  For it to work you will have to configure certain iptables rules
+	  and use policy routing. For more information on how to set it up
+	  see Documentation/networking/tproxy.txt.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+endif # NF_CONNTRACK
+
 config NETFILTER_XTABLES
 config NETFILTER_XTABLES
 	tristate "Netfilter Xtables support (required for ip_tables)"
 	tristate "Netfilter Xtables support (required for ip_tables)"
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
@@ -294,11 +300,12 @@ config NETFILTER_XTABLES
 	  This is required if you intend to use any of ip_tables,
 	  This is required if you intend to use any of ip_tables,
 	  ip6_tables or arp_tables.
 	  ip6_tables or arp_tables.
 
 
+if NETFILTER_XTABLES
+
 # alphabetically ordered list of targets
 # alphabetically ordered list of targets
 
 
 config NETFILTER_XT_TARGET_CLASSIFY
 config NETFILTER_XT_TARGET_CLASSIFY
 	tristate '"CLASSIFY" target support'
 	tristate '"CLASSIFY" target support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `CLASSIFY' target, which enables the user to set
 	  This option adds a `CLASSIFY' target, which enables the user to set
@@ -311,8 +318,6 @@ config NETFILTER_XT_TARGET_CLASSIFY
 
 
 config NETFILTER_XT_TARGET_CONNMARK
 config NETFILTER_XT_TARGET_CONNMARK
 	tristate  '"CONNMARK" target support'
 	tristate  '"CONNMARK" target support'
-	depends on NETFILTER_XTABLES
-	depends on IP_NF_MANGLE || IP6_NF_MANGLE
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	select NF_CONNTRACK_MARK
 	select NF_CONNTRACK_MARK
@@ -325,9 +330,20 @@ config NETFILTER_XT_TARGET_CONNMARK
 	  <file:Documentation/kbuild/modules.txt>.  The module will be called
 	  <file:Documentation/kbuild/modules.txt>.  The module will be called
 	  ipt_CONNMARK.ko.  If unsure, say `N'.
 	  ipt_CONNMARK.ko.  If unsure, say `N'.
 
 
+config NETFILTER_XT_TARGET_CONNSECMARK
+	tristate '"CONNSECMARK" target support'
+	depends on NF_CONNTRACK && NF_CONNTRACK_SECMARK
+	default m if NETFILTER_ADVANCED=n
+	help
+	  The CONNSECMARK target copies security markings from packets
+	  to connections, and restores security markings from connections
+	  to packets (if the packets are not already marked).  This would
+	  normally be used in conjunction with the SECMARK target.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_TARGET_DSCP
 config NETFILTER_XT_TARGET_DSCP
 	tristate '"DSCP" and "TOS" target support'
 	tristate '"DSCP" and "TOS" target support'
-	depends on NETFILTER_XTABLES
 	depends on IP_NF_MANGLE || IP6_NF_MANGLE
 	depends on IP_NF_MANGLE || IP6_NF_MANGLE
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
@@ -344,7 +360,6 @@ config NETFILTER_XT_TARGET_DSCP
 
 
 config NETFILTER_XT_TARGET_MARK
 config NETFILTER_XT_TARGET_MARK
 	tristate '"MARK" target support'
 	tristate '"MARK" target support'
-	depends on NETFILTER_XTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  This option adds a `MARK' target, which allows you to create rules
 	  This option adds a `MARK' target, which allows you to create rules
@@ -356,21 +371,8 @@ config NETFILTER_XT_TARGET_MARK
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config NETFILTER_XT_TARGET_NFQUEUE
-	tristate '"NFQUEUE" target Support'
-	depends on NETFILTER_XTABLES
-	depends on NETFILTER_ADVANCED
-	help
-	  This target replaced the old obsolete QUEUE target.
-
-	  As opposed to QUEUE, it supports 65535 different queues,
-	  not just one.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config NETFILTER_XT_TARGET_NFLOG
 config NETFILTER_XT_TARGET_NFLOG
 	tristate '"NFLOG" target support'
 	tristate '"NFLOG" target support'
-	depends on NETFILTER_XTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  This option enables the NFLOG target, which allows to LOG
 	  This option enables the NFLOG target, which allows to LOG
@@ -380,9 +382,19 @@ config NETFILTER_XT_TARGET_NFLOG
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+config NETFILTER_XT_TARGET_NFQUEUE
+	tristate '"NFQUEUE" target Support'
+	depends on NETFILTER_ADVANCED
+	help
+	  This target replaced the old obsolete QUEUE target.
+
+	  As opposed to QUEUE, it supports 65535 different queues,
+	  not just one.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_TARGET_NOTRACK
 config NETFILTER_XT_TARGET_NOTRACK
 	tristate  '"NOTRACK" target support'
 	tristate  '"NOTRACK" target support'
-	depends on NETFILTER_XTABLES
 	depends on IP_NF_RAW || IP6_NF_RAW
 	depends on IP_NF_RAW || IP6_NF_RAW
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
@@ -397,7 +409,6 @@ config NETFILTER_XT_TARGET_NOTRACK
 
 
 config NETFILTER_XT_TARGET_RATEEST
 config NETFILTER_XT_TARGET_RATEEST
 	tristate '"RATEEST" target support'
 	tristate '"RATEEST" target support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `RATEEST' target, which allows to measure
 	  This option adds a `RATEEST' target, which allows to measure
@@ -406,9 +417,23 @@ config NETFILTER_XT_TARGET_RATEEST
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+config NETFILTER_XT_TARGET_TPROXY
+	tristate '"TPROXY" target support (EXPERIMENTAL)'
+	depends on EXPERIMENTAL
+	depends on NETFILTER_TPROXY
+	depends on NETFILTER_XTABLES
+	depends on NETFILTER_ADVANCED
+	select NF_DEFRAG_IPV4
+	help
+	  This option adds a `TPROXY' target, which is somewhat similar to
+	  REDIRECT.  It can only be used in the mangle table and is useful
+	  to redirect traffic to a transparent proxy.  It does _not_ depend
+	  on Netfilter connection tracking and NAT, unlike REDIRECT.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_TARGET_TRACE
 config NETFILTER_XT_TARGET_TRACE
 	tristate  '"TRACE" target support'
 	tristate  '"TRACE" target support'
-	depends on NETFILTER_XTABLES
 	depends on IP_NF_RAW || IP6_NF_RAW
 	depends on IP_NF_RAW || IP6_NF_RAW
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
@@ -421,7 +446,7 @@ config NETFILTER_XT_TARGET_TRACE
 
 
 config NETFILTER_XT_TARGET_SECMARK
 config NETFILTER_XT_TARGET_SECMARK
 	tristate '"SECMARK" target support'
 	tristate '"SECMARK" target support'
-	depends on NETFILTER_XTABLES && NETWORK_SECMARK
+	depends on NETWORK_SECMARK
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  The SECMARK target allows security marking of network
 	  The SECMARK target allows security marking of network
@@ -429,21 +454,9 @@ config NETFILTER_XT_TARGET_SECMARK
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config NETFILTER_XT_TARGET_CONNSECMARK
-	tristate '"CONNSECMARK" target support'
-	depends on NETFILTER_XTABLES && NF_CONNTRACK && NF_CONNTRACK_SECMARK
-	default m if NETFILTER_ADVANCED=n
-	help
-	  The CONNSECMARK target copies security markings from packets
-	  to connections, and restores security markings from connections
-	  to packets (if the packets are not already marked).  This would
-	  normally be used in conjunction with the SECMARK target.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config NETFILTER_XT_TARGET_TCPMSS
 config NETFILTER_XT_TARGET_TCPMSS
 	tristate '"TCPMSS" target support'
 	tristate '"TCPMSS" target support'
-	depends on NETFILTER_XTABLES && (IPV6 || IPV6=n)
+	depends on (IPV6 || IPV6=n)
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	---help---
 	---help---
 	  This option adds a `TCPMSS' target, which allows you to alter the
 	  This option adds a `TCPMSS' target, which allows you to alter the
@@ -470,7 +483,7 @@ config NETFILTER_XT_TARGET_TCPMSS
 
 
 config NETFILTER_XT_TARGET_TCPOPTSTRIP
 config NETFILTER_XT_TARGET_TCPOPTSTRIP
 	tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)'
 	tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)'
-	depends on EXPERIMENTAL && NETFILTER_XTABLES
+	depends on EXPERIMENTAL
 	depends on IP_NF_MANGLE || IP6_NF_MANGLE
 	depends on IP_NF_MANGLE || IP6_NF_MANGLE
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
@@ -479,7 +492,6 @@ config NETFILTER_XT_TARGET_TCPOPTSTRIP
 
 
 config NETFILTER_XT_MATCH_COMMENT
 config NETFILTER_XT_MATCH_COMMENT
 	tristate  '"comment" match support'
 	tristate  '"comment" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `comment' dummy-match, which allows you to put
 	  This option adds a `comment' dummy-match, which allows you to put
@@ -490,7 +502,6 @@ config NETFILTER_XT_MATCH_COMMENT
 
 
 config NETFILTER_XT_MATCH_CONNBYTES
 config NETFILTER_XT_MATCH_CONNBYTES
 	tristate  '"connbytes" per-connection counter match support'
 	tristate  '"connbytes" per-connection counter match support'
-	depends on NETFILTER_XTABLES
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	select NF_CT_ACCT
 	select NF_CT_ACCT
@@ -503,7 +514,6 @@ config NETFILTER_XT_MATCH_CONNBYTES
 
 
 config NETFILTER_XT_MATCH_CONNLIMIT
 config NETFILTER_XT_MATCH_CONNLIMIT
 	tristate '"connlimit" match support"'
 	tristate '"connlimit" match support"'
-	depends on NETFILTER_XTABLES
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	---help---
 	---help---
@@ -512,7 +522,6 @@ config NETFILTER_XT_MATCH_CONNLIMIT
 
 
 config NETFILTER_XT_MATCH_CONNMARK
 config NETFILTER_XT_MATCH_CONNMARK
 	tristate  '"connmark" connection mark match support'
 	tristate  '"connmark" connection mark match support'
-	depends on NETFILTER_XTABLES
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	select NF_CONNTRACK_MARK
 	select NF_CONNTRACK_MARK
@@ -526,7 +535,6 @@ config NETFILTER_XT_MATCH_CONNMARK
 
 
 config NETFILTER_XT_MATCH_CONNTRACK
 config NETFILTER_XT_MATCH_CONNTRACK
 	tristate '"conntrack" connection tracking match support'
 	tristate '"conntrack" connection tracking match support'
-	depends on NETFILTER_XTABLES
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
@@ -540,7 +548,6 @@ config NETFILTER_XT_MATCH_CONNTRACK
 
 
 config NETFILTER_XT_MATCH_DCCP
 config NETFILTER_XT_MATCH_DCCP
 	tristate '"dccp" protocol match support'
 	tristate '"dccp" protocol match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	default IP_DCCP
 	default IP_DCCP
 	help
 	help
@@ -553,7 +560,6 @@ config NETFILTER_XT_MATCH_DCCP
 
 
 config NETFILTER_XT_MATCH_DSCP
 config NETFILTER_XT_MATCH_DSCP
 	tristate '"dscp" and "tos" match support'
 	tristate '"dscp" and "tos" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `DSCP' match, which allows you to match against
 	  This option adds a `DSCP' match, which allows you to match against
@@ -569,7 +575,6 @@ config NETFILTER_XT_MATCH_DSCP
 
 
 config NETFILTER_XT_MATCH_ESP
 config NETFILTER_XT_MATCH_ESP
 	tristate '"esp" match support'
 	tristate '"esp" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This match extension allows you to match a range of SPIs
 	  This match extension allows you to match a range of SPIs
@@ -577,9 +582,23 @@ config NETFILTER_XT_MATCH_ESP
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+config NETFILTER_XT_MATCH_HASHLIMIT
+	tristate '"hashlimit" match support'
+	depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
+	depends on NETFILTER_ADVANCED
+	help
+	  This option adds a `hashlimit' match.
+
+	  As opposed to `limit', this match dynamically creates a hash table
+	  of limit buckets, based on your selection of source/destination
+	  addresses and/or ports.
+
+	  It enables you to express policies like `10kpps for any given
+	  destination address' or `500pps from any given source address'
+	  with a single rule.
+
 config NETFILTER_XT_MATCH_HELPER
 config NETFILTER_XT_MATCH_HELPER
 	tristate '"helper" match support'
 	tristate '"helper" match support'
-	depends on NETFILTER_XTABLES
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
@@ -590,7 +609,6 @@ config NETFILTER_XT_MATCH_HELPER
 
 
 config NETFILTER_XT_MATCH_IPRANGE
 config NETFILTER_XT_MATCH_IPRANGE
 	tristate '"iprange" address range match support'
 	tristate '"iprange" address range match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	---help---
 	---help---
 	This option adds a "iprange" match, which allows you to match based on
 	This option adds a "iprange" match, which allows you to match based on
@@ -601,7 +619,6 @@ config NETFILTER_XT_MATCH_IPRANGE
 
 
 config NETFILTER_XT_MATCH_LENGTH
 config NETFILTER_XT_MATCH_LENGTH
 	tristate '"length" match support'
 	tristate '"length" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option allows you to match the length of a packet against a
 	  This option allows you to match the length of a packet against a
@@ -611,7 +628,6 @@ config NETFILTER_XT_MATCH_LENGTH
 
 
 config NETFILTER_XT_MATCH_LIMIT
 config NETFILTER_XT_MATCH_LIMIT
 	tristate '"limit" match support'
 	tristate '"limit" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  limit matching allows you to control the rate at which a rule can be
 	  limit matching allows you to control the rate at which a rule can be
@@ -622,7 +638,6 @@ config NETFILTER_XT_MATCH_LIMIT
 
 
 config NETFILTER_XT_MATCH_MAC
 config NETFILTER_XT_MATCH_MAC
 	tristate '"mac" address match support'
 	tristate '"mac" address match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  MAC matching allows you to match packets based on the source
 	  MAC matching allows you to match packets based on the source
@@ -632,7 +647,6 @@ config NETFILTER_XT_MATCH_MAC
 
 
 config NETFILTER_XT_MATCH_MARK
 config NETFILTER_XT_MATCH_MARK
 	tristate '"mark" match support'
 	tristate '"mark" match support'
-	depends on NETFILTER_XTABLES
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  Netfilter mark matching allows you to match packets based on the
 	  Netfilter mark matching allows you to match packets based on the
@@ -641,9 +655,18 @@ config NETFILTER_XT_MATCH_MARK
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
+config NETFILTER_XT_MATCH_MULTIPORT
+	tristate '"multiport" Multiple port match support'
+	depends on NETFILTER_ADVANCED
+	help
+	  Multiport matching allows you to match TCP or UDP packets based on
+	  a series of source or destination ports: normally a rule can only
+	  match a single range of ports.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_OWNER
 config NETFILTER_XT_MATCH_OWNER
 	tristate '"owner" match support'
 	tristate '"owner" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	---help---
 	---help---
 	Socket owner matching allows you to match locally-generated packets
 	Socket owner matching allows you to match locally-generated packets
@@ -652,7 +675,7 @@ config NETFILTER_XT_MATCH_OWNER
 
 
 config NETFILTER_XT_MATCH_POLICY
 config NETFILTER_XT_MATCH_POLICY
 	tristate 'IPsec "policy" match support'
 	tristate 'IPsec "policy" match support'
-	depends on NETFILTER_XTABLES && XFRM
+	depends on XFRM
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
 	  Policy matching allows you to match packets based on the
 	  Policy matching allows you to match packets based on the
@@ -661,20 +684,9 @@ config NETFILTER_XT_MATCH_POLICY
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
-config NETFILTER_XT_MATCH_MULTIPORT
-	tristate '"multiport" Multiple port match support'
-	depends on NETFILTER_XTABLES
-	depends on NETFILTER_ADVANCED
-	help
-	  Multiport matching allows you to match TCP or UDP packets based on
-	  a series of source or destination ports: normally a rule can only
-	  match a single range of ports.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config NETFILTER_XT_MATCH_PHYSDEV
 config NETFILTER_XT_MATCH_PHYSDEV
 	tristate '"physdev" match support'
 	tristate '"physdev" match support'
-	depends on NETFILTER_XTABLES && BRIDGE && BRIDGE_NETFILTER
+	depends on BRIDGE && BRIDGE_NETFILTER
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  Physdev packet matching matches against the physical bridge ports
 	  Physdev packet matching matches against the physical bridge ports
@@ -684,7 +696,6 @@ config NETFILTER_XT_MATCH_PHYSDEV
 
 
 config NETFILTER_XT_MATCH_PKTTYPE
 config NETFILTER_XT_MATCH_PKTTYPE
 	tristate '"pkttype" packet type match support'
 	tristate '"pkttype" packet type match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  Packet type matching allows you to match a packet by
 	  Packet type matching allows you to match a packet by
@@ -697,7 +708,6 @@ config NETFILTER_XT_MATCH_PKTTYPE
 
 
 config NETFILTER_XT_MATCH_QUOTA
 config NETFILTER_XT_MATCH_QUOTA
 	tristate '"quota" match support'
 	tristate '"quota" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `quota' match, which allows to match on a
 	  This option adds a `quota' match, which allows to match on a
@@ -708,7 +718,6 @@ config NETFILTER_XT_MATCH_QUOTA
 
 
 config NETFILTER_XT_MATCH_RATEEST
 config NETFILTER_XT_MATCH_RATEEST
 	tristate '"rateest" match support'
 	tristate '"rateest" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	select NETFILTER_XT_TARGET_RATEEST
 	select NETFILTER_XT_TARGET_RATEEST
 	help
 	help
@@ -719,7 +728,6 @@ config NETFILTER_XT_MATCH_RATEEST
 
 
 config NETFILTER_XT_MATCH_REALM
 config NETFILTER_XT_MATCH_REALM
 	tristate  '"realm" match support'
 	tristate  '"realm" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	select NET_CLS_ROUTE
 	select NET_CLS_ROUTE
 	help
 	help
@@ -732,9 +740,26 @@ config NETFILTER_XT_MATCH_REALM
 	  If you want to compile it as a module, say M here and read
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
 
+config NETFILTER_XT_MATCH_RECENT
+	tristate '"recent" match support'
+	depends on NETFILTER_ADVANCED
+	---help---
+	This match is used for creating one or many lists of recently
+	used addresses and then matching against that/those list(s).
+
+	Short options are available by using 'iptables -m recent -h'
+	Official Website: <http://snowman.net/projects/ipt_recent/>
+
+config NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
+	bool 'Enable obsolete /proc/net/ipt_recent'
+	depends on NETFILTER_XT_MATCH_RECENT && PROC_FS
+	---help---
+	This option enables the old /proc/net/ipt_recent interface,
+	which has been obsoleted by /proc/net/xt_recent.
+
 config NETFILTER_XT_MATCH_SCTP
 config NETFILTER_XT_MATCH_SCTP
 	tristate  '"sctp" protocol match support (EXPERIMENTAL)'
 	tristate  '"sctp" protocol match support (EXPERIMENTAL)'
-	depends on NETFILTER_XTABLES && EXPERIMENTAL
+	depends on EXPERIMENTAL
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	default IP_SCTP
 	default IP_SCTP
 	help
 	help
@@ -745,9 +770,23 @@ config NETFILTER_XT_MATCH_SCTP
 	  If you want to compile it as a module, say M here and read
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
 
+config NETFILTER_XT_MATCH_SOCKET
+	tristate '"socket" match support (EXPERIMENTAL)'
+	depends on EXPERIMENTAL
+	depends on NETFILTER_TPROXY
+	depends on NETFILTER_XTABLES
+	depends on NETFILTER_ADVANCED
+	select NF_DEFRAG_IPV4
+	help
+	  This option adds a `socket' match, which can be used to match
+	  packets for which a TCP or UDP socket lookup finds a valid socket.
+	  It can be used in combination with the MARK target and policy
+	  routing to implement full featured non-locally bound sockets.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_STATE
 config NETFILTER_XT_MATCH_STATE
 	tristate '"state" match support'
 	tristate '"state" match support'
-	depends on NETFILTER_XTABLES
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
 	default m if NETFILTER_ADVANCED=n
 	default m if NETFILTER_ADVANCED=n
 	help
 	help
@@ -759,7 +798,6 @@ config NETFILTER_XT_MATCH_STATE
 
 
 config NETFILTER_XT_MATCH_STATISTIC
 config NETFILTER_XT_MATCH_STATISTIC
 	tristate '"statistic" match support'
 	tristate '"statistic" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `statistic' match, which allows you to match
 	  This option adds a `statistic' match, which allows you to match
@@ -769,7 +807,6 @@ config NETFILTER_XT_MATCH_STATISTIC
 
 
 config NETFILTER_XT_MATCH_STRING
 config NETFILTER_XT_MATCH_STRING
 	tristate  '"string" match support'
 	tristate  '"string" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	select TEXTSEARCH
 	select TEXTSEARCH
 	select TEXTSEARCH_KMP
 	select TEXTSEARCH_KMP
@@ -783,7 +820,6 @@ config NETFILTER_XT_MATCH_STRING
 
 
 config NETFILTER_XT_MATCH_TCPMSS
 config NETFILTER_XT_MATCH_TCPMSS
 	tristate '"tcpmss" match support'
 	tristate '"tcpmss" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `tcpmss' match, which allows you to examine the
 	  This option adds a `tcpmss' match, which allows you to examine the
@@ -794,7 +830,6 @@ config NETFILTER_XT_MATCH_TCPMSS
 
 
 config NETFILTER_XT_MATCH_TIME
 config NETFILTER_XT_MATCH_TIME
 	tristate '"time" match support'
 	tristate '"time" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	---help---
 	---help---
 	  This option adds a "time" match, which allows you to match based on
 	  This option adds a "time" match, which allows you to match based on
@@ -809,7 +844,6 @@ config NETFILTER_XT_MATCH_TIME
 
 
 config NETFILTER_XT_MATCH_U32
 config NETFILTER_XT_MATCH_U32
 	tristate '"u32" match support'
 	tristate '"u32" match support'
-	depends on NETFILTER_XTABLES
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
 	---help---
 	---help---
 	  u32 allows you to extract quantities of up to 4 bytes from a packet,
 	  u32 allows you to extract quantities of up to 4 bytes from a packet,
@@ -821,20 +855,6 @@ config NETFILTER_XT_MATCH_U32
 
 
 	  Details and examples are in the kernel module source.
 	  Details and examples are in the kernel module source.
 
 
-config NETFILTER_XT_MATCH_HASHLIMIT
-	tristate '"hashlimit" match support'
-	depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
-	depends on NETFILTER_ADVANCED
-	help
-	  This option adds a `hashlimit' match.
-
-	  As opposed to `limit', this match dynamically creates a hash table
-	  of limit buckets, based on your selection of source/destination
-	  addresses and/or ports.
-
-	  It enables you to express policies like `10kpps for any given
-	  destination address' or `500pps from any given source address'
-	  with a single rule.
+endif # NETFILTER_XTABLES
 
 
 endmenu
 endmenu
-

+ 6 - 0
net/netfilter/Makefile

@@ -34,6 +34,9 @@ obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o
 obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
 obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
 obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
 obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
 
 
+# transparent proxy support
+obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
+
 # generic X tables 
 # generic X tables 
 obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
 obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
 
 
@@ -48,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
@@ -76,7 +80,9 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o

+ 5 - 13
net/netfilter/core.c

@@ -26,7 +26,7 @@
 
 
 static DEFINE_MUTEX(afinfo_mutex);
 static DEFINE_MUTEX(afinfo_mutex);
 
 
-const struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly;
+const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly;
 EXPORT_SYMBOL(nf_afinfo);
 EXPORT_SYMBOL(nf_afinfo);
 
 
 int nf_register_afinfo(const struct nf_afinfo *afinfo)
 int nf_register_afinfo(const struct nf_afinfo *afinfo)
@@ -51,7 +51,7 @@ void nf_unregister_afinfo(const struct nf_afinfo *afinfo)
 }
 }
 EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
 EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
 
 
-struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly;
+struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly;
 EXPORT_SYMBOL(nf_hooks);
 EXPORT_SYMBOL(nf_hooks);
 static DEFINE_MUTEX(nf_hook_mutex);
 static DEFINE_MUTEX(nf_hook_mutex);
 
 
@@ -113,7 +113,7 @@ EXPORT_SYMBOL(nf_unregister_hooks);
 
 
 unsigned int nf_iterate(struct list_head *head,
 unsigned int nf_iterate(struct list_head *head,
 			struct sk_buff *skb,
 			struct sk_buff *skb,
-			int hook,
+			unsigned int hook,
 			const struct net_device *indev,
 			const struct net_device *indev,
 			const struct net_device *outdev,
 			const struct net_device *outdev,
 			struct list_head **i,
 			struct list_head **i,
@@ -155,7 +155,7 @@ unsigned int nf_iterate(struct list_head *head,
 
 
 /* Returns 1 if okfn() needs to be executed by the caller,
 /* Returns 1 if okfn() needs to be executed by the caller,
  * -EPERM for NF_DROP, 0 otherwise. */
  * -EPERM for NF_DROP, 0 otherwise. */
-int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
+int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
 		 struct net_device *indev,
 		 struct net_device *indev,
 		 struct net_device *outdev,
 		 struct net_device *outdev,
 		 int (*okfn)(struct sk_buff *),
 		 int (*okfn)(struct sk_buff *),
@@ -165,14 +165,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
 	unsigned int verdict;
 	unsigned int verdict;
 	int ret = 0;
 	int ret = 0;
 
 
-#ifdef CONFIG_NET_NS
-	struct net *net;
-
-	net = indev == NULL ? dev_net(outdev) : dev_net(indev);
-	if (net != &init_net)
-		return 1;
-#endif
-
 	/* We may already have this, but read-locks nest anyway */
 	/* We may already have this, but read-locks nest anyway */
 	rcu_read_lock();
 	rcu_read_lock();
 
 
@@ -264,7 +256,7 @@ EXPORT_SYMBOL(proc_net_netfilter);
 void __init netfilter_init(void)
 void __init netfilter_init(void)
 {
 {
 	int i, h;
 	int i, h;
-	for (i = 0; i < NPROTO; i++) {
+	for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
 		for (h = 0; h < NF_MAX_HOOKS; h++)
 		for (h = 0; h < NF_MAX_HOOKS; h++)
 			INIT_LIST_HEAD(&nf_hooks[i][h]);
 			INIT_LIST_HEAD(&nf_hooks[i][h]);
 	}
 	}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно