aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-04-14 06:50:43 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-14 06:50:43 -0400
commit334f8b2afd9652e20f67ddee4fec483ed860425b (patch)
tree35d4fb46a9dc145e831fe5da026f2bfd9ee6657c
parent7477fd2e6b676fcd15861c2a96a7172f71afe0a5 (diff)
parentef1a5a50bbd509b8697dcd4d13017e9e0053867b (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.26
-rw-r--r--include/linux/netfilter.h76
-rw-r--r--include/linux/netfilter/nf_conntrack_dccp.h40
-rw-r--r--include/linux/netfilter/nfnetlink_conntrack.h8
-rw-r--r--include/linux/netfilter/x_tables.h4
-rw-r--r--include/linux/netfilter/xt_sctp.h84
-rw-r--r--include/linux/netfilter_arp/arp_tables.h17
-rw-r--r--include/linux/netfilter_bridge/ebt_nflog.h21
-rw-r--r--include/linux/netfilter_ipv4.h2
-rw-r--r--include/net/netfilter/nf_conntrack.h32
-rw-r--r--include/net/netfilter/nf_conntrack_core.h4
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h19
-rw-r--r--include/net/netfilter/nf_conntrack_l4proto.h13
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h47
-rw-r--r--include/net/netfilter/nf_nat_helper.h3
-rw-r--r--include/net/netfilter/nf_nat_protocol.h46
-rw-r--r--include/net/netfilter/nf_nat_rule.h3
-rw-r--r--net/bridge/netfilter/Kconfig14
-rw-r--r--net/bridge/netfilter/Makefile1
-rw-r--r--net/bridge/netfilter/ebt_nflog.c74
-rw-r--r--net/bridge/netfilter/ebtable_broute.c2
-rw-r--r--net/bridge/netfilter/ebtable_filter.c2
-rw-r--r--net/bridge/netfilter/ebtable_nat.c2
-rw-r--r--net/ipv4/netfilter.c37
-rw-r--r--net/ipv4/netfilter/Kconfig15
-rw-r--r--net/ipv4/netfilter/Makefile5
-rw-r--r--net/ipv4/netfilter/arp_tables.c66
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c12
-rw-r--r--net/ipv4/netfilter/arptable_filter.c7
-rw-r--r--net/ipv4/netfilter/ip_tables.c35
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c14
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c2
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c9
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c6
-rw-r--r--net/ipv4/netfilter/ipt_recent.c6
-rw-r--r--net/ipv4/netfilter/iptable_filter.c21
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c51
-rw-r--r--net/ipv4/netfilter/iptable_raw.c8
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c70
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c13
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c27
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c61
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c1
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_common.c120
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_dccp.c108
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_gre.c45
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_icmp.c19
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_sctp.c96
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_tcp.c80
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_udp.c77
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_udplite.c99
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_unknown.c25
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c25
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c17
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c76
-rw-r--r--net/ipv6/netfilter.c42
-rw-r--r--net/ipv6/netfilter/ip6_tables.c33
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c6
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c3
-rw-r--r--net/ipv6/netfilter/ip6t_ipv6header.c3
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c3
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c2
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c2
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c14
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c29
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c8
-rw-r--r--net/netfilter/Kconfig10
-rw-r--r--net/netfilter/Makefile1
-rw-r--r--net/netfilter/nf_conntrack_amanda.c6
-rw-r--r--net/netfilter/nf_conntrack_core.c29
-rw-r--r--net/netfilter/nf_conntrack_extend.c3
-rw-r--r--net/netfilter/nf_conntrack_ftp.c9
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c65
-rw-r--r--net/netfilter/nf_conntrack_helper.c2
-rw-r--r--net/netfilter/nf_conntrack_irc.c14
-rw-r--r--net/netfilter/nf_conntrack_l3proto_generic.c12
-rw-r--r--net/netfilter/nf_conntrack_netlink.c34
-rw-r--r--net/netfilter/nf_conntrack_pptp.c8
-rw-r--r--net/netfilter/nf_conntrack_proto.c9
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c815
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c20
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c31
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c50
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c64
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c18
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c55
-rw-r--r--net/netfilter/nf_conntrack_sane.c5
-rw-r--r--net/netfilter/nf_conntrack_sip.c21
-rw-r--r--net/netfilter/nf_conntrack_standalone.c131
-rw-r--r--net/netfilter/nf_conntrack_tftp.c10
-rw-r--r--net/netfilter/x_tables.c18
-rw-r--r--net/netfilter/xt_CONNSECMARK.c2
-rw-r--r--net/netfilter/xt_RATEEST.c2
-rw-r--r--net/netfilter/xt_connlimit.c10
-rw-r--r--net/netfilter/xt_conntrack.c4
-rw-r--r--net/netfilter/xt_dccp.c3
-rw-r--r--net/netfilter/xt_esp.c3
-rw-r--r--net/netfilter/xt_multiport.c6
-rw-r--r--net/netfilter/xt_policy.c2
-rw-r--r--net/netfilter/xt_rateest.c4
-rw-r--r--net/netfilter/xt_sctp.c6
-rw-r--r--net/netfilter/xt_tcpmss.c6
-rw-r--r--net/netfilter/xt_tcpudp.c9
-rw-r--r--net/netfilter/xt_time.c2
105 files changed, 2383 insertions, 1032 deletions
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 89e6c72ad295..e4c66593b5c6 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -6,11 +6,13 @@
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/skbuff.h> 7#include <linux/skbuff.h>
8#include <linux/net.h> 8#include <linux/net.h>
9#include <linux/netdevice.h>
9#include <linux/if.h> 10#include <linux/if.h>
10#include <linux/in.h> 11#include <linux/in.h>
11#include <linux/in6.h> 12#include <linux/in6.h>
12#include <linux/wait.h> 13#include <linux/wait.h>
13#include <linux/list.h> 14#include <linux/list.h>
15#include <net/net_namespace.h>
14#endif 16#endif
15#include <linux/compiler.h> 17#include <linux/compiler.h>
16 18
@@ -76,7 +78,6 @@ extern void netfilter_init(void);
76#define NF_MAX_HOOKS 8 78#define NF_MAX_HOOKS 8
77 79
78struct sk_buff; 80struct sk_buff;
79struct net_device;
80 81
81typedef unsigned int nf_hookfn(unsigned int hooknum, 82typedef unsigned int nf_hookfn(unsigned int hooknum,
82 struct sk_buff *skb, 83 struct sk_buff *skb,
@@ -233,6 +234,11 @@ struct nf_afinfo {
233 unsigned short family; 234 unsigned short family;
234 __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook, 235 __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook,
235 unsigned int dataoff, u_int8_t protocol); 236 unsigned int dataoff, u_int8_t protocol);
237 __sum16 (*checksum_partial)(struct sk_buff *skb,
238 unsigned int hook,
239 unsigned int dataoff,
240 unsigned int len,
241 u_int8_t protocol);
236 int (*route)(struct dst_entry **dst, struct flowi *fl); 242 int (*route)(struct dst_entry **dst, struct flowi *fl);
237 void (*saveroute)(const struct sk_buff *skb, 243 void (*saveroute)(const struct sk_buff *skb,
238 struct nf_queue_entry *entry); 244 struct nf_queue_entry *entry);
@@ -262,6 +268,23 @@ nf_checksum(struct sk_buff *skb, unsigned int hook, unsigned int dataoff,
262 return csum; 268 return csum;
263} 269}
264 270
271static inline __sum16
272nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
273 unsigned int dataoff, unsigned int len,
274 u_int8_t protocol, unsigned short family)
275{
276 const struct nf_afinfo *afinfo;
277 __sum16 csum = 0;
278
279 rcu_read_lock();
280 afinfo = nf_get_afinfo(family);
281 if (afinfo)
282 csum = afinfo->checksum_partial(skb, hook, dataoff, len,
283 protocol);
284 rcu_read_unlock();
285 return csum;
286}
287
265extern int nf_register_afinfo(const struct nf_afinfo *afinfo); 288extern int nf_register_afinfo(const struct nf_afinfo *afinfo);
266extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo); 289extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo);
267 290
@@ -320,5 +343,56 @@ extern void (*nf_ct_destroy)(struct nf_conntrack *);
320static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} 343static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
321#endif 344#endif
322 345
346static inline struct net *nf_pre_routing_net(const struct net_device *in,
347 const struct net_device *out)
348{
349#ifdef CONFIG_NET_NS
350 return in->nd_net;
351#else
352 return &init_net;
353#endif
354}
355
356static inline struct net *nf_local_in_net(const struct net_device *in,
357 const struct net_device *out)
358{
359#ifdef CONFIG_NET_NS
360 return in->nd_net;
361#else
362 return &init_net;
363#endif
364}
365
366static inline struct net *nf_forward_net(const struct net_device *in,
367 const struct net_device *out)
368{
369#ifdef CONFIG_NET_NS
370 BUG_ON(in->nd_net != out->nd_net);
371 return in->nd_net;
372#else
373 return &init_net;
374#endif
375}
376
377static inline struct net *nf_local_out_net(const struct net_device *in,
378 const struct net_device *out)
379{
380#ifdef CONFIG_NET_NS
381 return out->nd_net;
382#else
383 return &init_net;
384#endif
385}
386
387static inline struct net *nf_post_routing_net(const struct net_device *in,
388 const struct net_device *out)
389{
390#ifdef CONFIG_NET_NS
391 return out->nd_net;
392#else
393 return &init_net;
394#endif
395}
396
323#endif /*__KERNEL__*/ 397#endif /*__KERNEL__*/
324#endif /*__LINUX_NETFILTER_H*/ 398#endif /*__LINUX_NETFILTER_H*/
diff --git a/include/linux/netfilter/nf_conntrack_dccp.h b/include/linux/netfilter/nf_conntrack_dccp.h
new file mode 100644
index 000000000000..40dcc82058d1
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_dccp.h
@@ -0,0 +1,40 @@
1#ifndef _NF_CONNTRACK_DCCP_H
2#define _NF_CONNTRACK_DCCP_H
3
4/* Exposed to userspace over nfnetlink */
5enum ct_dccp_states {
6 CT_DCCP_NONE,
7 CT_DCCP_REQUEST,
8 CT_DCCP_RESPOND,
9 CT_DCCP_PARTOPEN,
10 CT_DCCP_OPEN,
11 CT_DCCP_CLOSEREQ,
12 CT_DCCP_CLOSING,
13 CT_DCCP_TIMEWAIT,
14 CT_DCCP_IGNORE,
15 CT_DCCP_INVALID,
16 __CT_DCCP_MAX
17};
18#define CT_DCCP_MAX (__CT_DCCP_MAX - 1)
19
20enum ct_dccp_roles {
21 CT_DCCP_ROLE_CLIENT,
22 CT_DCCP_ROLE_SERVER,
23 __CT_DCCP_ROLE_MAX
24};
25#define CT_DCCP_ROLE_MAX (__CT_DCCP_ROLE_MAX - 1)
26
27#ifdef __KERNEL__
28#include <net/netfilter/nf_conntrack_tuple.h>
29
30struct nf_ct_dccp {
31 u_int8_t role[IP_CT_DIR_MAX];
32 u_int8_t state;
33 u_int8_t last_pkt;
34 u_int8_t last_dir;
35 u_int64_t handshake_seq;
36};
37
38#endif /* __KERNEL__ */
39
40#endif /* _NF_CONNTRACK_DCCP_H */
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index e3e1533aba2d..0a383ac083cb 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -80,6 +80,7 @@ enum ctattr_l4proto {
80enum ctattr_protoinfo { 80enum ctattr_protoinfo {
81 CTA_PROTOINFO_UNSPEC, 81 CTA_PROTOINFO_UNSPEC,
82 CTA_PROTOINFO_TCP, 82 CTA_PROTOINFO_TCP,
83 CTA_PROTOINFO_DCCP,
83 __CTA_PROTOINFO_MAX 84 __CTA_PROTOINFO_MAX
84}; 85};
85#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1) 86#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
@@ -95,6 +96,13 @@ enum ctattr_protoinfo_tcp {
95}; 96};
96#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1) 97#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
97 98
99enum ctattr_protoinfo_dccp {
100 CTA_PROTOINFO_DCCP_UNSPEC,
101 CTA_PROTOINFO_DCCP_STATE,
102 __CTA_PROTOINFO_DCCP_MAX,
103};
104#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
105
98enum ctattr_counters { 106enum ctattr_counters {
99 CTA_COUNTERS_UNSPEC, 107 CTA_COUNTERS_UNSPEC,
100 CTA_COUNTERS_PACKETS, /* old 64bit counters */ 108 CTA_COUNTERS_PACKETS, /* old 64bit counters */
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index b2c62cc618f5..2326296b6f25 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -430,13 +430,13 @@ extern int xt_compat_add_offset(int af, unsigned int offset, short delta);
430extern void xt_compat_flush_offsets(int af); 430extern void xt_compat_flush_offsets(int af);
431extern short xt_compat_calc_jump(int af, unsigned int offset); 431extern short xt_compat_calc_jump(int af, unsigned int offset);
432 432
433extern int xt_compat_match_offset(struct xt_match *match); 433extern int xt_compat_match_offset(const struct xt_match *match);
434extern int xt_compat_match_from_user(struct xt_entry_match *m, 434extern int xt_compat_match_from_user(struct xt_entry_match *m,
435 void **dstptr, unsigned int *size); 435 void **dstptr, unsigned int *size);
436extern int xt_compat_match_to_user(struct xt_entry_match *m, 436extern int xt_compat_match_to_user(struct xt_entry_match *m,
437 void __user **dstptr, unsigned int *size); 437 void __user **dstptr, unsigned int *size);
438 438
439extern int xt_compat_target_offset(struct xt_target *target); 439extern int xt_compat_target_offset(const struct xt_target *target);
440extern void xt_compat_target_from_user(struct xt_entry_target *t, 440extern void xt_compat_target_from_user(struct xt_entry_target *t,
441 void **dstptr, unsigned int *size); 441 void **dstptr, unsigned int *size);
442extern int xt_compat_target_to_user(struct xt_entry_target *t, 442extern int xt_compat_target_to_user(struct xt_entry_target *t,
diff --git a/include/linux/netfilter/xt_sctp.h b/include/linux/netfilter/xt_sctp.h
index dd5a4fd4cfd3..32000ba6ecef 100644
--- a/include/linux/netfilter/xt_sctp.h
+++ b/include/linux/netfilter/xt_sctp.h
@@ -37,68 +37,54 @@ struct xt_sctp_info {
37 37
38#define SCTP_CHUNKMAP_SET(chunkmap, type) \ 38#define SCTP_CHUNKMAP_SET(chunkmap, type) \
39 do { \ 39 do { \
40 chunkmap[type / bytes(u_int32_t)] |= \ 40 (chunkmap)[type / bytes(u_int32_t)] |= \
41 1 << (type % bytes(u_int32_t)); \ 41 1 << (type % bytes(u_int32_t)); \
42 } while (0) 42 } while (0)
43 43
44#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \ 44#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
45 do { \ 45 do { \
46 chunkmap[type / bytes(u_int32_t)] &= \ 46 (chunkmap)[type / bytes(u_int32_t)] &= \
47 ~(1 << (type % bytes(u_int32_t))); \ 47 ~(1 << (type % bytes(u_int32_t))); \
48 } while (0) 48 } while (0)
49 49
50#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \ 50#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
51({ \ 51({ \
52 (chunkmap[type / bytes (u_int32_t)] & \ 52 ((chunkmap)[type / bytes (u_int32_t)] & \
53 (1 << (type % bytes (u_int32_t)))) ? 1: 0; \ 53 (1 << (type % bytes (u_int32_t)))) ? 1: 0; \
54}) 54})
55 55
56#define SCTP_CHUNKMAP_RESET(chunkmap) \ 56#define SCTP_CHUNKMAP_RESET(chunkmap) \
57 do { \ 57 memset((chunkmap), 0, sizeof(chunkmap))
58 int i; \ 58
59 for (i = 0; i < ARRAY_SIZE(chunkmap); i++) \ 59#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \
60 chunkmap[i] = 0; \ 60 memset((chunkmap), ~0U, sizeof(chunkmap))
61 } while (0) 61
62 62#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \
63#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \ 63 memcpy((destmap), (srcmap), sizeof(srcmap))
64 do { \ 64
65 int i; \ 65#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \
66 for (i = 0; i < ARRAY_SIZE(chunkmap); i++) \ 66 __sctp_chunkmap_is_clear((chunkmap), ARRAY_SIZE(chunkmap))
67 chunkmap[i] = ~0; \ 67static inline bool
68 } while (0) 68__sctp_chunkmap_is_clear(const u_int32_t *chunkmap, unsigned int n)
69 69{
70#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \ 70 unsigned int i;
71 do { \ 71 for (i = 0; i < n; ++i)
72 int i; \ 72 if (chunkmap[i])
73 for (i = 0; i < ARRAY_SIZE(srcmap); i++) \ 73 return false;
74 destmap[i] = srcmap[i]; \ 74 return true;
75 } while (0) 75}
76 76
77#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \ 77#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \
78({ \ 78 __sctp_chunkmap_is_all_set((chunkmap), ARRAY_SIZE(chunkmap))
79 int i; \ 79static inline bool
80 int flag = 1; \ 80__sctp_chunkmap_is_all_set(const u_int32_t *chunkmap, unsigned int n)
81 for (i = 0; i < ARRAY_SIZE(chunkmap); i++) { \ 81{
82 if (chunkmap[i]) { \ 82 unsigned int i;
83 flag = 0; \ 83 for (i = 0; i < n; ++i)
84 break; \ 84 if (chunkmap[i] != ~0U)
85 } \ 85 return false;
86 } \ 86 return true;
87 flag; \ 87}
88})
89
90#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \
91({ \
92 int i; \
93 int flag = 1; \
94 for (i = 0; i < ARRAY_SIZE(chunkmap); i++) { \
95 if (chunkmap[i] != ~0) { \
96 flag = 0; \
97 break; \
98 } \
99 } \
100 flag; \
101})
102 88
103#endif /* _XT_SCTP_H_ */ 89#endif /* _XT_SCTP_H_ */
104 90
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index db223ca92c8b..dd9c97f2d436 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -23,8 +23,6 @@
23 23
24#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 24#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
25#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN 25#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
26#define arpt_target xt_target
27#define arpt_table xt_table
28 26
29#define ARPT_DEV_ADDR_LEN_MAX 16 27#define ARPT_DEV_ADDR_LEN_MAX 16
30 28
@@ -266,20 +264,15 @@ struct arpt_error
266 .target.errorname = "ERROR", \ 264 .target.errorname = "ERROR", \
267} 265}
268 266
269#define arpt_register_target(tgt) \ 267extern struct xt_table *arpt_register_table(struct net *net,
270({ (tgt)->family = NF_ARP; \ 268 struct xt_table *table,
271 xt_register_target(tgt); }) 269 const struct arpt_replace *repl);
272#define arpt_unregister_target(tgt) xt_unregister_target(tgt) 270extern void arpt_unregister_table(struct xt_table *table);
273
274extern struct arpt_table *arpt_register_table(struct net *net,
275 struct arpt_table *table,
276 const struct arpt_replace *repl);
277extern void arpt_unregister_table(struct arpt_table *table);
278extern unsigned int arpt_do_table(struct sk_buff *skb, 271extern unsigned int arpt_do_table(struct sk_buff *skb,
279 unsigned int hook, 272 unsigned int hook,
280 const struct net_device *in, 273 const struct net_device *in,
281 const struct net_device *out, 274 const struct net_device *out,
282 struct arpt_table *table); 275 struct xt_table *table);
283 276
284#define ARPT_ALIGN(s) XT_ALIGN(s) 277#define ARPT_ALIGN(s) XT_ALIGN(s)
285 278
diff --git a/include/linux/netfilter_bridge/ebt_nflog.h b/include/linux/netfilter_bridge/ebt_nflog.h
new file mode 100644
index 000000000000..052817849b83
--- /dev/null
+++ b/include/linux/netfilter_bridge/ebt_nflog.h
@@ -0,0 +1,21 @@
1#ifndef __LINUX_BRIDGE_EBT_NFLOG_H
2#define __LINUX_BRIDGE_EBT_NFLOG_H
3
4#define EBT_NFLOG_MASK 0x0
5
6#define EBT_NFLOG_PREFIX_SIZE 64
7#define EBT_NFLOG_WATCHER "nflog"
8
9#define EBT_NFLOG_DEFAULT_GROUP 0x1
10#define EBT_NFLOG_DEFAULT_THRESHOLD 1
11
12struct ebt_nflog_info {
13 u_int32_t len;
14 u_int16_t group;
15 u_int16_t threshold;
16 u_int16_t flags;
17 u_int16_t pad;
18 char prefix[EBT_NFLOG_PREFIX_SIZE];
19};
20
21#endif /* __LINUX_BRIDGE_EBT_NFLOG_H */
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index 9a10092e358c..650318b0c405 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -62,8 +62,6 @@ enum nf_ip_hook_priorities {
62 NF_IP_PRI_FILTER = 0, 62 NF_IP_PRI_FILTER = 0,
63 NF_IP_PRI_NAT_SRC = 100, 63 NF_IP_PRI_NAT_SRC = 100,
64 NF_IP_PRI_SELINUX_LAST = 225, 64 NF_IP_PRI_SELINUX_LAST = 225,
65 NF_IP_PRI_CONNTRACK_HELPER = INT_MAX - 2,
66 NF_IP_PRI_NAT_SEQ_ADJUST = INT_MAX - 1,
67 NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, 65 NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
68 NF_IP_PRI_LAST = INT_MAX, 66 NF_IP_PRI_LAST = INT_MAX,
69}; 67};
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index a3567a7a6d67..2dbd6c015b94 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -20,6 +20,7 @@
20#include <asm/atomic.h> 20#include <asm/atomic.h>
21 21
22#include <linux/netfilter/nf_conntrack_tcp.h> 22#include <linux/netfilter/nf_conntrack_tcp.h>
23#include <linux/netfilter/nf_conntrack_dccp.h>
23#include <linux/netfilter/nf_conntrack_sctp.h> 24#include <linux/netfilter/nf_conntrack_sctp.h>
24#include <linux/netfilter/nf_conntrack_proto_gre.h> 25#include <linux/netfilter/nf_conntrack_proto_gre.h>
25#include <net/netfilter/ipv4/nf_conntrack_icmp.h> 26#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
@@ -30,6 +31,7 @@
30/* per conntrack: protocol private data */ 31/* per conntrack: protocol private data */
31union nf_conntrack_proto { 32union nf_conntrack_proto {
32 /* insert conntrack proto private data here */ 33 /* insert conntrack proto private data here */
34 struct nf_ct_dccp dccp;
33 struct ip_ct_sctp sctp; 35 struct ip_ct_sctp sctp;
34 struct ip_ct_tcp tcp; 36 struct ip_ct_tcp tcp;
35 struct ip_ct_icmp icmp; 37 struct ip_ct_icmp icmp;
@@ -63,14 +65,7 @@ union nf_conntrack_help {
63#include <linux/timer.h> 65#include <linux/timer.h>
64 66
65#ifdef CONFIG_NETFILTER_DEBUG 67#ifdef CONFIG_NETFILTER_DEBUG
66#define NF_CT_ASSERT(x) \ 68#define NF_CT_ASSERT(x) WARN_ON(!(x))
67do { \
68 if (!(x)) \
69 /* Wooah! I'm tripping my conntrack in a frenzy of \
70 netplay... */ \
71 printk("NF_CT_ASSERT: %s:%i(%s)\n", \
72 __FILE__, __LINE__, __FUNCTION__); \
73} while(0)
74#else 69#else
75#define NF_CT_ASSERT(x) 70#define NF_CT_ASSERT(x)
76#endif 71#endif
@@ -145,6 +140,16 @@ nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
145 tuplehash[hash->tuple.dst.dir]); 140 tuplehash[hash->tuple.dst.dir]);
146} 141}
147 142
143static inline u_int16_t nf_ct_l3num(const struct nf_conn *ct)
144{
145 return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
146}
147
148static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
149{
150 return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
151}
152
148/* get master conntrack via master expectation */ 153/* get master conntrack via master expectation */
149#define master_ct(conntr) (conntr->master) 154#define master_ct(conntr) (conntr->master)
150 155
@@ -189,12 +194,11 @@ extern void nf_conntrack_hash_insert(struct nf_conn *ct);
189 194
190extern void nf_conntrack_flush(void); 195extern void nf_conntrack_flush(void);
191 196
192extern int nf_ct_get_tuplepr(const struct sk_buff *skb, 197extern bool nf_ct_get_tuplepr(const struct sk_buff *skb,
193 unsigned int nhoff, 198 unsigned int nhoff, u_int16_t l3num,
194 u_int16_t l3num, 199 struct nf_conntrack_tuple *tuple);
195 struct nf_conntrack_tuple *tuple); 200extern bool nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
196extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 201 const struct nf_conntrack_tuple *orig);
197 const struct nf_conntrack_tuple *orig);
198 202
199extern void __nf_ct_refresh_acct(struct nf_conn *ct, 203extern void __nf_ct_refresh_acct(struct nf_conn *ct,
200 enum ip_conntrack_info ctinfo, 204 enum ip_conntrack_info ctinfo,
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 9ee26469c759..a81771210934 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -30,7 +30,7 @@ extern void nf_conntrack_cleanup(void);
30extern int nf_conntrack_proto_init(void); 30extern int nf_conntrack_proto_init(void);
31extern void nf_conntrack_proto_fini(void); 31extern void nf_conntrack_proto_fini(void);
32 32
33extern int 33extern bool
34nf_ct_get_tuple(const struct sk_buff *skb, 34nf_ct_get_tuple(const struct sk_buff *skb,
35 unsigned int nhoff, 35 unsigned int nhoff,
36 unsigned int dataoff, 36 unsigned int dataoff,
@@ -40,7 +40,7 @@ nf_ct_get_tuple(const struct sk_buff *skb,
40 const struct nf_conntrack_l3proto *l3proto, 40 const struct nf_conntrack_l3proto *l3proto,
41 const struct nf_conntrack_l4proto *l4proto); 41 const struct nf_conntrack_l4proto *l4proto);
42 42
43extern int 43extern bool
44nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, 44nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
45 const struct nf_conntrack_tuple *orig, 45 const struct nf_conntrack_tuple *orig,
46 const struct nf_conntrack_l3proto *l3proto, 46 const struct nf_conntrack_l3proto *l3proto,
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index b886e3ae6cad..0378676c3dd8 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -28,31 +28,20 @@ struct nf_conntrack_l3proto
28 * Try to fill in the third arg: nhoff is offset of l3 proto 28 * Try to fill in the third arg: nhoff is offset of l3 proto
29 * hdr. Return true if possible. 29 * hdr. Return true if possible.
30 */ 30 */
31 int (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int nhoff, 31 bool (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int nhoff,
32 struct nf_conntrack_tuple *tuple); 32 struct nf_conntrack_tuple *tuple);
33 33
34 /* 34 /*
35 * Invert the per-proto part of the tuple: ie. turn xmit into reply. 35 * Invert the per-proto part of the tuple: ie. turn xmit into reply.
36 * Some packets can't be inverted: return 0 in that case. 36 * Some packets can't be inverted: return 0 in that case.
37 */ 37 */
38 int (*invert_tuple)(struct nf_conntrack_tuple *inverse, 38 bool (*invert_tuple)(struct nf_conntrack_tuple *inverse,
39 const struct nf_conntrack_tuple *orig); 39 const struct nf_conntrack_tuple *orig);
40 40
41 /* Print out the per-protocol part of the tuple. */ 41 /* Print out the per-protocol part of the tuple. */
42 int (*print_tuple)(struct seq_file *s, 42 int (*print_tuple)(struct seq_file *s,
43 const struct nf_conntrack_tuple *); 43 const struct nf_conntrack_tuple *);
44 44
45 /* Returns verdict for packet, or -1 for invalid. */
46 int (*packet)(struct nf_conn *ct,
47 const struct sk_buff *skb,
48 enum ip_conntrack_info ctinfo);
49
50 /*
51 * Called when a new connection for this protocol found;
52 * returns TRUE if it's OK. If so, packet() called next.
53 */
54 int (*new)(struct nf_conn *ct, const struct sk_buff *skb);
55
56 /* 45 /*
57 * Called before tracking. 46 * Called before tracking.
58 * *dataoff: offset of protocol header (TCP, UDP,...) in skb 47 * *dataoff: offset of protocol header (TCP, UDP,...) in skb
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index efc16eccddb1..723df9d1cc35 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -25,15 +25,14 @@ struct nf_conntrack_l4proto
25 25
26 /* Try to fill in the third arg: dataoff is offset past network protocol 26 /* Try to fill in the third arg: dataoff is offset past network protocol
27 hdr. Return true if possible. */ 27 hdr. Return true if possible. */
28 int (*pkt_to_tuple)(const struct sk_buff *skb, 28 bool (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int dataoff,
29 unsigned int dataoff, 29 struct nf_conntrack_tuple *tuple);
30 struct nf_conntrack_tuple *tuple);
31 30
32 /* Invert the per-proto part of the tuple: ie. turn xmit into reply. 31 /* Invert the per-proto part of the tuple: ie. turn xmit into reply.
33 * Some packets can't be inverted: return 0 in that case. 32 * Some packets can't be inverted: return 0 in that case.
34 */ 33 */
35 int (*invert_tuple)(struct nf_conntrack_tuple *inverse, 34 bool (*invert_tuple)(struct nf_conntrack_tuple *inverse,
36 const struct nf_conntrack_tuple *orig); 35 const struct nf_conntrack_tuple *orig);
37 36
38 /* Returns verdict for packet, or -1 for invalid. */ 37 /* Returns verdict for packet, or -1 for invalid. */
39 int (*packet)(struct nf_conn *ct, 38 int (*packet)(struct nf_conn *ct,
@@ -45,8 +44,8 @@ struct nf_conntrack_l4proto
45 44
46 /* Called when a new connection for this protocol found; 45 /* Called when a new connection for this protocol found;
47 * returns TRUE if it's OK. If so, packet() called next. */ 46 * returns TRUE if it's OK. If so, packet() called next. */
48 int (*new)(struct nf_conn *ct, const struct sk_buff *skb, 47 bool (*new)(struct nf_conn *ct, const struct sk_buff *skb,
49 unsigned int dataoff); 48 unsigned int dataoff);
50 49
51 /* Called when a conntrack entry is destroyed */ 50 /* Called when a conntrack entry is destroyed */
52 void (*destroy)(struct nf_conn *ct); 51 void (*destroy)(struct nf_conn *ct);
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
index 168c91754d89..1bb7087833d3 100644
--- a/include/net/netfilter/nf_conntrack_tuple.h
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -41,6 +41,9 @@ union nf_conntrack_man_proto
41 } icmp; 41 } icmp;
42 struct { 42 struct {
43 __be16 port; 43 __be16 port;
44 } dccp;
45 struct {
46 __be16 port;
44 } sctp; 47 } sctp;
45 struct { 48 struct {
46 __be16 key; /* GRE key is 32bit, PPtP only uses 16bit */ 49 __be16 key; /* GRE key is 32bit, PPtP only uses 16bit */
@@ -79,6 +82,9 @@ struct nf_conntrack_tuple
79 } icmp; 82 } icmp;
80 struct { 83 struct {
81 __be16 port; 84 __be16 port;
85 } dccp;
86 struct {
87 __be16 port;
82 } sctp; 88 } sctp;
83 struct { 89 struct {
84 __be16 key; 90 __be16 key;
@@ -145,8 +151,6 @@ static inline void nf_ct_dump_tuple(const struct nf_conntrack_tuple *t)
145 } 151 }
146} 152}
147 153
148#define NF_CT_DUMP_TUPLE(tp) nf_ct_dump_tuple(tp)
149
150/* If we're the first tuple, it's the original dir. */ 154/* If we're the first tuple, it's the original dir. */
151#define NF_CT_DIRECTION(h) \ 155#define NF_CT_DIRECTION(h) \
152 ((enum ip_conntrack_dir)(h)->tuple.dst.dir) 156 ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
@@ -160,61 +164,64 @@ struct nf_conntrack_tuple_hash
160 164
161#endif /* __KERNEL__ */ 165#endif /* __KERNEL__ */
162 166
163static inline int __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1, 167static inline bool __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1,
164 const struct nf_conntrack_tuple *t2) 168 const struct nf_conntrack_tuple *t2)
165{ 169{
166 return (nf_inet_addr_cmp(&t1->src.u3, &t2->src.u3) && 170 return (nf_inet_addr_cmp(&t1->src.u3, &t2->src.u3) &&
167 t1->src.u.all == t2->src.u.all && 171 t1->src.u.all == t2->src.u.all &&
168 t1->src.l3num == t2->src.l3num); 172 t1->src.l3num == t2->src.l3num);
169} 173}
170 174
171static inline int __nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1, 175static inline bool __nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1,
172 const struct nf_conntrack_tuple *t2) 176 const struct nf_conntrack_tuple *t2)
173{ 177{
174 return (nf_inet_addr_cmp(&t1->dst.u3, &t2->dst.u3) && 178 return (nf_inet_addr_cmp(&t1->dst.u3, &t2->dst.u3) &&
175 t1->dst.u.all == t2->dst.u.all && 179 t1->dst.u.all == t2->dst.u.all &&
176 t1->dst.protonum == t2->dst.protonum); 180 t1->dst.protonum == t2->dst.protonum);
177} 181}
178 182
179static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1, 183static inline bool nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
180 const struct nf_conntrack_tuple *t2) 184 const struct nf_conntrack_tuple *t2)
181{ 185{
182 return __nf_ct_tuple_src_equal(t1, t2) && 186 return __nf_ct_tuple_src_equal(t1, t2) &&
183 __nf_ct_tuple_dst_equal(t1, t2); 187 __nf_ct_tuple_dst_equal(t1, t2);
184} 188}
185 189
186static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1, 190static inline bool
187 const struct nf_conntrack_tuple_mask *m2) 191nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
192 const struct nf_conntrack_tuple_mask *m2)
188{ 193{
189 return (nf_inet_addr_cmp(&m1->src.u3, &m2->src.u3) && 194 return (nf_inet_addr_cmp(&m1->src.u3, &m2->src.u3) &&
190 m1->src.u.all == m2->src.u.all); 195 m1->src.u.all == m2->src.u.all);
191} 196}
192 197
193static inline int nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1, 198static inline bool
194 const struct nf_conntrack_tuple *t2, 199nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1,
195 const struct nf_conntrack_tuple_mask *mask) 200 const struct nf_conntrack_tuple *t2,
201 const struct nf_conntrack_tuple_mask *mask)
196{ 202{
197 int count; 203 int count;
198 204
199 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) { 205 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) {
200 if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) & 206 if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) &
201 mask->src.u3.all[count]) 207 mask->src.u3.all[count])
202 return 0; 208 return false;
203 } 209 }
204 210
205 if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all) 211 if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all)
206 return 0; 212 return false;
207 213
208 if (t1->src.l3num != t2->src.l3num || 214 if (t1->src.l3num != t2->src.l3num ||
209 t1->dst.protonum != t2->dst.protonum) 215 t1->dst.protonum != t2->dst.protonum)
210 return 0; 216 return false;
211 217
212 return 1; 218 return true;
213} 219}
214 220
215static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t, 221static inline bool
216 const struct nf_conntrack_tuple *tuple, 222nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
217 const struct nf_conntrack_tuple_mask *mask) 223 const struct nf_conntrack_tuple *tuple,
224 const struct nf_conntrack_tuple_mask *mask)
218{ 225{
219 return nf_ct_tuple_src_mask_cmp(t, tuple, mask) && 226 return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
220 __nf_ct_tuple_dst_equal(t, tuple); 227 __nf_ct_tuple_dst_equal(t, tuple);
diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h
index 58dd22687949..237a961f40e1 100644
--- a/include/net/netfilter/nf_nat_helper.h
+++ b/include/net/netfilter/nf_nat_helper.h
@@ -24,6 +24,9 @@ extern int nf_nat_mangle_udp_packet(struct sk_buff *skb,
24extern int nf_nat_seq_adjust(struct sk_buff *skb, 24extern int nf_nat_seq_adjust(struct sk_buff *skb,
25 struct nf_conn *ct, 25 struct nf_conn *ct,
26 enum ip_conntrack_info ctinfo); 26 enum ip_conntrack_info ctinfo);
27extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
28 struct nf_conn *ct,
29 enum ip_conntrack_info ctinfo);
27 30
28/* Setup NAT on this expected conntrack so it follows master, but goes 31/* Setup NAT on this expected conntrack so it follows master, but goes
29 * to port ct->master->saved_proto. */ 32 * to port ct->master->saved_proto. */
diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h
index 4aa0edbb5b96..f3662c4394ef 100644
--- a/include/net/netfilter/nf_nat_protocol.h
+++ b/include/net/netfilter/nf_nat_protocol.h
@@ -8,9 +8,6 @@ struct nf_nat_range;
8 8
9struct nf_nat_protocol 9struct nf_nat_protocol
10{ 10{
11 /* Protocol name */
12 const char *name;
13
14 /* Protocol number. */ 11 /* Protocol number. */
15 unsigned int protonum; 12 unsigned int protonum;
16 13
@@ -18,25 +15,25 @@ struct nf_nat_protocol
18 15
19 /* Translate a packet to the target according to manip type. 16 /* Translate a packet to the target according to manip type.
20 Return true if succeeded. */ 17 Return true if succeeded. */
21 int (*manip_pkt)(struct sk_buff *skb, 18 bool (*manip_pkt)(struct sk_buff *skb,
22 unsigned int iphdroff, 19 unsigned int iphdroff,
23 const struct nf_conntrack_tuple *tuple, 20 const struct nf_conntrack_tuple *tuple,
24 enum nf_nat_manip_type maniptype); 21 enum nf_nat_manip_type maniptype);
25 22
26 /* Is the manipable part of the tuple between min and max incl? */ 23 /* Is the manipable part of the tuple between min and max incl? */
27 int (*in_range)(const struct nf_conntrack_tuple *tuple, 24 bool (*in_range)(const struct nf_conntrack_tuple *tuple,
28 enum nf_nat_manip_type maniptype, 25 enum nf_nat_manip_type maniptype,
29 const union nf_conntrack_man_proto *min, 26 const union nf_conntrack_man_proto *min,
30 const union nf_conntrack_man_proto *max); 27 const union nf_conntrack_man_proto *max);
31 28
32 /* Alter the per-proto part of the tuple (depending on 29 /* Alter the per-proto part of the tuple (depending on
33 maniptype), to give a unique tuple in the given range if 30 maniptype), to give a unique tuple in the given range if
34 possible; return false if not. Per-protocol part of tuple 31 possible; return false if not. Per-protocol part of tuple
35 is initialized to the incoming packet. */ 32 is initialized to the incoming packet. */
36 int (*unique_tuple)(struct nf_conntrack_tuple *tuple, 33 bool (*unique_tuple)(struct nf_conntrack_tuple *tuple,
37 const struct nf_nat_range *range, 34 const struct nf_nat_range *range,
38 enum nf_nat_manip_type maniptype, 35 enum nf_nat_manip_type maniptype,
39 const struct nf_conn *ct); 36 const struct nf_conn *ct);
40 37
41 int (*range_to_nlattr)(struct sk_buff *skb, 38 int (*range_to_nlattr)(struct sk_buff *skb,
42 const struct nf_nat_range *range); 39 const struct nf_nat_range *range);
@@ -62,9 +59,20 @@ extern int init_protocols(void) __init;
62extern void cleanup_protocols(void); 59extern void cleanup_protocols(void);
63extern const struct nf_nat_protocol *find_nat_proto(u_int16_t protonum); 60extern const struct nf_nat_protocol *find_nat_proto(u_int16_t protonum);
64 61
65extern int nf_nat_port_range_to_nlattr(struct sk_buff *skb, 62extern bool nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple,
66 const struct nf_nat_range *range); 63 enum nf_nat_manip_type maniptype,
67extern int nf_nat_port_nlattr_to_range(struct nlattr *tb[], 64 const union nf_conntrack_man_proto *min,
68 struct nf_nat_range *range); 65 const union nf_conntrack_man_proto *max);
66
67extern bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple,
68 const struct nf_nat_range *range,
69 enum nf_nat_manip_type maniptype,
70 const struct nf_conn *ct,
71 u_int16_t *rover);
72
73extern int nf_nat_proto_range_to_nlattr(struct sk_buff *skb,
74 const struct nf_nat_range *range);
75extern int nf_nat_proto_nlattr_to_range(struct nlattr *tb[],
76 struct nf_nat_range *range);
69 77
70#endif /*_NF_NAT_PROTO_H*/ 78#endif /*_NF_NAT_PROTO_H*/
diff --git a/include/net/netfilter/nf_nat_rule.h b/include/net/netfilter/nf_nat_rule.h
index 75d1825031d7..e4a18ae361c6 100644
--- a/include/net/netfilter/nf_nat_rule.h
+++ b/include/net/netfilter/nf_nat_rule.h
@@ -14,7 +14,4 @@ extern int nf_nat_rule_find(struct sk_buff *skb,
14 14
15extern unsigned int 15extern unsigned int
16alloc_null_binding(struct nf_conn *ct, unsigned int hooknum); 16alloc_null_binding(struct nf_conn *ct, unsigned int hooknum);
17
18extern unsigned int
19alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum);
20#endif /* _NF_NAT_RULE_H */ 17#endif /* _NF_NAT_RULE_H */
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 4a3e2bf892c7..7beeefa0f9c0 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -212,4 +212,18 @@ config BRIDGE_EBT_ULOG
212 212
213 To compile it as a module, choose M here. If unsure, say N. 213 To compile it as a module, choose M here. If unsure, say N.
214 214
215config BRIDGE_EBT_NFLOG
216 tristate "ebt: nflog support"
217 depends on BRIDGE_NF_EBTABLES
218 help
219 This option enables the nflog watcher, which allows to LOG
220 messages through the netfilter logging API, which can use
221 either the old LOG target, the old ULOG target or nfnetlink_log
222 as backend.
223
224 This option adds the ulog watcher, that you can use in any rule
225 in any ebtables table.
226
227 To compile it as a module, choose M here. If unsure, say N.
228
215endmenu 229endmenu
diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
index 905087e0d485..83715d73a503 100644
--- a/net/bridge/netfilter/Makefile
+++ b/net/bridge/netfilter/Makefile
@@ -30,3 +30,4 @@ obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o
30# watchers 30# watchers
31obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o 31obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o
32obj-$(CONFIG_BRIDGE_EBT_ULOG) += ebt_ulog.o 32obj-$(CONFIG_BRIDGE_EBT_ULOG) += ebt_ulog.o
33obj-$(CONFIG_BRIDGE_EBT_NFLOG) += ebt_nflog.o
diff --git a/net/bridge/netfilter/ebt_nflog.c b/net/bridge/netfilter/ebt_nflog.c
new file mode 100644
index 000000000000..8e799aa9e560
--- /dev/null
+++ b/net/bridge/netfilter/ebt_nflog.c
@@ -0,0 +1,74 @@
1/*
2 * ebt_nflog
3 *
4 * Author:
5 * Peter Warasin <peter@endian.com>
6 *
7 * February, 2008
8 *
9 * Based on:
10 * xt_NFLOG.c, (C) 2006 by Patrick McHardy <kaber@trash.net>
11 * ebt_ulog.c, (C) 2004 by Bart De Schuymer <bdschuym@pandora.be>
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/spinlock.h>
17#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_nflog.h>
19#include <net/netfilter/nf_log.h>
20
21static void ebt_nflog(const struct sk_buff *skb,
22 unsigned int hooknr,
23 const struct net_device *in,
24 const struct net_device *out,
25 const void *data, unsigned int datalen)
26{
27 struct ebt_nflog_info *info = (struct ebt_nflog_info *)data;
28 struct nf_loginfo li;
29
30 li.type = NF_LOG_TYPE_ULOG;
31 li.u.ulog.copy_len = info->len;
32 li.u.ulog.group = info->group;
33 li.u.ulog.qthreshold = info->threshold;
34
35 nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, "%s", info->prefix);
36}
37
38static int ebt_nflog_check(const char *tablename,
39 unsigned int hookmask,
40 const struct ebt_entry *e,
41 void *data, unsigned int datalen)
42{
43 struct ebt_nflog_info *info = (struct ebt_nflog_info *)data;
44
45 if (datalen != EBT_ALIGN(sizeof(struct ebt_nflog_info)))
46 return -EINVAL;
47 if (info->flags & ~EBT_NFLOG_MASK)
48 return -EINVAL;
49 info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
50 return 0;
51}
52
53static struct ebt_watcher nflog __read_mostly = {
54 .name = EBT_NFLOG_WATCHER,
55 .watcher = ebt_nflog,
56 .check = ebt_nflog_check,
57 .me = THIS_MODULE,
58};
59
60static int __init ebt_nflog_init(void)
61{
62 return ebt_register_watcher(&nflog);
63}
64
65static void __exit ebt_nflog_fini(void)
66{
67 ebt_unregister_watcher(&nflog);
68}
69
70module_init(ebt_nflog_init);
71module_exit(ebt_nflog_fini);
72MODULE_LICENSE("GPL");
73MODULE_AUTHOR("Peter Warasin <peter@endian.com>");
74MODULE_DESCRIPTION("ebtables NFLOG netfilter logging module");
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index be6f18681053..246626bb0c87 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -46,7 +46,7 @@ static struct ebt_table broute_table =
46 .name = "broute", 46 .name = "broute",
47 .table = &initial_table, 47 .table = &initial_table,
48 .valid_hooks = 1 << NF_BR_BROUTING, 48 .valid_hooks = 1 << NF_BR_BROUTING,
49 .lock = RW_LOCK_UNLOCKED, 49 .lock = __RW_LOCK_UNLOCKED(broute_table.lock),
50 .check = check, 50 .check = check,
51 .me = THIS_MODULE, 51 .me = THIS_MODULE,
52}; 52};
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index fb810908732f..690bc3ab186c 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -55,7 +55,7 @@ static struct ebt_table frame_filter =
55 .name = "filter", 55 .name = "filter",
56 .table = &initial_table, 56 .table = &initial_table,
57 .valid_hooks = FILTER_VALID_HOOKS, 57 .valid_hooks = FILTER_VALID_HOOKS,
58 .lock = RW_LOCK_UNLOCKED, 58 .lock = __RW_LOCK_UNLOCKED(frame_filter.lock),
59 .check = check, 59 .check = check,
60 .me = THIS_MODULE, 60 .me = THIS_MODULE,
61}; 61};
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index bc712730c54a..5b495fe2d0b6 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -55,7 +55,7 @@ static struct ebt_table frame_nat =
55 .name = "nat", 55 .name = "nat",
56 .table = &initial_table, 56 .table = &initial_table,
57 .valid_hooks = NAT_VALID_HOOKS, 57 .valid_hooks = NAT_VALID_HOOKS,
58 .lock = RW_LOCK_UNLOCKED, 58 .lock = __RW_LOCK_UNLOCKED(frame_nat.lock),
59 .check = check, 59 .check = check,
60 .me = THIS_MODULE, 60 .me = THIS_MODULE,
61}; 61};
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 9a904c6c0dc8..f8edacdf991d 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -182,21 +182,44 @@ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
182 } 182 }
183 return csum; 183 return csum;
184} 184}
185
186EXPORT_SYMBOL(nf_ip_checksum); 185EXPORT_SYMBOL(nf_ip_checksum);
187 186
187static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
188 unsigned int dataoff, unsigned int len,
189 u_int8_t protocol)
190{
191 const struct iphdr *iph = ip_hdr(skb);
192 __sum16 csum = 0;
193
194 switch (skb->ip_summed) {
195 case CHECKSUM_COMPLETE:
196 if (len == skb->len - dataoff)
197 return nf_ip_checksum(skb, hook, dataoff, protocol);
198 /* fall through */
199 case CHECKSUM_NONE:
200 skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, protocol,
201 skb->len - dataoff, 0);
202 skb->ip_summed = CHECKSUM_NONE;
203 csum = __skb_checksum_complete_head(skb, dataoff + len);
204 if (!csum)
205 skb->ip_summed = CHECKSUM_UNNECESSARY;
206 }
207 return csum;
208}
209
188static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) 210static int nf_ip_route(struct dst_entry **dst, struct flowi *fl)
189{ 211{
190 return ip_route_output_key(&init_net, (struct rtable **)dst, fl); 212 return ip_route_output_key(&init_net, (struct rtable **)dst, fl);
191} 213}
192 214
193static const struct nf_afinfo nf_ip_afinfo = { 215static const struct nf_afinfo nf_ip_afinfo = {
194 .family = AF_INET, 216 .family = AF_INET,
195 .checksum = nf_ip_checksum, 217 .checksum = nf_ip_checksum,
196 .route = nf_ip_route, 218 .checksum_partial = nf_ip_checksum_partial,
197 .saveroute = nf_ip_saveroute, 219 .route = nf_ip_route,
198 .reroute = nf_ip_reroute, 220 .saveroute = nf_ip_saveroute,
199 .route_key_size = sizeof(struct ip_rt_info), 221 .reroute = nf_ip_reroute,
222 .route_key_size = sizeof(struct ip_rt_info),
200}; 223};
201 224
202static int ipv4_netfilter_init(void) 225static int ipv4_netfilter_init(void)
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 9a077cb24798..0c95cd5872f3 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -241,10 +241,25 @@ config NF_NAT_SNMP_BASIC
241# <expr> '&&' <expr> (6) 241# <expr> '&&' <expr> (6)
242# 242#
243# (6) Returns the result of min(/expr/, /expr/). 243# (6) Returns the result of min(/expr/, /expr/).
244config NF_NAT_PROTO_DCCP
245 tristate
246 depends on NF_NAT && NF_CT_PROTO_DCCP
247 default NF_NAT && NF_CT_PROTO_DCCP
248
244config NF_NAT_PROTO_GRE 249config NF_NAT_PROTO_GRE
245 tristate 250 tristate
246 depends on NF_NAT && NF_CT_PROTO_GRE 251 depends on NF_NAT && NF_CT_PROTO_GRE
247 252
253config NF_NAT_PROTO_UDPLITE
254 tristate
255 depends on NF_NAT && NF_CT_PROTO_UDPLITE
256 default NF_NAT && NF_CT_PROTO_UDPLITE
257
258config NF_NAT_PROTO_SCTP
259 tristate
260 default NF_NAT && NF_CT_PROTO_SCTP
261 depends on NF_NAT && NF_CT_PROTO_SCTP
262
248config NF_NAT_FTP 263config NF_NAT_FTP
249 tristate 264 tristate
250 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 265 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 0c7dc78a62e9..d9b92fbf5579 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -10,7 +10,7 @@ nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o
10endif 10endif
11endif 11endif
12 12
13nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o 13nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
14iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o 14iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o
15 15
16# connection tracking 16# connection tracking
@@ -29,7 +29,10 @@ obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
29obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o 29obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
30 30
31# NAT protocols (nf_nat) 31# NAT protocols (nf_nat)
32obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o
32obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o 33obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
34obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o
35obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o
33 36
34# generic IP tables 37# generic IP tables
35obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o 38obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 1563f29b5117..03e83a65aec5 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -59,7 +59,7 @@ do { \
59#endif 59#endif
60 60
61static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, 61static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
62 char *hdr_addr, int len) 62 const char *hdr_addr, int len)
63{ 63{
64 int i, ret; 64 int i, ret;
65 65
@@ -80,8 +80,8 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
80 const char *outdev, 80 const char *outdev,
81 const struct arpt_arp *arpinfo) 81 const struct arpt_arp *arpinfo)
82{ 82{
83 char *arpptr = (char *)(arphdr + 1); 83 const char *arpptr = (char *)(arphdr + 1);
84 char *src_devaddr, *tgt_devaddr; 84 const char *src_devaddr, *tgt_devaddr;
85 __be32 src_ipaddr, tgt_ipaddr; 85 __be32 src_ipaddr, tgt_ipaddr;
86 int i, ret; 86 int i, ret;
87 87
@@ -222,16 +222,16 @@ unsigned int arpt_do_table(struct sk_buff *skb,
222 unsigned int hook, 222 unsigned int hook,
223 const struct net_device *in, 223 const struct net_device *in,
224 const struct net_device *out, 224 const struct net_device *out,
225 struct arpt_table *table) 225 struct xt_table *table)
226{ 226{
227 static const char nulldevname[IFNAMSIZ]; 227 static const char nulldevname[IFNAMSIZ];
228 unsigned int verdict = NF_DROP; 228 unsigned int verdict = NF_DROP;
229 struct arphdr *arp; 229 const struct arphdr *arp;
230 bool hotdrop = false; 230 bool hotdrop = false;
231 struct arpt_entry *e, *back; 231 struct arpt_entry *e, *back;
232 const char *indev, *outdev; 232 const char *indev, *outdev;
233 void *table_base; 233 void *table_base;
234 struct xt_table_info *private; 234 const struct xt_table_info *private;
235 235
236 if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) 236 if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
237 return NF_DROP; 237 return NF_DROP;
@@ -352,7 +352,7 @@ static int mark_source_chains(struct xt_table_info *newinfo,
352 e->counters.pcnt = pos; 352 e->counters.pcnt = pos;
353 353
354 for (;;) { 354 for (;;) {
355 struct arpt_standard_target *t 355 const struct arpt_standard_target *t
356 = (void *)arpt_get_target(e); 356 = (void *)arpt_get_target(e);
357 int visited = e->comefrom & (1 << hook); 357 int visited = e->comefrom & (1 << hook);
358 358
@@ -437,7 +437,7 @@ static int mark_source_chains(struct xt_table_info *newinfo,
437 437
438static inline int check_entry(struct arpt_entry *e, const char *name) 438static inline int check_entry(struct arpt_entry *e, const char *name)
439{ 439{
440 struct arpt_entry_target *t; 440 const struct arpt_entry_target *t;
441 441
442 if (!arp_checkentry(&e->arp)) { 442 if (!arp_checkentry(&e->arp)) {
443 duprintf("arp_tables: arp check failed %p %s.\n", e, name); 443 duprintf("arp_tables: arp check failed %p %s.\n", e, name);
@@ -457,7 +457,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name)
457static inline int check_target(struct arpt_entry *e, const char *name) 457static inline int check_target(struct arpt_entry *e, const char *name)
458{ 458{
459 struct arpt_entry_target *t; 459 struct arpt_entry_target *t;
460 struct arpt_target *target; 460 struct xt_target *target;
461 int ret; 461 int ret;
462 462
463 t = arpt_get_target(e); 463 t = arpt_get_target(e);
@@ -480,7 +480,7 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
480 unsigned int *i) 480 unsigned int *i)
481{ 481{
482 struct arpt_entry_target *t; 482 struct arpt_entry_target *t;
483 struct arpt_target *target; 483 struct xt_target *target;
484 int ret; 484 int ret;
485 485
486 ret = check_entry(e, name); 486 ret = check_entry(e, name);
@@ -706,11 +706,11 @@ static void get_counters(const struct xt_table_info *t,
706 } 706 }
707} 707}
708 708
709static inline struct xt_counters *alloc_counters(struct arpt_table *table) 709static inline struct xt_counters *alloc_counters(struct xt_table *table)
710{ 710{
711 unsigned int countersize; 711 unsigned int countersize;
712 struct xt_counters *counters; 712 struct xt_counters *counters;
713 struct xt_table_info *private = table->private; 713 const struct xt_table_info *private = table->private;
714 714
715 /* We need atomic snapshot of counters: rest doesn't change 715 /* We need atomic snapshot of counters: rest doesn't change
716 * (other than comefrom, which userspace doesn't care 716 * (other than comefrom, which userspace doesn't care
@@ -731,7 +731,7 @@ static inline struct xt_counters *alloc_counters(struct arpt_table *table)
731} 731}
732 732
733static int copy_entries_to_user(unsigned int total_size, 733static int copy_entries_to_user(unsigned int total_size,
734 struct arpt_table *table, 734 struct xt_table *table,
735 void __user *userptr) 735 void __user *userptr)
736{ 736{
737 unsigned int off, num; 737 unsigned int off, num;
@@ -851,7 +851,7 @@ static int compat_table_info(const struct xt_table_info *info,
851static int get_info(struct net *net, void __user *user, int *len, int compat) 851static int get_info(struct net *net, void __user *user, int *len, int compat)
852{ 852{
853 char name[ARPT_TABLE_MAXNAMELEN]; 853 char name[ARPT_TABLE_MAXNAMELEN];
854 struct arpt_table *t; 854 struct xt_table *t;
855 int ret; 855 int ret;
856 856
857 if (*len != sizeof(struct arpt_getinfo)) { 857 if (*len != sizeof(struct arpt_getinfo)) {
@@ -872,7 +872,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
872 "arptable_%s", name); 872 "arptable_%s", name);
873 if (t && !IS_ERR(t)) { 873 if (t && !IS_ERR(t)) {
874 struct arpt_getinfo info; 874 struct arpt_getinfo info;
875 struct xt_table_info *private = t->private; 875 const struct xt_table_info *private = t->private;
876 876
877#ifdef CONFIG_COMPAT 877#ifdef CONFIG_COMPAT
878 if (compat) { 878 if (compat) {
@@ -911,7 +911,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
911{ 911{
912 int ret; 912 int ret;
913 struct arpt_get_entries get; 913 struct arpt_get_entries get;
914 struct arpt_table *t; 914 struct xt_table *t;
915 915
916 if (*len < sizeof(get)) { 916 if (*len < sizeof(get)) {
917 duprintf("get_entries: %u < %Zu\n", *len, sizeof(get)); 917 duprintf("get_entries: %u < %Zu\n", *len, sizeof(get));
@@ -927,7 +927,8 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
927 927
928 t = xt_find_table_lock(net, NF_ARP, get.name); 928 t = xt_find_table_lock(net, NF_ARP, get.name);
929 if (t && !IS_ERR(t)) { 929 if (t && !IS_ERR(t)) {
930 struct xt_table_info *private = t->private; 930 const struct xt_table_info *private = t->private;
931
931 duprintf("t->private->number = %u\n", 932 duprintf("t->private->number = %u\n",
932 private->number); 933 private->number);
933 if (get.size == private->size) 934 if (get.size == private->size)
@@ -936,7 +937,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
936 else { 937 else {
937 duprintf("get_entries: I've got %u not %u!\n", 938 duprintf("get_entries: I've got %u not %u!\n",
938 private->size, get.size); 939 private->size, get.size);
939 ret = -EINVAL; 940 ret = -EAGAIN;
940 } 941 }
941 module_put(t->me); 942 module_put(t->me);
942 xt_table_unlock(t); 943 xt_table_unlock(t);
@@ -953,7 +954,7 @@ static int __do_replace(struct net *net, const char *name,
953 void __user *counters_ptr) 954 void __user *counters_ptr)
954{ 955{
955 int ret; 956 int ret;
956 struct arpt_table *t; 957 struct xt_table *t;
957 struct xt_table_info *oldinfo; 958 struct xt_table_info *oldinfo;
958 struct xt_counters *counters; 959 struct xt_counters *counters;
959 void *loc_cpu_old_entry; 960 void *loc_cpu_old_entry;
@@ -1087,11 +1088,11 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len,
1087 struct xt_counters_info tmp; 1088 struct xt_counters_info tmp;
1088 struct xt_counters *paddc; 1089 struct xt_counters *paddc;
1089 unsigned int num_counters; 1090 unsigned int num_counters;
1090 char *name; 1091 const char *name;
1091 int size; 1092 int size;
1092 void *ptmp; 1093 void *ptmp;
1093 struct arpt_table *t; 1094 struct xt_table *t;
1094 struct xt_table_info *private; 1095 const struct xt_table_info *private;
1095 int ret = 0; 1096 int ret = 0;
1096 void *loc_cpu_entry; 1097 void *loc_cpu_entry;
1097#ifdef CONFIG_COMPAT 1098#ifdef CONFIG_COMPAT
@@ -1554,11 +1555,11 @@ out:
1554} 1555}
1555 1556
1556static int compat_copy_entries_to_user(unsigned int total_size, 1557static int compat_copy_entries_to_user(unsigned int total_size,
1557 struct arpt_table *table, 1558 struct xt_table *table,
1558 void __user *userptr) 1559 void __user *userptr)
1559{ 1560{
1560 struct xt_counters *counters; 1561 struct xt_counters *counters;
1561 struct xt_table_info *private = table->private; 1562 const struct xt_table_info *private = table->private;
1562 void __user *pos; 1563 void __user *pos;
1563 unsigned int size; 1564 unsigned int size;
1564 int ret = 0; 1565 int ret = 0;
@@ -1592,7 +1593,7 @@ static int compat_get_entries(struct net *net,
1592{ 1593{
1593 int ret; 1594 int ret;
1594 struct compat_arpt_get_entries get; 1595 struct compat_arpt_get_entries get;
1595 struct arpt_table *t; 1596 struct xt_table *t;
1596 1597
1597 if (*len < sizeof(get)) { 1598 if (*len < sizeof(get)) {
1598 duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get)); 1599 duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
@@ -1609,7 +1610,7 @@ static int compat_get_entries(struct net *net,
1609 xt_compat_lock(NF_ARP); 1610 xt_compat_lock(NF_ARP);
1610 t = xt_find_table_lock(net, NF_ARP, get.name); 1611 t = xt_find_table_lock(net, NF_ARP, get.name);
1611 if (t && !IS_ERR(t)) { 1612 if (t && !IS_ERR(t)) {
1612 struct xt_table_info *private = t->private; 1613 const struct xt_table_info *private = t->private;
1613 struct xt_table_info info; 1614 struct xt_table_info info;
1614 1615
1615 duprintf("t->private->number = %u\n", private->number); 1616 duprintf("t->private->number = %u\n", private->number);
@@ -1620,7 +1621,7 @@ static int compat_get_entries(struct net *net,
1620 } else if (!ret) { 1621 } else if (!ret) {
1621 duprintf("compat_get_entries: I've got %u not %u!\n", 1622 duprintf("compat_get_entries: I've got %u not %u!\n",
1622 private->size, get.size); 1623 private->size, get.size);
1623 ret = -EINVAL; 1624 ret = -EAGAIN;
1624 } 1625 }
1625 xt_compat_flush_offsets(NF_ARP); 1626 xt_compat_flush_offsets(NF_ARP);
1626 module_put(t->me); 1627 module_put(t->me);
@@ -1722,9 +1723,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
1722 return ret; 1723 return ret;
1723} 1724}
1724 1725
1725struct arpt_table *arpt_register_table(struct net *net, 1726struct xt_table *arpt_register_table(struct net *net, struct xt_table *table,
1726 struct arpt_table *table, 1727 const struct arpt_replace *repl)
1727 const struct arpt_replace *repl)
1728{ 1728{
1729 int ret; 1729 int ret;
1730 struct xt_table_info *newinfo; 1730 struct xt_table_info *newinfo;
@@ -1766,7 +1766,7 @@ out:
1766 return ERR_PTR(ret); 1766 return ERR_PTR(ret);
1767} 1767}
1768 1768
1769void arpt_unregister_table(struct arpt_table *table) 1769void arpt_unregister_table(struct xt_table *table)
1770{ 1770{
1771 struct xt_table_info *private; 1771 struct xt_table_info *private;
1772 void *loc_cpu_entry; 1772 void *loc_cpu_entry;
@@ -1784,7 +1784,7 @@ void arpt_unregister_table(struct arpt_table *table)
1784} 1784}
1785 1785
1786/* The built-in targets: standard (NULL) and error. */ 1786/* The built-in targets: standard (NULL) and error. */
1787static struct arpt_target arpt_standard_target __read_mostly = { 1787static struct xt_target arpt_standard_target __read_mostly = {
1788 .name = ARPT_STANDARD_TARGET, 1788 .name = ARPT_STANDARD_TARGET,
1789 .targetsize = sizeof(int), 1789 .targetsize = sizeof(int),
1790 .family = NF_ARP, 1790 .family = NF_ARP,
@@ -1795,7 +1795,7 @@ static struct arpt_target arpt_standard_target __read_mostly = {
1795#endif 1795#endif
1796}; 1796};
1797 1797
1798static struct arpt_target arpt_error_target __read_mostly = { 1798static struct xt_target arpt_error_target __read_mostly = {
1799 .name = ARPT_ERROR_TARGET, 1799 .name = ARPT_ERROR_TARGET,
1800 .target = arpt_error, 1800 .target = arpt_error,
1801 .targetsize = ARPT_FUNCTION_MAXNAMELEN, 1801 .targetsize = ARPT_FUNCTION_MAXNAMELEN,
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index 3f4222b0a803..a385959d2655 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -15,7 +15,7 @@ target(struct sk_buff *skb,
15 const void *targinfo) 15 const void *targinfo)
16{ 16{
17 const struct arpt_mangle *mangle = targinfo; 17 const struct arpt_mangle *mangle = targinfo;
18 struct arphdr *arp; 18 const struct arphdr *arp;
19 unsigned char *arpptr; 19 unsigned char *arpptr;
20 int pln, hln; 20 int pln, hln;
21 21
@@ -73,8 +73,9 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target,
73 return true; 73 return true;
74} 74}
75 75
76static struct arpt_target arpt_mangle_reg __read_mostly = { 76static struct xt_target arpt_mangle_reg __read_mostly = {
77 .name = "mangle", 77 .name = "mangle",
78 .family = NF_ARP,
78 .target = target, 79 .target = target,
79 .targetsize = sizeof(struct arpt_mangle), 80 .targetsize = sizeof(struct arpt_mangle),
80 .checkentry = checkentry, 81 .checkentry = checkentry,
@@ -83,15 +84,12 @@ static struct arpt_target arpt_mangle_reg __read_mostly = {
83 84
84static int __init arpt_mangle_init(void) 85static int __init arpt_mangle_init(void)
85{ 86{
86 if (arpt_register_target(&arpt_mangle_reg)) 87 return xt_register_target(&arpt_mangle_reg);
87 return -EINVAL;
88
89 return 0;
90} 88}
91 89
92static void __exit arpt_mangle_fini(void) 90static void __exit arpt_mangle_fini(void)
93{ 91{
94 arpt_unregister_target(&arpt_mangle_reg); 92 xt_unregister_target(&arpt_mangle_reg);
95} 93}
96 94
97module_init(arpt_mangle_init); 95module_init(arpt_mangle_init);
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 4e9c496a30c2..3be4d07e7ed9 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -45,10 +45,10 @@ static struct
45 .term = ARPT_ERROR_INIT, 45 .term = ARPT_ERROR_INIT,
46}; 46};
47 47
48static struct arpt_table packet_filter = { 48static struct xt_table packet_filter = {
49 .name = "filter", 49 .name = "filter",
50 .valid_hooks = FILTER_VALID_HOOKS, 50 .valid_hooks = FILTER_VALID_HOOKS,
51 .lock = RW_LOCK_UNLOCKED, 51 .lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
52 .private = NULL, 52 .private = NULL,
53 .me = THIS_MODULE, 53 .me = THIS_MODULE,
54 .af = NF_ARP, 54 .af = NF_ARP,
@@ -70,18 +70,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
70 .owner = THIS_MODULE, 70 .owner = THIS_MODULE,
71 .pf = NF_ARP, 71 .pf = NF_ARP,
72 .hooknum = NF_ARP_IN, 72 .hooknum = NF_ARP_IN,
73 .priority = NF_IP_PRI_FILTER,
73 }, 74 },
74 { 75 {
75 .hook = arpt_hook, 76 .hook = arpt_hook,
76 .owner = THIS_MODULE, 77 .owner = THIS_MODULE,
77 .pf = NF_ARP, 78 .pf = NF_ARP,
78 .hooknum = NF_ARP_OUT, 79 .hooknum = NF_ARP_OUT,
80 .priority = NF_IP_PRI_FILTER,
79 }, 81 },
80 { 82 {
81 .hook = arpt_hook, 83 .hook = arpt_hook,
82 .owner = THIS_MODULE, 84 .owner = THIS_MODULE,
83 .pf = NF_ARP, 85 .pf = NF_ARP,
84 .hooknum = NF_ARP_FORWARD, 86 .hooknum = NF_ARP_FORWARD,
87 .priority = NF_IP_PRI_FILTER,
85 }, 88 },
86}; 89};
87 90
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index a819d191e1aa..4e7c719445c2 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -296,7 +296,7 @@ static void trace_packet(struct sk_buff *skb,
296 struct ipt_entry *e) 296 struct ipt_entry *e)
297{ 297{
298 void *table_base; 298 void *table_base;
299 struct ipt_entry *root; 299 const struct ipt_entry *root;
300 char *hookname, *chainname, *comment; 300 char *hookname, *chainname, *comment;
301 unsigned int rulenum = 0; 301 unsigned int rulenum = 0;
302 302
@@ -327,7 +327,7 @@ ipt_do_table(struct sk_buff *skb,
327{ 327{
328 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 328 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
329 u_int16_t offset; 329 u_int16_t offset;
330 struct iphdr *ip; 330 const struct iphdr *ip;
331 u_int16_t datalen; 331 u_int16_t datalen;
332 bool hotdrop = false; 332 bool hotdrop = false;
333 /* Initializing verdict to NF_DROP keeps gcc happy. */ 333 /* Initializing verdict to NF_DROP keeps gcc happy. */
@@ -926,7 +926,7 @@ static struct xt_counters * alloc_counters(struct xt_table *table)
926{ 926{
927 unsigned int countersize; 927 unsigned int countersize;
928 struct xt_counters *counters; 928 struct xt_counters *counters;
929 struct xt_table_info *private = table->private; 929 const struct xt_table_info *private = table->private;
930 930
931 /* We need atomic snapshot of counters: rest doesn't change 931 /* We need atomic snapshot of counters: rest doesn't change
932 (other than comefrom, which userspace doesn't care 932 (other than comefrom, which userspace doesn't care
@@ -953,9 +953,9 @@ copy_entries_to_user(unsigned int total_size,
953 unsigned int off, num; 953 unsigned int off, num;
954 struct ipt_entry *e; 954 struct ipt_entry *e;
955 struct xt_counters *counters; 955 struct xt_counters *counters;
956 struct xt_table_info *private = table->private; 956 const struct xt_table_info *private = table->private;
957 int ret = 0; 957 int ret = 0;
958 void *loc_cpu_entry; 958 const void *loc_cpu_entry;
959 959
960 counters = alloc_counters(table); 960 counters = alloc_counters(table);
961 if (IS_ERR(counters)) 961 if (IS_ERR(counters))
@@ -975,8 +975,8 @@ copy_entries_to_user(unsigned int total_size,
975 /* ... then go back and fix counters and names */ 975 /* ... then go back and fix counters and names */
976 for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ 976 for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
977 unsigned int i; 977 unsigned int i;
978 struct ipt_entry_match *m; 978 const struct ipt_entry_match *m;
979 struct ipt_entry_target *t; 979 const struct ipt_entry_target *t;
980 980
981 e = (struct ipt_entry *)(loc_cpu_entry + off); 981 e = (struct ipt_entry *)(loc_cpu_entry + off);
982 if (copy_to_user(userptr + off 982 if (copy_to_user(userptr + off
@@ -1116,7 +1116,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
1116 "iptable_%s", name); 1116 "iptable_%s", name);
1117 if (t && !IS_ERR(t)) { 1117 if (t && !IS_ERR(t)) {
1118 struct ipt_getinfo info; 1118 struct ipt_getinfo info;
1119 struct xt_table_info *private = t->private; 1119 const struct xt_table_info *private = t->private;
1120 1120
1121#ifdef CONFIG_COMPAT 1121#ifdef CONFIG_COMPAT
1122 if (compat) { 1122 if (compat) {
@@ -1172,7 +1172,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
1172 1172
1173 t = xt_find_table_lock(net, AF_INET, get.name); 1173 t = xt_find_table_lock(net, AF_INET, get.name);
1174 if (t && !IS_ERR(t)) { 1174 if (t && !IS_ERR(t)) {
1175 struct xt_table_info *private = t->private; 1175 const struct xt_table_info *private = t->private;
1176 duprintf("t->private->number = %u\n", private->number); 1176 duprintf("t->private->number = %u\n", private->number);
1177 if (get.size == private->size) 1177 if (get.size == private->size)
1178 ret = copy_entries_to_user(private->size, 1178 ret = copy_entries_to_user(private->size,
@@ -1180,7 +1180,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
1180 else { 1180 else {
1181 duprintf("get_entries: I've got %u not %u!\n", 1181 duprintf("get_entries: I've got %u not %u!\n",
1182 private->size, get.size); 1182 private->size, get.size);
1183 ret = -EINVAL; 1183 ret = -EAGAIN;
1184 } 1184 }
1185 module_put(t->me); 1185 module_put(t->me);
1186 xt_table_unlock(t); 1186 xt_table_unlock(t);
@@ -1337,11 +1337,11 @@ do_add_counters(struct net *net, void __user *user, unsigned int len, int compat
1337 struct xt_counters_info tmp; 1337 struct xt_counters_info tmp;
1338 struct xt_counters *paddc; 1338 struct xt_counters *paddc;
1339 unsigned int num_counters; 1339 unsigned int num_counters;
1340 char *name; 1340 const char *name;
1341 int size; 1341 int size;
1342 void *ptmp; 1342 void *ptmp;
1343 struct xt_table *t; 1343 struct xt_table *t;
1344 struct xt_table_info *private; 1344 const struct xt_table_info *private;
1345 int ret = 0; 1345 int ret = 0;
1346 void *loc_cpu_entry; 1346 void *loc_cpu_entry;
1347#ifdef CONFIG_COMPAT 1347#ifdef CONFIG_COMPAT
@@ -1878,11 +1878,11 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
1878 void __user *userptr) 1878 void __user *userptr)
1879{ 1879{
1880 struct xt_counters *counters; 1880 struct xt_counters *counters;
1881 struct xt_table_info *private = table->private; 1881 const struct xt_table_info *private = table->private;
1882 void __user *pos; 1882 void __user *pos;
1883 unsigned int size; 1883 unsigned int size;
1884 int ret = 0; 1884 int ret = 0;
1885 void *loc_cpu_entry; 1885 const void *loc_cpu_entry;
1886 unsigned int i = 0; 1886 unsigned int i = 0;
1887 1887
1888 counters = alloc_counters(table); 1888 counters = alloc_counters(table);
@@ -1929,7 +1929,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
1929 xt_compat_lock(AF_INET); 1929 xt_compat_lock(AF_INET);
1930 t = xt_find_table_lock(net, AF_INET, get.name); 1930 t = xt_find_table_lock(net, AF_INET, get.name);
1931 if (t && !IS_ERR(t)) { 1931 if (t && !IS_ERR(t)) {
1932 struct xt_table_info *private = t->private; 1932 const struct xt_table_info *private = t->private;
1933 struct xt_table_info info; 1933 struct xt_table_info info;
1934 duprintf("t->private->number = %u\n", private->number); 1934 duprintf("t->private->number = %u\n", private->number);
1935 ret = compat_table_info(private, &info); 1935 ret = compat_table_info(private, &info);
@@ -1939,7 +1939,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
1939 } else if (!ret) { 1939 } else if (!ret) {
1940 duprintf("compat_get_entries: I've got %u not %u!\n", 1940 duprintf("compat_get_entries: I've got %u not %u!\n",
1941 private->size, get.size); 1941 private->size, get.size);
1942 ret = -EINVAL; 1942 ret = -EAGAIN;
1943 } 1943 }
1944 xt_compat_flush_offsets(AF_INET); 1944 xt_compat_flush_offsets(AF_INET);
1945 module_put(t->me); 1945 module_put(t->me);
@@ -2130,7 +2130,8 @@ icmp_match(const struct sk_buff *skb,
2130 unsigned int protoff, 2130 unsigned int protoff,
2131 bool *hotdrop) 2131 bool *hotdrop)
2132{ 2132{
2133 struct icmphdr _icmph, *ic; 2133 const struct icmphdr *ic;
2134 struct icmphdr _icmph;
2134 const struct ipt_icmp *icmpinfo = matchinfo; 2135 const struct ipt_icmp *icmpinfo = matchinfo;
2135 2136
2136 /* Must not be a fragment. */ 2137 /* Must not be a fragment. */
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 380d8daac72b..22d8e7cd9197 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -144,7 +144,7 @@ clusterip_config_init_nodelist(struct clusterip_config *c,
144} 144}
145 145
146static struct clusterip_config * 146static struct clusterip_config *
147clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip, 147clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
148 struct net_device *dev) 148 struct net_device *dev)
149{ 149{
150 struct clusterip_config *c; 150 struct clusterip_config *c;
@@ -333,7 +333,7 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in,
333 } 333 }
334 334
335#ifdef DEBUG 335#ifdef DEBUG
336 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 336 nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
337#endif 337#endif
338 pr_debug("hash=%u ct_hash=%u ", hash, ct->mark); 338 pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
339 if (!clusterip_responsible(cipinfo->config, hash)) { 339 if (!clusterip_responsible(cipinfo->config, hash)) {
@@ -418,7 +418,7 @@ clusterip_tg_check(const char *tablename, const void *e_void,
418/* drop reference count of cluster config when rule is deleted */ 418/* drop reference count of cluster config when rule is deleted */
419static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) 419static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
420{ 420{
421 struct ipt_clusterip_tgt_info *cipinfo = targinfo; 421 const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
422 422
423 /* if no more entries are referencing the config, remove it 423 /* if no more entries are referencing the config, remove it
424 * from the list and destroy the proc entry */ 424 * from the list and destroy the proc entry */
@@ -567,7 +567,7 @@ struct clusterip_seq_position {
567 567
568static void *clusterip_seq_start(struct seq_file *s, loff_t *pos) 568static void *clusterip_seq_start(struct seq_file *s, loff_t *pos)
569{ 569{
570 struct proc_dir_entry *pde = s->private; 570 const struct proc_dir_entry *pde = s->private;
571 struct clusterip_config *c = pde->data; 571 struct clusterip_config *c = pde->data;
572 unsigned int weight; 572 unsigned int weight;
573 u_int32_t local_nodes; 573 u_int32_t local_nodes;
@@ -594,7 +594,7 @@ static void *clusterip_seq_start(struct seq_file *s, loff_t *pos)
594 594
595static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos) 595static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos)
596{ 596{
597 struct clusterip_seq_position *idx = (struct clusterip_seq_position *)v; 597 struct clusterip_seq_position *idx = v;
598 598
599 *pos = ++idx->pos; 599 *pos = ++idx->pos;
600 if (*pos >= idx->weight) { 600 if (*pos >= idx->weight) {
@@ -613,7 +613,7 @@ static void clusterip_seq_stop(struct seq_file *s, void *v)
613 613
614static int clusterip_seq_show(struct seq_file *s, void *v) 614static int clusterip_seq_show(struct seq_file *s, void *v)
615{ 615{
616 struct clusterip_seq_position *idx = (struct clusterip_seq_position *)v; 616 struct clusterip_seq_position *idx = v;
617 617
618 if (idx->pos != 0) 618 if (idx->pos != 0)
619 seq_putc(s, ','); 619 seq_putc(s, ',');
@@ -669,7 +669,7 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input,
669{ 669{
670#define PROC_WRITELEN 10 670#define PROC_WRITELEN 10
671 char buffer[PROC_WRITELEN+1]; 671 char buffer[PROC_WRITELEN+1];
672 struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); 672 const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
673 struct clusterip_config *c = pde->data; 673 struct clusterip_config *c = pde->data;
674 unsigned long nodenum; 674 unsigned long nodenum;
675 675
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index 21395bc2b27f..d60139c134ca 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -100,7 +100,7 @@ ecn_tg_check(const char *tablename, const void *e_void,
100 const struct xt_target *target, void *targinfo, 100 const struct xt_target *target, void *targinfo,
101 unsigned int hook_mask) 101 unsigned int hook_mask)
102{ 102{
103 const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; 103 const struct ipt_ECN_info *einfo = targinfo;
104 const struct ipt_entry *e = e_void; 104 const struct ipt_entry *e = e_void;
105 105
106 if (einfo->operation & IPT_ECN_OP_MASK) { 106 if (einfo->operation & IPT_ECN_OP_MASK) {
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index b38d7850f506..0af14137137b 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -76,7 +76,8 @@ static void dump_packet(const struct nf_loginfo *info,
76 76
77 if ((logflags & IPT_LOG_IPOPT) 77 if ((logflags & IPT_LOG_IPOPT)
78 && ih->ihl * 4 > sizeof(struct iphdr)) { 78 && ih->ihl * 4 > sizeof(struct iphdr)) {
79 unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op; 79 const unsigned char *op;
80 unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
80 unsigned int i, optsize; 81 unsigned int i, optsize;
81 82
82 optsize = ih->ihl * 4 - sizeof(struct iphdr); 83 optsize = ih->ihl * 4 - sizeof(struct iphdr);
@@ -338,12 +339,16 @@ static void dump_packet(const struct nf_loginfo *info,
338 if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { 339 if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
339 read_lock_bh(&skb->sk->sk_callback_lock); 340 read_lock_bh(&skb->sk->sk_callback_lock);
340 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 341 if (skb->sk->sk_socket && skb->sk->sk_socket->file)
341 printk("UID=%u GID=%u", 342 printk("UID=%u GID=%u ",
342 skb->sk->sk_socket->file->f_uid, 343 skb->sk->sk_socket->file->f_uid,
343 skb->sk->sk_socket->file->f_gid); 344 skb->sk->sk_socket->file->f_gid);
344 read_unlock_bh(&skb->sk->sk_callback_lock); 345 read_unlock_bh(&skb->sk->sk_callback_lock);
345 } 346 }
346 347
348 /* Max length: 16 "MARK=0xFFFFFFFF " */
349 if (!iphoff && skb->mark)
350 printk("MARK=0x%x ", skb->mark);
351
347 /* Proto Max log string length */ 352 /* Proto Max log string length */
348 /* IP: 40+46+6+11+127 = 230 */ 353 /* IP: 40+46+6+11+127 = 230 */
349 /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */ 354 /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 22606e2baa16..2639872849da 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -35,8 +35,10 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv4");
35static void send_reset(struct sk_buff *oldskb, int hook) 35static void send_reset(struct sk_buff *oldskb, int hook)
36{ 36{
37 struct sk_buff *nskb; 37 struct sk_buff *nskb;
38 struct iphdr *oiph, *niph; 38 const struct iphdr *oiph;
39 struct tcphdr _otcph, *oth, *tcph; 39 struct iphdr *niph;
40 const struct tcphdr *oth;
41 struct tcphdr _otcph, *tcph;
40 unsigned int addr_type; 42 unsigned int addr_type;
41 43
42 /* IP header checks: fragment. */ 44 /* IP header checks: fragment. */
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 50e06690eb5b..21cb053f5d7d 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -340,7 +340,7 @@ static void *recent_seq_start(struct seq_file *seq, loff_t *pos)
340static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos) 340static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos)
341{ 341{
342 struct recent_iter_state *st = seq->private; 342 struct recent_iter_state *st = seq->private;
343 struct recent_table *t = st->table; 343 const struct recent_table *t = st->table;
344 struct recent_entry *e = v; 344 struct recent_entry *e = v;
345 struct list_head *head = e->list.next; 345 struct list_head *head = e->list.next;
346 346
@@ -361,7 +361,7 @@ static void recent_seq_stop(struct seq_file *s, void *v)
361 361
362static int recent_seq_show(struct seq_file *seq, void *v) 362static int recent_seq_show(struct seq_file *seq, void *v)
363{ 363{
364 struct recent_entry *e = v; 364 const struct recent_entry *e = v;
365 unsigned int i; 365 unsigned int i;
366 366
367 i = (e->index - 1) % ip_pkt_list_tot; 367 i = (e->index - 1) % ip_pkt_list_tot;
@@ -396,7 +396,7 @@ static int recent_seq_open(struct inode *inode, struct file *file)
396static ssize_t recent_proc_write(struct file *file, const char __user *input, 396static ssize_t recent_proc_write(struct file *file, const char __user *input,
397 size_t size, loff_t *loff) 397 size_t size, loff_t *loff)
398{ 398{
399 struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); 399 const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
400 struct recent_table *t = pde->data; 400 struct recent_table *t = pde->data;
401 struct recent_entry *e; 401 struct recent_entry *e;
402 char buf[sizeof("+255.255.255.255")], *c = buf; 402 char buf[sizeof("+255.255.255.255")], *c = buf;
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 69f3d7e6e96f..1ea677dcf845 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -56,20 +56,32 @@ static struct
56static struct xt_table packet_filter = { 56static struct xt_table packet_filter = {
57 .name = "filter", 57 .name = "filter",
58 .valid_hooks = FILTER_VALID_HOOKS, 58 .valid_hooks = FILTER_VALID_HOOKS,
59 .lock = RW_LOCK_UNLOCKED, 59 .lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
60 .me = THIS_MODULE, 60 .me = THIS_MODULE,
61 .af = AF_INET, 61 .af = AF_INET,
62}; 62};
63 63
64/* The work comes in here from netfilter.c. */ 64/* The work comes in here from netfilter.c. */
65static unsigned int 65static unsigned int
66ipt_local_in_hook(unsigned int hook,
67 struct sk_buff *skb,
68 const struct net_device *in,
69 const struct net_device *out,
70 int (*okfn)(struct sk_buff *))
71{
72 return ipt_do_table(skb, hook, in, out,
73 nf_local_in_net(in, out)->ipv4.iptable_filter);
74}
75
76static unsigned int
66ipt_hook(unsigned int hook, 77ipt_hook(unsigned int hook,
67 struct sk_buff *skb, 78 struct sk_buff *skb,
68 const struct net_device *in, 79 const struct net_device *in,
69 const struct net_device *out, 80 const struct net_device *out,
70 int (*okfn)(struct sk_buff *)) 81 int (*okfn)(struct sk_buff *))
71{ 82{
72 return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter); 83 return ipt_do_table(skb, hook, in, out,
84 nf_forward_net(in, out)->ipv4.iptable_filter);
73} 85}
74 86
75static unsigned int 87static unsigned int
@@ -88,12 +100,13 @@ ipt_local_out_hook(unsigned int hook,
88 return NF_ACCEPT; 100 return NF_ACCEPT;
89 } 101 }
90 102
91 return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter); 103 return ipt_do_table(skb, hook, in, out,
104 nf_local_out_net(in, out)->ipv4.iptable_filter);
92} 105}
93 106
94static struct nf_hook_ops ipt_ops[] __read_mostly = { 107static struct nf_hook_ops ipt_ops[] __read_mostly = {
95 { 108 {
96 .hook = ipt_hook, 109 .hook = ipt_local_in_hook,
97 .owner = THIS_MODULE, 110 .owner = THIS_MODULE,
98 .pf = PF_INET, 111 .pf = PF_INET,
99 .hooknum = NF_INET_LOCAL_IN, 112 .hooknum = NF_INET_LOCAL_IN,
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index c55a210853a7..da59182f2226 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -67,20 +67,54 @@ static struct
67static struct xt_table packet_mangler = { 67static struct xt_table packet_mangler = {
68 .name = "mangle", 68 .name = "mangle",
69 .valid_hooks = MANGLE_VALID_HOOKS, 69 .valid_hooks = MANGLE_VALID_HOOKS,
70 .lock = RW_LOCK_UNLOCKED, 70 .lock = __RW_LOCK_UNLOCKED(packet_mangler.lock),
71 .me = THIS_MODULE, 71 .me = THIS_MODULE,
72 .af = AF_INET, 72 .af = AF_INET,
73}; 73};
74 74
75/* The work comes in here from netfilter.c. */ 75/* The work comes in here from netfilter.c. */
76static unsigned int 76static unsigned int
77ipt_route_hook(unsigned int hook, 77ipt_pre_routing_hook(unsigned int hook,
78 struct sk_buff *skb,
79 const struct net_device *in,
80 const struct net_device *out,
81 int (*okfn)(struct sk_buff *))
82{
83 return ipt_do_table(skb, hook, in, out,
84 nf_pre_routing_net(in, out)->ipv4.iptable_mangle);
85}
86
87static unsigned int
88ipt_post_routing_hook(unsigned int hook,
89 struct sk_buff *skb,
90 const struct net_device *in,
91 const struct net_device *out,
92 int (*okfn)(struct sk_buff *))
93{
94 return ipt_do_table(skb, hook, in, out,
95 nf_post_routing_net(in, out)->ipv4.iptable_mangle);
96}
97
98static unsigned int
99ipt_local_in_hook(unsigned int hook,
100 struct sk_buff *skb,
101 const struct net_device *in,
102 const struct net_device *out,
103 int (*okfn)(struct sk_buff *))
104{
105 return ipt_do_table(skb, hook, in, out,
106 nf_local_in_net(in, out)->ipv4.iptable_mangle);
107}
108
109static unsigned int
110ipt_forward_hook(unsigned int hook,
78 struct sk_buff *skb, 111 struct sk_buff *skb,
79 const struct net_device *in, 112 const struct net_device *in,
80 const struct net_device *out, 113 const struct net_device *out,
81 int (*okfn)(struct sk_buff *)) 114 int (*okfn)(struct sk_buff *))
82{ 115{
83 return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle); 116 return ipt_do_table(skb, hook, in, out,
117 nf_forward_net(in, out)->ipv4.iptable_mangle);
84} 118}
85 119
86static unsigned int 120static unsigned int
@@ -112,7 +146,8 @@ ipt_local_hook(unsigned int hook,
112 daddr = iph->daddr; 146 daddr = iph->daddr;
113 tos = iph->tos; 147 tos = iph->tos;
114 148
115 ret = ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle); 149 ret = ipt_do_table(skb, hook, in, out,
150 nf_local_out_net(in, out)->ipv4.iptable_mangle);
116 /* Reroute for ANY change. */ 151 /* Reroute for ANY change. */
117 if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { 152 if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
118 iph = ip_hdr(skb); 153 iph = ip_hdr(skb);
@@ -130,21 +165,21 @@ ipt_local_hook(unsigned int hook,
130 165
131static struct nf_hook_ops ipt_ops[] __read_mostly = { 166static struct nf_hook_ops ipt_ops[] __read_mostly = {
132 { 167 {
133 .hook = ipt_route_hook, 168 .hook = ipt_pre_routing_hook,
134 .owner = THIS_MODULE, 169 .owner = THIS_MODULE,
135 .pf = PF_INET, 170 .pf = PF_INET,
136 .hooknum = NF_INET_PRE_ROUTING, 171 .hooknum = NF_INET_PRE_ROUTING,
137 .priority = NF_IP_PRI_MANGLE, 172 .priority = NF_IP_PRI_MANGLE,
138 }, 173 },
139 { 174 {
140 .hook = ipt_route_hook, 175 .hook = ipt_local_in_hook,
141 .owner = THIS_MODULE, 176 .owner = THIS_MODULE,
142 .pf = PF_INET, 177 .pf = PF_INET,
143 .hooknum = NF_INET_LOCAL_IN, 178 .hooknum = NF_INET_LOCAL_IN,
144 .priority = NF_IP_PRI_MANGLE, 179 .priority = NF_IP_PRI_MANGLE,
145 }, 180 },
146 { 181 {
147 .hook = ipt_route_hook, 182 .hook = ipt_forward_hook,
148 .owner = THIS_MODULE, 183 .owner = THIS_MODULE,
149 .pf = PF_INET, 184 .pf = PF_INET,
150 .hooknum = NF_INET_FORWARD, 185 .hooknum = NF_INET_FORWARD,
@@ -158,7 +193,7 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
158 .priority = NF_IP_PRI_MANGLE, 193 .priority = NF_IP_PRI_MANGLE,
159 }, 194 },
160 { 195 {
161 .hook = ipt_route_hook, 196 .hook = ipt_post_routing_hook,
162 .owner = THIS_MODULE, 197 .owner = THIS_MODULE,
163 .pf = PF_INET, 198 .pf = PF_INET,
164 .hooknum = NF_INET_POST_ROUTING, 199 .hooknum = NF_INET_POST_ROUTING,
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index e41fe8ca4e1c..fddce7754b72 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -39,7 +39,7 @@ static struct
39static struct xt_table packet_raw = { 39static struct xt_table packet_raw = {
40 .name = "raw", 40 .name = "raw",
41 .valid_hooks = RAW_VALID_HOOKS, 41 .valid_hooks = RAW_VALID_HOOKS,
42 .lock = RW_LOCK_UNLOCKED, 42 .lock = __RW_LOCK_UNLOCKED(packet_raw.lock),
43 .me = THIS_MODULE, 43 .me = THIS_MODULE,
44 .af = AF_INET, 44 .af = AF_INET,
45}; 45};
@@ -52,7 +52,8 @@ ipt_hook(unsigned int hook,
52 const struct net_device *out, 52 const struct net_device *out,
53 int (*okfn)(struct sk_buff *)) 53 int (*okfn)(struct sk_buff *))
54{ 54{
55 return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw); 55 return ipt_do_table(skb, hook, in, out,
56 nf_pre_routing_net(in, out)->ipv4.iptable_raw);
56} 57}
57 58
58static unsigned int 59static unsigned int
@@ -70,7 +71,8 @@ ipt_local_hook(unsigned int hook,
70 "packet.\n"); 71 "packet.\n");
71 return NF_ACCEPT; 72 return NF_ACCEPT;
72 } 73 }
73 return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw); 74 return ipt_do_table(skb, hook, in, out,
75 nf_local_out_net(in, out)->ipv4.iptable_raw);
74} 76}
75 77
76/* 'raw' is the very first table. */ 78/* 'raw' is the very first table. */
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index a65b845c5f15..cacb9cb27dab 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -23,30 +23,36 @@
23#include <net/netfilter/nf_conntrack_l3proto.h> 23#include <net/netfilter/nf_conntrack_l3proto.h>
24#include <net/netfilter/nf_conntrack_core.h> 24#include <net/netfilter/nf_conntrack_core.h>
25#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 25#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
26#include <net/netfilter/nf_nat_helper.h>
26 27
27static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 28int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
28 struct nf_conntrack_tuple *tuple) 29 struct nf_conn *ct,
30 enum ip_conntrack_info ctinfo);
31EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook);
32
33static bool ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
34 struct nf_conntrack_tuple *tuple)
29{ 35{
30 const __be32 *ap; 36 const __be32 *ap;
31 __be32 _addrs[2]; 37 __be32 _addrs[2];
32 ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr), 38 ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
33 sizeof(u_int32_t) * 2, _addrs); 39 sizeof(u_int32_t) * 2, _addrs);
34 if (ap == NULL) 40 if (ap == NULL)
35 return 0; 41 return false;
36 42
37 tuple->src.u3.ip = ap[0]; 43 tuple->src.u3.ip = ap[0];
38 tuple->dst.u3.ip = ap[1]; 44 tuple->dst.u3.ip = ap[1];
39 45
40 return 1; 46 return true;
41} 47}
42 48
43static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, 49static bool ipv4_invert_tuple(struct nf_conntrack_tuple *tuple,
44 const struct nf_conntrack_tuple *orig) 50 const struct nf_conntrack_tuple *orig)
45{ 51{
46 tuple->src.u3.ip = orig->dst.u3.ip; 52 tuple->src.u3.ip = orig->dst.u3.ip;
47 tuple->dst.u3.ip = orig->src.u3.ip; 53 tuple->dst.u3.ip = orig->src.u3.ip;
48 54
49 return 1; 55 return true;
50} 56}
51 57
52static int ipv4_print_tuple(struct seq_file *s, 58static int ipv4_print_tuple(struct seq_file *s,
@@ -101,35 +107,41 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
101 const struct net_device *out, 107 const struct net_device *out,
102 int (*okfn)(struct sk_buff *)) 108 int (*okfn)(struct sk_buff *))
103{ 109{
104 /* We've seen it coming out the other side: confirm it */
105 return nf_conntrack_confirm(skb);
106}
107
108static unsigned int ipv4_conntrack_help(unsigned int hooknum,
109 struct sk_buff *skb,
110 const struct net_device *in,
111 const struct net_device *out,
112 int (*okfn)(struct sk_buff *))
113{
114 struct nf_conn *ct; 110 struct nf_conn *ct;
115 enum ip_conntrack_info ctinfo; 111 enum ip_conntrack_info ctinfo;
116 const struct nf_conn_help *help; 112 const struct nf_conn_help *help;
117 const struct nf_conntrack_helper *helper; 113 const struct nf_conntrack_helper *helper;
114 unsigned int ret;
118 115
119 /* This is where we call the helper: as the packet goes out. */ 116 /* This is where we call the helper: as the packet goes out. */
120 ct = nf_ct_get(skb, &ctinfo); 117 ct = nf_ct_get(skb, &ctinfo);
121 if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) 118 if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
122 return NF_ACCEPT; 119 goto out;
123 120
124 help = nfct_help(ct); 121 help = nfct_help(ct);
125 if (!help) 122 if (!help)
126 return NF_ACCEPT; 123 goto out;
124
127 /* rcu_read_lock()ed by nf_hook_slow */ 125 /* rcu_read_lock()ed by nf_hook_slow */
128 helper = rcu_dereference(help->helper); 126 helper = rcu_dereference(help->helper);
129 if (!helper) 127 if (!helper)
130 return NF_ACCEPT; 128 goto out;
131 return helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), 129
132 ct, ctinfo); 130 ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
131 ct, ctinfo);
132 if (ret != NF_ACCEPT)
133 return ret;
134
135 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
136 typeof(nf_nat_seq_adjust_hook) seq_adjust;
137
138 seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook);
139 if (!seq_adjust || !seq_adjust(skb, ct, ctinfo))
140 return NF_DROP;
141 }
142out:
143 /* We've seen it coming out the other side: confirm it */
144 return nf_conntrack_confirm(skb);
133} 145}
134 146
135static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, 147static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
@@ -211,20 +223,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
211 .priority = NF_IP_PRI_CONNTRACK, 223 .priority = NF_IP_PRI_CONNTRACK,
212 }, 224 },
213 { 225 {
214 .hook = ipv4_conntrack_help,
215 .owner = THIS_MODULE,
216 .pf = PF_INET,
217 .hooknum = NF_INET_POST_ROUTING,
218 .priority = NF_IP_PRI_CONNTRACK_HELPER,
219 },
220 {
221 .hook = ipv4_conntrack_help,
222 .owner = THIS_MODULE,
223 .pf = PF_INET,
224 .hooknum = NF_INET_LOCAL_IN,
225 .priority = NF_IP_PRI_CONNTRACK_HELPER,
226 },
227 {
228 .hook = ipv4_confirm, 226 .hook = ipv4_confirm,
229 .owner = THIS_MODULE, 227 .owner = THIS_MODULE,
230 .pf = PF_INET, 228 .pf = PF_INET,
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index e60b885d2dcd..40a46d482490 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -106,21 +106,16 @@ static int ct_seq_show(struct seq_file *s, void *v)
106 /* we only want to print DIR_ORIGINAL */ 106 /* we only want to print DIR_ORIGINAL */
107 if (NF_CT_DIRECTION(hash)) 107 if (NF_CT_DIRECTION(hash))
108 return 0; 108 return 0;
109 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num != AF_INET) 109 if (nf_ct_l3num(ct) != AF_INET)
110 return 0; 110 return 0;
111 111
112 l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL] 112 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
113 .tuple.src.l3num);
114 NF_CT_ASSERT(l3proto); 113 NF_CT_ASSERT(l3proto);
115 l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL] 114 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
116 .tuple.src.l3num,
117 ct->tuplehash[IP_CT_DIR_ORIGINAL]
118 .tuple.dst.protonum);
119 NF_CT_ASSERT(l4proto); 115 NF_CT_ASSERT(l4proto);
120 116
121 if (seq_printf(s, "%-8s %u %ld ", 117 if (seq_printf(s, "%-8s %u %ld ",
122 l4proto->name, 118 l4proto->name, nf_ct_protonum(ct),
123 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
124 timer_pending(&ct->timeout) 119 timer_pending(&ct->timeout)
125 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0) 120 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
126 return -ENOSPC; 121 return -ENOSPC;
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 6873fddb3529..78ab19accace 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -22,22 +22,21 @@
22 22
23static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; 23static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ;
24 24
25static int icmp_pkt_to_tuple(const struct sk_buff *skb, 25static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
26 unsigned int dataoff, 26 struct nf_conntrack_tuple *tuple)
27 struct nf_conntrack_tuple *tuple)
28{ 27{
29 const struct icmphdr *hp; 28 const struct icmphdr *hp;
30 struct icmphdr _hdr; 29 struct icmphdr _hdr;
31 30
32 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 31 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
33 if (hp == NULL) 32 if (hp == NULL)
34 return 0; 33 return false;
35 34
36 tuple->dst.u.icmp.type = hp->type; 35 tuple->dst.u.icmp.type = hp->type;
37 tuple->src.u.icmp.id = hp->un.echo.id; 36 tuple->src.u.icmp.id = hp->un.echo.id;
38 tuple->dst.u.icmp.code = hp->code; 37 tuple->dst.u.icmp.code = hp->code;
39 38
40 return 1; 39 return true;
41} 40}
42 41
43/* Add 1; spaces filled with 0. */ 42/* Add 1; spaces filled with 0. */
@@ -52,17 +51,17 @@ static const u_int8_t invmap[] = {
52 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 51 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1
53}; 52};
54 53
55static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple, 54static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
56 const struct nf_conntrack_tuple *orig) 55 const struct nf_conntrack_tuple *orig)
57{ 56{
58 if (orig->dst.u.icmp.type >= sizeof(invmap) 57 if (orig->dst.u.icmp.type >= sizeof(invmap)
59 || !invmap[orig->dst.u.icmp.type]) 58 || !invmap[orig->dst.u.icmp.type])
60 return 0; 59 return false;
61 60
62 tuple->src.u.icmp.id = orig->src.u.icmp.id; 61 tuple->src.u.icmp.id = orig->src.u.icmp.id;
63 tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1; 62 tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1;
64 tuple->dst.u.icmp.code = orig->dst.u.icmp.code; 63 tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
65 return 1; 64 return true;
66} 65}
67 66
68/* Print out the per-protocol part of the tuple. */ 67/* Print out the per-protocol part of the tuple. */
@@ -101,8 +100,8 @@ static int icmp_packet(struct nf_conn *ct,
101} 100}
102 101
103/* Called when a new connection for this protocol found. */ 102/* Called when a new connection for this protocol found. */
104static int icmp_new(struct nf_conn *ct, 103static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
105 const struct sk_buff *skb, unsigned int dataoff) 104 unsigned int dataoff)
106{ 105{
107 static const u_int8_t valid_new[] = { 106 static const u_int8_t valid_new[] = {
108 [ICMP_ECHO] = 1, 107 [ICMP_ECHO] = 1,
@@ -116,11 +115,11 @@ static int icmp_new(struct nf_conn *ct,
116 /* Can't create a new ICMP `conn' with this. */ 115 /* Can't create a new ICMP `conn' with this. */
117 pr_debug("icmp: can't create new conn with type %u\n", 116 pr_debug("icmp: can't create new conn with type %u\n",
118 ct->tuplehash[0].tuple.dst.u.icmp.type); 117 ct->tuplehash[0].tuple.dst.u.icmp.type);
119 NF_CT_DUMP_TUPLE(&ct->tuplehash[0].tuple); 118 nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple);
120 return 0; 119 return false;
121 } 120 }
122 atomic_set(&ct->proto.icmp.count, 0); 121 atomic_set(&ct->proto.icmp.count, 0);
123 return 1; 122 return true;
124} 123}
125 124
126/* Returns conntrack if it dealt with ICMP, and filled in skb fields */ 125/* Returns conntrack if it dealt with ICMP, and filled in skb fields */
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 36b4e3bb056f..04578593e100 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -150,9 +150,9 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
150 const struct nf_nat_range *range) 150 const struct nf_nat_range *range)
151{ 151{
152 unsigned int h = hash_by_src(tuple); 152 unsigned int h = hash_by_src(tuple);
153 struct nf_conn_nat *nat; 153 const struct nf_conn_nat *nat;
154 struct nf_conn *ct; 154 const struct nf_conn *ct;
155 struct hlist_node *n; 155 const struct hlist_node *n;
156 156
157 rcu_read_lock(); 157 rcu_read_lock();
158 hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) { 158 hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) {
@@ -349,7 +349,7 @@ nf_nat_setup_info(struct nf_conn *ct,
349EXPORT_SYMBOL(nf_nat_setup_info); 349EXPORT_SYMBOL(nf_nat_setup_info);
350 350
351/* Returns true if succeeded. */ 351/* Returns true if succeeded. */
352static int 352static bool
353manip_pkt(u_int16_t proto, 353manip_pkt(u_int16_t proto,
354 struct sk_buff *skb, 354 struct sk_buff *skb,
355 unsigned int iphdroff, 355 unsigned int iphdroff,
@@ -360,7 +360,7 @@ manip_pkt(u_int16_t proto,
360 const struct nf_nat_protocol *p; 360 const struct nf_nat_protocol *p;
361 361
362 if (!skb_make_writable(skb, iphdroff + sizeof(*iph))) 362 if (!skb_make_writable(skb, iphdroff + sizeof(*iph)))
363 return 0; 363 return false;
364 364
365 iph = (void *)skb->data + iphdroff; 365 iph = (void *)skb->data + iphdroff;
366 366
@@ -369,7 +369,7 @@ manip_pkt(u_int16_t proto,
369 /* rcu_read_lock()ed by nf_hook_slow */ 369 /* rcu_read_lock()ed by nf_hook_slow */
370 p = __nf_nat_proto_find(proto); 370 p = __nf_nat_proto_find(proto);
371 if (!p->manip_pkt(skb, iphdroff, target, maniptype)) 371 if (!p->manip_pkt(skb, iphdroff, target, maniptype))
372 return 0; 372 return false;
373 373
374 iph = (void *)skb->data + iphdroff; 374 iph = (void *)skb->data + iphdroff;
375 375
@@ -380,7 +380,7 @@ manip_pkt(u_int16_t proto,
380 csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip); 380 csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip);
381 iph->daddr = target->dst.u3.ip; 381 iph->daddr = target->dst.u3.ip;
382 } 382 }
383 return 1; 383 return true;
384} 384}
385 385
386/* Do packet manipulations according to nf_nat_setup_info. */ 386/* Do packet manipulations according to nf_nat_setup_info. */
@@ -426,7 +426,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
426 struct icmphdr icmp; 426 struct icmphdr icmp;
427 struct iphdr ip; 427 struct iphdr ip;
428 } *inside; 428 } *inside;
429 struct nf_conntrack_l4proto *l4proto; 429 const struct nf_conntrack_l4proto *l4proto;
430 struct nf_conntrack_tuple inner, target; 430 struct nf_conntrack_tuple inner, target;
431 int hdrlen = ip_hdrlen(skb); 431 int hdrlen = ip_hdrlen(skb);
432 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 432 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
@@ -544,46 +544,6 @@ void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto)
544} 544}
545EXPORT_SYMBOL(nf_nat_protocol_unregister); 545EXPORT_SYMBOL(nf_nat_protocol_unregister);
546 546
547#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
548int
549nf_nat_port_range_to_nlattr(struct sk_buff *skb,
550 const struct nf_nat_range *range)
551{
552 NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MIN, range->min.tcp.port);
553 NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MAX, range->max.tcp.port);
554
555 return 0;
556
557nla_put_failure:
558 return -1;
559}
560EXPORT_SYMBOL_GPL(nf_nat_port_nlattr_to_range);
561
562int
563nf_nat_port_nlattr_to_range(struct nlattr *tb[], struct nf_nat_range *range)
564{
565 int ret = 0;
566
567 /* we have to return whether we actually parsed something or not */
568
569 if (tb[CTA_PROTONAT_PORT_MIN]) {
570 ret = 1;
571 range->min.tcp.port = nla_get_be16(tb[CTA_PROTONAT_PORT_MIN]);
572 }
573
574 if (!tb[CTA_PROTONAT_PORT_MAX]) {
575 if (ret)
576 range->max.tcp.port = range->min.tcp.port;
577 } else {
578 ret = 1;
579 range->max.tcp.port = nla_get_be16(tb[CTA_PROTONAT_PORT_MAX]);
580 }
581
582 return ret;
583}
584EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nlattr);
585#endif
586
587/* Noone using conntrack by the time this called. */ 547/* Noone using conntrack by the time this called. */
588static void nf_nat_cleanup_conntrack(struct nf_conn *ct) 548static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
589{ 549{
@@ -660,6 +620,9 @@ static int __init nf_nat_init(void)
660 nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK; 620 nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
661 621
662 l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET); 622 l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
623
624 BUG_ON(nf_nat_seq_adjust_hook != NULL);
625 rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
663 return 0; 626 return 0;
664 627
665 cleanup_extend: 628 cleanup_extend:
@@ -686,6 +649,8 @@ static void __exit nf_nat_cleanup(void)
686 nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size); 649 nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
687 nf_ct_l3proto_put(l3proto); 650 nf_ct_l3proto_put(l3proto);
688 nf_ct_extend_unregister(&nat_extend); 651 nf_ct_extend_unregister(&nat_extend);
652 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
653 synchronize_net();
689} 654}
690 655
691MODULE_LICENSE("GPL"); 656MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 2fca727aa8ba..11976ea29884 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -416,7 +416,6 @@ nf_nat_seq_adjust(struct sk_buff *skb,
416 416
417 return 1; 417 return 1;
418} 418}
419EXPORT_SYMBOL(nf_nat_seq_adjust);
420 419
421/* Setup NAT on this expected conntrack so it follows master. */ 420/* Setup NAT on this expected conntrack so it follows master. */
422/* If we fail to get a free NAT slot, we'll get dropped on confirm */ 421/* If we fail to get a free NAT slot, we'll get dropped on confirm */
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index 3a1e6d6afc0a..da3d91a5ef5c 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -72,7 +72,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
72 } 72 }
73 73
74 pr_debug("trying to unexpect other dir: "); 74 pr_debug("trying to unexpect other dir: ");
75 NF_CT_DUMP_TUPLE(&t); 75 nf_ct_dump_tuple_ip(&t);
76 other_exp = nf_ct_expect_find_get(&t); 76 other_exp = nf_ct_expect_find_get(&t);
77 if (other_exp) { 77 if (other_exp) {
78 nf_ct_unexpect_related(other_exp); 78 nf_ct_unexpect_related(other_exp);
diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c
new file mode 100644
index 000000000000..91537f11273f
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_common.c
@@ -0,0 +1,120 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
3 * (C) 2008 Patrick McHardy <kaber@trash.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/types.h>
11#include <linux/random.h>
12#include <linux/ip.h>
13
14#include <linux/netfilter.h>
15#include <net/netfilter/nf_nat.h>
16#include <net/netfilter/nf_nat_core.h>
17#include <net/netfilter/nf_nat_rule.h>
18#include <net/netfilter/nf_nat_protocol.h>
19
20bool nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple,
21 enum nf_nat_manip_type maniptype,
22 const union nf_conntrack_man_proto *min,
23 const union nf_conntrack_man_proto *max)
24{
25 __be16 port;
26
27 if (maniptype == IP_NAT_MANIP_SRC)
28 port = tuple->src.u.all;
29 else
30 port = tuple->dst.u.all;
31
32 return ntohs(port) >= ntohs(min->all) &&
33 ntohs(port) <= ntohs(max->all);
34}
35EXPORT_SYMBOL_GPL(nf_nat_proto_in_range);
36
37bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple,
38 const struct nf_nat_range *range,
39 enum nf_nat_manip_type maniptype,
40 const struct nf_conn *ct,
41 u_int16_t *rover)
42{
43 unsigned int range_size, min, i;
44 __be16 *portptr;
45 u_int16_t off;
46
47 if (maniptype == IP_NAT_MANIP_SRC)
48 portptr = &tuple->src.u.all;
49 else
50 portptr = &tuple->dst.u.all;
51
52 /* If no range specified... */
53 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
54 /* If it's dst rewrite, can't change port */
55 if (maniptype == IP_NAT_MANIP_DST)
56 return false;
57
58 if (ntohs(*portptr) < 1024) {
59 /* Loose convention: >> 512 is credential passing */
60 if (ntohs(*portptr) < 512) {
61 min = 1;
62 range_size = 511 - min + 1;
63 } else {
64 min = 600;
65 range_size = 1023 - min + 1;
66 }
67 } else {
68 min = 1024;
69 range_size = 65535 - 1024 + 1;
70 }
71 } else {
72 min = ntohs(range->min.all);
73 range_size = ntohs(range->max.all) - min + 1;
74 }
75
76 off = *rover;
77 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
78 off = net_random();
79
80 for (i = 0; i < range_size; i++, off++) {
81 *portptr = htons(min + off % range_size);
82 if (nf_nat_used_tuple(tuple, ct))
83 continue;
84 if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
85 *rover = off;
86 return true;
87 }
88 return false;
89}
90EXPORT_SYMBOL_GPL(nf_nat_proto_unique_tuple);
91
92#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
93int nf_nat_proto_range_to_nlattr(struct sk_buff *skb,
94 const struct nf_nat_range *range)
95{
96 NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MIN, range->min.all);
97 NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MAX, range->max.all);
98 return 0;
99
100nla_put_failure:
101 return -1;
102}
103EXPORT_SYMBOL_GPL(nf_nat_proto_nlattr_to_range);
104
105int nf_nat_proto_nlattr_to_range(struct nlattr *tb[],
106 struct nf_nat_range *range)
107{
108 if (tb[CTA_PROTONAT_PORT_MIN]) {
109 range->min.all = nla_get_be16(tb[CTA_PROTONAT_PORT_MIN]);
110 range->max.all = range->min.tcp.port;
111 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
112 }
113 if (tb[CTA_PROTONAT_PORT_MAX]) {
114 range->max.all = nla_get_be16(tb[CTA_PROTONAT_PORT_MAX]);
115 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
116 }
117 return 0;
118}
119EXPORT_SYMBOL_GPL(nf_nat_proto_range_to_nlattr);
120#endif
diff --git a/net/ipv4/netfilter/nf_nat_proto_dccp.c b/net/ipv4/netfilter/nf_nat_proto_dccp.c
new file mode 100644
index 000000000000..22485ce306d4
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_dccp.c
@@ -0,0 +1,108 @@
1/*
2 * DCCP NAT protocol helper
3 *
4 * Copyright (c) 2005, 2006. 2008 Patrick McHardy <kaber@trash.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/skbuff.h>
16#include <linux/ip.h>
17#include <linux/dccp.h>
18
19#include <net/netfilter/nf_conntrack.h>
20#include <net/netfilter/nf_nat.h>
21#include <net/netfilter/nf_nat_protocol.h>
22
23static u_int16_t dccp_port_rover;
24
25static bool
26dccp_unique_tuple(struct nf_conntrack_tuple *tuple,
27 const struct nf_nat_range *range,
28 enum nf_nat_manip_type maniptype,
29 const struct nf_conn *ct)
30{
31 return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
32 &dccp_port_rover);
33}
34
35static bool
36dccp_manip_pkt(struct sk_buff *skb,
37 unsigned int iphdroff,
38 const struct nf_conntrack_tuple *tuple,
39 enum nf_nat_manip_type maniptype)
40{
41 const struct iphdr *iph = (const void *)(skb->data + iphdroff);
42 struct dccp_hdr *hdr;
43 unsigned int hdroff = iphdroff + iph->ihl * 4;
44 __be32 oldip, newip;
45 __be16 *portptr, oldport, newport;
46 int hdrsize = 8; /* DCCP connection tracking guarantees this much */
47
48 if (skb->len >= hdroff + sizeof(struct dccp_hdr))
49 hdrsize = sizeof(struct dccp_hdr);
50
51 if (!skb_make_writable(skb, hdroff + hdrsize))
52 return false;
53
54 iph = (struct iphdr *)(skb->data + iphdroff);
55 hdr = (struct dccp_hdr *)(skb->data + hdroff);
56
57 if (maniptype == IP_NAT_MANIP_SRC) {
58 oldip = iph->saddr;
59 newip = tuple->src.u3.ip;
60 newport = tuple->src.u.dccp.port;
61 portptr = &hdr->dccph_sport;
62 } else {
63 oldip = iph->daddr;
64 newip = tuple->dst.u3.ip;
65 newport = tuple->dst.u.dccp.port;
66 portptr = &hdr->dccph_dport;
67 }
68
69 oldport = *portptr;
70 *portptr = newport;
71
72 if (hdrsize < sizeof(*hdr))
73 return true;
74
75 inet_proto_csum_replace4(&hdr->dccph_checksum, skb, oldip, newip, 1);
76 inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport,
77 0);
78 return true;
79}
80
81static const struct nf_nat_protocol nf_nat_protocol_dccp = {
82 .protonum = IPPROTO_DCCP,
83 .me = THIS_MODULE,
84 .manip_pkt = dccp_manip_pkt,
85 .in_range = nf_nat_proto_in_range,
86 .unique_tuple = dccp_unique_tuple,
87#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
88 .range_to_nlattr = nf_nat_proto_range_to_nlattr,
89 .nlattr_to_range = nf_nat_proto_nlattr_to_range,
90#endif
91};
92
93static int __init nf_nat_proto_dccp_init(void)
94{
95 return nf_nat_protocol_register(&nf_nat_protocol_dccp);
96}
97
98static void __exit nf_nat_proto_dccp_fini(void)
99{
100 nf_nat_protocol_unregister(&nf_nat_protocol_dccp);
101}
102
103module_init(nf_nat_proto_dccp_init);
104module_exit(nf_nat_proto_dccp_fini);
105
106MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
107MODULE_DESCRIPTION("DCCP NAT protocol helper");
108MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
index a1e4da16da2e..d7e89201351e 100644
--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -36,26 +36,8 @@ MODULE_LICENSE("GPL");
36MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); 36MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
37MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); 37MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
38 38
39/* is key in given range between min and max */
40static int
41gre_in_range(const struct nf_conntrack_tuple *tuple,
42 enum nf_nat_manip_type maniptype,
43 const union nf_conntrack_man_proto *min,
44 const union nf_conntrack_man_proto *max)
45{
46 __be16 key;
47
48 if (maniptype == IP_NAT_MANIP_SRC)
49 key = tuple->src.u.gre.key;
50 else
51 key = tuple->dst.u.gre.key;
52
53 return ntohs(key) >= ntohs(min->gre.key) &&
54 ntohs(key) <= ntohs(max->gre.key);
55}
56
57/* generate unique tuple ... */ 39/* generate unique tuple ... */
58static int 40static bool
59gre_unique_tuple(struct nf_conntrack_tuple *tuple, 41gre_unique_tuple(struct nf_conntrack_tuple *tuple,
60 const struct nf_nat_range *range, 42 const struct nf_nat_range *range,
61 enum nf_nat_manip_type maniptype, 43 enum nf_nat_manip_type maniptype,
@@ -68,7 +50,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
68 /* If there is no master conntrack we are not PPTP, 50 /* If there is no master conntrack we are not PPTP,
69 do not change tuples */ 51 do not change tuples */
70 if (!ct->master) 52 if (!ct->master)
71 return 0; 53 return false;
72 54
73 if (maniptype == IP_NAT_MANIP_SRC) 55 if (maniptype == IP_NAT_MANIP_SRC)
74 keyptr = &tuple->src.u.gre.key; 56 keyptr = &tuple->src.u.gre.key;
@@ -89,20 +71,20 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
89 for (i = 0; i < range_size; i++, key++) { 71 for (i = 0; i < range_size; i++, key++) {
90 *keyptr = htons(min + key % range_size); 72 *keyptr = htons(min + key % range_size);
91 if (!nf_nat_used_tuple(tuple, ct)) 73 if (!nf_nat_used_tuple(tuple, ct))
92 return 1; 74 return true;
93 } 75 }
94 76
95 pr_debug("%p: no NAT mapping\n", ct); 77 pr_debug("%p: no NAT mapping\n", ct);
96 return 0; 78 return false;
97} 79}
98 80
99/* manipulate a GRE packet according to maniptype */ 81/* manipulate a GRE packet according to maniptype */
100static int 82static bool
101gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff, 83gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
102 const struct nf_conntrack_tuple *tuple, 84 const struct nf_conntrack_tuple *tuple,
103 enum nf_nat_manip_type maniptype) 85 enum nf_nat_manip_type maniptype)
104{ 86{
105 struct gre_hdr *greh; 87 const struct gre_hdr *greh;
106 struct gre_hdr_pptp *pgreh; 88 struct gre_hdr_pptp *pgreh;
107 const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); 89 const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
108 unsigned int hdroff = iphdroff + iph->ihl * 4; 90 unsigned int hdroff = iphdroff + iph->ihl * 4;
@@ -110,7 +92,7 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
110 /* pgreh includes two optional 32bit fields which are not required 92 /* pgreh includes two optional 32bit fields which are not required
111 * to be there. That's where the magic '8' comes from */ 93 * to be there. That's where the magic '8' comes from */
112 if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8)) 94 if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8))
113 return 0; 95 return false;
114 96
115 greh = (void *)skb->data + hdroff; 97 greh = (void *)skb->data + hdroff;
116 pgreh = (struct gre_hdr_pptp *)greh; 98 pgreh = (struct gre_hdr_pptp *)greh;
@@ -118,7 +100,7 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
118 /* we only have destination manip of a packet, since 'source key' 100 /* we only have destination manip of a packet, since 'source key'
119 * is not present in the packet itself */ 101 * is not present in the packet itself */
120 if (maniptype != IP_NAT_MANIP_DST) 102 if (maniptype != IP_NAT_MANIP_DST)
121 return 1; 103 return true;
122 switch (greh->version) { 104 switch (greh->version) {
123 case GRE_VERSION_1701: 105 case GRE_VERSION_1701:
124 /* We do not currently NAT any GREv0 packets. 106 /* We do not currently NAT any GREv0 packets.
@@ -130,21 +112,20 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
130 break; 112 break;
131 default: 113 default:
132 pr_debug("can't nat unknown GRE version\n"); 114 pr_debug("can't nat unknown GRE version\n");
133 return 0; 115 return false;
134 } 116 }
135 return 1; 117 return true;
136} 118}
137 119
138static const struct nf_nat_protocol gre = { 120static const struct nf_nat_protocol gre = {
139 .name = "GRE",
140 .protonum = IPPROTO_GRE, 121 .protonum = IPPROTO_GRE,
141 .me = THIS_MODULE, 122 .me = THIS_MODULE,
142 .manip_pkt = gre_manip_pkt, 123 .manip_pkt = gre_manip_pkt,
143 .in_range = gre_in_range, 124 .in_range = nf_nat_proto_in_range,
144 .unique_tuple = gre_unique_tuple, 125 .unique_tuple = gre_unique_tuple,
145#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 126#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
146 .range_to_nlattr = nf_nat_port_range_to_nlattr, 127 .range_to_nlattr = nf_nat_proto_range_to_nlattr,
147 .nlattr_to_range = nf_nat_port_nlattr_to_range, 128 .nlattr_to_range = nf_nat_proto_nlattr_to_range,
148#endif 129#endif
149}; 130};
150 131
diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c
index 03a02969aa57..19a8b0b07d8e 100644
--- a/net/ipv4/netfilter/nf_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c
@@ -17,7 +17,7 @@
17#include <net/netfilter/nf_nat_rule.h> 17#include <net/netfilter/nf_nat_rule.h>
18#include <net/netfilter/nf_nat_protocol.h> 18#include <net/netfilter/nf_nat_protocol.h>
19 19
20static int 20static bool
21icmp_in_range(const struct nf_conntrack_tuple *tuple, 21icmp_in_range(const struct nf_conntrack_tuple *tuple,
22 enum nf_nat_manip_type maniptype, 22 enum nf_nat_manip_type maniptype,
23 const union nf_conntrack_man_proto *min, 23 const union nf_conntrack_man_proto *min,
@@ -27,7 +27,7 @@ icmp_in_range(const struct nf_conntrack_tuple *tuple,
27 ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id); 27 ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id);
28} 28}
29 29
30static int 30static bool
31icmp_unique_tuple(struct nf_conntrack_tuple *tuple, 31icmp_unique_tuple(struct nf_conntrack_tuple *tuple,
32 const struct nf_nat_range *range, 32 const struct nf_nat_range *range,
33 enum nf_nat_manip_type maniptype, 33 enum nf_nat_manip_type maniptype,
@@ -46,12 +46,12 @@ icmp_unique_tuple(struct nf_conntrack_tuple *tuple,
46 tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) + 46 tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) +
47 (id % range_size)); 47 (id % range_size));
48 if (!nf_nat_used_tuple(tuple, ct)) 48 if (!nf_nat_used_tuple(tuple, ct))
49 return 1; 49 return true;
50 } 50 }
51 return 0; 51 return false;
52} 52}
53 53
54static int 54static bool
55icmp_manip_pkt(struct sk_buff *skb, 55icmp_manip_pkt(struct sk_buff *skb,
56 unsigned int iphdroff, 56 unsigned int iphdroff,
57 const struct nf_conntrack_tuple *tuple, 57 const struct nf_conntrack_tuple *tuple,
@@ -62,24 +62,23 @@ icmp_manip_pkt(struct sk_buff *skb,
62 unsigned int hdroff = iphdroff + iph->ihl*4; 62 unsigned int hdroff = iphdroff + iph->ihl*4;
63 63
64 if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 64 if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
65 return 0; 65 return false;
66 66
67 hdr = (struct icmphdr *)(skb->data + hdroff); 67 hdr = (struct icmphdr *)(skb->data + hdroff);
68 inet_proto_csum_replace2(&hdr->checksum, skb, 68 inet_proto_csum_replace2(&hdr->checksum, skb,
69 hdr->un.echo.id, tuple->src.u.icmp.id, 0); 69 hdr->un.echo.id, tuple->src.u.icmp.id, 0);
70 hdr->un.echo.id = tuple->src.u.icmp.id; 70 hdr->un.echo.id = tuple->src.u.icmp.id;
71 return 1; 71 return true;
72} 72}
73 73
74const struct nf_nat_protocol nf_nat_protocol_icmp = { 74const struct nf_nat_protocol nf_nat_protocol_icmp = {
75 .name = "ICMP",
76 .protonum = IPPROTO_ICMP, 75 .protonum = IPPROTO_ICMP,
77 .me = THIS_MODULE, 76 .me = THIS_MODULE,
78 .manip_pkt = icmp_manip_pkt, 77 .manip_pkt = icmp_manip_pkt,
79 .in_range = icmp_in_range, 78 .in_range = icmp_in_range,
80 .unique_tuple = icmp_unique_tuple, 79 .unique_tuple = icmp_unique_tuple,
81#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 80#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
82 .range_to_nlattr = nf_nat_port_range_to_nlattr, 81 .range_to_nlattr = nf_nat_proto_range_to_nlattr,
83 .nlattr_to_range = nf_nat_port_nlattr_to_range, 82 .nlattr_to_range = nf_nat_proto_nlattr_to_range,
84#endif 83#endif
85}; 84};
diff --git a/net/ipv4/netfilter/nf_nat_proto_sctp.c b/net/ipv4/netfilter/nf_nat_proto_sctp.c
new file mode 100644
index 000000000000..82e4c0e286b8
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_sctp.c
@@ -0,0 +1,96 @@
1/*
2 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/types.h>
10#include <linux/init.h>
11#include <linux/ip.h>
12#include <linux/sctp.h>
13#include <net/sctp/checksum.h>
14
15#include <net/netfilter/nf_nat_protocol.h>
16
17static u_int16_t nf_sctp_port_rover;
18
19static bool
20sctp_unique_tuple(struct nf_conntrack_tuple *tuple,
21 const struct nf_nat_range *range,
22 enum nf_nat_manip_type maniptype,
23 const struct nf_conn *ct)
24{
25 return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
26 &nf_sctp_port_rover);
27}
28
29static bool
30sctp_manip_pkt(struct sk_buff *skb,
31 unsigned int iphdroff,
32 const struct nf_conntrack_tuple *tuple,
33 enum nf_nat_manip_type maniptype)
34{
35 const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
36 sctp_sctphdr_t *hdr;
37 unsigned int hdroff = iphdroff + iph->ihl*4;
38 __be32 oldip, newip;
39 u32 crc32;
40
41 if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
42 return false;
43
44 iph = (struct iphdr *)(skb->data + iphdroff);
45 hdr = (struct sctphdr *)(skb->data + hdroff);
46
47 if (maniptype == IP_NAT_MANIP_SRC) {
48 /* Get rid of src ip and src pt */
49 oldip = iph->saddr;
50 newip = tuple->src.u3.ip;
51 hdr->source = tuple->src.u.sctp.port;
52 } else {
53 /* Get rid of dst ip and dst pt */
54 oldip = iph->daddr;
55 newip = tuple->dst.u3.ip;
56 hdr->dest = tuple->dst.u.sctp.port;
57 }
58
59 crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff);
60 for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
61 crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb),
62 crc32);
63 crc32 = sctp_end_cksum(crc32);
64 hdr->checksum = htonl(crc32);
65
66 return true;
67}
68
69static const struct nf_nat_protocol nf_nat_protocol_sctp = {
70 .protonum = IPPROTO_SCTP,
71 .me = THIS_MODULE,
72 .manip_pkt = sctp_manip_pkt,
73 .in_range = nf_nat_proto_in_range,
74 .unique_tuple = sctp_unique_tuple,
75#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
76 .range_to_nlattr = nf_nat_proto_range_to_nlattr,
77 .nlattr_to_range = nf_nat_proto_nlattr_to_range,
78#endif
79};
80
81static int __init nf_nat_proto_sctp_init(void)
82{
83 return nf_nat_protocol_register(&nf_nat_protocol_sctp);
84}
85
86static void __exit nf_nat_proto_sctp_exit(void)
87{
88 nf_nat_protocol_unregister(&nf_nat_protocol_sctp);
89}
90
91module_init(nf_nat_proto_sctp_init);
92module_exit(nf_nat_proto_sctp_exit);
93
94MODULE_LICENSE("GPL");
95MODULE_DESCRIPTION("SCTP NAT protocol helper");
96MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
index ffd5d1589eca..399e2cfa263b 100644
--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -8,7 +8,6 @@
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/random.h>
12#include <linux/ip.h> 11#include <linux/ip.h>
13#include <linux/tcp.h> 12#include <linux/tcp.h>
14 13
@@ -19,75 +18,19 @@
19#include <net/netfilter/nf_nat_protocol.h> 18#include <net/netfilter/nf_nat_protocol.h>
20#include <net/netfilter/nf_nat_core.h> 19#include <net/netfilter/nf_nat_core.h>
21 20
22static int 21static u_int16_t tcp_port_rover;
23tcp_in_range(const struct nf_conntrack_tuple *tuple,
24 enum nf_nat_manip_type maniptype,
25 const union nf_conntrack_man_proto *min,
26 const union nf_conntrack_man_proto *max)
27{
28 __be16 port;
29
30 if (maniptype == IP_NAT_MANIP_SRC)
31 port = tuple->src.u.tcp.port;
32 else
33 port = tuple->dst.u.tcp.port;
34
35 return ntohs(port) >= ntohs(min->tcp.port) &&
36 ntohs(port) <= ntohs(max->tcp.port);
37}
38 22
39static int 23static bool
40tcp_unique_tuple(struct nf_conntrack_tuple *tuple, 24tcp_unique_tuple(struct nf_conntrack_tuple *tuple,
41 const struct nf_nat_range *range, 25 const struct nf_nat_range *range,
42 enum nf_nat_manip_type maniptype, 26 enum nf_nat_manip_type maniptype,
43 const struct nf_conn *ct) 27 const struct nf_conn *ct)
44{ 28{
45 static u_int16_t port; 29 return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
46 __be16 *portptr; 30 &tcp_port_rover);
47 unsigned int range_size, min, i;
48
49 if (maniptype == IP_NAT_MANIP_SRC)
50 portptr = &tuple->src.u.tcp.port;
51 else
52 portptr = &tuple->dst.u.tcp.port;
53
54 /* If no range specified... */
55 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
56 /* If it's dst rewrite, can't change port */
57 if (maniptype == IP_NAT_MANIP_DST)
58 return 0;
59
60 /* Map privileged onto privileged. */
61 if (ntohs(*portptr) < 1024) {
62 /* Loose convention: >> 512 is credential passing */
63 if (ntohs(*portptr)<512) {
64 min = 1;
65 range_size = 511 - min + 1;
66 } else {
67 min = 600;
68 range_size = 1023 - min + 1;
69 }
70 } else {
71 min = 1024;
72 range_size = 65535 - 1024 + 1;
73 }
74 } else {
75 min = ntohs(range->min.tcp.port);
76 range_size = ntohs(range->max.tcp.port) - min + 1;
77 }
78
79 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
80 port = net_random();
81
82 for (i = 0; i < range_size; i++, port++) {
83 *portptr = htons(min + port % range_size);
84 if (!nf_nat_used_tuple(tuple, ct))
85 return 1;
86 }
87 return 0;
88} 31}
89 32
90static int 33static bool
91tcp_manip_pkt(struct sk_buff *skb, 34tcp_manip_pkt(struct sk_buff *skb,
92 unsigned int iphdroff, 35 unsigned int iphdroff,
93 const struct nf_conntrack_tuple *tuple, 36 const struct nf_conntrack_tuple *tuple,
@@ -107,7 +50,7 @@ tcp_manip_pkt(struct sk_buff *skb,
107 hdrsize = sizeof(struct tcphdr); 50 hdrsize = sizeof(struct tcphdr);
108 51
109 if (!skb_make_writable(skb, hdroff + hdrsize)) 52 if (!skb_make_writable(skb, hdroff + hdrsize))
110 return 0; 53 return false;
111 54
112 iph = (struct iphdr *)(skb->data + iphdroff); 55 iph = (struct iphdr *)(skb->data + iphdroff);
113 hdr = (struct tcphdr *)(skb->data + hdroff); 56 hdr = (struct tcphdr *)(skb->data + hdroff);
@@ -130,22 +73,21 @@ tcp_manip_pkt(struct sk_buff *skb,
130 *portptr = newport; 73 *portptr = newport;
131 74
132 if (hdrsize < sizeof(*hdr)) 75 if (hdrsize < sizeof(*hdr))
133 return 1; 76 return true;
134 77
135 inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1); 78 inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
136 inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0); 79 inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0);
137 return 1; 80 return true;
138} 81}
139 82
140const struct nf_nat_protocol nf_nat_protocol_tcp = { 83const struct nf_nat_protocol nf_nat_protocol_tcp = {
141 .name = "TCP",
142 .protonum = IPPROTO_TCP, 84 .protonum = IPPROTO_TCP,
143 .me = THIS_MODULE, 85 .me = THIS_MODULE,
144 .manip_pkt = tcp_manip_pkt, 86 .manip_pkt = tcp_manip_pkt,
145 .in_range = tcp_in_range, 87 .in_range = nf_nat_proto_in_range,
146 .unique_tuple = tcp_unique_tuple, 88 .unique_tuple = tcp_unique_tuple,
147#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 89#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
148 .range_to_nlattr = nf_nat_port_range_to_nlattr, 90 .range_to_nlattr = nf_nat_proto_range_to_nlattr,
149 .nlattr_to_range = nf_nat_port_nlattr_to_range, 91 .nlattr_to_range = nf_nat_proto_nlattr_to_range,
150#endif 92#endif
151}; 93};
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
index 4b8f49910ff2..9e61c79492e4 100644
--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -8,7 +8,6 @@
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/random.h>
12#include <linux/ip.h> 11#include <linux/ip.h>
13#include <linux/udp.h> 12#include <linux/udp.h>
14 13
@@ -18,74 +17,19 @@
18#include <net/netfilter/nf_nat_rule.h> 17#include <net/netfilter/nf_nat_rule.h>
19#include <net/netfilter/nf_nat_protocol.h> 18#include <net/netfilter/nf_nat_protocol.h>
20 19
21static int 20static u_int16_t udp_port_rover;
22udp_in_range(const struct nf_conntrack_tuple *tuple,
23 enum nf_nat_manip_type maniptype,
24 const union nf_conntrack_man_proto *min,
25 const union nf_conntrack_man_proto *max)
26{
27 __be16 port;
28
29 if (maniptype == IP_NAT_MANIP_SRC)
30 port = tuple->src.u.udp.port;
31 else
32 port = tuple->dst.u.udp.port;
33
34 return ntohs(port) >= ntohs(min->udp.port) &&
35 ntohs(port) <= ntohs(max->udp.port);
36}
37 21
38static int 22static bool
39udp_unique_tuple(struct nf_conntrack_tuple *tuple, 23udp_unique_tuple(struct nf_conntrack_tuple *tuple,
40 const struct nf_nat_range *range, 24 const struct nf_nat_range *range,
41 enum nf_nat_manip_type maniptype, 25 enum nf_nat_manip_type maniptype,
42 const struct nf_conn *ct) 26 const struct nf_conn *ct)
43{ 27{
44 static u_int16_t port; 28 return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
45 __be16 *portptr; 29 &udp_port_rover);
46 unsigned int range_size, min, i;
47
48 if (maniptype == IP_NAT_MANIP_SRC)
49 portptr = &tuple->src.u.udp.port;
50 else
51 portptr = &tuple->dst.u.udp.port;
52
53 /* If no range specified... */
54 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
55 /* If it's dst rewrite, can't change port */
56 if (maniptype == IP_NAT_MANIP_DST)
57 return 0;
58
59 if (ntohs(*portptr) < 1024) {
60 /* Loose convention: >> 512 is credential passing */
61 if (ntohs(*portptr)<512) {
62 min = 1;
63 range_size = 511 - min + 1;
64 } else {
65 min = 600;
66 range_size = 1023 - min + 1;
67 }
68 } else {
69 min = 1024;
70 range_size = 65535 - 1024 + 1;
71 }
72 } else {
73 min = ntohs(range->min.udp.port);
74 range_size = ntohs(range->max.udp.port) - min + 1;
75 }
76
77 if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
78 port = net_random();
79
80 for (i = 0; i < range_size; i++, port++) {
81 *portptr = htons(min + port % range_size);
82 if (!nf_nat_used_tuple(tuple, ct))
83 return 1;
84 }
85 return 0;
86} 30}
87 31
88static int 32static bool
89udp_manip_pkt(struct sk_buff *skb, 33udp_manip_pkt(struct sk_buff *skb,
90 unsigned int iphdroff, 34 unsigned int iphdroff,
91 const struct nf_conntrack_tuple *tuple, 35 const struct nf_conntrack_tuple *tuple,
@@ -98,7 +42,7 @@ udp_manip_pkt(struct sk_buff *skb,
98 __be16 *portptr, newport; 42 __be16 *portptr, newport;
99 43
100 if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 44 if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
101 return 0; 45 return false;
102 46
103 iph = (struct iphdr *)(skb->data + iphdroff); 47 iph = (struct iphdr *)(skb->data + iphdroff);
104 hdr = (struct udphdr *)(skb->data + hdroff); 48 hdr = (struct udphdr *)(skb->data + hdroff);
@@ -124,18 +68,17 @@ udp_manip_pkt(struct sk_buff *skb,
124 hdr->check = CSUM_MANGLED_0; 68 hdr->check = CSUM_MANGLED_0;
125 } 69 }
126 *portptr = newport; 70 *portptr = newport;
127 return 1; 71 return true;
128} 72}
129 73
130const struct nf_nat_protocol nf_nat_protocol_udp = { 74const struct nf_nat_protocol nf_nat_protocol_udp = {
131 .name = "UDP",
132 .protonum = IPPROTO_UDP, 75 .protonum = IPPROTO_UDP,
133 .me = THIS_MODULE, 76 .me = THIS_MODULE,
134 .manip_pkt = udp_manip_pkt, 77 .manip_pkt = udp_manip_pkt,
135 .in_range = udp_in_range, 78 .in_range = nf_nat_proto_in_range,
136 .unique_tuple = udp_unique_tuple, 79 .unique_tuple = udp_unique_tuple,
137#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 80#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
138 .range_to_nlattr = nf_nat_port_range_to_nlattr, 81 .range_to_nlattr = nf_nat_proto_range_to_nlattr,
139 .nlattr_to_range = nf_nat_port_nlattr_to_range, 82 .nlattr_to_range = nf_nat_proto_nlattr_to_range,
140#endif 83#endif
141}; 84};
diff --git a/net/ipv4/netfilter/nf_nat_proto_udplite.c b/net/ipv4/netfilter/nf_nat_proto_udplite.c
new file mode 100644
index 000000000000..440a229bbd87
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_udplite.c
@@ -0,0 +1,99 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
3 * (C) 2008 Patrick McHardy <kaber@trash.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/types.h>
11#include <linux/init.h>
12#include <linux/ip.h>
13#include <linux/udp.h>
14
15#include <linux/netfilter.h>
16#include <net/netfilter/nf_nat.h>
17#include <net/netfilter/nf_nat_protocol.h>
18
19static u_int16_t udplite_port_rover;
20
21static bool
22udplite_unique_tuple(struct nf_conntrack_tuple *tuple,
23 const struct nf_nat_range *range,
24 enum nf_nat_manip_type maniptype,
25 const struct nf_conn *ct)
26{
27 return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
28 &udplite_port_rover);
29}
30
31static bool
32udplite_manip_pkt(struct sk_buff *skb,
33 unsigned int iphdroff,
34 const struct nf_conntrack_tuple *tuple,
35 enum nf_nat_manip_type maniptype)
36{
37 const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
38 struct udphdr *hdr;
39 unsigned int hdroff = iphdroff + iph->ihl*4;
40 __be32 oldip, newip;
41 __be16 *portptr, newport;
42
43 if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
44 return false;
45
46 iph = (struct iphdr *)(skb->data + iphdroff);
47 hdr = (struct udphdr *)(skb->data + hdroff);
48
49 if (maniptype == IP_NAT_MANIP_SRC) {
50 /* Get rid of src ip and src pt */
51 oldip = iph->saddr;
52 newip = tuple->src.u3.ip;
53 newport = tuple->src.u.udp.port;
54 portptr = &hdr->source;
55 } else {
56 /* Get rid of dst ip and dst pt */
57 oldip = iph->daddr;
58 newip = tuple->dst.u3.ip;
59 newport = tuple->dst.u.udp.port;
60 portptr = &hdr->dest;
61 }
62
63 inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
64 inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport, 0);
65 if (!hdr->check)
66 hdr->check = CSUM_MANGLED_0;
67
68 *portptr = newport;
69 return true;
70}
71
72static const struct nf_nat_protocol nf_nat_protocol_udplite = {
73 .protonum = IPPROTO_UDPLITE,
74 .me = THIS_MODULE,
75 .manip_pkt = udplite_manip_pkt,
76 .in_range = nf_nat_proto_in_range,
77 .unique_tuple = udplite_unique_tuple,
78#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
79 .range_to_nlattr = nf_nat_proto_range_to_nlattr,
80 .nlattr_to_range = nf_nat_proto_nlattr_to_range,
81#endif
82};
83
84static int __init nf_nat_proto_udplite_init(void)
85{
86 return nf_nat_protocol_register(&nf_nat_protocol_udplite);
87}
88
89static void __exit nf_nat_proto_udplite_fini(void)
90{
91 nf_nat_protocol_unregister(&nf_nat_protocol_udplite);
92}
93
94module_init(nf_nat_proto_udplite_init);
95module_exit(nf_nat_proto_udplite_fini);
96
97MODULE_LICENSE("GPL");
98MODULE_DESCRIPTION("UDP-Lite NAT protocol helper");
99MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/ipv4/netfilter/nf_nat_proto_unknown.c b/net/ipv4/netfilter/nf_nat_proto_unknown.c
index a26efeb073cb..14381c62acea 100644
--- a/net/ipv4/netfilter/nf_nat_proto_unknown.c
+++ b/net/ipv4/netfilter/nf_nat_proto_unknown.c
@@ -18,35 +18,34 @@
18#include <net/netfilter/nf_nat_rule.h> 18#include <net/netfilter/nf_nat_rule.h>
19#include <net/netfilter/nf_nat_protocol.h> 19#include <net/netfilter/nf_nat_protocol.h>
20 20
21static int unknown_in_range(const struct nf_conntrack_tuple *tuple, 21static bool unknown_in_range(const struct nf_conntrack_tuple *tuple,
22 enum nf_nat_manip_type manip_type, 22 enum nf_nat_manip_type manip_type,
23 const union nf_conntrack_man_proto *min, 23 const union nf_conntrack_man_proto *min,
24 const union nf_conntrack_man_proto *max) 24 const union nf_conntrack_man_proto *max)
25{ 25{
26 return 1; 26 return true;
27} 27}
28 28
29static int unknown_unique_tuple(struct nf_conntrack_tuple *tuple, 29static bool unknown_unique_tuple(struct nf_conntrack_tuple *tuple,
30 const struct nf_nat_range *range, 30 const struct nf_nat_range *range,
31 enum nf_nat_manip_type maniptype, 31 enum nf_nat_manip_type maniptype,
32 const struct nf_conn *ct) 32 const struct nf_conn *ct)
33{ 33{
34 /* Sorry: we can't help you; if it's not unique, we can't frob 34 /* Sorry: we can't help you; if it's not unique, we can't frob
35 anything. */ 35 anything. */
36 return 0; 36 return false;
37} 37}
38 38
39static int 39static bool
40unknown_manip_pkt(struct sk_buff *skb, 40unknown_manip_pkt(struct sk_buff *skb,
41 unsigned int iphdroff, 41 unsigned int iphdroff,
42 const struct nf_conntrack_tuple *tuple, 42 const struct nf_conntrack_tuple *tuple,
43 enum nf_nat_manip_type maniptype) 43 enum nf_nat_manip_type maniptype)
44{ 44{
45 return 1; 45 return true;
46} 46}
47 47
48const struct nf_nat_protocol nf_nat_unknown_protocol = { 48const struct nf_nat_protocol nf_nat_unknown_protocol = {
49 .name = "unknown",
50 /* .me isn't set: getting a ref to this cannot fail. */ 49 /* .me isn't set: getting a ref to this cannot fail. */
51 .manip_pkt = unknown_manip_pkt, 50 .manip_pkt = unknown_manip_pkt,
52 .in_range = unknown_in_range, 51 .in_range = unknown_in_range,
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index f8fda57ba20b..e8b4d0d4439e 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -61,7 +61,7 @@ static struct
61static struct xt_table __nat_table = { 61static struct xt_table __nat_table = {
62 .name = "nat", 62 .name = "nat",
63 .valid_hooks = NAT_VALID_HOOKS, 63 .valid_hooks = NAT_VALID_HOOKS,
64 .lock = RW_LOCK_UNLOCKED, 64 .lock = __RW_LOCK_UNLOCKED(__nat_table.lock),
65 .me = THIS_MODULE, 65 .me = THIS_MODULE,
66 .af = AF_INET, 66 .af = AF_INET,
67}; 67};
@@ -143,7 +143,7 @@ static bool ipt_snat_checkentry(const char *tablename,
143 void *targinfo, 143 void *targinfo,
144 unsigned int hook_mask) 144 unsigned int hook_mask)
145{ 145{
146 struct nf_nat_multi_range_compat *mr = targinfo; 146 const struct nf_nat_multi_range_compat *mr = targinfo;
147 147
148 /* Must be a valid range */ 148 /* Must be a valid range */
149 if (mr->rangesize != 1) { 149 if (mr->rangesize != 1) {
@@ -159,7 +159,7 @@ static bool ipt_dnat_checkentry(const char *tablename,
159 void *targinfo, 159 void *targinfo,
160 unsigned int hook_mask) 160 unsigned int hook_mask)
161{ 161{
162 struct nf_nat_multi_range_compat *mr = targinfo; 162 const struct nf_nat_multi_range_compat *mr = targinfo;
163 163
164 /* Must be a valid range */ 164 /* Must be a valid range */
165 if (mr->rangesize != 1) { 165 if (mr->rangesize != 1) {
@@ -188,25 +188,6 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
188 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); 188 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
189} 189}
190 190
191unsigned int
192alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
193{
194 __be32 ip
195 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
196 ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip
197 : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip);
198 __be16 all
199 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
200 ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all
201 : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all);
202 struct nf_nat_range range
203 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
204
205 pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
206 ct, NIPQUAD(ip));
207 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
208}
209
210int nf_nat_rule_find(struct sk_buff *skb, 191int nf_nat_rule_find(struct sk_buff *skb,
211 unsigned int hooknum, 192 unsigned int hooknum,
212 const struct net_device *in, 193 const struct net_device *in,
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 000e080bac5c..5daefad3d193 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -220,7 +220,7 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx,
220 if (ch < 0x80) 220 if (ch < 0x80)
221 *len = ch; 221 *len = ch;
222 else { 222 else {
223 cnt = (unsigned char) (ch & 0x7F); 223 cnt = ch & 0x7F;
224 *len = 0; 224 *len = 0;
225 225
226 while (cnt > 0) { 226 while (cnt > 0) {
@@ -618,8 +618,7 @@ struct snmp_cnv
618 int syntax; 618 int syntax;
619}; 619};
620 620
621static struct snmp_cnv snmp_conv [] = 621static const struct snmp_cnv snmp_conv[] = {
622{
623 {ASN1_UNI, ASN1_NUL, SNMP_NULL}, 622 {ASN1_UNI, ASN1_NUL, SNMP_NULL},
624 {ASN1_UNI, ASN1_INT, SNMP_INTEGER}, 623 {ASN1_UNI, ASN1_INT, SNMP_INTEGER},
625 {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR}, 624 {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR},
@@ -644,7 +643,7 @@ static unsigned char snmp_tag_cls2syntax(unsigned int tag,
644 unsigned int cls, 643 unsigned int cls,
645 unsigned short *syntax) 644 unsigned short *syntax)
646{ 645{
647 struct snmp_cnv *cnv; 646 const struct snmp_cnv *cnv;
648 647
649 cnv = snmp_conv; 648 cnv = snmp_conv;
650 649
@@ -904,7 +903,7 @@ static inline void mangle_address(unsigned char *begin,
904 u_int32_t old; 903 u_int32_t old;
905 904
906 if (debug) 905 if (debug)
907 memcpy(&old, (unsigned char *)addr, sizeof(old)); 906 memcpy(&old, addr, sizeof(old));
908 907
909 *addr = map->to; 908 *addr = map->to;
910 909
@@ -999,7 +998,7 @@ err_id_free:
999 * 998 *
1000 *****************************************************************************/ 999 *****************************************************************************/
1001 1000
1002static void hex_dump(unsigned char *buf, size_t len) 1001static void hex_dump(const unsigned char *buf, size_t len)
1003{ 1002{
1004 size_t i; 1003 size_t i;
1005 1004
@@ -1080,7 +1079,7 @@ static int snmp_parse_mangle(unsigned char *msg,
1080 if (cls != ASN1_CTX || con != ASN1_CON) 1079 if (cls != ASN1_CTX || con != ASN1_CON)
1081 return 0; 1080 return 0;
1082 if (debug > 1) { 1081 if (debug > 1) {
1083 unsigned char *pdus[] = { 1082 static const unsigned char *const pdus[] = {
1084 [SNMP_PDU_GET] = "get", 1083 [SNMP_PDU_GET] = "get",
1085 [SNMP_PDU_NEXT] = "get-next", 1084 [SNMP_PDU_NEXT] = "get-next",
1086 [SNMP_PDU_RESPONSE] = "response", 1085 [SNMP_PDU_RESPONSE] = "response",
@@ -1232,8 +1231,8 @@ static int help(struct sk_buff *skb, unsigned int protoff,
1232{ 1231{
1233 int dir = CTINFO2DIR(ctinfo); 1232 int dir = CTINFO2DIR(ctinfo);
1234 unsigned int ret; 1233 unsigned int ret;
1235 struct iphdr *iph = ip_hdr(skb); 1234 const struct iphdr *iph = ip_hdr(skb);
1236 struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); 1235 const struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
1237 1236
1238 /* SNMP replies and originating SNMP traps get mangled */ 1237 /* SNMP replies and originating SNMP traps get mangled */
1239 if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY) 1238 if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 99b2c788d5a8..b7dd695691a0 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -30,8 +30,8 @@
30#ifdef CONFIG_XFRM 30#ifdef CONFIG_XFRM
31static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) 31static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
32{ 32{
33 struct nf_conn *ct; 33 const struct nf_conn *ct;
34 struct nf_conntrack_tuple *t; 34 const struct nf_conntrack_tuple *t;
35 enum ip_conntrack_info ctinfo; 35 enum ip_conntrack_info ctinfo;
36 enum ip_conntrack_dir dir; 36 enum ip_conntrack_dir dir;
37 unsigned long statusbit; 37 unsigned long statusbit;
@@ -50,7 +50,10 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
50 if (ct->status & statusbit) { 50 if (ct->status & statusbit) {
51 fl->fl4_dst = t->dst.u3.ip; 51 fl->fl4_dst = t->dst.u3.ip;
52 if (t->dst.protonum == IPPROTO_TCP || 52 if (t->dst.protonum == IPPROTO_TCP ||
53 t->dst.protonum == IPPROTO_UDP) 53 t->dst.protonum == IPPROTO_UDP ||
54 t->dst.protonum == IPPROTO_UDPLITE ||
55 t->dst.protonum == IPPROTO_DCCP ||
56 t->dst.protonum == IPPROTO_SCTP)
54 fl->fl_ip_dport = t->dst.u.tcp.port; 57 fl->fl_ip_dport = t->dst.u.tcp.port;
55 } 58 }
56 59
@@ -59,7 +62,10 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
59 if (ct->status & statusbit) { 62 if (ct->status & statusbit) {
60 fl->fl4_src = t->src.u3.ip; 63 fl->fl4_src = t->src.u3.ip;
61 if (t->dst.protonum == IPPROTO_TCP || 64 if (t->dst.protonum == IPPROTO_TCP ||
62 t->dst.protonum == IPPROTO_UDP) 65 t->dst.protonum == IPPROTO_UDP ||
66 t->dst.protonum == IPPROTO_UDPLITE ||
67 t->dst.protonum == IPPROTO_DCCP ||
68 t->dst.protonum == IPPROTO_SCTP)
63 fl->fl_ip_sport = t->src.u.tcp.port; 69 fl->fl_ip_sport = t->src.u.tcp.port;
64 } 70 }
65} 71}
@@ -87,21 +93,8 @@ nf_nat_fn(unsigned int hooknum,
87 have dropped it. Hence it's the user's responsibilty to 93 have dropped it. Hence it's the user's responsibilty to
88 packet filter it out, or implement conntrack/NAT for that 94 packet filter it out, or implement conntrack/NAT for that
89 protocol. 8) --RR */ 95 protocol. 8) --RR */
90 if (!ct) { 96 if (!ct)
91 /* Exception: ICMP redirect to new connection (not in
92 hash table yet). We must not let this through, in
93 case we're doing NAT to the same network. */
94 if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
95 struct icmphdr _hdr, *hp;
96
97 hp = skb_header_pointer(skb, ip_hdrlen(skb),
98 sizeof(_hdr), &_hdr);
99 if (hp != NULL &&
100 hp->type == ICMP_REDIRECT)
101 return NF_DROP;
102 }
103 return NF_ACCEPT; 97 return NF_ACCEPT;
104 }
105 98
106 /* Don't try to NAT if this packet is not conntracked */ 99 /* Don't try to NAT if this packet is not conntracked */
107 if (ct == &nf_conntrack_untracked) 100 if (ct == &nf_conntrack_untracked)
@@ -109,6 +102,9 @@ nf_nat_fn(unsigned int hooknum,
109 102
110 nat = nfct_nat(ct); 103 nat = nfct_nat(ct);
111 if (!nat) { 104 if (!nat) {
105 /* NAT module was loaded late. */
106 if (nf_ct_is_confirmed(ct))
107 return NF_ACCEPT;
112 nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC); 108 nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
113 if (nat == NULL) { 109 if (nat == NULL) {
114 pr_debug("failed to add NAT extension\n"); 110 pr_debug("failed to add NAT extension\n");
@@ -134,10 +130,7 @@ nf_nat_fn(unsigned int hooknum,
134 if (!nf_nat_initialized(ct, maniptype)) { 130 if (!nf_nat_initialized(ct, maniptype)) {
135 unsigned int ret; 131 unsigned int ret;
136 132
137 if (unlikely(nf_ct_is_confirmed(ct))) 133 if (hooknum == NF_INET_LOCAL_IN)
138 /* NAT module was loaded late */
139 ret = alloc_null_binding_confirmed(ct, hooknum);
140 else if (hooknum == NF_INET_LOCAL_IN)
141 /* LOCAL_IN hook doesn't have a chain! */ 134 /* LOCAL_IN hook doesn't have a chain! */
142 ret = alloc_null_binding(ct, hooknum); 135 ret = alloc_null_binding(ct, hooknum);
143 else 136 else
@@ -189,7 +182,7 @@ nf_nat_out(unsigned int hooknum,
189 int (*okfn)(struct sk_buff *)) 182 int (*okfn)(struct sk_buff *))
190{ 183{
191#ifdef CONFIG_XFRM 184#ifdef CONFIG_XFRM
192 struct nf_conn *ct; 185 const struct nf_conn *ct;
193 enum ip_conntrack_info ctinfo; 186 enum ip_conntrack_info ctinfo;
194#endif 187#endif
195 unsigned int ret; 188 unsigned int ret;
@@ -223,7 +216,7 @@ nf_nat_local_fn(unsigned int hooknum,
223 const struct net_device *out, 216 const struct net_device *out,
224 int (*okfn)(struct sk_buff *)) 217 int (*okfn)(struct sk_buff *))
225{ 218{
226 struct nf_conn *ct; 219 const struct nf_conn *ct;
227 enum ip_conntrack_info ctinfo; 220 enum ip_conntrack_info ctinfo;
228 unsigned int ret; 221 unsigned int ret;
229 222
@@ -252,25 +245,6 @@ nf_nat_local_fn(unsigned int hooknum,
252 return ret; 245 return ret;
253} 246}
254 247
255static unsigned int
256nf_nat_adjust(unsigned int hooknum,
257 struct sk_buff *skb,
258 const struct net_device *in,
259 const struct net_device *out,
260 int (*okfn)(struct sk_buff *))
261{
262 struct nf_conn *ct;
263 enum ip_conntrack_info ctinfo;
264
265 ct = nf_ct_get(skb, &ctinfo);
266 if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
267 pr_debug("nf_nat_standalone: adjusting sequence number\n");
268 if (!nf_nat_seq_adjust(skb, ct, ctinfo))
269 return NF_DROP;
270 }
271 return NF_ACCEPT;
272}
273
274/* We must be after connection tracking and before packet filtering. */ 248/* We must be after connection tracking and before packet filtering. */
275 249
276static struct nf_hook_ops nf_nat_ops[] __read_mostly = { 250static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
@@ -290,14 +264,6 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
290 .hooknum = NF_INET_POST_ROUTING, 264 .hooknum = NF_INET_POST_ROUTING,
291 .priority = NF_IP_PRI_NAT_SRC, 265 .priority = NF_IP_PRI_NAT_SRC,
292 }, 266 },
293 /* After conntrack, adjust sequence number */
294 {
295 .hook = nf_nat_adjust,
296 .owner = THIS_MODULE,
297 .pf = PF_INET,
298 .hooknum = NF_INET_POST_ROUTING,
299 .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
300 },
301 /* Before packet filtering, change destination */ 267 /* Before packet filtering, change destination */
302 { 268 {
303 .hook = nf_nat_local_fn, 269 .hook = nf_nat_local_fn,
@@ -314,14 +280,6 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
314 .hooknum = NF_INET_LOCAL_IN, 280 .hooknum = NF_INET_LOCAL_IN,
315 .priority = NF_IP_PRI_NAT_SRC, 281 .priority = NF_IP_PRI_NAT_SRC,
316 }, 282 },
317 /* After conntrack, adjust sequence number */
318 {
319 .hook = nf_nat_adjust,
320 .owner = THIS_MODULE,
321 .pf = PF_INET,
322 .hooknum = NF_INET_LOCAL_IN,
323 .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
324 },
325}; 283};
326 284
327static int __init nf_nat_standalone_init(void) 285static int __init nf_nat_standalone_init(void)
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index aed51bcc66b4..8c6c5e71f210 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -121,16 +121,44 @@ __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
121 } 121 }
122 return csum; 122 return csum;
123} 123}
124
125EXPORT_SYMBOL(nf_ip6_checksum); 124EXPORT_SYMBOL(nf_ip6_checksum);
126 125
126static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
127 unsigned int dataoff, unsigned int len,
128 u_int8_t protocol)
129{
130 struct ipv6hdr *ip6h = ipv6_hdr(skb);
131 __wsum hsum;
132 __sum16 csum = 0;
133
134 switch (skb->ip_summed) {
135 case CHECKSUM_COMPLETE:
136 if (len == skb->len - dataoff)
137 return nf_ip6_checksum(skb, hook, dataoff, protocol);
138 /* fall through */
139 case CHECKSUM_NONE:
140 hsum = skb_checksum(skb, 0, dataoff, 0);
141 skb->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
142 &ip6h->daddr,
143 skb->len - dataoff,
144 protocol,
145 csum_sub(0, hsum)));
146 skb->ip_summed = CHECKSUM_NONE;
147 csum = __skb_checksum_complete_head(skb, dataoff + len);
148 if (!csum)
149 skb->ip_summed = CHECKSUM_UNNECESSARY;
150 }
151 return csum;
152};
153
127static const struct nf_afinfo nf_ip6_afinfo = { 154static const struct nf_afinfo nf_ip6_afinfo = {
128 .family = AF_INET6, 155 .family = AF_INET6,
129 .checksum = nf_ip6_checksum, 156 .checksum = nf_ip6_checksum,
130 .route = nf_ip6_route, 157 .checksum_partial = nf_ip6_checksum_partial,
131 .saveroute = nf_ip6_saveroute, 158 .route = nf_ip6_route,
132 .reroute = nf_ip6_reroute, 159 .saveroute = nf_ip6_saveroute,
133 .route_key_size = sizeof(struct ip6_rt_info), 160 .reroute = nf_ip6_reroute,
161 .route_key_size = sizeof(struct ip6_rt_info),
134}; 162};
135 163
136int __init ipv6_netfilter_init(void) 164int __init ipv6_netfilter_init(void)
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 70ef0d276cc0..0b4557e03431 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -325,7 +325,7 @@ static void trace_packet(struct sk_buff *skb,
325 struct ip6t_entry *e) 325 struct ip6t_entry *e)
326{ 326{
327 void *table_base; 327 void *table_base;
328 struct ip6t_entry *root; 328 const struct ip6t_entry *root;
329 char *hookname, *chainname, *comment; 329 char *hookname, *chainname, *comment;
330 unsigned int rulenum = 0; 330 unsigned int rulenum = 0;
331 331
@@ -952,7 +952,7 @@ static struct xt_counters *alloc_counters(struct xt_table *table)
952{ 952{
953 unsigned int countersize; 953 unsigned int countersize;
954 struct xt_counters *counters; 954 struct xt_counters *counters;
955 struct xt_table_info *private = table->private; 955 const struct xt_table_info *private = table->private;
956 956
957 /* We need atomic snapshot of counters: rest doesn't change 957 /* We need atomic snapshot of counters: rest doesn't change
958 (other than comefrom, which userspace doesn't care 958 (other than comefrom, which userspace doesn't care
@@ -979,9 +979,9 @@ copy_entries_to_user(unsigned int total_size,
979 unsigned int off, num; 979 unsigned int off, num;
980 struct ip6t_entry *e; 980 struct ip6t_entry *e;
981 struct xt_counters *counters; 981 struct xt_counters *counters;
982 struct xt_table_info *private = table->private; 982 const struct xt_table_info *private = table->private;
983 int ret = 0; 983 int ret = 0;
984 void *loc_cpu_entry; 984 const void *loc_cpu_entry;
985 985
986 counters = alloc_counters(table); 986 counters = alloc_counters(table);
987 if (IS_ERR(counters)) 987 if (IS_ERR(counters))
@@ -1001,8 +1001,8 @@ copy_entries_to_user(unsigned int total_size,
1001 /* ... then go back and fix counters and names */ 1001 /* ... then go back and fix counters and names */
1002 for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ 1002 for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
1003 unsigned int i; 1003 unsigned int i;
1004 struct ip6t_entry_match *m; 1004 const struct ip6t_entry_match *m;
1005 struct ip6t_entry_target *t; 1005 const struct ip6t_entry_target *t;
1006 1006
1007 e = (struct ip6t_entry *)(loc_cpu_entry + off); 1007 e = (struct ip6t_entry *)(loc_cpu_entry + off);
1008 if (copy_to_user(userptr + off 1008 if (copy_to_user(userptr + off
@@ -1142,7 +1142,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
1142 "ip6table_%s", name); 1142 "ip6table_%s", name);
1143 if (t && !IS_ERR(t)) { 1143 if (t && !IS_ERR(t)) {
1144 struct ip6t_getinfo info; 1144 struct ip6t_getinfo info;
1145 struct xt_table_info *private = t->private; 1145 const struct xt_table_info *private = t->private;
1146 1146
1147#ifdef CONFIG_COMPAT 1147#ifdef CONFIG_COMPAT
1148 if (compat) { 1148 if (compat) {
@@ -1206,7 +1206,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, int *len)
1206 else { 1206 else {
1207 duprintf("get_entries: I've got %u not %u!\n", 1207 duprintf("get_entries: I've got %u not %u!\n",
1208 private->size, get.size); 1208 private->size, get.size);
1209 ret = -EINVAL; 1209 ret = -EAGAIN;
1210 } 1210 }
1211 module_put(t->me); 1211 module_put(t->me);
1212 xt_table_unlock(t); 1212 xt_table_unlock(t);
@@ -1225,7 +1225,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1225 struct xt_table *t; 1225 struct xt_table *t;
1226 struct xt_table_info *oldinfo; 1226 struct xt_table_info *oldinfo;
1227 struct xt_counters *counters; 1227 struct xt_counters *counters;
1228 void *loc_cpu_old_entry; 1228 const void *loc_cpu_old_entry;
1229 1229
1230 ret = 0; 1230 ret = 0;
1231 counters = vmalloc_node(num_counters * sizeof(struct xt_counters), 1231 counters = vmalloc_node(num_counters * sizeof(struct xt_counters),
@@ -1369,9 +1369,9 @@ do_add_counters(struct net *net, void __user *user, unsigned int len,
1369 int size; 1369 int size;
1370 void *ptmp; 1370 void *ptmp;
1371 struct xt_table *t; 1371 struct xt_table *t;
1372 struct xt_table_info *private; 1372 const struct xt_table_info *private;
1373 int ret = 0; 1373 int ret = 0;
1374 void *loc_cpu_entry; 1374 const void *loc_cpu_entry;
1375#ifdef CONFIG_COMPAT 1375#ifdef CONFIG_COMPAT
1376 struct compat_xt_counters_info compat_tmp; 1376 struct compat_xt_counters_info compat_tmp;
1377 1377
@@ -1905,11 +1905,11 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
1905 void __user *userptr) 1905 void __user *userptr)
1906{ 1906{
1907 struct xt_counters *counters; 1907 struct xt_counters *counters;
1908 struct xt_table_info *private = table->private; 1908 const struct xt_table_info *private = table->private;
1909 void __user *pos; 1909 void __user *pos;
1910 unsigned int size; 1910 unsigned int size;
1911 int ret = 0; 1911 int ret = 0;
1912 void *loc_cpu_entry; 1912 const void *loc_cpu_entry;
1913 unsigned int i = 0; 1913 unsigned int i = 0;
1914 1914
1915 counters = alloc_counters(table); 1915 counters = alloc_counters(table);
@@ -1956,7 +1956,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
1956 xt_compat_lock(AF_INET6); 1956 xt_compat_lock(AF_INET6);
1957 t = xt_find_table_lock(net, AF_INET6, get.name); 1957 t = xt_find_table_lock(net, AF_INET6, get.name);
1958 if (t && !IS_ERR(t)) { 1958 if (t && !IS_ERR(t)) {
1959 struct xt_table_info *private = t->private; 1959 const struct xt_table_info *private = t->private;
1960 struct xt_table_info info; 1960 struct xt_table_info info;
1961 duprintf("t->private->number = %u\n", private->number); 1961 duprintf("t->private->number = %u\n", private->number);
1962 ret = compat_table_info(private, &info); 1962 ret = compat_table_info(private, &info);
@@ -1966,7 +1966,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
1966 } else if (!ret) { 1966 } else if (!ret) {
1967 duprintf("compat_get_entries: I've got %u not %u!\n", 1967 duprintf("compat_get_entries: I've got %u not %u!\n",
1968 private->size, get.size); 1968 private->size, get.size);
1969 ret = -EINVAL; 1969 ret = -EAGAIN;
1970 } 1970 }
1971 xt_compat_flush_offsets(AF_INET6); 1971 xt_compat_flush_offsets(AF_INET6);
1972 module_put(t->me); 1972 module_put(t->me);
@@ -2155,7 +2155,8 @@ icmp6_match(const struct sk_buff *skb,
2155 unsigned int protoff, 2155 unsigned int protoff,
2156 bool *hotdrop) 2156 bool *hotdrop)
2157{ 2157{
2158 struct icmp6hdr _icmph, *ic; 2158 const struct icmp6hdr *ic;
2159 struct icmp6hdr _icmph;
2159 const struct ip6t_icmp *icmpinfo = matchinfo; 2160 const struct ip6t_icmp *icmpinfo = matchinfo;
2160 2161
2161 /* Must not be a fragment. */ 2162 /* Must not be a fragment. */
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 86a613810b69..3a2316974f83 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -363,11 +363,15 @@ static void dump_packet(const struct nf_loginfo *info,
363 if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) { 363 if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
364 read_lock_bh(&skb->sk->sk_callback_lock); 364 read_lock_bh(&skb->sk->sk_callback_lock);
365 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 365 if (skb->sk->sk_socket && skb->sk->sk_socket->file)
366 printk("UID=%u GID=%u", 366 printk("UID=%u GID=%u ",
367 skb->sk->sk_socket->file->f_uid, 367 skb->sk->sk_socket->file->f_uid,
368 skb->sk->sk_socket->file->f_gid); 368 skb->sk->sk_socket->file->f_gid);
369 read_unlock_bh(&skb->sk->sk_callback_lock); 369 read_unlock_bh(&skb->sk->sk_callback_lock);
370 } 370 }
371
372 /* Max length: 16 "MARK=0xFFFFFFFF " */
373 if (!recurse && skb->mark)
374 printk("MARK=0x%x ", skb->mark);
371} 375}
372 376
373static struct nf_loginfo default_loginfo = { 377static struct nf_loginfo default_loginfo = {
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index baf829075f6f..44c8d65a2431 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -41,7 +41,8 @@ static void send_reset(struct sk_buff *oldskb)
41 struct tcphdr otcph, *tcph; 41 struct tcphdr otcph, *tcph;
42 unsigned int otcplen, hh_len; 42 unsigned int otcplen, hh_len;
43 int tcphoff, needs_ack; 43 int tcphoff, needs_ack;
44 struct ipv6hdr *oip6h = ipv6_hdr(oldskb), *ip6h; 44 const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
45 struct ipv6hdr *ip6h;
45 struct dst_entry *dst = NULL; 46 struct dst_entry *dst = NULL;
46 u8 proto; 47 u8 proto;
47 struct flowi fl; 48 struct flowi fl;
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index 3a940171f829..317a8960a757 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -49,7 +49,8 @@ ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
49 temp = 0; 49 temp = 0;
50 50
51 while (ip6t_ext_hdr(nexthdr)) { 51 while (ip6t_ext_hdr(nexthdr)) {
52 struct ipv6_opt_hdr _hdr, *hp; 52 const struct ipv6_opt_hdr *hp;
53 struct ipv6_opt_hdr _hdr;
53 int hdrlen; 54 int hdrlen;
54 55
55 /* Is there enough space for the next ext header? */ 56 /* Is there enough space for the next ext header? */
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 12a9efe9886e..81aaf7aaaabf 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -110,7 +110,8 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
110 !!(rtinfo->invflags & IP6T_RT_INV_TYP))); 110 !!(rtinfo->invflags & IP6T_RT_INV_TYP)));
111 111
112 if (ret && (rtinfo->flags & IP6T_RT_RES)) { 112 if (ret && (rtinfo->flags & IP6T_RT_RES)) {
113 u_int32_t *rp, _reserved; 113 const u_int32_t *rp;
114 u_int32_t _reserved;
114 rp = skb_header_pointer(skb, 115 rp = skb_header_pointer(skb,
115 ptr + offsetof(struct rt0_hdr, 116 ptr + offsetof(struct rt0_hdr,
116 reserved), 117 reserved),
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 2d9cd095a72c..f979e48b469b 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -54,7 +54,7 @@ static struct
54static struct xt_table packet_filter = { 54static struct xt_table packet_filter = {
55 .name = "filter", 55 .name = "filter",
56 .valid_hooks = FILTER_VALID_HOOKS, 56 .valid_hooks = FILTER_VALID_HOOKS,
57 .lock = RW_LOCK_UNLOCKED, 57 .lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
58 .me = THIS_MODULE, 58 .me = THIS_MODULE,
59 .af = AF_INET6, 59 .af = AF_INET6,
60}; 60};
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 035343a90ffe..27a5e8b48d93 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -60,7 +60,7 @@ static struct
60static struct xt_table packet_mangler = { 60static struct xt_table packet_mangler = {
61 .name = "mangle", 61 .name = "mangle",
62 .valid_hooks = MANGLE_VALID_HOOKS, 62 .valid_hooks = MANGLE_VALID_HOOKS,
63 .lock = RW_LOCK_UNLOCKED, 63 .lock = __RW_LOCK_UNLOCKED(packet_mangler.lock),
64 .me = THIS_MODULE, 64 .me = THIS_MODULE,
65 .af = AF_INET6, 65 .af = AF_INET6,
66}; 66};
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 5cd84203abfe..92b91077ac29 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -38,7 +38,7 @@ static struct
38static struct xt_table packet_raw = { 38static struct xt_table packet_raw = {
39 .name = "raw", 39 .name = "raw",
40 .valid_hooks = RAW_VALID_HOOKS, 40 .valid_hooks = RAW_VALID_HOOKS,
41 .lock = RW_LOCK_UNLOCKED, 41 .lock = __RW_LOCK_UNLOCKED(packet_raw.lock),
42 .me = THIS_MODULE, 42 .me = THIS_MODULE,
43 .af = AF_INET6, 43 .af = AF_INET6,
44}; 44};
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 3717bdf34f6e..85050c072abd 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -27,8 +27,8 @@
27#include <net/netfilter/nf_conntrack_l3proto.h> 27#include <net/netfilter/nf_conntrack_l3proto.h>
28#include <net/netfilter/nf_conntrack_core.h> 28#include <net/netfilter/nf_conntrack_core.h>
29 29
30static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 30static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
31 struct nf_conntrack_tuple *tuple) 31 struct nf_conntrack_tuple *tuple)
32{ 32{
33 const u_int32_t *ap; 33 const u_int32_t *ap;
34 u_int32_t _addrs[8]; 34 u_int32_t _addrs[8];
@@ -36,21 +36,21 @@ static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
36 ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr), 36 ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr),
37 sizeof(_addrs), _addrs); 37 sizeof(_addrs), _addrs);
38 if (ap == NULL) 38 if (ap == NULL)
39 return 0; 39 return false;
40 40
41 memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6)); 41 memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
42 memcpy(tuple->dst.u3.ip6, ap + 4, sizeof(tuple->dst.u3.ip6)); 42 memcpy(tuple->dst.u3.ip6, ap + 4, sizeof(tuple->dst.u3.ip6));
43 43
44 return 1; 44 return true;
45} 45}
46 46
47static int ipv6_invert_tuple(struct nf_conntrack_tuple *tuple, 47static bool ipv6_invert_tuple(struct nf_conntrack_tuple *tuple,
48 const struct nf_conntrack_tuple *orig) 48 const struct nf_conntrack_tuple *orig)
49{ 49{
50 memcpy(tuple->src.u3.ip6, orig->dst.u3.ip6, sizeof(tuple->src.u3.ip6)); 50 memcpy(tuple->src.u3.ip6, orig->dst.u3.ip6, sizeof(tuple->src.u3.ip6));
51 memcpy(tuple->dst.u3.ip6, orig->src.u3.ip6, sizeof(tuple->dst.u3.ip6)); 51 memcpy(tuple->dst.u3.ip6, orig->src.u3.ip6, sizeof(tuple->dst.u3.ip6));
52 52
53 return 1; 53 return true;
54} 54}
55 55
56static int ipv6_print_tuple(struct seq_file *s, 56static int ipv6_print_tuple(struct seq_file *s,
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 0897d0f4c4a2..ee713b03e9ec 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -28,21 +28,21 @@
28 28
29static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ; 29static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
30 30
31static int icmpv6_pkt_to_tuple(const struct sk_buff *skb, 31static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb,
32 unsigned int dataoff, 32 unsigned int dataoff,
33 struct nf_conntrack_tuple *tuple) 33 struct nf_conntrack_tuple *tuple)
34{ 34{
35 const struct icmp6hdr *hp; 35 const struct icmp6hdr *hp;
36 struct icmp6hdr _hdr; 36 struct icmp6hdr _hdr;
37 37
38 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 38 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
39 if (hp == NULL) 39 if (hp == NULL)
40 return 0; 40 return false;
41 tuple->dst.u.icmp.type = hp->icmp6_type; 41 tuple->dst.u.icmp.type = hp->icmp6_type;
42 tuple->src.u.icmp.id = hp->icmp6_identifier; 42 tuple->src.u.icmp.id = hp->icmp6_identifier;
43 tuple->dst.u.icmp.code = hp->icmp6_code; 43 tuple->dst.u.icmp.code = hp->icmp6_code;
44 44
45 return 1; 45 return true;
46} 46}
47 47
48/* Add 1; spaces filled with 0. */ 48/* Add 1; spaces filled with 0. */
@@ -53,17 +53,17 @@ static const u_int8_t invmap[] = {
53 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1 53 [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1
54}; 54};
55 55
56static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, 56static bool icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
57 const struct nf_conntrack_tuple *orig) 57 const struct nf_conntrack_tuple *orig)
58{ 58{
59 int type = orig->dst.u.icmp.type - 128; 59 int type = orig->dst.u.icmp.type - 128;
60 if (type < 0 || type >= sizeof(invmap) || !invmap[type]) 60 if (type < 0 || type >= sizeof(invmap) || !invmap[type])
61 return 0; 61 return false;
62 62
63 tuple->src.u.icmp.id = orig->src.u.icmp.id; 63 tuple->src.u.icmp.id = orig->src.u.icmp.id;
64 tuple->dst.u.icmp.type = invmap[type] - 1; 64 tuple->dst.u.icmp.type = invmap[type] - 1;
65 tuple->dst.u.icmp.code = orig->dst.u.icmp.code; 65 tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
66 return 1; 66 return true;
67} 67}
68 68
69/* Print out the per-protocol part of the tuple. */ 69/* Print out the per-protocol part of the tuple. */
@@ -102,9 +102,8 @@ static int icmpv6_packet(struct nf_conn *ct,
102} 102}
103 103
104/* Called when a new connection for this protocol found. */ 104/* Called when a new connection for this protocol found. */
105static int icmpv6_new(struct nf_conn *ct, 105static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
106 const struct sk_buff *skb, 106 unsigned int dataoff)
107 unsigned int dataoff)
108{ 107{
109 static const u_int8_t valid_new[] = { 108 static const u_int8_t valid_new[] = {
110 [ICMPV6_ECHO_REQUEST - 128] = 1, 109 [ICMPV6_ECHO_REQUEST - 128] = 1,
@@ -116,11 +115,11 @@ static int icmpv6_new(struct nf_conn *ct,
116 /* Can't create a new ICMPv6 `conn' with this. */ 115 /* Can't create a new ICMPv6 `conn' with this. */
117 pr_debug("icmpv6: can't create new conn with type %u\n", 116 pr_debug("icmpv6: can't create new conn with type %u\n",
118 type + 128); 117 type + 128);
119 NF_CT_DUMP_TUPLE(&ct->tuplehash[0].tuple); 118 nf_ct_dump_tuple_ipv6(&ct->tuplehash[0].tuple);
120 return 0; 119 return false;
121 } 120 }
122 atomic_set(&ct->proto.icmp.count, 0); 121 atomic_set(&ct->proto.icmp.count, 0);
123 return 1; 122 return true;
124} 123}
125 124
126static int 125static int
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 9e5f305b2022..2dccad48058c 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -103,8 +103,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
103}; 103};
104#endif 104#endif
105 105
106static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, 106static unsigned int ip6qhashfn(__be32 id, const struct in6_addr *saddr,
107 struct in6_addr *daddr) 107 const struct in6_addr *daddr)
108{ 108{
109 u32 a, b, c; 109 u32 a, b, c;
110 110
@@ -132,7 +132,7 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
132 132
133static unsigned int nf_hashfn(struct inet_frag_queue *q) 133static unsigned int nf_hashfn(struct inet_frag_queue *q)
134{ 134{
135 struct nf_ct_frag6_queue *nq; 135 const struct nf_ct_frag6_queue *nq;
136 136
137 nq = container_of(q, struct nf_ct_frag6_queue, q); 137 nq = container_of(q, struct nf_ct_frag6_queue, q);
138 return ip6qhashfn(nq->id, &nq->saddr, &nq->daddr); 138 return ip6qhashfn(nq->id, &nq->saddr, &nq->daddr);
@@ -222,7 +222,7 @@ oom:
222 222
223 223
224static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, 224static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
225 struct frag_hdr *fhdr, int nhoff) 225 const struct frag_hdr *fhdr, int nhoff)
226{ 226{
227 struct sk_buff *prev, *next; 227 struct sk_buff *prev, *next;
228 int offset, end; 228 int offset, end;
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index daf5b881064d..c1fc0f1a641c 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -86,6 +86,16 @@ config NF_CONNTRACK_EVENTS
86 86
87 If unsure, say `N'. 87 If unsure, say `N'.
88 88
89config NF_CT_PROTO_DCCP
90 tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
91 depends on EXPERIMENTAL && NF_CONNTRACK
92 depends on NETFILTER_ADVANCED
93 help
94 With this option enabled, the layer 3 independent connection
95 tracking code will be able to do state tracking on DCCP connections.
96
97 If unsure, say 'N'.
98
89config NF_CT_PROTO_GRE 99config NF_CT_PROTO_GRE
90 tristate 100 tristate
91 depends on NF_CONNTRACK 101 depends on NF_CONNTRACK
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index ea7508387f95..5c4b183f6422 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
13obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o 13obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
14 14
15# SCTP protocol connection tracking 15# SCTP protocol connection tracking
16obj-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
16obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o 17obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
17obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o 18obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
18obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o 19obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index d14585a19b7d..38aedeeaf4e1 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -53,7 +53,7 @@ enum amanda_strings {
53}; 53};
54 54
55static struct { 55static struct {
56 char *string; 56 const char *string;
57 size_t len; 57 size_t len;
58 struct ts_config *ts; 58 struct ts_config *ts;
59} search[] __read_mostly = { 59} search[] __read_mostly = {
@@ -91,7 +91,6 @@ static int amanda_help(struct sk_buff *skb,
91 char pbuf[sizeof("65535")], *tmp; 91 char pbuf[sizeof("65535")], *tmp;
92 u_int16_t len; 92 u_int16_t len;
93 __be16 port; 93 __be16 port;
94 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
95 int ret = NF_ACCEPT; 94 int ret = NF_ACCEPT;
96 typeof(nf_nat_amanda_hook) nf_nat_amanda; 95 typeof(nf_nat_amanda_hook) nf_nat_amanda;
97 96
@@ -148,7 +147,8 @@ static int amanda_help(struct sk_buff *skb,
148 goto out; 147 goto out;
149 } 148 }
150 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 149 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
151 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, family, 150 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
151 nf_ct_l3num(ct),
152 &tuple->src.u3, &tuple->dst.u3, 152 &tuple->src.u3, &tuple->dst.u3,
153 IPPROTO_TCP, NULL, &port); 153 IPPROTO_TCP, NULL, &port);
154 154
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b77eb56a87e3..4eac65c74ed0 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -94,7 +94,7 @@ static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
94 nf_conntrack_hash_rnd); 94 nf_conntrack_hash_rnd);
95} 95}
96 96
97int 97bool
98nf_ct_get_tuple(const struct sk_buff *skb, 98nf_ct_get_tuple(const struct sk_buff *skb,
99 unsigned int nhoff, 99 unsigned int nhoff,
100 unsigned int dataoff, 100 unsigned int dataoff,
@@ -108,7 +108,7 @@ nf_ct_get_tuple(const struct sk_buff *skb,
108 108
109 tuple->src.l3num = l3num; 109 tuple->src.l3num = l3num;
110 if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0) 110 if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
111 return 0; 111 return false;
112 112
113 tuple->dst.protonum = protonum; 113 tuple->dst.protonum = protonum;
114 tuple->dst.dir = IP_CT_DIR_ORIGINAL; 114 tuple->dst.dir = IP_CT_DIR_ORIGINAL;
@@ -117,10 +117,8 @@ nf_ct_get_tuple(const struct sk_buff *skb,
117} 117}
118EXPORT_SYMBOL_GPL(nf_ct_get_tuple); 118EXPORT_SYMBOL_GPL(nf_ct_get_tuple);
119 119
120int nf_ct_get_tuplepr(const struct sk_buff *skb, 120bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff,
121 unsigned int nhoff, 121 u_int16_t l3num, struct nf_conntrack_tuple *tuple)
122 u_int16_t l3num,
123 struct nf_conntrack_tuple *tuple)
124{ 122{
125 struct nf_conntrack_l3proto *l3proto; 123 struct nf_conntrack_l3proto *l3proto;
126 struct nf_conntrack_l4proto *l4proto; 124 struct nf_conntrack_l4proto *l4proto;
@@ -134,7 +132,7 @@ int nf_ct_get_tuplepr(const struct sk_buff *skb,
134 ret = l3proto->get_l4proto(skb, nhoff, &protoff, &protonum); 132 ret = l3proto->get_l4proto(skb, nhoff, &protoff, &protonum);
135 if (ret != NF_ACCEPT) { 133 if (ret != NF_ACCEPT) {
136 rcu_read_unlock(); 134 rcu_read_unlock();
137 return 0; 135 return false;
138 } 136 }
139 137
140 l4proto = __nf_ct_l4proto_find(l3num, protonum); 138 l4proto = __nf_ct_l4proto_find(l3num, protonum);
@@ -147,7 +145,7 @@ int nf_ct_get_tuplepr(const struct sk_buff *skb,
147} 145}
148EXPORT_SYMBOL_GPL(nf_ct_get_tuplepr); 146EXPORT_SYMBOL_GPL(nf_ct_get_tuplepr);
149 147
150int 148bool
151nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, 149nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
152 const struct nf_conntrack_tuple *orig, 150 const struct nf_conntrack_tuple *orig,
153 const struct nf_conntrack_l3proto *l3proto, 151 const struct nf_conntrack_l3proto *l3proto,
@@ -157,7 +155,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
157 155
158 inverse->src.l3num = orig->src.l3num; 156 inverse->src.l3num = orig->src.l3num;
159 if (l3proto->invert_tuple(inverse, orig) == 0) 157 if (l3proto->invert_tuple(inverse, orig) == 0)
160 return 0; 158 return false;
161 159
162 inverse->dst.dir = !orig->dst.dir; 160 inverse->dst.dir = !orig->dst.dir;
163 161
@@ -194,8 +192,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
194 * destroy_conntrack() MUST NOT be called with a write lock 192 * destroy_conntrack() MUST NOT be called with a write lock
195 * to nf_conntrack_lock!!! -HW */ 193 * to nf_conntrack_lock!!! -HW */
196 rcu_read_lock(); 194 rcu_read_lock();
197 l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, 195 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
198 ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
199 if (l4proto && l4proto->destroy) 196 if (l4proto && l4proto->destroy)
200 l4proto->destroy(ct); 197 l4proto->destroy(ct);
201 198
@@ -739,10 +736,10 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb)
739} 736}
740EXPORT_SYMBOL_GPL(nf_conntrack_in); 737EXPORT_SYMBOL_GPL(nf_conntrack_in);
741 738
742int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 739bool nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
743 const struct nf_conntrack_tuple *orig) 740 const struct nf_conntrack_tuple *orig)
744{ 741{
745 int ret; 742 bool ret;
746 743
747 rcu_read_lock(); 744 rcu_read_lock();
748 ret = nf_ct_invert_tuple(inverse, orig, 745 ret = nf_ct_invert_tuple(inverse, orig,
@@ -766,10 +763,10 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
766 NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); 763 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
767 764
768 pr_debug("Altering reply tuple of %p to ", ct); 765 pr_debug("Altering reply tuple of %p to ", ct);
769 NF_CT_DUMP_TUPLE(newreply); 766 nf_ct_dump_tuple(newreply);
770 767
771 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; 768 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
772 if (ct->master || (help && help->expecting != 0)) 769 if (ct->master || (help && !hlist_empty(&help->expectations)))
773 return; 770 return;
774 771
775 rcu_read_lock(); 772 rcu_read_lock();
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
index 2bd9963b5b3e..bcc19fa4ed1e 100644
--- a/net/netfilter/nf_conntrack_extend.c
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -71,6 +71,9 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
71 int i, newlen, newoff; 71 int i, newlen, newoff;
72 struct nf_ct_ext_type *t; 72 struct nf_ct_ext_type *t;
73 73
74 /* Conntrack must not be confirmed to avoid races on reallocation. */
75 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
76
74 if (!ct->ext) 77 if (!ct->ext)
75 return nf_ct_ext_create(&ct->ext, id, gfp); 78 return nf_ct_ext_create(&ct->ext, id, gfp);
76 79
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 7eff876bb8bc..bb20672fe036 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -350,8 +350,9 @@ static int help(struct sk_buff *skb,
350 enum ip_conntrack_info ctinfo) 350 enum ip_conntrack_info ctinfo)
351{ 351{
352 unsigned int dataoff, datalen; 352 unsigned int dataoff, datalen;
353 struct tcphdr _tcph, *th; 353 const struct tcphdr *th;
354 char *fb_ptr; 354 struct tcphdr _tcph;
355 const char *fb_ptr;
355 int ret; 356 int ret;
356 u32 seq; 357 u32 seq;
357 int dir = CTINFO2DIR(ctinfo); 358 int dir = CTINFO2DIR(ctinfo);
@@ -405,7 +406,7 @@ static int help(struct sk_buff *skb,
405 406
406 /* Initialize IP/IPv6 addr to expected address (it's not mentioned 407 /* Initialize IP/IPv6 addr to expected address (it's not mentioned
407 in EPSV responses) */ 408 in EPSV responses) */
408 cmd.l3num = ct->tuplehash[dir].tuple.src.l3num; 409 cmd.l3num = nf_ct_l3num(ct);
409 memcpy(cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all, 410 memcpy(cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
410 sizeof(cmd.u3.all)); 411 sizeof(cmd.u3.all));
411 412
@@ -452,7 +453,7 @@ static int help(struct sk_buff *skb,
452 daddr = &ct->tuplehash[!dir].tuple.dst.u3; 453 daddr = &ct->tuplehash[!dir].tuple.dst.u3;
453 454
454 /* Update the ftp info */ 455 /* Update the ftp info */
455 if ((cmd.l3num == ct->tuplehash[dir].tuple.src.l3num) && 456 if ((cmd.l3num == nf_ct_l3num(ct)) &&
456 memcmp(&cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all, 457 memcmp(&cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
457 sizeof(cmd.u3.all))) { 458 sizeof(cmd.u3.all))) {
458 /* Enrico Scholz's passive FTP to partially RNAT'd ftp 459 /* Enrico Scholz's passive FTP to partially RNAT'd ftp
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 505052d495cf..95da1a24aab7 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -218,7 +218,6 @@ static int get_h245_addr(struct nf_conn *ct, const unsigned char *data,
218 union nf_inet_addr *addr, __be16 *port) 218 union nf_inet_addr *addr, __be16 *port)
219{ 219{
220 const unsigned char *p; 220 const unsigned char *p;
221 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
222 int len; 221 int len;
223 222
224 if (taddr->choice != eH245_TransportAddress_unicastAddress) 223 if (taddr->choice != eH245_TransportAddress_unicastAddress)
@@ -226,13 +225,13 @@ static int get_h245_addr(struct nf_conn *ct, const unsigned char *data,
226 225
227 switch (taddr->unicastAddress.choice) { 226 switch (taddr->unicastAddress.choice) {
228 case eUnicastAddress_iPAddress: 227 case eUnicastAddress_iPAddress:
229 if (family != AF_INET) 228 if (nf_ct_l3num(ct) != AF_INET)
230 return 0; 229 return 0;
231 p = data + taddr->unicastAddress.iPAddress.network; 230 p = data + taddr->unicastAddress.iPAddress.network;
232 len = 4; 231 len = 4;
233 break; 232 break;
234 case eUnicastAddress_iP6Address: 233 case eUnicastAddress_iP6Address:
235 if (family != AF_INET6) 234 if (nf_ct_l3num(ct) != AF_INET6)
236 return 0; 235 return 0;
237 p = data + taddr->unicastAddress.iP6Address.network; 236 p = data + taddr->unicastAddress.iP6Address.network;
238 len = 16; 237 len = 16;
@@ -277,8 +276,7 @@ static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
277 /* Create expect for RTP */ 276 /* Create expect for RTP */
278 if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL) 277 if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL)
279 return -1; 278 return -1;
280 nf_ct_expect_init(rtp_exp, NF_CT_EXPECT_CLASS_DEFAULT, 279 nf_ct_expect_init(rtp_exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
281 ct->tuplehash[!dir].tuple.src.l3num,
282 &ct->tuplehash[!dir].tuple.src.u3, 280 &ct->tuplehash[!dir].tuple.src.u3,
283 &ct->tuplehash[!dir].tuple.dst.u3, 281 &ct->tuplehash[!dir].tuple.dst.u3,
284 IPPROTO_UDP, NULL, &rtp_port); 282 IPPROTO_UDP, NULL, &rtp_port);
@@ -288,8 +286,7 @@ static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
288 nf_ct_expect_put(rtp_exp); 286 nf_ct_expect_put(rtp_exp);
289 return -1; 287 return -1;
290 } 288 }
291 nf_ct_expect_init(rtcp_exp, NF_CT_EXPECT_CLASS_DEFAULT, 289 nf_ct_expect_init(rtcp_exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
292 ct->tuplehash[!dir].tuple.src.l3num,
293 &ct->tuplehash[!dir].tuple.src.u3, 290 &ct->tuplehash[!dir].tuple.src.u3,
294 &ct->tuplehash[!dir].tuple.dst.u3, 291 &ct->tuplehash[!dir].tuple.dst.u3,
295 IPPROTO_UDP, NULL, &rtcp_port); 292 IPPROTO_UDP, NULL, &rtcp_port);
@@ -306,9 +303,9 @@ static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
306 if (nf_ct_expect_related(rtp_exp) == 0) { 303 if (nf_ct_expect_related(rtp_exp) == 0) {
307 if (nf_ct_expect_related(rtcp_exp) == 0) { 304 if (nf_ct_expect_related(rtcp_exp) == 0) {
308 pr_debug("nf_ct_h323: expect RTP "); 305 pr_debug("nf_ct_h323: expect RTP ");
309 NF_CT_DUMP_TUPLE(&rtp_exp->tuple); 306 nf_ct_dump_tuple(&rtp_exp->tuple);
310 pr_debug("nf_ct_h323: expect RTCP "); 307 pr_debug("nf_ct_h323: expect RTCP ");
311 NF_CT_DUMP_TUPLE(&rtcp_exp->tuple); 308 nf_ct_dump_tuple(&rtcp_exp->tuple);
312 } else { 309 } else {
313 nf_ct_unexpect_related(rtp_exp); 310 nf_ct_unexpect_related(rtp_exp);
314 ret = -1; 311 ret = -1;
@@ -346,8 +343,7 @@ static int expect_t120(struct sk_buff *skb,
346 /* Create expect for T.120 connections */ 343 /* Create expect for T.120 connections */
347 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 344 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
348 return -1; 345 return -1;
349 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 346 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
350 ct->tuplehash[!dir].tuple.src.l3num,
351 &ct->tuplehash[!dir].tuple.src.u3, 347 &ct->tuplehash[!dir].tuple.src.u3,
352 &ct->tuplehash[!dir].tuple.dst.u3, 348 &ct->tuplehash[!dir].tuple.dst.u3,
353 IPPROTO_TCP, NULL, &port); 349 IPPROTO_TCP, NULL, &port);
@@ -364,7 +360,7 @@ static int expect_t120(struct sk_buff *skb,
364 } else { /* Conntrack only */ 360 } else { /* Conntrack only */
365 if (nf_ct_expect_related(exp) == 0) { 361 if (nf_ct_expect_related(exp) == 0) {
366 pr_debug("nf_ct_h323: expect T.120 "); 362 pr_debug("nf_ct_h323: expect T.120 ");
367 NF_CT_DUMP_TUPLE(&exp->tuple); 363 nf_ct_dump_tuple(&exp->tuple);
368 } else 364 } else
369 ret = -1; 365 ret = -1;
370 } 366 }
@@ -586,7 +582,7 @@ static int h245_help(struct sk_buff *skb, unsigned int protoff,
586 while (get_tpkt_data(skb, protoff, ct, ctinfo, 582 while (get_tpkt_data(skb, protoff, ct, ctinfo,
587 &data, &datalen, &dataoff)) { 583 &data, &datalen, &dataoff)) {
588 pr_debug("nf_ct_h245: TPKT len=%d ", datalen); 584 pr_debug("nf_ct_h245: TPKT len=%d ", datalen);
589 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); 585 nf_ct_dump_tuple(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
590 586
591 /* Decode H.245 signal */ 587 /* Decode H.245 signal */
592 ret = DecodeMultimediaSystemControlMessage(data, datalen, 588 ret = DecodeMultimediaSystemControlMessage(data, datalen,
@@ -634,18 +630,17 @@ int get_h225_addr(struct nf_conn *ct, unsigned char *data,
634 union nf_inet_addr *addr, __be16 *port) 630 union nf_inet_addr *addr, __be16 *port)
635{ 631{
636 const unsigned char *p; 632 const unsigned char *p;
637 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
638 int len; 633 int len;
639 634
640 switch (taddr->choice) { 635 switch (taddr->choice) {
641 case eTransportAddress_ipAddress: 636 case eTransportAddress_ipAddress:
642 if (family != AF_INET) 637 if (nf_ct_l3num(ct) != AF_INET)
643 return 0; 638 return 0;
644 p = data + taddr->ipAddress.ip; 639 p = data + taddr->ipAddress.ip;
645 len = 4; 640 len = 4;
646 break; 641 break;
647 case eTransportAddress_ip6Address: 642 case eTransportAddress_ip6Address:
648 if (family != AF_INET6) 643 if (nf_ct_l3num(ct) != AF_INET6)
649 return 0; 644 return 0;
650 p = data + taddr->ip6Address.ip; 645 p = data + taddr->ip6Address.ip;
651 len = 16; 646 len = 16;
@@ -683,8 +678,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
683 /* Create expect for h245 connection */ 678 /* Create expect for h245 connection */
684 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 679 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
685 return -1; 680 return -1;
686 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 681 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
687 ct->tuplehash[!dir].tuple.src.l3num,
688 &ct->tuplehash[!dir].tuple.src.u3, 682 &ct->tuplehash[!dir].tuple.src.u3,
689 &ct->tuplehash[!dir].tuple.dst.u3, 683 &ct->tuplehash[!dir].tuple.dst.u3,
690 IPPROTO_TCP, NULL, &port); 684 IPPROTO_TCP, NULL, &port);
@@ -701,7 +695,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
701 } else { /* Conntrack only */ 695 } else { /* Conntrack only */
702 if (nf_ct_expect_related(exp) == 0) { 696 if (nf_ct_expect_related(exp) == 0) {
703 pr_debug("nf_ct_q931: expect H.245 "); 697 pr_debug("nf_ct_q931: expect H.245 ");
704 NF_CT_DUMP_TUPLE(&exp->tuple); 698 nf_ct_dump_tuple(&exp->tuple);
705 } else 699 } else
706 ret = -1; 700 ret = -1;
707 } 701 }
@@ -792,7 +786,7 @@ static int expect_callforwarding(struct sk_buff *skb,
792 * we don't need to track the second call */ 786 * we don't need to track the second call */
793 if (callforward_filter && 787 if (callforward_filter &&
794 callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3, 788 callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3,
795 ct->tuplehash[!dir].tuple.src.l3num)) { 789 nf_ct_l3num(ct))) {
796 pr_debug("nf_ct_q931: Call Forwarding not tracked\n"); 790 pr_debug("nf_ct_q931: Call Forwarding not tracked\n");
797 return 0; 791 return 0;
798 } 792 }
@@ -800,8 +794,7 @@ static int expect_callforwarding(struct sk_buff *skb,
800 /* Create expect for the second call leg */ 794 /* Create expect for the second call leg */
801 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 795 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
802 return -1; 796 return -1;
803 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 797 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
804 ct->tuplehash[!dir].tuple.src.l3num,
805 &ct->tuplehash[!dir].tuple.src.u3, &addr, 798 &ct->tuplehash[!dir].tuple.src.u3, &addr,
806 IPPROTO_TCP, NULL, &port); 799 IPPROTO_TCP, NULL, &port);
807 exp->helper = nf_conntrack_helper_q931; 800 exp->helper = nf_conntrack_helper_q931;
@@ -817,7 +810,7 @@ static int expect_callforwarding(struct sk_buff *skb,
817 } else { /* Conntrack only */ 810 } else { /* Conntrack only */
818 if (nf_ct_expect_related(exp) == 0) { 811 if (nf_ct_expect_related(exp) == 0) {
819 pr_debug("nf_ct_q931: expect Call Forwarding "); 812 pr_debug("nf_ct_q931: expect Call Forwarding ");
820 NF_CT_DUMP_TUPLE(&exp->tuple); 813 nf_ct_dump_tuple(&exp->tuple);
821 } else 814 } else
822 ret = -1; 815 ret = -1;
823 } 816 }
@@ -1137,7 +1130,7 @@ static int q931_help(struct sk_buff *skb, unsigned int protoff,
1137 while (get_tpkt_data(skb, protoff, ct, ctinfo, 1130 while (get_tpkt_data(skb, protoff, ct, ctinfo,
1138 &data, &datalen, &dataoff)) { 1131 &data, &datalen, &dataoff)) {
1139 pr_debug("nf_ct_q931: TPKT len=%d ", datalen); 1132 pr_debug("nf_ct_q931: TPKT len=%d ", datalen);
1140 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); 1133 nf_ct_dump_tuple(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
1141 1134
1142 /* Decode Q.931 signal */ 1135 /* Decode Q.931 signal */
1143 ret = DecodeQ931(data, datalen, &q931); 1136 ret = DecodeQ931(data, datalen, &q931);
@@ -1272,8 +1265,7 @@ static int expect_q931(struct sk_buff *skb, struct nf_conn *ct,
1272 /* Create expect for Q.931 */ 1265 /* Create expect for Q.931 */
1273 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1266 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1274 return -1; 1267 return -1;
1275 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 1268 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
1276 ct->tuplehash[!dir].tuple.src.l3num,
1277 gkrouted_only ? /* only accept calls from GK? */ 1269 gkrouted_only ? /* only accept calls from GK? */
1278 &ct->tuplehash[!dir].tuple.src.u3 : NULL, 1270 &ct->tuplehash[!dir].tuple.src.u3 : NULL,
1279 &ct->tuplehash[!dir].tuple.dst.u3, 1271 &ct->tuplehash[!dir].tuple.dst.u3,
@@ -1287,7 +1279,7 @@ static int expect_q931(struct sk_buff *skb, struct nf_conn *ct,
1287 } else { /* Conntrack only */ 1279 } else { /* Conntrack only */
1288 if (nf_ct_expect_related(exp) == 0) { 1280 if (nf_ct_expect_related(exp) == 0) {
1289 pr_debug("nf_ct_ras: expect Q.931 "); 1281 pr_debug("nf_ct_ras: expect Q.931 ");
1290 NF_CT_DUMP_TUPLE(&exp->tuple); 1282 nf_ct_dump_tuple(&exp->tuple);
1291 1283
1292 /* Save port for looking up expect in processing RCF */ 1284 /* Save port for looking up expect in processing RCF */
1293 info->sig_port[dir] = port; 1285 info->sig_port[dir] = port;
@@ -1344,15 +1336,14 @@ static int process_gcf(struct sk_buff *skb, struct nf_conn *ct,
1344 /* Need new expect */ 1336 /* Need new expect */
1345 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1337 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1346 return -1; 1338 return -1;
1347 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 1339 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
1348 ct->tuplehash[!dir].tuple.src.l3num,
1349 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1340 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1350 IPPROTO_UDP, NULL, &port); 1341 IPPROTO_UDP, NULL, &port);
1351 exp->helper = nf_conntrack_helper_ras; 1342 exp->helper = nf_conntrack_helper_ras;
1352 1343
1353 if (nf_ct_expect_related(exp) == 0) { 1344 if (nf_ct_expect_related(exp) == 0) {
1354 pr_debug("nf_ct_ras: expect RAS "); 1345 pr_debug("nf_ct_ras: expect RAS ");
1355 NF_CT_DUMP_TUPLE(&exp->tuple); 1346 nf_ct_dump_tuple(&exp->tuple);
1356 } else 1347 } else
1357 ret = -1; 1348 ret = -1;
1358 1349
@@ -1436,7 +1427,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
1436 pr_debug("nf_ct_ras: set Q.931 expect " 1427 pr_debug("nf_ct_ras: set Q.931 expect "
1437 "timeout to %u seconds for", 1428 "timeout to %u seconds for",
1438 info->timeout); 1429 info->timeout);
1439 NF_CT_DUMP_TUPLE(&exp->tuple); 1430 nf_ct_dump_tuple(&exp->tuple);
1440 set_expect_timeout(exp, info->timeout); 1431 set_expect_timeout(exp, info->timeout);
1441 } 1432 }
1442 spin_unlock_bh(&nf_conntrack_lock); 1433 spin_unlock_bh(&nf_conntrack_lock);
@@ -1549,8 +1540,7 @@ static int process_acf(struct sk_buff *skb, struct nf_conn *ct,
1549 /* Need new expect */ 1540 /* Need new expect */
1550 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1541 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1551 return -1; 1542 return -1;
1552 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 1543 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
1553 ct->tuplehash[!dir].tuple.src.l3num,
1554 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1544 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1555 IPPROTO_TCP, NULL, &port); 1545 IPPROTO_TCP, NULL, &port);
1556 exp->flags = NF_CT_EXPECT_PERMANENT; 1546 exp->flags = NF_CT_EXPECT_PERMANENT;
@@ -1558,7 +1548,7 @@ static int process_acf(struct sk_buff *skb, struct nf_conn *ct,
1558 1548
1559 if (nf_ct_expect_related(exp) == 0) { 1549 if (nf_ct_expect_related(exp) == 0) {
1560 pr_debug("nf_ct_ras: expect Q.931 "); 1550 pr_debug("nf_ct_ras: expect Q.931 ");
1561 NF_CT_DUMP_TUPLE(&exp->tuple); 1551 nf_ct_dump_tuple(&exp->tuple);
1562 } else 1552 } else
1563 ret = -1; 1553 ret = -1;
1564 1554
@@ -1603,8 +1593,7 @@ static int process_lcf(struct sk_buff *skb, struct nf_conn *ct,
1603 /* Need new expect for call signal */ 1593 /* Need new expect for call signal */
1604 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1594 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1605 return -1; 1595 return -1;
1606 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 1596 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
1607 ct->tuplehash[!dir].tuple.src.l3num,
1608 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1597 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1609 IPPROTO_TCP, NULL, &port); 1598 IPPROTO_TCP, NULL, &port);
1610 exp->flags = NF_CT_EXPECT_PERMANENT; 1599 exp->flags = NF_CT_EXPECT_PERMANENT;
@@ -1612,7 +1601,7 @@ static int process_lcf(struct sk_buff *skb, struct nf_conn *ct,
1612 1601
1613 if (nf_ct_expect_related(exp) == 0) { 1602 if (nf_ct_expect_related(exp) == 0) {
1614 pr_debug("nf_ct_ras: expect Q.931 "); 1603 pr_debug("nf_ct_ras: expect Q.931 ");
1615 NF_CT_DUMP_TUPLE(&exp->tuple); 1604 nf_ct_dump_tuple(&exp->tuple);
1616 } else 1605 } else
1617 ret = -1; 1606 ret = -1;
1618 1607
@@ -1716,7 +1705,7 @@ static int ras_help(struct sk_buff *skb, unsigned int protoff,
1716 if (data == NULL) 1705 if (data == NULL)
1717 goto accept; 1706 goto accept;
1718 pr_debug("nf_ct_ras: RAS message len=%d ", datalen); 1707 pr_debug("nf_ct_ras: RAS message len=%d ", datalen);
1719 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); 1708 nf_ct_dump_tuple(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
1720 1709
1721 /* Decode RAS message */ 1710 /* Decode RAS message */
1722 ret = DecodeRasMessage(data, datalen, &ras); 1711 ret = DecodeRasMessage(data, datalen, &ras);
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index e350f56d43c9..7d1b11703741 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -126,7 +126,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
126{ 126{
127 struct nf_conntrack_tuple_hash *h; 127 struct nf_conntrack_tuple_hash *h;
128 struct nf_conntrack_expect *exp; 128 struct nf_conntrack_expect *exp;
129 struct hlist_node *n, *next; 129 const struct hlist_node *n, *next;
130 unsigned int i; 130 unsigned int i;
131 131
132 mutex_lock(&nf_ct_helper_mutex); 132 mutex_lock(&nf_ct_helper_mutex);
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 02f21cbe5ae7..1b1226d6653f 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per "
50module_param(dcc_timeout, uint, 0400); 50module_param(dcc_timeout, uint, 0400);
51MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); 51MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
52 52
53static const char *dccprotos[] = { 53static const char *const dccprotos[] = {
54 "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " 54 "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT "
55}; 55};
56 56
@@ -65,7 +65,7 @@ static const char *dccprotos[] = {
65 * ad_beg_p returns pointer to first byte of addr data 65 * ad_beg_p returns pointer to first byte of addr data
66 * ad_end_p returns pointer to last byte of addr data 66 * ad_end_p returns pointer to last byte of addr data
67 */ 67 */
68static int parse_dcc(char *data, char *data_end, u_int32_t *ip, 68static int parse_dcc(char *data, const char *data_end, u_int32_t *ip,
69 u_int16_t *port, char **ad_beg_p, char **ad_end_p) 69 u_int16_t *port, char **ad_beg_p, char **ad_end_p)
70{ 70{
71 /* at least 12: "AAAAAAAA P\1\n" */ 71 /* at least 12: "AAAAAAAA P\1\n" */
@@ -93,9 +93,11 @@ static int help(struct sk_buff *skb, unsigned int protoff,
93 struct nf_conn *ct, enum ip_conntrack_info ctinfo) 93 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
94{ 94{
95 unsigned int dataoff; 95 unsigned int dataoff;
96 struct iphdr *iph; 96 const struct iphdr *iph;
97 struct tcphdr _tcph, *th; 97 const struct tcphdr *th;
98 char *data, *data_limit, *ib_ptr; 98 struct tcphdr _tcph;
99 const char *data_limit;
100 char *data, *ib_ptr;
99 int dir = CTINFO2DIR(ctinfo); 101 int dir = CTINFO2DIR(ctinfo);
100 struct nf_conntrack_expect *exp; 102 struct nf_conntrack_expect *exp;
101 struct nf_conntrack_tuple *tuple; 103 struct nf_conntrack_tuple *tuple;
@@ -159,7 +161,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
159 /* we have at least 161 /* we have at least
160 * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid 162 * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
161 * data left (== 14/13 bytes) */ 163 * data left (== 14/13 bytes) */
162 if (parse_dcc((char *)data, data_limit, &dcc_ip, 164 if (parse_dcc(data, data_limit, &dcc_ip,
163 &dcc_port, &addr_beg_p, &addr_end_p)) { 165 &dcc_port, &addr_beg_p, &addr_end_p)) {
164 pr_debug("unable to parse dcc command\n"); 166 pr_debug("unable to parse dcc command\n");
165 continue; 167 continue;
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
index 8e914e5ffea8..e7eb807fe07d 100644
--- a/net/netfilter/nf_conntrack_l3proto_generic.c
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -31,22 +31,22 @@
31#include <net/netfilter/nf_conntrack_core.h> 31#include <net/netfilter/nf_conntrack_core.h>
32#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 32#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
33 33
34static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 34static bool generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
35 struct nf_conntrack_tuple *tuple) 35 struct nf_conntrack_tuple *tuple)
36{ 36{
37 memset(&tuple->src.u3, 0, sizeof(tuple->src.u3)); 37 memset(&tuple->src.u3, 0, sizeof(tuple->src.u3));
38 memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3)); 38 memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3));
39 39
40 return 1; 40 return true;
41} 41}
42 42
43static int generic_invert_tuple(struct nf_conntrack_tuple *tuple, 43static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple,
44 const struct nf_conntrack_tuple *orig) 44 const struct nf_conntrack_tuple *orig)
45{ 45{
46 memset(&tuple->src.u3, 0, sizeof(tuple->src.u3)); 46 memset(&tuple->src.u3, 0, sizeof(tuple->src.u3));
47 memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3)); 47 memset(&tuple->dst.u3, 0, sizeof(tuple->dst.u3));
48 48
49 return 1; 49 return true;
50} 50}
51 51
52static int generic_print_tuple(struct seq_file *s, 52static int generic_print_tuple(struct seq_file *s,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 4a1b42b2b7a5..16774ecd1c4e 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -145,10 +145,11 @@ nla_put_failure:
145static inline int 145static inline int
146ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) 146ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
147{ 147{
148 struct nf_conntrack_l4proto *l4proto = nf_ct_l4proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 148 struct nf_conntrack_l4proto *l4proto;
149 struct nlattr *nest_proto; 149 struct nlattr *nest_proto;
150 int ret; 150 int ret;
151 151
152 l4proto = nf_ct_l4proto_find_get(nf_ct_l3num(ct), nf_ct_protonum(ct));
152 if (!l4proto->to_nlattr) { 153 if (!l4proto->to_nlattr) {
153 nf_ct_l4proto_put(l4proto); 154 nf_ct_l4proto_put(l4proto);
154 return 0; 155 return 0;
@@ -368,8 +369,7 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
368 nfmsg = NLMSG_DATA(nlh); 369 nfmsg = NLMSG_DATA(nlh);
369 370
370 nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0; 371 nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
371 nfmsg->nfgen_family = 372 nfmsg->nfgen_family = nf_ct_l3num(ct);
372 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
373 nfmsg->version = NFNETLINK_V0; 373 nfmsg->version = NFNETLINK_V0;
374 nfmsg->res_id = 0; 374 nfmsg->res_id = 0;
375 375
@@ -454,7 +454,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
454 nfmsg = NLMSG_DATA(nlh); 454 nfmsg = NLMSG_DATA(nlh);
455 455
456 nlh->nlmsg_flags = flags; 456 nlh->nlmsg_flags = flags;
457 nfmsg->nfgen_family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; 457 nfmsg->nfgen_family = nf_ct_l3num(ct);
458 nfmsg->version = NFNETLINK_V0; 458 nfmsg->version = NFNETLINK_V0;
459 nfmsg->res_id = 0; 459 nfmsg->res_id = 0;
460 460
@@ -535,8 +535,6 @@ static int ctnetlink_done(struct netlink_callback *cb)
535 return 0; 535 return 0;
536} 536}
537 537
538#define L3PROTO(ct) (ct)->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num
539
540static int 538static int
541ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 539ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
542{ 540{
@@ -558,7 +556,7 @@ restart:
558 /* Dump entries of a given L3 protocol number. 556 /* Dump entries of a given L3 protocol number.
559 * If it is not specified, ie. l3proto == 0, 557 * If it is not specified, ie. l3proto == 0,
560 * then dump everything. */ 558 * then dump everything. */
561 if (l3proto && L3PROTO(ct) != l3proto) 559 if (l3proto && nf_ct_l3num(ct) != l3proto)
562 continue; 560 continue;
563 if (cb->args[1]) { 561 if (cb->args[1]) {
564 if (ct != last) 562 if (ct != last)
@@ -704,20 +702,11 @@ static int nfnetlink_parse_nat_proto(struct nlattr *attr,
704 if (err < 0) 702 if (err < 0)
705 return err; 703 return err;
706 704
707 npt = nf_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 705 npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
708 706 if (npt->nlattr_to_range)
709 if (!npt->nlattr_to_range) { 707 err = npt->nlattr_to_range(tb, range);
710 nf_nat_proto_put(npt);
711 return 0;
712 }
713
714 /* nlattr_to_range returns 1 if it parsed, 0 if not, neg. on error */
715 if (npt->nlattr_to_range(tb, range) > 0)
716 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
717
718 nf_nat_proto_put(npt); 708 nf_nat_proto_put(npt);
719 709 return err;
720 return 0;
721} 710}
722 711
723static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = { 712static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
@@ -1010,14 +999,11 @@ ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[])
1010{ 999{
1011 struct nlattr *tb[CTA_PROTOINFO_MAX+1], *attr = cda[CTA_PROTOINFO]; 1000 struct nlattr *tb[CTA_PROTOINFO_MAX+1], *attr = cda[CTA_PROTOINFO];
1012 struct nf_conntrack_l4proto *l4proto; 1001 struct nf_conntrack_l4proto *l4proto;
1013 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
1014 u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
1015 int err = 0; 1002 int err = 0;
1016 1003
1017 nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, NULL); 1004 nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, NULL);
1018 1005
1019 l4proto = nf_ct_l4proto_find_get(l3num, npt); 1006 l4proto = nf_ct_l4proto_find_get(nf_ct_l3num(ct), nf_ct_protonum(ct));
1020
1021 if (l4proto->from_nlattr) 1007 if (l4proto->from_nlattr)
1022 err = l4proto->from_nlattr(tb, ct); 1008 err = l4proto->from_nlattr(tb, ct);
1023 nf_ct_l4proto_put(l4proto); 1009 nf_ct_l4proto_put(l4proto);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 8fd83470d1b3..97e54b0e43a3 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -119,7 +119,7 @@ static void pptp_expectfn(struct nf_conn *ct,
119 /* obviously this tuple inversion only works until you do NAT */ 119 /* obviously this tuple inversion only works until you do NAT */
120 nf_ct_invert_tuplepr(&inv_t, &exp->tuple); 120 nf_ct_invert_tuplepr(&inv_t, &exp->tuple);
121 pr_debug("trying to unexpect other dir: "); 121 pr_debug("trying to unexpect other dir: ");
122 NF_CT_DUMP_TUPLE(&inv_t); 122 nf_ct_dump_tuple(&inv_t);
123 123
124 exp_other = nf_ct_expect_find_get(&inv_t); 124 exp_other = nf_ct_expect_find_get(&inv_t);
125 if (exp_other) { 125 if (exp_other) {
@@ -141,7 +141,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
141 struct nf_conn *sibling; 141 struct nf_conn *sibling;
142 142
143 pr_debug("trying to timeout ct or exp for tuple "); 143 pr_debug("trying to timeout ct or exp for tuple ");
144 NF_CT_DUMP_TUPLE(t); 144 nf_ct_dump_tuple(t);
145 145
146 h = nf_conntrack_find_get(t); 146 h = nf_conntrack_find_get(t);
147 if (h) { 147 if (h) {
@@ -209,7 +209,7 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
209 /* original direction, PNS->PAC */ 209 /* original direction, PNS->PAC */
210 dir = IP_CT_DIR_ORIGINAL; 210 dir = IP_CT_DIR_ORIGINAL;
211 nf_ct_expect_init(exp_orig, NF_CT_EXPECT_CLASS_DEFAULT, 211 nf_ct_expect_init(exp_orig, NF_CT_EXPECT_CLASS_DEFAULT,
212 ct->tuplehash[dir].tuple.src.l3num, 212 nf_ct_l3num(ct),
213 &ct->tuplehash[dir].tuple.src.u3, 213 &ct->tuplehash[dir].tuple.src.u3,
214 &ct->tuplehash[dir].tuple.dst.u3, 214 &ct->tuplehash[dir].tuple.dst.u3,
215 IPPROTO_GRE, &peer_callid, &callid); 215 IPPROTO_GRE, &peer_callid, &callid);
@@ -218,7 +218,7 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
218 /* reply direction, PAC->PNS */ 218 /* reply direction, PAC->PNS */
219 dir = IP_CT_DIR_REPLY; 219 dir = IP_CT_DIR_REPLY;
220 nf_ct_expect_init(exp_reply, NF_CT_EXPECT_CLASS_DEFAULT, 220 nf_ct_expect_init(exp_reply, NF_CT_EXPECT_CLASS_DEFAULT,
221 ct->tuplehash[dir].tuple.src.l3num, 221 nf_ct_l3num(ct),
222 &ct->tuplehash[dir].tuple.src.u3, 222 &ct->tuplehash[dir].tuple.src.u3,
223 &ct->tuplehash[dir].tuple.dst.u3, 223 &ct->tuplehash[dir].tuple.dst.u3,
224 IPPROTO_GRE, &callid, &peer_callid); 224 IPPROTO_GRE, &callid, &peer_callid);
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 8595b5946acf..a49fc932629b 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -146,18 +146,15 @@ EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put);
146 146
147static int kill_l3proto(struct nf_conn *i, void *data) 147static int kill_l3proto(struct nf_conn *i, void *data)
148{ 148{
149 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num == 149 return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto;
150 ((struct nf_conntrack_l3proto *)data)->l3proto);
151} 150}
152 151
153static int kill_l4proto(struct nf_conn *i, void *data) 152static int kill_l4proto(struct nf_conn *i, void *data)
154{ 153{
155 struct nf_conntrack_l4proto *l4proto; 154 struct nf_conntrack_l4proto *l4proto;
156 l4proto = (struct nf_conntrack_l4proto *)data; 155 l4proto = (struct nf_conntrack_l4proto *)data;
157 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == 156 return nf_ct_protonum(i) == l4proto->l4proto &&
158 l4proto->l4proto) && 157 nf_ct_l3num(i) == l4proto->l3proto;
159 (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
160 l4proto->l3proto);
161} 158}
162 159
163static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto) 160static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto)
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
new file mode 100644
index 000000000000..afb4a1861d2c
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -0,0 +1,815 @@
1/*
2 * DCCP connection tracking protocol helper
3 *
4 * Copyright (c) 2005, 2006, 2008 Patrick McHardy <kaber@trash.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sysctl.h>
15#include <linux/spinlock.h>
16#include <linux/skbuff.h>
17#include <linux/dccp.h>
18
19#include <linux/netfilter/nfnetlink_conntrack.h>
20#include <net/netfilter/nf_conntrack.h>
21#include <net/netfilter/nf_conntrack_l4proto.h>
22#include <net/netfilter/nf_log.h>
23
24static DEFINE_RWLOCK(dccp_lock);
25
26static int nf_ct_dccp_loose __read_mostly = 1;
27
28/* Timeouts are based on values from RFC4340:
29 *
30 * - REQUEST:
31 *
32 * 8.1.2. Client Request
33 *
34 * A client MAY give up on its DCCP-Requests after some time
35 * (3 minutes, for example).
36 *
37 * - RESPOND:
38 *
39 * 8.1.3. Server Response
40 *
41 * It MAY also leave the RESPOND state for CLOSED after a timeout of
42 * not less than 4MSL (8 minutes);
43 *
44 * - PARTOPEN:
45 *
46 * 8.1.5. Handshake Completion
47 *
48 * If the client remains in PARTOPEN for more than 4MSL (8 minutes),
49 * it SHOULD reset the connection with Reset Code 2, "Aborted".
50 *
51 * - OPEN:
52 *
53 * The DCCP timestamp overflows after 11.9 hours. If the connection
54 * stays idle this long the sequence number won't be recognized
55 * as valid anymore.
56 *
57 * - CLOSEREQ/CLOSING:
58 *
59 * 8.3. Termination
60 *
61 * The retransmission timer should initially be set to go off in two
62 * round-trip times and should back off to not less than once every
63 * 64 seconds ...
64 *
65 * - TIMEWAIT:
66 *
67 * 4.3. States
68 *
69 * A server or client socket remains in this state for 2MSL (4 minutes)
70 * after the connection has been town down, ...
71 */
72
73#define DCCP_MSL (2 * 60 * HZ)
74
75static unsigned int dccp_timeout[CT_DCCP_MAX + 1] __read_mostly = {
76 [CT_DCCP_REQUEST] = 2 * DCCP_MSL,
77 [CT_DCCP_RESPOND] = 4 * DCCP_MSL,
78 [CT_DCCP_PARTOPEN] = 4 * DCCP_MSL,
79 [CT_DCCP_OPEN] = 12 * 3600 * HZ,
80 [CT_DCCP_CLOSEREQ] = 64 * HZ,
81 [CT_DCCP_CLOSING] = 64 * HZ,
82 [CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL,
83};
84
85static const char * const dccp_state_names[] = {
86 [CT_DCCP_NONE] = "NONE",
87 [CT_DCCP_REQUEST] = "REQUEST",
88 [CT_DCCP_RESPOND] = "RESPOND",
89 [CT_DCCP_PARTOPEN] = "PARTOPEN",
90 [CT_DCCP_OPEN] = "OPEN",
91 [CT_DCCP_CLOSEREQ] = "CLOSEREQ",
92 [CT_DCCP_CLOSING] = "CLOSING",
93 [CT_DCCP_TIMEWAIT] = "TIMEWAIT",
94 [CT_DCCP_IGNORE] = "IGNORE",
95 [CT_DCCP_INVALID] = "INVALID",
96};
97
98#define sNO CT_DCCP_NONE
99#define sRQ CT_DCCP_REQUEST
100#define sRS CT_DCCP_RESPOND
101#define sPO CT_DCCP_PARTOPEN
102#define sOP CT_DCCP_OPEN
103#define sCR CT_DCCP_CLOSEREQ
104#define sCG CT_DCCP_CLOSING
105#define sTW CT_DCCP_TIMEWAIT
106#define sIG CT_DCCP_IGNORE
107#define sIV CT_DCCP_INVALID
108
109/*
110 * DCCP state transistion table
111 *
112 * The assumption is the same as for TCP tracking:
113 *
114 * We are the man in the middle. All the packets go through us but might
115 * get lost in transit to the destination. It is assumed that the destination
116 * can't receive segments we haven't seen.
117 *
118 * The following states exist:
119 *
120 * NONE: Initial state, expecting Request
121 * REQUEST: Request seen, waiting for Response from server
122 * RESPOND: Response from server seen, waiting for Ack from client
123 * PARTOPEN: Ack after Response seen, waiting for packet other than Response,
124 * Reset or Sync from server
125 * OPEN: Packet other than Response, Reset or Sync seen
126 * CLOSEREQ: CloseReq from server seen, expecting Close from client
127 * CLOSING: Close seen, expecting Reset
128 * TIMEWAIT: Reset seen
129 * IGNORE: Not determinable whether packet is valid
130 *
131 * Some states exist only on one side of the connection: REQUEST, RESPOND,
132 * PARTOPEN, CLOSEREQ. For the other side these states are equivalent to
133 * the one it was in before.
134 *
135 * Packets are marked as ignored (sIG) if we don't know if they're valid
136 * (for example a reincarnation of a connection we didn't notice is dead
137 * already) and the server may send back a connection closing Reset or a
138 * Response. They're also used for Sync/SyncAck packets, which we don't
139 * care about.
140 */
141static const u_int8_t
142dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = {
143 [CT_DCCP_ROLE_CLIENT] = {
144 [DCCP_PKT_REQUEST] = {
145 /*
146 * sNO -> sRQ Regular Request
147 * sRQ -> sRQ Retransmitted Request or reincarnation
148 * sRS -> sRS Retransmitted Request (apparently Response
149 * got lost after we saw it) or reincarnation
150 * sPO -> sIG Ignore, conntrack might be out of sync
151 * sOP -> sIG Ignore, conntrack might be out of sync
152 * sCR -> sIG Ignore, conntrack might be out of sync
153 * sCG -> sIG Ignore, conntrack might be out of sync
154 * sTW -> sRQ Reincarnation
155 *
156 * sNO, sRQ, sRS, sPO. sOP, sCR, sCG, sTW, */
157 sRQ, sRQ, sRS, sIG, sIG, sIG, sIG, sRQ,
158 },
159 [DCCP_PKT_RESPONSE] = {
160 /*
161 * sNO -> sIV Invalid
162 * sRQ -> sIG Ignore, might be response to ignored Request
163 * sRS -> sIG Ignore, might be response to ignored Request
164 * sPO -> sIG Ignore, might be response to ignored Request
165 * sOP -> sIG Ignore, might be response to ignored Request
166 * sCR -> sIG Ignore, might be response to ignored Request
167 * sCG -> sIG Ignore, might be response to ignored Request
168 * sTW -> sIV Invalid, reincarnation in reverse direction
169 * goes through sRQ
170 *
171 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
172 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIV,
173 },
174 [DCCP_PKT_ACK] = {
175 /*
176 * sNO -> sIV No connection
177 * sRQ -> sIV No connection
178 * sRS -> sPO Ack for Response, move to PARTOPEN (8.1.5.)
179 * sPO -> sPO Retransmitted Ack for Response, remain in PARTOPEN
180 * sOP -> sOP Regular ACK, remain in OPEN
181 * sCR -> sCR Ack in CLOSEREQ MAY be processed (8.3.)
182 * sCG -> sCG Ack in CLOSING MAY be processed (8.3.)
183 * sTW -> sIV
184 *
185 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
186 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
187 },
188 [DCCP_PKT_DATA] = {
189 /*
190 * sNO -> sIV No connection
191 * sRQ -> sIV No connection
192 * sRS -> sIV No connection
193 * sPO -> sIV MUST use DataAck in PARTOPEN state (8.1.5.)
194 * sOP -> sOP Regular Data packet
195 * sCR -> sCR Data in CLOSEREQ MAY be processed (8.3.)
196 * sCG -> sCG Data in CLOSING MAY be processed (8.3.)
197 * sTW -> sIV
198 *
199 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
200 sIV, sIV, sIV, sIV, sOP, sCR, sCG, sIV,
201 },
202 [DCCP_PKT_DATAACK] = {
203 /*
204 * sNO -> sIV No connection
205 * sRQ -> sIV No connection
206 * sRS -> sPO Ack for Response, move to PARTOPEN (8.1.5.)
207 * sPO -> sPO Remain in PARTOPEN state
208 * sOP -> sOP Regular DataAck packet in OPEN state
209 * sCR -> sCR DataAck in CLOSEREQ MAY be processed (8.3.)
210 * sCG -> sCG DataAck in CLOSING MAY be processed (8.3.)
211 * sTW -> sIV
212 *
213 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
214 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
215 },
216 [DCCP_PKT_CLOSEREQ] = {
217 /*
218 * CLOSEREQ may only be sent by the server.
219 *
220 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
221 sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV
222 },
223 [DCCP_PKT_CLOSE] = {
224 /*
225 * sNO -> sIV No connection
226 * sRQ -> sIV No connection
227 * sRS -> sIV No connection
228 * sPO -> sCG Client-initiated close
229 * sOP -> sCG Client-initiated close
230 * sCR -> sCG Close in response to CloseReq (8.3.)
231 * sCG -> sCG Retransmit
232 * sTW -> sIV Late retransmit, already in TIME_WAIT
233 *
234 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
235 sIV, sIV, sIV, sCG, sCG, sCG, sIV, sIV
236 },
237 [DCCP_PKT_RESET] = {
238 /*
239 * sNO -> sIV No connection
240 * sRQ -> sTW Sync received or timeout, SHOULD send Reset (8.1.1.)
241 * sRS -> sTW Response received without Request
242 * sPO -> sTW Timeout, SHOULD send Reset (8.1.5.)
243 * sOP -> sTW Connection reset
244 * sCR -> sTW Connection reset
245 * sCG -> sTW Connection reset
246 * sTW -> sIG Ignore (don't refresh timer)
247 *
248 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
249 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sIG
250 },
251 [DCCP_PKT_SYNC] = {
252 /*
253 * We currently ignore Sync packets
254 *
255 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
256 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
257 },
258 [DCCP_PKT_SYNCACK] = {
259 /*
260 * We currently ignore SyncAck packets
261 *
262 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
263 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
264 },
265 },
266 [CT_DCCP_ROLE_SERVER] = {
267 [DCCP_PKT_REQUEST] = {
268 /*
269 * sNO -> sIV Invalid
270 * sRQ -> sIG Ignore, conntrack might be out of sync
271 * sRS -> sIG Ignore, conntrack might be out of sync
272 * sPO -> sIG Ignore, conntrack might be out of sync
273 * sOP -> sIG Ignore, conntrack might be out of sync
274 * sCR -> sIG Ignore, conntrack might be out of sync
275 * sCG -> sIG Ignore, conntrack might be out of sync
276 * sTW -> sRQ Reincarnation, must reverse roles
277 *
278 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
279 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sRQ
280 },
281 [DCCP_PKT_RESPONSE] = {
282 /*
283 * sNO -> sIV Response without Request
284 * sRQ -> sRS Response to clients Request
285 * sRS -> sRS Retransmitted Response (8.1.3. SHOULD NOT)
286 * sPO -> sIG Response to an ignored Request or late retransmit
287 * sOP -> sIG Ignore, might be response to ignored Request
288 * sCR -> sIG Ignore, might be response to ignored Request
289 * sCG -> sIG Ignore, might be response to ignored Request
290 * sTW -> sIV Invalid, Request from client in sTW moves to sRQ
291 *
292 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
293 sIV, sRS, sRS, sIG, sIG, sIG, sIG, sIV
294 },
295 [DCCP_PKT_ACK] = {
296 /*
297 * sNO -> sIV No connection
298 * sRQ -> sIV No connection
299 * sRS -> sIV No connection
300 * sPO -> sOP Enter OPEN state (8.1.5.)
301 * sOP -> sOP Regular Ack in OPEN state
302 * sCR -> sIV Waiting for Close from client
303 * sCG -> sCG Ack in CLOSING MAY be processed (8.3.)
304 * sTW -> sIV
305 *
306 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
307 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
308 },
309 [DCCP_PKT_DATA] = {
310 /*
311 * sNO -> sIV No connection
312 * sRQ -> sIV No connection
313 * sRS -> sIV No connection
314 * sPO -> sOP Enter OPEN state (8.1.5.)
315 * sOP -> sOP Regular Data packet in OPEN state
316 * sCR -> sIV Waiting for Close from client
317 * sCG -> sCG Data in CLOSING MAY be processed (8.3.)
318 * sTW -> sIV
319 *
320 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
321 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
322 },
323 [DCCP_PKT_DATAACK] = {
324 /*
325 * sNO -> sIV No connection
326 * sRQ -> sIV No connection
327 * sRS -> sIV No connection
328 * sPO -> sOP Enter OPEN state (8.1.5.)
329 * sOP -> sOP Regular DataAck in OPEN state
330 * sCR -> sIV Waiting for Close from client
331 * sCG -> sCG Data in CLOSING MAY be processed (8.3.)
332 * sTW -> sIV
333 *
334 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
335 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
336 },
337 [DCCP_PKT_CLOSEREQ] = {
338 /*
339 * sNO -> sIV No connection
340 * sRQ -> sIV No connection
341 * sRS -> sIV No connection
342 * sPO -> sOP -> sCR Move directly to CLOSEREQ (8.1.5.)
343 * sOP -> sCR CloseReq in OPEN state
344 * sCR -> sCR Retransmit
345 * sCG -> sCR Simultaneous close, client sends another Close
346 * sTW -> sIV Already closed
347 *
348 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
349 sIV, sIV, sIV, sCR, sCR, sCR, sCR, sIV
350 },
351 [DCCP_PKT_CLOSE] = {
352 /*
353 * sNO -> sIV No connection
354 * sRQ -> sIV No connection
355 * sRS -> sIV No connection
356 * sPO -> sOP -> sCG Move direcly to CLOSING
357 * sOP -> sCG Move to CLOSING
358 * sCR -> sIV Close after CloseReq is invalid
359 * sCG -> sCG Retransmit
360 * sTW -> sIV Already closed
361 *
362 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
363 sIV, sIV, sIV, sCG, sCG, sIV, sCG, sIV
364 },
365 [DCCP_PKT_RESET] = {
366 /*
367 * sNO -> sIV No connection
368 * sRQ -> sTW Reset in response to Request
369 * sRS -> sTW Timeout, SHOULD send Reset (8.1.3.)
370 * sPO -> sTW Timeout, SHOULD send Reset (8.1.3.)
371 * sOP -> sTW
372 * sCR -> sTW
373 * sCG -> sTW
374 * sTW -> sIG Ignore (don't refresh timer)
375 *
376 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW, sTW */
377 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sTW, sIG
378 },
379 [DCCP_PKT_SYNC] = {
380 /*
381 * We currently ignore Sync packets
382 *
383 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
384 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
385 },
386 [DCCP_PKT_SYNCACK] = {
387 /*
388 * We currently ignore SyncAck packets
389 *
390 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
391 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
392 },
393 },
394};
395
396static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
397 struct nf_conntrack_tuple *tuple)
398{
399 struct dccp_hdr _hdr, *dh;
400
401 dh = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
402 if (dh == NULL)
403 return false;
404
405 tuple->src.u.dccp.port = dh->dccph_sport;
406 tuple->dst.u.dccp.port = dh->dccph_dport;
407 return true;
408}
409
410static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv,
411 const struct nf_conntrack_tuple *tuple)
412{
413 inv->src.u.dccp.port = tuple->dst.u.dccp.port;
414 inv->dst.u.dccp.port = tuple->src.u.dccp.port;
415 return true;
416}
417
418static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
419 unsigned int dataoff)
420{
421 struct dccp_hdr _dh, *dh;
422 const char *msg;
423 u_int8_t state;
424
425 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
426 BUG_ON(dh == NULL);
427
428 state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
429 switch (state) {
430 default:
431 if (nf_ct_dccp_loose == 0) {
432 msg = "nf_ct_dccp: not picking up existing connection ";
433 goto out_invalid;
434 }
435 case CT_DCCP_REQUEST:
436 break;
437 case CT_DCCP_INVALID:
438 msg = "nf_ct_dccp: invalid state transition ";
439 goto out_invalid;
440 }
441
442 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
443 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
444 ct->proto.dccp.state = CT_DCCP_NONE;
445 return true;
446
447out_invalid:
448 if (LOG_INVALID(IPPROTO_DCCP))
449 nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, msg);
450 return false;
451}
452
453static u64 dccp_ack_seq(const struct dccp_hdr *dh)
454{
455 const struct dccp_hdr_ack_bits *dhack;
456
457 dhack = (void *)dh + __dccp_basic_hdr_len(dh);
458 return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) +
459 ntohl(dhack->dccph_ack_nr_low);
460}
461
462static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
463 unsigned int dataoff, enum ip_conntrack_info ctinfo,
464 int pf, unsigned int hooknum)
465{
466 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
467 struct dccp_hdr _dh, *dh;
468 u_int8_t type, old_state, new_state;
469 enum ct_dccp_roles role;
470
471 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
472 BUG_ON(dh == NULL);
473 type = dh->dccph_type;
474
475 if (type == DCCP_PKT_RESET &&
476 !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
477 /* Tear down connection immediately if only reply is a RESET */
478 if (del_timer(&ct->timeout))
479 ct->timeout.function((unsigned long)ct);
480 return NF_ACCEPT;
481 }
482
483 write_lock_bh(&dccp_lock);
484
485 role = ct->proto.dccp.role[dir];
486 old_state = ct->proto.dccp.state;
487 new_state = dccp_state_table[role][type][old_state];
488
489 switch (new_state) {
490 case CT_DCCP_REQUEST:
491 if (old_state == CT_DCCP_TIMEWAIT &&
492 role == CT_DCCP_ROLE_SERVER) {
493 /* Reincarnation in the reverse direction: reopen and
494 * reverse client/server roles. */
495 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_CLIENT;
496 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_SERVER;
497 }
498 break;
499 case CT_DCCP_RESPOND:
500 if (old_state == CT_DCCP_REQUEST)
501 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
502 break;
503 case CT_DCCP_PARTOPEN:
504 if (old_state == CT_DCCP_RESPOND &&
505 type == DCCP_PKT_ACK &&
506 dccp_ack_seq(dh) == ct->proto.dccp.handshake_seq)
507 set_bit(IPS_ASSURED_BIT, &ct->status);
508 break;
509 case CT_DCCP_IGNORE:
510 /*
511 * Connection tracking might be out of sync, so we ignore
512 * packets that might establish a new connection and resync
513 * if the server responds with a valid Response.
514 */
515 if (ct->proto.dccp.last_dir == !dir &&
516 ct->proto.dccp.last_pkt == DCCP_PKT_REQUEST &&
517 type == DCCP_PKT_RESPONSE) {
518 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_CLIENT;
519 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_SERVER;
520 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
521 new_state = CT_DCCP_RESPOND;
522 break;
523 }
524 ct->proto.dccp.last_dir = dir;
525 ct->proto.dccp.last_pkt = type;
526
527 write_unlock_bh(&dccp_lock);
528 if (LOG_INVALID(IPPROTO_DCCP))
529 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
530 "nf_ct_dccp: invalid packet ignored ");
531 return NF_ACCEPT;
532 case CT_DCCP_INVALID:
533 write_unlock_bh(&dccp_lock);
534 if (LOG_INVALID(IPPROTO_DCCP))
535 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
536 "nf_ct_dccp: invalid state transition ");
537 return -NF_ACCEPT;
538 }
539
540 ct->proto.dccp.last_dir = dir;
541 ct->proto.dccp.last_pkt = type;
542 ct->proto.dccp.state = new_state;
543 write_unlock_bh(&dccp_lock);
544 nf_ct_refresh_acct(ct, ctinfo, skb, dccp_timeout[new_state]);
545
546 return NF_ACCEPT;
547}
548
549static int dccp_error(struct sk_buff *skb, unsigned int dataoff,
550 enum ip_conntrack_info *ctinfo, int pf,
551 unsigned int hooknum)
552{
553 struct dccp_hdr _dh, *dh;
554 unsigned int dccp_len = skb->len - dataoff;
555 unsigned int cscov;
556 const char *msg;
557
558 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
559 if (dh == NULL) {
560 msg = "nf_ct_dccp: short packet ";
561 goto out_invalid;
562 }
563
564 if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
565 dh->dccph_doff * 4 > dccp_len) {
566 msg = "nf_ct_dccp: truncated/malformed packet ";
567 goto out_invalid;
568 }
569
570 cscov = dccp_len;
571 if (dh->dccph_cscov) {
572 cscov = (dh->dccph_cscov - 1) * 4;
573 if (cscov > dccp_len) {
574 msg = "nf_ct_dccp: bad checksum coverage ";
575 goto out_invalid;
576 }
577 }
578
579 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
580 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP,
581 pf)) {
582 msg = "nf_ct_dccp: bad checksum ";
583 goto out_invalid;
584 }
585
586 if (dh->dccph_type >= DCCP_PKT_INVALID) {
587 msg = "nf_ct_dccp: reserved packet type ";
588 goto out_invalid;
589 }
590
591 return NF_ACCEPT;
592
593out_invalid:
594 if (LOG_INVALID(IPPROTO_DCCP))
595 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg);
596 return -NF_ACCEPT;
597}
598
599static int dccp_print_tuple(struct seq_file *s,
600 const struct nf_conntrack_tuple *tuple)
601{
602 return seq_printf(s, "sport=%hu dport=%hu ",
603 ntohs(tuple->src.u.dccp.port),
604 ntohs(tuple->dst.u.dccp.port));
605}
606
607static int dccp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
608{
609 return seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]);
610}
611
612#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
613static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
614 const struct nf_conn *ct)
615{
616 struct nlattr *nest_parms;
617
618 read_lock_bh(&dccp_lock);
619 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP | NLA_F_NESTED);
620 if (!nest_parms)
621 goto nla_put_failure;
622 NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state);
623 nla_nest_end(skb, nest_parms);
624 read_unlock_bh(&dccp_lock);
625 return 0;
626
627nla_put_failure:
628 read_unlock_bh(&dccp_lock);
629 return -1;
630}
631
632static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = {
633 [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 },
634};
635
636static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
637{
638 struct nlattr *attr = cda[CTA_PROTOINFO_DCCP];
639 struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1];
640 int err;
641
642 if (!attr)
643 return 0;
644
645 err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr,
646 dccp_nla_policy);
647 if (err < 0)
648 return err;
649
650 if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
651 nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE)
652 return -EINVAL;
653
654 write_lock_bh(&dccp_lock);
655 ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
656 write_unlock_bh(&dccp_lock);
657 return 0;
658}
659#endif
660
661#ifdef CONFIG_SYSCTL
662static unsigned int dccp_sysctl_table_users;
663static struct ctl_table_header *dccp_sysctl_header;
664static ctl_table dccp_sysctl_table[] = {
665 {
666 .ctl_name = CTL_UNNUMBERED,
667 .procname = "nf_conntrack_dccp_timeout_request",
668 .data = &dccp_timeout[CT_DCCP_REQUEST],
669 .maxlen = sizeof(unsigned int),
670 .mode = 0644,
671 .proc_handler = proc_dointvec_jiffies,
672 },
673 {
674 .ctl_name = CTL_UNNUMBERED,
675 .procname = "nf_conntrack_dccp_timeout_respond",
676 .data = &dccp_timeout[CT_DCCP_RESPOND],
677 .maxlen = sizeof(unsigned int),
678 .mode = 0644,
679 .proc_handler = proc_dointvec_jiffies,
680 },
681 {
682 .ctl_name = CTL_UNNUMBERED,
683 .procname = "nf_conntrack_dccp_timeout_partopen",
684 .data = &dccp_timeout[CT_DCCP_PARTOPEN],
685 .maxlen = sizeof(unsigned int),
686 .mode = 0644,
687 .proc_handler = proc_dointvec_jiffies,
688 },
689 {
690 .ctl_name = CTL_UNNUMBERED,
691 .procname = "nf_conntrack_dccp_timeout_open",
692 .data = &dccp_timeout[CT_DCCP_OPEN],
693 .maxlen = sizeof(unsigned int),
694 .mode = 0644,
695 .proc_handler = proc_dointvec_jiffies,
696 },
697 {
698 .ctl_name = CTL_UNNUMBERED,
699 .procname = "nf_conntrack_dccp_timeout_closereq",
700 .data = &dccp_timeout[CT_DCCP_CLOSEREQ],
701 .maxlen = sizeof(unsigned int),
702 .mode = 0644,
703 .proc_handler = proc_dointvec_jiffies,
704 },
705 {
706 .ctl_name = CTL_UNNUMBERED,
707 .procname = "nf_conntrack_dccp_timeout_closing",
708 .data = &dccp_timeout[CT_DCCP_CLOSING],
709 .maxlen = sizeof(unsigned int),
710 .mode = 0644,
711 .proc_handler = proc_dointvec_jiffies,
712 },
713 {
714 .ctl_name = CTL_UNNUMBERED,
715 .procname = "nf_conntrack_dccp_timeout_timewait",
716 .data = &dccp_timeout[CT_DCCP_TIMEWAIT],
717 .maxlen = sizeof(unsigned int),
718 .mode = 0644,
719 .proc_handler = proc_dointvec_jiffies,
720 },
721 {
722 .ctl_name = CTL_UNNUMBERED,
723 .procname = "nf_conntrack_dccp_loose",
724 .data = &nf_ct_dccp_loose,
725 .maxlen = sizeof(nf_ct_dccp_loose),
726 .mode = 0644,
727 .proc_handler = proc_dointvec,
728 },
729 {
730 .ctl_name = 0,
731 }
732};
733#endif /* CONFIG_SYSCTL */
734
735static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
736 .l3proto = AF_INET,
737 .l4proto = IPPROTO_DCCP,
738 .name = "dccp",
739 .pkt_to_tuple = dccp_pkt_to_tuple,
740 .invert_tuple = dccp_invert_tuple,
741 .new = dccp_new,
742 .packet = dccp_packet,
743 .error = dccp_error,
744 .print_tuple = dccp_print_tuple,
745 .print_conntrack = dccp_print_conntrack,
746#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
747 .to_nlattr = dccp_to_nlattr,
748 .from_nlattr = nlattr_to_dccp,
749 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
750 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
751 .nla_policy = nf_ct_port_nla_policy,
752#endif
753#ifdef CONFIG_SYSCTL
754 .ctl_table_users = &dccp_sysctl_table_users,
755 .ctl_table_header = &dccp_sysctl_header,
756 .ctl_table = dccp_sysctl_table,
757#endif
758};
759
760static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
761 .l3proto = AF_INET6,
762 .l4proto = IPPROTO_DCCP,
763 .name = "dccp",
764 .pkt_to_tuple = dccp_pkt_to_tuple,
765 .invert_tuple = dccp_invert_tuple,
766 .new = dccp_new,
767 .packet = dccp_packet,
768 .error = dccp_error,
769 .print_tuple = dccp_print_tuple,
770 .print_conntrack = dccp_print_conntrack,
771#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
772 .to_nlattr = dccp_to_nlattr,
773 .from_nlattr = nlattr_to_dccp,
774 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
775 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
776 .nla_policy = nf_ct_port_nla_policy,
777#endif
778#ifdef CONFIG_SYSCTL
779 .ctl_table_users = &dccp_sysctl_table_users,
780 .ctl_table_header = &dccp_sysctl_header,
781 .ctl_table = dccp_sysctl_table,
782#endif
783};
784
785static int __init nf_conntrack_proto_dccp_init(void)
786{
787 int err;
788
789 err = nf_conntrack_l4proto_register(&dccp_proto4);
790 if (err < 0)
791 goto err1;
792
793 err = nf_conntrack_l4proto_register(&dccp_proto6);
794 if (err < 0)
795 goto err2;
796 return 0;
797
798err2:
799 nf_conntrack_l4proto_unregister(&dccp_proto4);
800err1:
801 return err;
802}
803
804static void __exit nf_conntrack_proto_dccp_fini(void)
805{
806 nf_conntrack_l4proto_unregister(&dccp_proto6);
807 nf_conntrack_l4proto_unregister(&dccp_proto4);
808}
809
810module_init(nf_conntrack_proto_dccp_init);
811module_exit(nf_conntrack_proto_dccp_fini);
812
813MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
814MODULE_DESCRIPTION("DCCP connection tracking protocol helper");
815MODULE_LICENSE("GPL");
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index 55458915575f..e31b0e7bd0b1 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -14,23 +14,23 @@
14 14
15static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; 15static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
16 16
17static int generic_pkt_to_tuple(const struct sk_buff *skb, 17static bool generic_pkt_to_tuple(const struct sk_buff *skb,
18 unsigned int dataoff, 18 unsigned int dataoff,
19 struct nf_conntrack_tuple *tuple) 19 struct nf_conntrack_tuple *tuple)
20{ 20{
21 tuple->src.u.all = 0; 21 tuple->src.u.all = 0;
22 tuple->dst.u.all = 0; 22 tuple->dst.u.all = 0;
23 23
24 return 1; 24 return true;
25} 25}
26 26
27static int generic_invert_tuple(struct nf_conntrack_tuple *tuple, 27static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple,
28 const struct nf_conntrack_tuple *orig) 28 const struct nf_conntrack_tuple *orig)
29{ 29{
30 tuple->src.u.all = 0; 30 tuple->src.u.all = 0;
31 tuple->dst.u.all = 0; 31 tuple->dst.u.all = 0;
32 32
33 return 1; 33 return true;
34} 34}
35 35
36/* Print out the per-protocol part of the tuple. */ 36/* Print out the per-protocol part of the tuple. */
@@ -53,10 +53,10 @@ static int packet(struct nf_conn *ct,
53} 53}
54 54
55/* Called when a new connection for this protocol found. */ 55/* Called when a new connection for this protocol found. */
56static int new(struct nf_conn *ct, const struct sk_buff *skb, 56static bool new(struct nf_conn *ct, const struct sk_buff *skb,
57 unsigned int dataoff) 57 unsigned int dataoff)
58{ 58{
59 return 1; 59 return true;
60} 60}
61 61
62#ifdef CONFIG_SYSCTL 62#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index e10024a1b666..654a4f7f12c6 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -82,7 +82,7 @@ static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t)
82 read_unlock_bh(&nf_ct_gre_lock); 82 read_unlock_bh(&nf_ct_gre_lock);
83 83
84 pr_debug("lookup src key 0x%x for ", key); 84 pr_debug("lookup src key 0x%x for ", key);
85 NF_CT_DUMP_TUPLE(t); 85 nf_ct_dump_tuple(t);
86 86
87 return key; 87 return key;
88} 88}
@@ -113,7 +113,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
113 *kmp = km; 113 *kmp = km;
114 114
115 pr_debug("adding new entry %p: ", km); 115 pr_debug("adding new entry %p: ", km);
116 NF_CT_DUMP_TUPLE(&km->tuple); 116 nf_ct_dump_tuple(&km->tuple);
117 117
118 write_lock_bh(&nf_ct_gre_lock); 118 write_lock_bh(&nf_ct_gre_lock);
119 list_add_tail(&km->list, &gre_keymap_list); 119 list_add_tail(&km->list, &gre_keymap_list);
@@ -148,18 +148,17 @@ EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy);
148/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */ 148/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */
149 149
150/* invert gre part of tuple */ 150/* invert gre part of tuple */
151static int gre_invert_tuple(struct nf_conntrack_tuple *tuple, 151static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple,
152 const struct nf_conntrack_tuple *orig) 152 const struct nf_conntrack_tuple *orig)
153{ 153{
154 tuple->dst.u.gre.key = orig->src.u.gre.key; 154 tuple->dst.u.gre.key = orig->src.u.gre.key;
155 tuple->src.u.gre.key = orig->dst.u.gre.key; 155 tuple->src.u.gre.key = orig->dst.u.gre.key;
156 return 1; 156 return true;
157} 157}
158 158
159/* gre hdr info to tuple */ 159/* gre hdr info to tuple */
160static int gre_pkt_to_tuple(const struct sk_buff *skb, 160static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
161 unsigned int dataoff, 161 struct nf_conntrack_tuple *tuple)
162 struct nf_conntrack_tuple *tuple)
163{ 162{
164 const struct gre_hdr_pptp *pgrehdr; 163 const struct gre_hdr_pptp *pgrehdr;
165 struct gre_hdr_pptp _pgrehdr; 164 struct gre_hdr_pptp _pgrehdr;
@@ -173,24 +172,24 @@ static int gre_pkt_to_tuple(const struct sk_buff *skb,
173 /* try to behave like "nf_conntrack_proto_generic" */ 172 /* try to behave like "nf_conntrack_proto_generic" */
174 tuple->src.u.all = 0; 173 tuple->src.u.all = 0;
175 tuple->dst.u.all = 0; 174 tuple->dst.u.all = 0;
176 return 1; 175 return true;
177 } 176 }
178 177
179 /* PPTP header is variable length, only need up to the call_id field */ 178 /* PPTP header is variable length, only need up to the call_id field */
180 pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr); 179 pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr);
181 if (!pgrehdr) 180 if (!pgrehdr)
182 return 1; 181 return true;
183 182
184 if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) { 183 if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
185 pr_debug("GRE_VERSION_PPTP but unknown proto\n"); 184 pr_debug("GRE_VERSION_PPTP but unknown proto\n");
186 return 0; 185 return false;
187 } 186 }
188 187
189 tuple->dst.u.gre.key = pgrehdr->call_id; 188 tuple->dst.u.gre.key = pgrehdr->call_id;
190 srckey = gre_keymap_lookup(tuple); 189 srckey = gre_keymap_lookup(tuple);
191 tuple->src.u.gre.key = srckey; 190 tuple->src.u.gre.key = srckey;
192 191
193 return 1; 192 return true;
194} 193}
195 194
196/* print gre part of tuple */ 195/* print gre part of tuple */
@@ -235,18 +234,18 @@ static int gre_packet(struct nf_conn *ct,
235} 234}
236 235
237/* Called when a new connection for this protocol found. */ 236/* Called when a new connection for this protocol found. */
238static int gre_new(struct nf_conn *ct, const struct sk_buff *skb, 237static bool gre_new(struct nf_conn *ct, const struct sk_buff *skb,
239 unsigned int dataoff) 238 unsigned int dataoff)
240{ 239{
241 pr_debug(": "); 240 pr_debug(": ");
242 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 241 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
243 242
244 /* initialize to sane value. Ideally a conntrack helper 243 /* initialize to sane value. Ideally a conntrack helper
245 * (e.g. in case of pptp) is increasing them */ 244 * (e.g. in case of pptp) is increasing them */
246 ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT; 245 ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT;
247 ct->proto.gre.timeout = GRE_TIMEOUT; 246 ct->proto.gre.timeout = GRE_TIMEOUT;
248 247
249 return 1; 248 return true;
250} 249}
251 250
252/* Called when a conntrack entry has already been removed from the hashes 251/* Called when a conntrack entry has already been removed from the hashes
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index f9a08370dbb3..cbf2e27a22b2 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -33,7 +33,7 @@ static DEFINE_RWLOCK(sctp_lock);
33 33
34 And so for me for SCTP :D -Kiran */ 34 And so for me for SCTP :D -Kiran */
35 35
36static const char *sctp_conntrack_names[] = { 36static const char *const sctp_conntrack_names[] = {
37 "NONE", 37 "NONE",
38 "CLOSED", 38 "CLOSED",
39 "COOKIE_WAIT", 39 "COOKIE_WAIT",
@@ -130,28 +130,28 @@ static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
130 } 130 }
131}; 131};
132 132
133static int sctp_pkt_to_tuple(const struct sk_buff *skb, 133static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
134 unsigned int dataoff, 134 struct nf_conntrack_tuple *tuple)
135 struct nf_conntrack_tuple *tuple)
136{ 135{
137 sctp_sctphdr_t _hdr, *hp; 136 const struct sctphdr *hp;
137 struct sctphdr _hdr;
138 138
139 /* Actually only need first 8 bytes. */ 139 /* Actually only need first 8 bytes. */
140 hp = skb_header_pointer(skb, dataoff, 8, &_hdr); 140 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
141 if (hp == NULL) 141 if (hp == NULL)
142 return 0; 142 return false;
143 143
144 tuple->src.u.sctp.port = hp->source; 144 tuple->src.u.sctp.port = hp->source;
145 tuple->dst.u.sctp.port = hp->dest; 145 tuple->dst.u.sctp.port = hp->dest;
146 return 1; 146 return true;
147} 147}
148 148
149static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple, 149static bool sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
150 const struct nf_conntrack_tuple *orig) 150 const struct nf_conntrack_tuple *orig)
151{ 151{
152 tuple->src.u.sctp.port = orig->dst.u.sctp.port; 152 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
153 tuple->dst.u.sctp.port = orig->src.u.sctp.port; 153 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
154 return 1; 154 return true;
155} 155}
156 156
157/* Print out the per-protocol part of the tuple. */ 157/* Print out the per-protocol part of the tuple. */
@@ -292,8 +292,10 @@ static int sctp_packet(struct nf_conn *ct,
292{ 292{
293 enum sctp_conntrack new_state, old_state; 293 enum sctp_conntrack new_state, old_state;
294 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 294 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
295 sctp_sctphdr_t _sctph, *sh; 295 const struct sctphdr *sh;
296 sctp_chunkhdr_t _sch, *sch; 296 struct sctphdr _sctph;
297 const struct sctp_chunkhdr *sch;
298 struct sctp_chunkhdr _sch;
297 u_int32_t offset, count; 299 u_int32_t offset, count;
298 unsigned long map[256 / sizeof(unsigned long)] = { 0 }; 300 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
299 301
@@ -390,27 +392,29 @@ out:
390} 392}
391 393
392/* Called when a new connection for this protocol found. */ 394/* Called when a new connection for this protocol found. */
393static int sctp_new(struct nf_conn *ct, const struct sk_buff *skb, 395static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
394 unsigned int dataoff) 396 unsigned int dataoff)
395{ 397{
396 enum sctp_conntrack new_state; 398 enum sctp_conntrack new_state;
397 sctp_sctphdr_t _sctph, *sh; 399 const struct sctphdr *sh;
398 sctp_chunkhdr_t _sch, *sch; 400 struct sctphdr _sctph;
401 const struct sctp_chunkhdr *sch;
402 struct sctp_chunkhdr _sch;
399 u_int32_t offset, count; 403 u_int32_t offset, count;
400 unsigned long map[256 / sizeof(unsigned long)] = { 0 }; 404 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
401 405
402 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); 406 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
403 if (sh == NULL) 407 if (sh == NULL)
404 return 0; 408 return false;
405 409
406 if (do_basic_checks(ct, skb, dataoff, map) != 0) 410 if (do_basic_checks(ct, skb, dataoff, map) != 0)
407 return 0; 411 return false;
408 412
409 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */ 413 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
410 if (test_bit(SCTP_CID_ABORT, map) || 414 if (test_bit(SCTP_CID_ABORT, map) ||
411 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) || 415 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
412 test_bit(SCTP_CID_COOKIE_ACK, map)) 416 test_bit(SCTP_CID_COOKIE_ACK, map))
413 return 0; 417 return false;
414 418
415 new_state = SCTP_CONNTRACK_MAX; 419 new_state = SCTP_CONNTRACK_MAX;
416 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { 420 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
@@ -422,7 +426,7 @@ static int sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
422 if (new_state == SCTP_CONNTRACK_NONE || 426 if (new_state == SCTP_CONNTRACK_NONE ||
423 new_state == SCTP_CONNTRACK_MAX) { 427 new_state == SCTP_CONNTRACK_MAX) {
424 pr_debug("nf_conntrack_sctp: invalid new deleting.\n"); 428 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
425 return 0; 429 return false;
426 } 430 }
427 431
428 /* Copy the vtag into the state info */ 432 /* Copy the vtag into the state info */
@@ -433,7 +437,7 @@ static int sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
433 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t), 437 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
434 sizeof(_inithdr), &_inithdr); 438 sizeof(_inithdr), &_inithdr);
435 if (ih == NULL) 439 if (ih == NULL)
436 return 0; 440 return false;
437 441
438 pr_debug("Setting vtag %x for new conn\n", 442 pr_debug("Setting vtag %x for new conn\n",
439 ih->init_tag); 443 ih->init_tag);
@@ -442,7 +446,7 @@ static int sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
442 ih->init_tag; 446 ih->init_tag;
443 } else { 447 } else {
444 /* Sec 8.5.1 (A) */ 448 /* Sec 8.5.1 (A) */
445 return 0; 449 return false;
446 } 450 }
447 } 451 }
448 /* If it is a shutdown ack OOTB packet, we expect a return 452 /* If it is a shutdown ack OOTB packet, we expect a return
@@ -456,7 +460,7 @@ static int sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
456 ct->proto.sctp.state = new_state; 460 ct->proto.sctp.state = new_state;
457 } 461 }
458 462
459 return 1; 463 return true;
460} 464}
461 465
462#ifdef CONFIG_SYSCTL 466#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 62567959b66e..ba94004fe323 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -257,9 +257,8 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
257 } 257 }
258}; 258};
259 259
260static int tcp_pkt_to_tuple(const struct sk_buff *skb, 260static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
261 unsigned int dataoff, 261 struct nf_conntrack_tuple *tuple)
262 struct nf_conntrack_tuple *tuple)
263{ 262{
264 const struct tcphdr *hp; 263 const struct tcphdr *hp;
265 struct tcphdr _hdr; 264 struct tcphdr _hdr;
@@ -267,20 +266,20 @@ static int tcp_pkt_to_tuple(const struct sk_buff *skb,
267 /* Actually only need first 8 bytes. */ 266 /* Actually only need first 8 bytes. */
268 hp = skb_header_pointer(skb, dataoff, 8, &_hdr); 267 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
269 if (hp == NULL) 268 if (hp == NULL)
270 return 0; 269 return false;
271 270
272 tuple->src.u.tcp.port = hp->source; 271 tuple->src.u.tcp.port = hp->source;
273 tuple->dst.u.tcp.port = hp->dest; 272 tuple->dst.u.tcp.port = hp->dest;
274 273
275 return 1; 274 return true;
276} 275}
277 276
278static int tcp_invert_tuple(struct nf_conntrack_tuple *tuple, 277static bool tcp_invert_tuple(struct nf_conntrack_tuple *tuple,
279 const struct nf_conntrack_tuple *orig) 278 const struct nf_conntrack_tuple *orig)
280{ 279{
281 tuple->src.u.tcp.port = orig->dst.u.tcp.port; 280 tuple->src.u.tcp.port = orig->dst.u.tcp.port;
282 tuple->dst.u.tcp.port = orig->src.u.tcp.port; 281 tuple->dst.u.tcp.port = orig->src.u.tcp.port;
283 return 1; 282 return true;
284} 283}
285 284
286/* Print out the per-protocol part of the tuple. */ 285/* Print out the per-protocol part of the tuple. */
@@ -478,20 +477,20 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
478 } 477 }
479} 478}
480 479
481static int tcp_in_window(const struct nf_conn *ct, 480static bool tcp_in_window(const struct nf_conn *ct,
482 struct ip_ct_tcp *state, 481 struct ip_ct_tcp *state,
483 enum ip_conntrack_dir dir, 482 enum ip_conntrack_dir dir,
484 unsigned int index, 483 unsigned int index,
485 const struct sk_buff *skb, 484 const struct sk_buff *skb,
486 unsigned int dataoff, 485 unsigned int dataoff,
487 const struct tcphdr *tcph, 486 const struct tcphdr *tcph,
488 int pf) 487 int pf)
489{ 488{
490 struct ip_ct_tcp_state *sender = &state->seen[dir]; 489 struct ip_ct_tcp_state *sender = &state->seen[dir];
491 struct ip_ct_tcp_state *receiver = &state->seen[!dir]; 490 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
492 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; 491 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
493 __u32 seq, ack, sack, end, win, swin; 492 __u32 seq, ack, sack, end, win, swin;
494 int res; 493 bool res;
495 494
496 /* 495 /*
497 * Get the required data from the packet. 496 * Get the required data from the packet.
@@ -506,7 +505,7 @@ static int tcp_in_window(const struct nf_conn *ct,
506 505
507 pr_debug("tcp_in_window: START\n"); 506 pr_debug("tcp_in_window: START\n");
508 pr_debug("tcp_in_window: "); 507 pr_debug("tcp_in_window: ");
509 NF_CT_DUMP_TUPLE(tuple); 508 nf_ct_dump_tuple(tuple);
510 pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n", 509 pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n",
511 seq, ack, sack, win, end); 510 seq, ack, sack, win, end);
512 pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " 511 pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
@@ -593,7 +592,7 @@ static int tcp_in_window(const struct nf_conn *ct,
593 seq = end = sender->td_end; 592 seq = end = sender->td_end;
594 593
595 pr_debug("tcp_in_window: "); 594 pr_debug("tcp_in_window: ");
596 NF_CT_DUMP_TUPLE(tuple); 595 nf_ct_dump_tuple(tuple);
597 pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n", 596 pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n",
598 seq, ack, sack, win, end); 597 seq, ack, sack, win, end);
599 pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " 598 pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
@@ -657,12 +656,12 @@ static int tcp_in_window(const struct nf_conn *ct,
657 state->retrans = 0; 656 state->retrans = 0;
658 } 657 }
659 } 658 }
660 res = 1; 659 res = true;
661 } else { 660 } else {
662 res = 0; 661 res = false;
663 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || 662 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
664 nf_ct_tcp_be_liberal) 663 nf_ct_tcp_be_liberal)
665 res = 1; 664 res = true;
666 if (!res && LOG_INVALID(IPPROTO_TCP)) 665 if (!res && LOG_INVALID(IPPROTO_TCP))
667 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 666 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
668 "nf_ct_tcp: %s ", 667 "nf_ct_tcp: %s ",
@@ -676,7 +675,7 @@ static int tcp_in_window(const struct nf_conn *ct,
676 : "SEQ is over the upper bound (over the window of the receiver)"); 675 : "SEQ is over the upper bound (over the window of the receiver)");
677 } 676 }
678 677
679 pr_debug("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " 678 pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u "
680 "receiver end=%u maxend=%u maxwin=%u\n", 679 "receiver end=%u maxend=%u maxwin=%u\n",
681 res, sender->td_end, sender->td_maxend, sender->td_maxwin, 680 res, sender->td_end, sender->td_maxend, sender->td_maxwin,
682 receiver->td_end, receiver->td_maxend, receiver->td_maxwin); 681 receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
@@ -937,7 +936,7 @@ static int tcp_packet(struct nf_conn *ct,
937 ct->proto.tcp.last_dir = dir; 936 ct->proto.tcp.last_dir = dir;
938 937
939 pr_debug("tcp_conntracks: "); 938 pr_debug("tcp_conntracks: ");
940 NF_CT_DUMP_TUPLE(tuple); 939 nf_ct_dump_tuple(tuple);
941 pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n", 940 pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
942 (th->syn ? 1 : 0), (th->ack ? 1 : 0), 941 (th->syn ? 1 : 0), (th->ack ? 1 : 0),
943 (th->fin ? 1 : 0), (th->rst ? 1 : 0), 942 (th->fin ? 1 : 0), (th->rst ? 1 : 0),
@@ -982,9 +981,8 @@ static int tcp_packet(struct nf_conn *ct,
982} 981}
983 982
984/* Called when a new connection for this protocol found. */ 983/* Called when a new connection for this protocol found. */
985static int tcp_new(struct nf_conn *ct, 984static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
986 const struct sk_buff *skb, 985 unsigned int dataoff)
987 unsigned int dataoff)
988{ 986{
989 enum tcp_conntrack new_state; 987 enum tcp_conntrack new_state;
990 const struct tcphdr *th; 988 const struct tcphdr *th;
@@ -1003,7 +1001,7 @@ static int tcp_new(struct nf_conn *ct,
1003 /* Invalid: delete conntrack */ 1001 /* Invalid: delete conntrack */
1004 if (new_state >= TCP_CONNTRACK_MAX) { 1002 if (new_state >= TCP_CONNTRACK_MAX) {
1005 pr_debug("nf_ct_tcp: invalid new deleting.\n"); 1003 pr_debug("nf_ct_tcp: invalid new deleting.\n");
1006 return 0; 1004 return false;
1007 } 1005 }
1008 1006
1009 if (new_state == TCP_CONNTRACK_SYN_SENT) { 1007 if (new_state == TCP_CONNTRACK_SYN_SENT) {
@@ -1021,7 +1019,7 @@ static int tcp_new(struct nf_conn *ct,
1021 ct->proto.tcp.seen[1].flags = 0; 1019 ct->proto.tcp.seen[1].flags = 0;
1022 } else if (nf_ct_tcp_loose == 0) { 1020 } else if (nf_ct_tcp_loose == 0) {
1023 /* Don't try to pick up connections. */ 1021 /* Don't try to pick up connections. */
1024 return 0; 1022 return false;
1025 } else { 1023 } else {
1026 /* 1024 /*
1027 * We are in the middle of a connection, 1025 * We are in the middle of a connection,
@@ -1061,7 +1059,7 @@ static int tcp_new(struct nf_conn *ct,
1061 sender->td_scale, 1059 sender->td_scale,
1062 receiver->td_end, receiver->td_maxend, receiver->td_maxwin, 1060 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
1063 receiver->td_scale); 1061 receiver->td_scale);
1064 return 1; 1062 return true;
1065} 1063}
1066 1064
1067#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 1065#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
@@ -1129,11 +1127,13 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
1129 if (err < 0) 1127 if (err < 0)
1130 return err; 1128 return err;
1131 1129
1132 if (!tb[CTA_PROTOINFO_TCP_STATE]) 1130 if (tb[CTA_PROTOINFO_TCP_STATE] &&
1131 nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]) >= TCP_CONNTRACK_MAX)
1133 return -EINVAL; 1132 return -EINVAL;
1134 1133
1135 write_lock_bh(&tcp_lock); 1134 write_lock_bh(&tcp_lock);
1136 ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]); 1135 if (tb[CTA_PROTOINFO_TCP_STATE])
1136 ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
1137 1137
1138 if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) { 1138 if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
1139 struct nf_ct_tcp_flags *attr = 1139 struct nf_ct_tcp_flags *attr =
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index b8a35cc06416..8b21762e65de 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -26,7 +26,7 @@
26static unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ; 26static unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ;
27static unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ; 27static unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ;
28 28
29static int udp_pkt_to_tuple(const struct sk_buff *skb, 29static bool udp_pkt_to_tuple(const struct sk_buff *skb,
30 unsigned int dataoff, 30 unsigned int dataoff,
31 struct nf_conntrack_tuple *tuple) 31 struct nf_conntrack_tuple *tuple)
32{ 32{
@@ -36,20 +36,20 @@ static int udp_pkt_to_tuple(const struct sk_buff *skb,
36 /* Actually only need first 8 bytes. */ 36 /* Actually only need first 8 bytes. */
37 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 37 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
38 if (hp == NULL) 38 if (hp == NULL)
39 return 0; 39 return false;
40 40
41 tuple->src.u.udp.port = hp->source; 41 tuple->src.u.udp.port = hp->source;
42 tuple->dst.u.udp.port = hp->dest; 42 tuple->dst.u.udp.port = hp->dest;
43 43
44 return 1; 44 return true;
45} 45}
46 46
47static int udp_invert_tuple(struct nf_conntrack_tuple *tuple, 47static bool udp_invert_tuple(struct nf_conntrack_tuple *tuple,
48 const struct nf_conntrack_tuple *orig) 48 const struct nf_conntrack_tuple *orig)
49{ 49{
50 tuple->src.u.udp.port = orig->dst.u.udp.port; 50 tuple->src.u.udp.port = orig->dst.u.udp.port;
51 tuple->dst.u.udp.port = orig->src.u.udp.port; 51 tuple->dst.u.udp.port = orig->src.u.udp.port;
52 return 1; 52 return true;
53} 53}
54 54
55/* Print out the per-protocol part of the tuple. */ 55/* Print out the per-protocol part of the tuple. */
@@ -83,10 +83,10 @@ static int udp_packet(struct nf_conn *ct,
83} 83}
84 84
85/* Called when a new connection for this protocol found. */ 85/* Called when a new connection for this protocol found. */
86static int udp_new(struct nf_conn *ct, const struct sk_buff *skb, 86static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,
87 unsigned int dataoff) 87 unsigned int dataoff)
88{ 88{
89 return 1; 89 return true;
90} 90}
91 91
92static int udp_error(struct sk_buff *skb, unsigned int dataoff, 92static int udp_error(struct sk_buff *skb, unsigned int dataoff,
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 9dd03c7aeac6..1fa62f3c24f1 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -27,28 +27,28 @@
27static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ; 27static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ;
28static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ; 28static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ;
29 29
30static int udplite_pkt_to_tuple(const struct sk_buff *skb, 30static bool udplite_pkt_to_tuple(const struct sk_buff *skb,
31 unsigned int dataoff, 31 unsigned int dataoff,
32 struct nf_conntrack_tuple *tuple) 32 struct nf_conntrack_tuple *tuple)
33{ 33{
34 const struct udphdr *hp; 34 const struct udphdr *hp;
35 struct udphdr _hdr; 35 struct udphdr _hdr;
36 36
37 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 37 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
38 if (hp == NULL) 38 if (hp == NULL)
39 return 0; 39 return false;
40 40
41 tuple->src.u.udp.port = hp->source; 41 tuple->src.u.udp.port = hp->source;
42 tuple->dst.u.udp.port = hp->dest; 42 tuple->dst.u.udp.port = hp->dest;
43 return 1; 43 return true;
44} 44}
45 45
46static int udplite_invert_tuple(struct nf_conntrack_tuple *tuple, 46static bool udplite_invert_tuple(struct nf_conntrack_tuple *tuple,
47 const struct nf_conntrack_tuple *orig) 47 const struct nf_conntrack_tuple *orig)
48{ 48{
49 tuple->src.u.udp.port = orig->dst.u.udp.port; 49 tuple->src.u.udp.port = orig->dst.u.udp.port;
50 tuple->dst.u.udp.port = orig->src.u.udp.port; 50 tuple->dst.u.udp.port = orig->src.u.udp.port;
51 return 1; 51 return true;
52} 52}
53 53
54/* Print out the per-protocol part of the tuple. */ 54/* Print out the per-protocol part of the tuple. */
@@ -83,10 +83,10 @@ static int udplite_packet(struct nf_conn *ct,
83} 83}
84 84
85/* Called when a new connection for this protocol found. */ 85/* Called when a new connection for this protocol found. */
86static int udplite_new(struct nf_conn *ct, const struct sk_buff *skb, 86static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
87 unsigned int dataoff) 87 unsigned int dataoff)
88{ 88{
89 return 1; 89 return true;
90} 90}
91 91
92static int udplite_error(struct sk_buff *skb, unsigned int dataoff, 92static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
@@ -127,32 +127,13 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
127 } 127 }
128 128
129 /* Checksum invalid? Ignore. */ 129 /* Checksum invalid? Ignore. */
130 if (nf_conntrack_checksum && !skb_csum_unnecessary(skb) && 130 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
131 hooknum == NF_INET_PRE_ROUTING) { 131 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP,
132 if (pf == PF_INET) { 132 pf)) {
133 struct iphdr *iph = ip_hdr(skb); 133 if (LOG_INVALID(IPPROTO_UDPLITE))
134 134 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
135 skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, 135 "nf_ct_udplite: bad UDPLite checksum ");
136 udplen, IPPROTO_UDPLITE, 0); 136 return -NF_ACCEPT;
137 } else {
138 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
139 __wsum hsum = skb_checksum(skb, 0, dataoff, 0);
140
141 skb->csum = ~csum_unfold(
142 csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
143 udplen, IPPROTO_UDPLITE,
144 csum_sub(0, hsum)));
145 }
146
147 skb->ip_summed = CHECKSUM_NONE;
148 if (__skb_checksum_complete_head(skb, dataoff + cscov)) {
149 if (LOG_INVALID(IPPROTO_UDPLITE))
150 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
151 "nf_ct_udplite: bad UDPLite "
152 "checksum ");
153 return -NF_ACCEPT;
154 }
155 skb->ip_summed = CHECKSUM_UNNECESSARY;
156 } 137 }
157 138
158 return NF_ACCEPT; 139 return NF_ACCEPT;
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index 7542e25eede3..a94294b2b23c 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -72,7 +72,6 @@ static int help(struct sk_buff *skb,
72 struct nf_conntrack_tuple *tuple; 72 struct nf_conntrack_tuple *tuple;
73 struct sane_request *req; 73 struct sane_request *req;
74 struct sane_reply_net_start *reply; 74 struct sane_reply_net_start *reply;
75 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
76 75
77 ct_sane_info = &nfct_help(ct)->help.ct_sane_info; 76 ct_sane_info = &nfct_help(ct)->help.ct_sane_info;
78 /* Until there's been traffic both ways, don't look in packets. */ 77 /* Until there's been traffic both ways, don't look in packets. */
@@ -143,12 +142,12 @@ static int help(struct sk_buff *skb,
143 } 142 }
144 143
145 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 144 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
146 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, family, 145 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
147 &tuple->src.u3, &tuple->dst.u3, 146 &tuple->src.u3, &tuple->dst.u3,
148 IPPROTO_TCP, NULL, &reply->port); 147 IPPROTO_TCP, NULL, &reply->port);
149 148
150 pr_debug("nf_ct_sane: expect: "); 149 pr_debug("nf_ct_sane: expect: ");
151 NF_CT_DUMP_TUPLE(&exp->tuple); 150 nf_ct_dump_tuple(&exp->tuple);
152 151
153 /* Can't expect this? Best to drop packet now. */ 152 /* Can't expect this? Best to drop packet now. */
154 if (nf_ct_expect_related(exp) != 0) 153 if (nf_ct_expect_related(exp) != 0)
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index da5dec6e6158..65b3ba57a3b7 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -142,10 +142,10 @@ static int parse_addr(const struct nf_conn *ct, const char *cp,
142 const char *limit) 142 const char *limit)
143{ 143{
144 const char *end; 144 const char *end;
145 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
146 int ret = 0; 145 int ret = 0;
147 146
148 switch (family) { 147 memset(addr, 0, sizeof(*addr));
148 switch (nf_ct_l3num(ct)) {
149 case AF_INET: 149 case AF_INET:
150 ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end); 150 ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
151 break; 151 break;
@@ -739,7 +739,6 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
739 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 739 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
740 union nf_inet_addr *saddr; 740 union nf_inet_addr *saddr;
741 struct nf_conntrack_tuple tuple; 741 struct nf_conntrack_tuple tuple;
742 int family = ct->tuplehash[!dir].tuple.src.l3num;
743 int direct_rtp = 0, skip_expect = 0, ret = NF_DROP; 742 int direct_rtp = 0, skip_expect = 0, ret = NF_DROP;
744 u_int16_t base_port; 743 u_int16_t base_port;
745 __be16 rtp_port, rtcp_port; 744 __be16 rtp_port, rtcp_port;
@@ -769,7 +768,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
769 memset(&tuple, 0, sizeof(tuple)); 768 memset(&tuple, 0, sizeof(tuple));
770 if (saddr) 769 if (saddr)
771 tuple.src.u3 = *saddr; 770 tuple.src.u3 = *saddr;
772 tuple.src.l3num = family; 771 tuple.src.l3num = nf_ct_l3num(ct);
773 tuple.dst.protonum = IPPROTO_UDP; 772 tuple.dst.protonum = IPPROTO_UDP;
774 tuple.dst.u3 = *daddr; 773 tuple.dst.u3 = *daddr;
775 tuple.dst.u.udp.port = port; 774 tuple.dst.u.udp.port = port;
@@ -814,13 +813,13 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
814 rtp_exp = nf_ct_expect_alloc(ct); 813 rtp_exp = nf_ct_expect_alloc(ct);
815 if (rtp_exp == NULL) 814 if (rtp_exp == NULL)
816 goto err1; 815 goto err1;
817 nf_ct_expect_init(rtp_exp, class, family, saddr, daddr, 816 nf_ct_expect_init(rtp_exp, class, nf_ct_l3num(ct), saddr, daddr,
818 IPPROTO_UDP, NULL, &rtp_port); 817 IPPROTO_UDP, NULL, &rtp_port);
819 818
820 rtcp_exp = nf_ct_expect_alloc(ct); 819 rtcp_exp = nf_ct_expect_alloc(ct);
821 if (rtcp_exp == NULL) 820 if (rtcp_exp == NULL)
822 goto err2; 821 goto err2;
823 nf_ct_expect_init(rtcp_exp, class, family, saddr, daddr, 822 nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr,
824 IPPROTO_UDP, NULL, &rtcp_port); 823 IPPROTO_UDP, NULL, &rtcp_port);
825 824
826 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook); 825 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook);
@@ -870,7 +869,6 @@ static int process_sdp(struct sk_buff *skb,
870{ 869{
871 enum ip_conntrack_info ctinfo; 870 enum ip_conntrack_info ctinfo;
872 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 871 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
873 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
874 unsigned int matchoff, matchlen; 872 unsigned int matchoff, matchlen;
875 unsigned int mediaoff, medialen; 873 unsigned int mediaoff, medialen;
876 unsigned int sdpoff; 874 unsigned int sdpoff;
@@ -885,8 +883,8 @@ static int process_sdp(struct sk_buff *skb,
885 typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session; 883 typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session;
886 884
887 nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook); 885 nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook);
888 c_hdr = family == AF_INET ? SDP_HDR_CONNECTION_IP4 : 886 c_hdr = nf_ct_l3num(ct) == AF_INET ? SDP_HDR_CONNECTION_IP4 :
889 SDP_HDR_CONNECTION_IP6; 887 SDP_HDR_CONNECTION_IP6;
890 888
891 /* Find beginning of session description */ 889 /* Find beginning of session description */
892 if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen, 890 if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
@@ -1033,7 +1031,6 @@ static int process_register_request(struct sk_buff *skb,
1033 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1031 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1034 struct nf_conn_help *help = nfct_help(ct); 1032 struct nf_conn_help *help = nfct_help(ct);
1035 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 1033 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1036 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
1037 unsigned int matchoff, matchlen; 1034 unsigned int matchoff, matchlen;
1038 struct nf_conntrack_expect *exp; 1035 struct nf_conntrack_expect *exp;
1039 union nf_inet_addr *saddr, daddr; 1036 union nf_inet_addr *saddr, daddr;
@@ -1088,8 +1085,8 @@ static int process_register_request(struct sk_buff *skb,
1088 if (sip_direct_signalling) 1085 if (sip_direct_signalling)
1089 saddr = &ct->tuplehash[!dir].tuple.src.u3; 1086 saddr = &ct->tuplehash[!dir].tuple.src.u3;
1090 1087
1091 nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, family, saddr, &daddr, 1088 nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct),
1092 IPPROTO_UDP, NULL, &port); 1089 saddr, &daddr, IPPROTO_UDP, NULL, &port);
1093 exp->timeout.expires = sip_timeout * HZ; 1090 exp->timeout.expires = sip_timeout * HZ;
1094 exp->helper = nfct_help(ct)->helper; 1091 exp->helper = nfct_help(ct)->helper;
1095 exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE; 1092 exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE;
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 9d0b8bb4113c..b59871f6bdda 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -127,21 +127,14 @@ static int ct_seq_show(struct seq_file *s, void *v)
127 if (NF_CT_DIRECTION(hash)) 127 if (NF_CT_DIRECTION(hash))
128 return 0; 128 return 0;
129 129
130 l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL] 130 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
131 .tuple.src.l3num);
132
133 NF_CT_ASSERT(l3proto); 131 NF_CT_ASSERT(l3proto);
134 l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL] 132 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
135 .tuple.src.l3num,
136 ct->tuplehash[IP_CT_DIR_ORIGINAL]
137 .tuple.dst.protonum);
138 NF_CT_ASSERT(l4proto); 133 NF_CT_ASSERT(l4proto);
139 134
140 if (seq_printf(s, "%-8s %u %-8s %u %ld ", 135 if (seq_printf(s, "%-8s %u %-8s %u %ld ",
141 l3proto->name, 136 l3proto->name, nf_ct_l3num(ct),
142 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, 137 l4proto->name, nf_ct_protonum(ct),
143 l4proto->name,
144 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
145 timer_pending(&ct->timeout) 138 timer_pending(&ct->timeout)
146 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0) 139 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
147 return -ENOSPC; 140 return -ENOSPC;
@@ -295,6 +288,41 @@ static const struct file_operations ct_cpu_seq_fops = {
295 .llseek = seq_lseek, 288 .llseek = seq_lseek,
296 .release = seq_release, 289 .release = seq_release,
297}; 290};
291
292static int nf_conntrack_standalone_init_proc(void)
293{
294 struct proc_dir_entry *pde;
295
296 pde = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops);
297 if (!pde)
298 goto out_nf_conntrack;
299 pde = create_proc_entry("nf_conntrack", S_IRUGO, init_net.proc_net_stat);
300 if (!pde)
301 goto out_stat_nf_conntrack;
302 pde->proc_fops = &ct_cpu_seq_fops;
303 pde->owner = THIS_MODULE;
304 return 0;
305
306out_stat_nf_conntrack:
307 proc_net_remove(&init_net, "nf_conntrack");
308out_nf_conntrack:
309 return -ENOMEM;
310}
311
312static void nf_conntrack_standalone_fini_proc(void)
313{
314 remove_proc_entry("nf_conntrack", init_net.proc_net_stat);
315 proc_net_remove(&init_net, "nf_conntrack");
316}
317#else
318static int nf_conntrack_standalone_init_proc(void)
319{
320 return 0;
321}
322
323static void nf_conntrack_standalone_fini_proc(void)
324{
325}
298#endif /* CONFIG_PROC_FS */ 326#endif /* CONFIG_PROC_FS */
299 327
300/* Sysctl support */ 328/* Sysctl support */
@@ -390,60 +418,61 @@ static struct ctl_path nf_ct_path[] = {
390}; 418};
391 419
392EXPORT_SYMBOL_GPL(nf_ct_log_invalid); 420EXPORT_SYMBOL_GPL(nf_ct_log_invalid);
421
422static int nf_conntrack_standalone_init_sysctl(void)
423{
424 nf_ct_sysctl_header =
425 register_sysctl_paths(nf_ct_path, nf_ct_netfilter_table);
426 if (nf_ct_sysctl_header == NULL) {
427 printk("nf_conntrack: can't register to sysctl.\n");
428 return -ENOMEM;
429 }
430 return 0;
431
432}
433
434static void nf_conntrack_standalone_fini_sysctl(void)
435{
436 unregister_sysctl_table(nf_ct_sysctl_header);
437}
438#else
439static int nf_conntrack_standalone_init_sysctl(void)
440{
441 return 0;
442}
443
444static void nf_conntrack_standalone_fini_sysctl(void)
445{
446}
393#endif /* CONFIG_SYSCTL */ 447#endif /* CONFIG_SYSCTL */
394 448
395static int __init nf_conntrack_standalone_init(void) 449static int __init nf_conntrack_standalone_init(void)
396{ 450{
397#ifdef CONFIG_PROC_FS 451 int ret;
398 struct proc_dir_entry *proc;
399#endif
400 int ret = 0;
401 452
402 ret = nf_conntrack_init(); 453 ret = nf_conntrack_init();
403 if (ret < 0) 454 if (ret < 0)
404 return ret; 455 goto out;
405 456 ret = nf_conntrack_standalone_init_proc();
406#ifdef CONFIG_PROC_FS 457 if (ret < 0)
407 proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops); 458 goto out_proc;
408 if (!proc) goto cleanup_init; 459 ret = nf_conntrack_standalone_init_sysctl();
409 460 if (ret < 0)
410 if (!proc_create("nf_conntrack", S_IRUGO, 461 goto out_sysctl;
411 init_net.proc_net_stat, &ct_cpu_seq_fops)) 462 return 0;
412 goto cleanup_proc;
413#endif
414#ifdef CONFIG_SYSCTL
415 nf_ct_sysctl_header = register_sysctl_paths(nf_ct_path,
416 nf_ct_netfilter_table);
417 if (nf_ct_sysctl_header == NULL) {
418 printk("nf_conntrack: can't register to sysctl.\n");
419 ret = -ENOMEM;
420 goto cleanup_proc_stat;
421 }
422#endif
423 return ret;
424 463
425#ifdef CONFIG_SYSCTL 464out_sysctl:
426 cleanup_proc_stat: 465 nf_conntrack_standalone_fini_proc();
427#endif 466out_proc:
428#ifdef CONFIG_PROC_FS
429 remove_proc_entry("nf_conntrack", init_net. proc_net_stat);
430 cleanup_proc:
431 proc_net_remove(&init_net, "nf_conntrack");
432 cleanup_init:
433#endif /* CNFIG_PROC_FS */
434 nf_conntrack_cleanup(); 467 nf_conntrack_cleanup();
468out:
435 return ret; 469 return ret;
436} 470}
437 471
438static void __exit nf_conntrack_standalone_fini(void) 472static void __exit nf_conntrack_standalone_fini(void)
439{ 473{
440#ifdef CONFIG_SYSCTL 474 nf_conntrack_standalone_fini_sysctl();
441 unregister_sysctl_table(nf_ct_sysctl_header); 475 nf_conntrack_standalone_fini_proc();
442#endif
443#ifdef CONFIG_PROC_FS
444 remove_proc_entry("nf_conntrack", init_net.proc_net_stat);
445 proc_net_remove(&init_net, "nf_conntrack");
446#endif /* CNFIG_PROC_FS */
447 nf_conntrack_cleanup(); 476 nf_conntrack_cleanup();
448} 477}
449 478
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index a28341b30f21..f57f6e7a71ee 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -44,7 +44,6 @@ static int tftp_help(struct sk_buff *skb,
44 struct nf_conntrack_expect *exp; 44 struct nf_conntrack_expect *exp;
45 struct nf_conntrack_tuple *tuple; 45 struct nf_conntrack_tuple *tuple;
46 unsigned int ret = NF_ACCEPT; 46 unsigned int ret = NF_ACCEPT;
47 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
48 typeof(nf_nat_tftp_hook) nf_nat_tftp; 47 typeof(nf_nat_tftp_hook) nf_nat_tftp;
49 48
50 tfh = skb_header_pointer(skb, protoff + sizeof(struct udphdr), 49 tfh = skb_header_pointer(skb, protoff + sizeof(struct udphdr),
@@ -56,19 +55,20 @@ static int tftp_help(struct sk_buff *skb,
56 case TFTP_OPCODE_READ: 55 case TFTP_OPCODE_READ:
57 case TFTP_OPCODE_WRITE: 56 case TFTP_OPCODE_WRITE:
58 /* RRQ and WRQ works the same way */ 57 /* RRQ and WRQ works the same way */
59 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 58 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
60 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); 59 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
61 60
62 exp = nf_ct_expect_alloc(ct); 61 exp = nf_ct_expect_alloc(ct);
63 if (exp == NULL) 62 if (exp == NULL)
64 return NF_DROP; 63 return NF_DROP;
65 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; 64 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
66 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, family, 65 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
66 nf_ct_l3num(ct),
67 &tuple->src.u3, &tuple->dst.u3, 67 &tuple->src.u3, &tuple->dst.u3,
68 IPPROTO_UDP, NULL, &tuple->dst.u.udp.port); 68 IPPROTO_UDP, NULL, &tuple->dst.u.udp.port);
69 69
70 pr_debug("expect: "); 70 pr_debug("expect: ");
71 NF_CT_DUMP_TUPLE(&exp->tuple); 71 nf_ct_dump_tuple(&exp->tuple);
72 72
73 nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook); 73 nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);
74 if (nf_nat_tftp && ct->status & IPS_NAT_MASK) 74 if (nf_nat_tftp && ct->status & IPS_NAT_MASK)
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 0bd95680a494..f52f7f810ac4 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -58,7 +58,7 @@ static struct xt_af *xt;
58#define duprintf(format, args...) 58#define duprintf(format, args...)
59#endif 59#endif
60 60
61static const char *xt_prefix[NPROTO] = { 61static const char *const xt_prefix[NPROTO] = {
62 [AF_INET] = "ip", 62 [AF_INET] = "ip",
63 [AF_INET6] = "ip6", 63 [AF_INET6] = "ip6",
64 [NF_ARP] = "arp", 64 [NF_ARP] = "arp",
@@ -248,7 +248,7 @@ EXPORT_SYMBOL_GPL(xt_request_find_target);
248 248
249static int match_revfn(int af, const char *name, u8 revision, int *bestp) 249static int match_revfn(int af, const char *name, u8 revision, int *bestp)
250{ 250{
251 struct xt_match *m; 251 const struct xt_match *m;
252 int have_rev = 0; 252 int have_rev = 0;
253 253
254 list_for_each_entry(m, &xt[af].match, list) { 254 list_for_each_entry(m, &xt[af].match, list) {
@@ -264,7 +264,7 @@ static int match_revfn(int af, const char *name, u8 revision, int *bestp)
264 264
265static int target_revfn(int af, const char *name, u8 revision, int *bestp) 265static int target_revfn(int af, const char *name, u8 revision, int *bestp)
266{ 266{
267 struct xt_target *t; 267 const struct xt_target *t;
268 int have_rev = 0; 268 int have_rev = 0;
269 269
270 list_for_each_entry(t, &xt[af].target, list) { 270 list_for_each_entry(t, &xt[af].target, list) {
@@ -385,7 +385,7 @@ short xt_compat_calc_jump(int af, unsigned int offset)
385} 385}
386EXPORT_SYMBOL_GPL(xt_compat_calc_jump); 386EXPORT_SYMBOL_GPL(xt_compat_calc_jump);
387 387
388int xt_compat_match_offset(struct xt_match *match) 388int xt_compat_match_offset(const struct xt_match *match)
389{ 389{
390 u_int16_t csize = match->compatsize ? : match->matchsize; 390 u_int16_t csize = match->compatsize ? : match->matchsize;
391 return XT_ALIGN(match->matchsize) - COMPAT_XT_ALIGN(csize); 391 return XT_ALIGN(match->matchsize) - COMPAT_XT_ALIGN(csize);
@@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(xt_compat_match_offset);
395int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr, 395int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
396 unsigned int *size) 396 unsigned int *size)
397{ 397{
398 struct xt_match *match = m->u.kernel.match; 398 const struct xt_match *match = m->u.kernel.match;
399 struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m; 399 struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
400 int pad, off = xt_compat_match_offset(match); 400 int pad, off = xt_compat_match_offset(match);
401 u_int16_t msize = cm->u.user.match_size; 401 u_int16_t msize = cm->u.user.match_size;
@@ -422,7 +422,7 @@ EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
422int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr, 422int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr,
423 unsigned int *size) 423 unsigned int *size)
424{ 424{
425 struct xt_match *match = m->u.kernel.match; 425 const struct xt_match *match = m->u.kernel.match;
426 struct compat_xt_entry_match __user *cm = *dstptr; 426 struct compat_xt_entry_match __user *cm = *dstptr;
427 int off = xt_compat_match_offset(match); 427 int off = xt_compat_match_offset(match);
428 u_int16_t msize = m->u.user.match_size - off; 428 u_int16_t msize = m->u.user.match_size - off;
@@ -479,7 +479,7 @@ int xt_check_target(const struct xt_target *target, unsigned short family,
479EXPORT_SYMBOL_GPL(xt_check_target); 479EXPORT_SYMBOL_GPL(xt_check_target);
480 480
481#ifdef CONFIG_COMPAT 481#ifdef CONFIG_COMPAT
482int xt_compat_target_offset(struct xt_target *target) 482int xt_compat_target_offset(const struct xt_target *target)
483{ 483{
484 u_int16_t csize = target->compatsize ? : target->targetsize; 484 u_int16_t csize = target->compatsize ? : target->targetsize;
485 return XT_ALIGN(target->targetsize) - COMPAT_XT_ALIGN(csize); 485 return XT_ALIGN(target->targetsize) - COMPAT_XT_ALIGN(csize);
@@ -489,7 +489,7 @@ EXPORT_SYMBOL_GPL(xt_compat_target_offset);
489void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr, 489void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
490 unsigned int *size) 490 unsigned int *size)
491{ 491{
492 struct xt_target *target = t->u.kernel.target; 492 const struct xt_target *target = t->u.kernel.target;
493 struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t; 493 struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
494 int pad, off = xt_compat_target_offset(target); 494 int pad, off = xt_compat_target_offset(target);
495 u_int16_t tsize = ct->u.user.target_size; 495 u_int16_t tsize = ct->u.user.target_size;
@@ -515,7 +515,7 @@ EXPORT_SYMBOL_GPL(xt_compat_target_from_user);
515int xt_compat_target_to_user(struct xt_entry_target *t, void __user **dstptr, 515int xt_compat_target_to_user(struct xt_entry_target *t, void __user **dstptr,
516 unsigned int *size) 516 unsigned int *size)
517{ 517{
518 struct xt_target *target = t->u.kernel.target; 518 const struct xt_target *target = t->u.kernel.target;
519 struct compat_xt_entry_target __user *ct = *dstptr; 519 struct compat_xt_entry_target __user *ct = *dstptr;
520 int off = xt_compat_target_offset(target); 520 int off = xt_compat_target_offset(target);
521 u_int16_t tsize = t->u.user.target_size - off; 521 u_int16_t tsize = t->u.user.target_size - off;
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 1faa9136195d..211189eb2b67 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -55,7 +55,7 @@ static void secmark_save(const struct sk_buff *skb)
55static void secmark_restore(struct sk_buff *skb) 55static void secmark_restore(struct sk_buff *skb)
56{ 56{
57 if (!skb->secmark) { 57 if (!skb->secmark) {
58 struct nf_conn *ct; 58 const struct nf_conn *ct;
59 enum ip_conntrack_info ctinfo; 59 enum ip_conntrack_info ctinfo;
60 60
61 ct = nf_ct_get(skb, &ctinfo); 61 ct = nf_ct_get(skb, &ctinfo);
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
index 24c73ba31eaa..64d6ad380293 100644
--- a/net/netfilter/xt_RATEEST.c
+++ b/net/netfilter/xt_RATEEST.c
@@ -96,7 +96,7 @@ xt_rateest_tg_checkentry(const char *tablename,
96 void *targinfo, 96 void *targinfo,
97 unsigned int hook_mask) 97 unsigned int hook_mask)
98{ 98{
99 struct xt_rateest_target_info *info = (void *)targinfo; 99 struct xt_rateest_target_info *info = targinfo;
100 struct xt_rateest *est; 100 struct xt_rateest *est;
101 struct { 101 struct {
102 struct nlattr opt; 102 struct nlattr opt;
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 3b0111933f60..2e89a00df92c 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -72,9 +72,7 @@ connlimit_iphash6(const union nf_inet_addr *addr,
72 72
73static inline bool already_closed(const struct nf_conn *conn) 73static inline bool already_closed(const struct nf_conn *conn)
74{ 74{
75 u_int16_t proto = conn->tuplehash[0].tuple.dst.protonum; 75 if (nf_ct_protonum(conn) == IPPROTO_TCP)
76
77 if (proto == IPPROTO_TCP)
78 return conn->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT; 76 return conn->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT;
79 else 77 else
80 return 0; 78 return 0;
@@ -106,10 +104,10 @@ static int count_them(struct xt_connlimit_data *data,
106 const union nf_inet_addr *mask, 104 const union nf_inet_addr *mask,
107 const struct xt_match *match) 105 const struct xt_match *match)
108{ 106{
109 struct nf_conntrack_tuple_hash *found; 107 const struct nf_conntrack_tuple_hash *found;
110 struct xt_connlimit_conn *conn; 108 struct xt_connlimit_conn *conn;
111 struct xt_connlimit_conn *tmp; 109 struct xt_connlimit_conn *tmp;
112 struct nf_conn *found_ct; 110 const struct nf_conn *found_ct;
113 struct list_head *hash; 111 struct list_head *hash;
114 bool addit = true; 112 bool addit = true;
115 int matches = 0; 113 int matches = 0;
@@ -256,7 +254,7 @@ connlimit_mt_check(const char *tablename, const void *ip,
256static void 254static void
257connlimit_mt_destroy(const struct xt_match *match, void *matchinfo) 255connlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
258{ 256{
259 struct xt_connlimit_info *info = matchinfo; 257 const struct xt_connlimit_info *info = matchinfo;
260 struct xt_connlimit_conn *conn; 258 struct xt_connlimit_conn *conn;
261 struct xt_connlimit_conn *tmp; 259 struct xt_connlimit_conn *tmp;
262 struct list_head *hash = info->data->iphash; 260 struct list_head *hash = info->data->iphash;
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 0c50b2894055..d61412f58ef7 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -65,7 +65,7 @@ conntrack_mt_v0(const struct sk_buff *skb, const struct net_device *in,
65 } 65 }
66 66
67 if (sinfo->flags & XT_CONNTRACK_PROTO && 67 if (sinfo->flags & XT_CONNTRACK_PROTO &&
68 FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != 68 FWINV(nf_ct_protonum(ct) !=
69 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, 69 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum,
70 XT_CONNTRACK_PROTO)) 70 XT_CONNTRACK_PROTO))
71 return false; 71 return false;
@@ -174,7 +174,7 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
174 174
175 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 175 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
176 if ((info->match_flags & XT_CONNTRACK_PROTO) && 176 if ((info->match_flags & XT_CONNTRACK_PROTO) &&
177 (tuple->dst.protonum == info->l4proto) ^ 177 (nf_ct_protonum(ct) == info->l4proto) ^
178 !(info->invert_flags & XT_CONNTRACK_PROTO)) 178 !(info->invert_flags & XT_CONNTRACK_PROTO))
179 return false; 179 return false;
180 180
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c
index 667f45e72cd9..8b6522186d9f 100644
--- a/net/netfilter/xt_dccp.c
+++ b/net/netfilter/xt_dccp.c
@@ -98,7 +98,8 @@ dccp_mt(const struct sk_buff *skb, const struct net_device *in,
98 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) 98 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
99{ 99{
100 const struct xt_dccp_info *info = matchinfo; 100 const struct xt_dccp_info *info = matchinfo;
101 struct dccp_hdr _dh, *dh; 101 const struct dccp_hdr *dh;
102 struct dccp_hdr _dh;
102 103
103 if (offset) 104 if (offset)
104 return false; 105 return false;
diff --git a/net/netfilter/xt_esp.c b/net/netfilter/xt_esp.c
index 71c7c3785266..a133eb9b23e1 100644
--- a/net/netfilter/xt_esp.c
+++ b/net/netfilter/xt_esp.c
@@ -47,7 +47,8 @@ esp_mt(const struct sk_buff *skb, const struct net_device *in,
47 const struct net_device *out, const struct xt_match *match, 47 const struct net_device *out, const struct xt_match *match,
48 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) 48 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
49{ 49{
50 struct ip_esp_hdr _esp, *eh; 50 const struct ip_esp_hdr *eh;
51 struct ip_esp_hdr _esp;
51 const struct xt_esp *espinfo = matchinfo; 52 const struct xt_esp *espinfo = matchinfo;
52 53
53 /* Must not be a fragment. */ 54 /* Must not be a fragment. */
diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c
index 31daa8192422..fd88c489b70e 100644
--- a/net/netfilter/xt_multiport.c
+++ b/net/netfilter/xt_multiport.c
@@ -100,7 +100,8 @@ multiport_mt_v0(const struct sk_buff *skb, const struct net_device *in,
100 const void *matchinfo, int offset, unsigned int protoff, 100 const void *matchinfo, int offset, unsigned int protoff,
101 bool *hotdrop) 101 bool *hotdrop)
102{ 102{
103 __be16 _ports[2], *pptr; 103 const __be16 *pptr;
104 __be16 _ports[2];
104 const struct xt_multiport *multiinfo = matchinfo; 105 const struct xt_multiport *multiinfo = matchinfo;
105 106
106 if (offset) 107 if (offset)
@@ -126,7 +127,8 @@ multiport_mt(const struct sk_buff *skb, const struct net_device *in,
126 const void *matchinfo, int offset, unsigned int protoff, 127 const void *matchinfo, int offset, unsigned int protoff,
127 bool *hotdrop) 128 bool *hotdrop)
128{ 129{
129 __be16 _ports[2], *pptr; 130 const __be16 *pptr;
131 __be16 _ports[2];
130 const struct xt_multiport_v1 *multiinfo = matchinfo; 132 const struct xt_multiport_v1 *multiinfo = matchinfo;
131 133
132 if (offset) 134 if (offset)
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c
index 9e918add2282..d351582b2a3d 100644
--- a/net/netfilter/xt_policy.c
+++ b/net/netfilter/xt_policy.c
@@ -136,7 +136,7 @@ policy_mt_check(const char *tablename, const void *ip_void,
136 const struct xt_match *match, void *matchinfo, 136 const struct xt_match *match, void *matchinfo,
137 unsigned int hook_mask) 137 unsigned int hook_mask)
138{ 138{
139 struct xt_policy_info *info = matchinfo; 139 const struct xt_policy_info *info = matchinfo;
140 140
141 if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) { 141 if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
142 printk(KERN_ERR "xt_policy: neither incoming nor " 142 printk(KERN_ERR "xt_policy: neither incoming nor "
diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c
index fdb86a515146..ebd84f1b4f62 100644
--- a/net/netfilter/xt_rateest.c
+++ b/net/netfilter/xt_rateest.c
@@ -86,7 +86,7 @@ static bool xt_rateest_mt_checkentry(const char *tablename,
86 void *matchinfo, 86 void *matchinfo,
87 unsigned int hook_mask) 87 unsigned int hook_mask)
88{ 88{
89 struct xt_rateest_match_info *info = (void *)matchinfo; 89 struct xt_rateest_match_info *info = matchinfo;
90 struct xt_rateest *est1, *est2; 90 struct xt_rateest *est1, *est2;
91 91
92 if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | 92 if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS |
@@ -130,7 +130,7 @@ err1:
130static void xt_rateest_mt_destroy(const struct xt_match *match, 130static void xt_rateest_mt_destroy(const struct xt_match *match,
131 void *matchinfo) 131 void *matchinfo)
132{ 132{
133 struct xt_rateest_match_info *info = (void *)matchinfo; 133 struct xt_rateest_match_info *info = matchinfo;
134 134
135 xt_rateest_put(info->est1); 135 xt_rateest_put(info->est1);
136 if (info->est2) 136 if (info->est2)
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index b718ec64333d..e6e4681fa047 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -46,7 +46,8 @@ match_packet(const struct sk_buff *skb,
46 bool *hotdrop) 46 bool *hotdrop)
47{ 47{
48 u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; 48 u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
49 sctp_chunkhdr_t _sch, *sch; 49 const sctp_chunkhdr_t *sch;
50 sctp_chunkhdr_t _sch;
50 int chunk_match_type = info->chunk_match_type; 51 int chunk_match_type = info->chunk_match_type;
51 const struct xt_sctp_flag_info *flag_info = info->flag_info; 52 const struct xt_sctp_flag_info *flag_info = info->flag_info;
52 int flag_count = info->flag_count; 53 int flag_count = info->flag_count;
@@ -121,7 +122,8 @@ sctp_mt(const struct sk_buff *skb, const struct net_device *in,
121 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) 122 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
122{ 123{
123 const struct xt_sctp_info *info = matchinfo; 124 const struct xt_sctp_info *info = matchinfo;
124 sctp_sctphdr_t _sh, *sh; 125 const sctp_sctphdr_t *sh;
126 sctp_sctphdr_t _sh;
125 127
126 if (offset) { 128 if (offset) {
127 duprintf("Dropping non-first fragment.. FIXME\n"); 129 duprintf("Dropping non-first fragment.. FIXME\n");
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index d7a5b27fe81e..6771bf01275b 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -31,9 +31,11 @@ tcpmss_mt(const struct sk_buff *skb, const struct net_device *in,
31 bool *hotdrop) 31 bool *hotdrop)
32{ 32{
33 const struct xt_tcpmss_match_info *info = matchinfo; 33 const struct xt_tcpmss_match_info *info = matchinfo;
34 struct tcphdr _tcph, *th; 34 const struct tcphdr *th;
35 struct tcphdr _tcph;
35 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 36 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
36 u8 _opt[15 * 4 - sizeof(_tcph)], *op; 37 const u_int8_t *op;
38 u8 _opt[15 * 4 - sizeof(_tcph)];
37 unsigned int i, optlen; 39 unsigned int i, optlen;
38 40
39 /* If we don't have the whole header, drop packet. */ 41 /* If we don't have the whole header, drop packet. */
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index 4fa3b669f691..951b06b8d701 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -42,7 +42,8 @@ tcp_find_option(u_int8_t option,
42 bool *hotdrop) 42 bool *hotdrop)
43{ 43{
44 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 44 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
45 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 45 const u_int8_t *op;
46 u_int8_t _opt[60 - sizeof(struct tcphdr)];
46 unsigned int i; 47 unsigned int i;
47 48
48 duprintf("tcp_match: finding option\n"); 49 duprintf("tcp_match: finding option\n");
@@ -72,7 +73,8 @@ tcp_mt(const struct sk_buff *skb, const struct net_device *in,
72 const struct net_device *out, const struct xt_match *match, 73 const struct net_device *out, const struct xt_match *match,
73 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) 74 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
74{ 75{
75 struct tcphdr _tcph, *th; 76 const struct tcphdr *th;
77 struct tcphdr _tcph;
76 const struct xt_tcp *tcpinfo = matchinfo; 78 const struct xt_tcp *tcpinfo = matchinfo;
77 79
78 if (offset) { 80 if (offset) {
@@ -144,7 +146,8 @@ udp_mt(const struct sk_buff *skb, const struct net_device *in,
144 const struct net_device *out, const struct xt_match *match, 146 const struct net_device *out, const struct xt_match *match,
145 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) 147 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
146{ 148{
147 struct udphdr _udph, *uh; 149 const struct udphdr *uh;
150 struct udphdr _udph;
148 const struct xt_udp *udpinfo = matchinfo; 151 const struct xt_udp *udpinfo = matchinfo;
149 152
150 /* Must not be a fragment. */ 153 /* Must not be a fragment. */
diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c
index 9fa2e0824708..ed76baab4734 100644
--- a/net/netfilter/xt_time.c
+++ b/net/netfilter/xt_time.c
@@ -223,7 +223,7 @@ time_mt_check(const char *tablename, const void *ip,
223 const struct xt_match *match, void *matchinfo, 223 const struct xt_match *match, void *matchinfo,
224 unsigned int hook_mask) 224 unsigned int hook_mask)
225{ 225{
226 struct xt_time_info *info = matchinfo; 226 const struct xt_time_info *info = matchinfo;
227 227
228 if (info->daytime_start > XT_TIME_MAX_DAYTIME || 228 if (info->daytime_start > XT_TIME_MAX_DAYTIME ||
229 info->daytime_stop > XT_TIME_MAX_DAYTIME) { 229 info->daytime_stop > XT_TIME_MAX_DAYTIME) {