diff options
author | David S. Miller <davem@davemloft.net> | 2008-04-14 06:50:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-14 06:50:43 -0400 |
commit | 334f8b2afd9652e20f67ddee4fec483ed860425b (patch) | |
tree | 35d4fb46a9dc145e831fe5da026f2bfd9ee6657c | |
parent | 7477fd2e6b676fcd15861c2a96a7172f71afe0a5 (diff) | |
parent | ef1a5a50bbd509b8697dcd4d13017e9e0053867b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.26
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 | ||
78 | struct sk_buff; | 80 | struct sk_buff; |
79 | struct net_device; | ||
80 | 81 | ||
81 | typedef unsigned int nf_hookfn(unsigned int hooknum, | 82 | typedef 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 | ||
271 | static inline __sum16 | ||
272 | nf_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 | |||
265 | extern int nf_register_afinfo(const struct nf_afinfo *afinfo); | 288 | extern int nf_register_afinfo(const struct nf_afinfo *afinfo); |
266 | extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo); | 289 | extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo); |
267 | 290 | ||
@@ -320,5 +343,56 @@ extern void (*nf_ct_destroy)(struct nf_conntrack *); | |||
320 | static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} | 343 | static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} |
321 | #endif | 344 | #endif |
322 | 345 | ||
346 | static 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 | |||
356 | static 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 | |||
366 | static 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 | |||
377 | static 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 | |||
387 | static 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 */ | ||
5 | enum 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 | |||
20 | enum 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 | |||
30 | struct 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 { | |||
80 | enum ctattr_protoinfo { | 80 | enum 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 | ||
99 | enum 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 | |||
98 | enum ctattr_counters { | 106 | enum 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); | |||
430 | extern void xt_compat_flush_offsets(int af); | 430 | extern void xt_compat_flush_offsets(int af); |
431 | extern short xt_compat_calc_jump(int af, unsigned int offset); | 431 | extern short xt_compat_calc_jump(int af, unsigned int offset); |
432 | 432 | ||
433 | extern int xt_compat_match_offset(struct xt_match *match); | 433 | extern int xt_compat_match_offset(const struct xt_match *match); |
434 | extern int xt_compat_match_from_user(struct xt_entry_match *m, | 434 | extern int xt_compat_match_from_user(struct xt_entry_match *m, |
435 | void **dstptr, unsigned int *size); | 435 | void **dstptr, unsigned int *size); |
436 | extern int xt_compat_match_to_user(struct xt_entry_match *m, | 436 | extern 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 | ||
439 | extern int xt_compat_target_offset(struct xt_target *target); | 439 | extern int xt_compat_target_offset(const struct xt_target *target); |
440 | extern void xt_compat_target_from_user(struct xt_entry_target *t, | 440 | extern void xt_compat_target_from_user(struct xt_entry_target *t, |
441 | void **dstptr, unsigned int *size); | 441 | void **dstptr, unsigned int *size); |
442 | extern int xt_compat_target_to_user(struct xt_entry_target *t, | 442 | extern 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; \ | 67 | static 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; \ | 79 | static 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) \ | 267 | extern 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) | 270 | extern void arpt_unregister_table(struct xt_table *table); |
273 | |||
274 | extern struct arpt_table *arpt_register_table(struct net *net, | ||
275 | struct arpt_table *table, | ||
276 | const struct arpt_replace *repl); | ||
277 | extern void arpt_unregister_table(struct arpt_table *table); | ||
278 | extern unsigned int arpt_do_table(struct sk_buff *skb, | 271 | extern 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 | |||
12 | struct 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 */ |
31 | union nf_conntrack_proto { | 32 | union 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)) |
67 | do { \ | ||
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 | ||
143 | static 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 | |||
148 | static 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 | ||
190 | extern void nf_conntrack_flush(void); | 195 | extern void nf_conntrack_flush(void); |
191 | 196 | ||
192 | extern int nf_ct_get_tuplepr(const struct sk_buff *skb, | 197 | extern 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); | 200 | extern bool nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, |
196 | extern 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 | ||
199 | extern void __nf_ct_refresh_acct(struct nf_conn *ct, | 203 | extern 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); | |||
30 | extern int nf_conntrack_proto_init(void); | 30 | extern int nf_conntrack_proto_init(void); |
31 | extern void nf_conntrack_proto_fini(void); | 31 | extern void nf_conntrack_proto_fini(void); |
32 | 32 | ||
33 | extern int | 33 | extern bool |
34 | nf_ct_get_tuple(const struct sk_buff *skb, | 34 | nf_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 | ||
43 | extern int | 43 | extern bool |
44 | nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, | 44 | nf_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 | ||
163 | static inline int __nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1, | 167 | static 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 | ||
171 | static inline int __nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1, | 175 | static 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 | ||
179 | static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1, | 183 | static 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 | ||
186 | static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1, | 190 | static inline bool |
187 | const struct nf_conntrack_tuple_mask *m2) | 191 | nf_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 | ||
193 | static inline int nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1, | 198 | static inline bool |
194 | const struct nf_conntrack_tuple *t2, | 199 | nf_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 | ||
215 | static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t, | 221 | static inline bool |
216 | const struct nf_conntrack_tuple *tuple, | 222 | nf_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, | |||
24 | extern int nf_nat_seq_adjust(struct sk_buff *skb, | 24 | extern 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); |
27 | extern 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 | ||
9 | struct nf_nat_protocol | 9 | struct 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; | |||
62 | extern void cleanup_protocols(void); | 59 | extern void cleanup_protocols(void); |
63 | extern const struct nf_nat_protocol *find_nat_proto(u_int16_t protonum); | 60 | extern const struct nf_nat_protocol *find_nat_proto(u_int16_t protonum); |
64 | 61 | ||
65 | extern int nf_nat_port_range_to_nlattr(struct sk_buff *skb, | 62 | extern 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, |
67 | extern 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 | |||
67 | extern 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 | |||
73 | extern int nf_nat_proto_range_to_nlattr(struct sk_buff *skb, | ||
74 | const struct nf_nat_range *range); | ||
75 | extern 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 | ||
15 | extern unsigned int | 15 | extern unsigned int |
16 | alloc_null_binding(struct nf_conn *ct, unsigned int hooknum); | 16 | alloc_null_binding(struct nf_conn *ct, unsigned int hooknum); |
17 | |||
18 | extern unsigned int | ||
19 | alloc_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 | ||
215 | config 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 | |||
215 | endmenu | 229 | endmenu |
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 |
31 | obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o | 31 | obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o |
32 | obj-$(CONFIG_BRIDGE_EBT_ULOG) += ebt_ulog.o | 32 | obj-$(CONFIG_BRIDGE_EBT_ULOG) += ebt_ulog.o |
33 | obj-$(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 | |||
21 | static 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 | |||
38 | static 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 | |||
53 | static 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 | |||
60 | static int __init ebt_nflog_init(void) | ||
61 | { | ||
62 | return ebt_register_watcher(&nflog); | ||
63 | } | ||
64 | |||
65 | static void __exit ebt_nflog_fini(void) | ||
66 | { | ||
67 | ebt_unregister_watcher(&nflog); | ||
68 | } | ||
69 | |||
70 | module_init(ebt_nflog_init); | ||
71 | module_exit(ebt_nflog_fini); | ||
72 | MODULE_LICENSE("GPL"); | ||
73 | MODULE_AUTHOR("Peter Warasin <peter@endian.com>"); | ||
74 | MODULE_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 | |||
186 | EXPORT_SYMBOL(nf_ip_checksum); | 185 | EXPORT_SYMBOL(nf_ip_checksum); |
187 | 186 | ||
187 | static __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 | |||
188 | static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) | 210 | static 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 | ||
193 | static const struct nf_afinfo nf_ip_afinfo = { | 215 | static 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 | ||
202 | static int ipv4_netfilter_init(void) | 225 | static 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/). |
244 | config NF_NAT_PROTO_DCCP | ||
245 | tristate | ||
246 | depends on NF_NAT && NF_CT_PROTO_DCCP | ||
247 | default NF_NAT && NF_CT_PROTO_DCCP | ||
248 | |||
244 | config NF_NAT_PROTO_GRE | 249 | config 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 | ||
253 | config NF_NAT_PROTO_UDPLITE | ||
254 | tristate | ||
255 | depends on NF_NAT && NF_CT_PROTO_UDPLITE | ||
256 | default NF_NAT && NF_CT_PROTO_UDPLITE | ||
257 | |||
258 | config NF_NAT_PROTO_SCTP | ||
259 | tristate | ||
260 | default NF_NAT && NF_CT_PROTO_SCTP | ||
261 | depends on NF_NAT && NF_CT_PROTO_SCTP | ||
262 | |||
248 | config NF_NAT_FTP | 263 | config 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 | |||
10 | endif | 10 | endif |
11 | endif | 11 | endif |
12 | 12 | ||
13 | nf_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 | 13 | nf_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 |
14 | iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o | 14 | iptable_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 | |||
29 | obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o | 29 | obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o |
30 | 30 | ||
31 | # NAT protocols (nf_nat) | 31 | # NAT protocols (nf_nat) |
32 | obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o | ||
32 | obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o | 33 | obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o |
34 | obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o | ||
35 | obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o | ||
33 | 36 | ||
34 | # generic IP tables | 37 | # generic IP tables |
35 | obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o | 38 | obj-$(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 | ||
61 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, | 61 | static 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 | ||
438 | static inline int check_entry(struct arpt_entry *e, const char *name) | 438 | static 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) | |||
457 | static inline int check_target(struct arpt_entry *e, const char *name) | 457 | static 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 | ||
709 | static inline struct xt_counters *alloc_counters(struct arpt_table *table) | 709 | static 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 | ||
733 | static int copy_entries_to_user(unsigned int total_size, | 733 | static 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, | |||
851 | static int get_info(struct net *net, void __user *user, int *len, int compat) | 851 | static 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 | ||
1556 | static int compat_copy_entries_to_user(unsigned int total_size, | 1557 | static 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 | ||
1725 | struct arpt_table *arpt_register_table(struct net *net, | 1726 | struct 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 | ||
1769 | void arpt_unregister_table(struct arpt_table *table) | 1769 | void 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. */ |
1787 | static struct arpt_target arpt_standard_target __read_mostly = { | 1787 | static 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 | ||
1798 | static struct arpt_target arpt_error_target __read_mostly = { | 1798 | static 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 | ||
76 | static struct arpt_target arpt_mangle_reg __read_mostly = { | 76 | static 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 | ||
84 | static int __init arpt_mangle_init(void) | 85 | static 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 | ||
92 | static void __exit arpt_mangle_fini(void) | 90 | static 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 | ||
97 | module_init(arpt_mangle_init); | 95 | module_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 | ||
48 | static struct arpt_table packet_filter = { | 48 | static 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 | ||
146 | static struct clusterip_config * | 146 | static struct clusterip_config * |
147 | clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip, | 147 | clusterip_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 */ |
419 | static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) | 419 | static 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 | ||
568 | static void *clusterip_seq_start(struct seq_file *s, loff_t *pos) | 568 | static 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 | ||
595 | static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos) | 595 | static 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 | ||
614 | static int clusterip_seq_show(struct seq_file *s, void *v) | 614 | static 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"); | |||
35 | static void send_reset(struct sk_buff *oldskb, int hook) | 35 | static 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) | |||
340 | static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 340 | static 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 | ||
362 | static int recent_seq_show(struct seq_file *seq, void *v) | 362 | static 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) | |||
396 | static ssize_t recent_proc_write(struct file *file, const char __user *input, | 396 | static 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 | |||
56 | static struct xt_table packet_filter = { | 56 | static 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. */ |
65 | static unsigned int | 65 | static unsigned int |
66 | ipt_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 | |||
76 | static unsigned int | ||
66 | ipt_hook(unsigned int hook, | 77 | ipt_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 | ||
75 | static unsigned int | 87 | static 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 | ||
94 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 107 | static 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 | |||
67 | static struct xt_table packet_mangler = { | 67 | static 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. */ |
76 | static unsigned int | 76 | static unsigned int |
77 | ipt_route_hook(unsigned int hook, | 77 | ipt_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 | |||
87 | static unsigned int | ||
88 | ipt_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 | |||
98 | static unsigned int | ||
99 | ipt_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 | |||
109 | static unsigned int | ||
110 | ipt_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 | ||
86 | static unsigned int | 120 | static 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 | ||
131 | static struct nf_hook_ops ipt_ops[] __read_mostly = { | 166 | static 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 | |||
39 | static struct xt_table packet_raw = { | 39 | static 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 | ||
58 | static unsigned int | 59 | static 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 | ||
27 | static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, | 28 | int (*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); | ||
31 | EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook); | ||
32 | |||
33 | static 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 | ||
43 | static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, | 49 | static 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 | ||
52 | static int ipv4_print_tuple(struct seq_file *s, | 58 | static 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 | |||
108 | static 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 | } | ||
142 | out: | ||
143 | /* We've seen it coming out the other side: confirm it */ | ||
144 | return nf_conntrack_confirm(skb); | ||
133 | } | 145 | } |
134 | 146 | ||
135 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | 147 | static 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 | ||
23 | static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; | 23 | static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; |
24 | 24 | ||
25 | static int icmp_pkt_to_tuple(const struct sk_buff *skb, | 25 | static 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 | ||
55 | static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple, | 54 | static 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. */ |
104 | static int icmp_new(struct nf_conn *ct, | 103 | static 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, | |||
349 | EXPORT_SYMBOL(nf_nat_setup_info); | 349 | EXPORT_SYMBOL(nf_nat_setup_info); |
350 | 350 | ||
351 | /* Returns true if succeeded. */ | 351 | /* Returns true if succeeded. */ |
352 | static int | 352 | static bool |
353 | manip_pkt(u_int16_t proto, | 353 | manip_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 | } |
545 | EXPORT_SYMBOL(nf_nat_protocol_unregister); | 545 | EXPORT_SYMBOL(nf_nat_protocol_unregister); |
546 | 546 | ||
547 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
548 | int | ||
549 | nf_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 | |||
557 | nla_put_failure: | ||
558 | return -1; | ||
559 | } | ||
560 | EXPORT_SYMBOL_GPL(nf_nat_port_nlattr_to_range); | ||
561 | |||
562 | int | ||
563 | nf_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 | } | ||
584 | EXPORT_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. */ |
588 | static void nf_nat_cleanup_conntrack(struct nf_conn *ct) | 548 | static 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 | ||
691 | MODULE_LICENSE("GPL"); | 656 | MODULE_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 | } |
419 | EXPORT_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 | |||
20 | bool 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 | } | ||
35 | EXPORT_SYMBOL_GPL(nf_nat_proto_in_range); | ||
36 | |||
37 | bool 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 | } | ||
90 | EXPORT_SYMBOL_GPL(nf_nat_proto_unique_tuple); | ||
91 | |||
92 | #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
93 | int 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 | |||
100 | nla_put_failure: | ||
101 | return -1; | ||
102 | } | ||
103 | EXPORT_SYMBOL_GPL(nf_nat_proto_nlattr_to_range); | ||
104 | |||
105 | int 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 | } | ||
119 | EXPORT_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 | |||
23 | static u_int16_t dccp_port_rover; | ||
24 | |||
25 | static bool | ||
26 | dccp_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 | |||
35 | static bool | ||
36 | dccp_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 | |||
81 | static 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 | |||
93 | static int __init nf_nat_proto_dccp_init(void) | ||
94 | { | ||
95 | return nf_nat_protocol_register(&nf_nat_protocol_dccp); | ||
96 | } | ||
97 | |||
98 | static void __exit nf_nat_proto_dccp_fini(void) | ||
99 | { | ||
100 | nf_nat_protocol_unregister(&nf_nat_protocol_dccp); | ||
101 | } | ||
102 | |||
103 | module_init(nf_nat_proto_dccp_init); | ||
104 | module_exit(nf_nat_proto_dccp_fini); | ||
105 | |||
106 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
107 | MODULE_DESCRIPTION("DCCP NAT protocol helper"); | ||
108 | MODULE_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"); | |||
36 | MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); | 36 | MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); |
37 | MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); | 37 | MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); |
38 | 38 | ||
39 | /* is key in given range between min and max */ | ||
40 | static int | ||
41 | gre_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 ... */ |
58 | static int | 40 | static bool |
59 | gre_unique_tuple(struct nf_conntrack_tuple *tuple, | 41 | gre_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 */ |
100 | static int | 82 | static bool |
101 | gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff, | 83 | gre_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 | ||
138 | static const struct nf_nat_protocol gre = { | 120 | static 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 | ||
20 | static int | 20 | static bool |
21 | icmp_in_range(const struct nf_conntrack_tuple *tuple, | 21 | icmp_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 | ||
30 | static int | 30 | static bool |
31 | icmp_unique_tuple(struct nf_conntrack_tuple *tuple, | 31 | icmp_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 | ||
54 | static int | 54 | static bool |
55 | icmp_manip_pkt(struct sk_buff *skb, | 55 | icmp_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 | ||
74 | const struct nf_nat_protocol nf_nat_protocol_icmp = { | 74 | const 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 | |||
17 | static u_int16_t nf_sctp_port_rover; | ||
18 | |||
19 | static bool | ||
20 | sctp_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 | |||
29 | static bool | ||
30 | sctp_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 | |||
69 | static 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 | |||
81 | static int __init nf_nat_proto_sctp_init(void) | ||
82 | { | ||
83 | return nf_nat_protocol_register(&nf_nat_protocol_sctp); | ||
84 | } | ||
85 | |||
86 | static void __exit nf_nat_proto_sctp_exit(void) | ||
87 | { | ||
88 | nf_nat_protocol_unregister(&nf_nat_protocol_sctp); | ||
89 | } | ||
90 | |||
91 | module_init(nf_nat_proto_sctp_init); | ||
92 | module_exit(nf_nat_proto_sctp_exit); | ||
93 | |||
94 | MODULE_LICENSE("GPL"); | ||
95 | MODULE_DESCRIPTION("SCTP NAT protocol helper"); | ||
96 | MODULE_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 | ||
22 | static int | 21 | static u_int16_t tcp_port_rover; |
23 | tcp_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 | ||
39 | static int | 23 | static bool |
40 | tcp_unique_tuple(struct nf_conntrack_tuple *tuple, | 24 | tcp_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 | ||
90 | static int | 33 | static bool |
91 | tcp_manip_pkt(struct sk_buff *skb, | 34 | tcp_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 | ||
140 | const struct nf_nat_protocol nf_nat_protocol_tcp = { | 83 | const 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 | ||
21 | static int | 20 | static u_int16_t udp_port_rover; |
22 | udp_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 | ||
38 | static int | 22 | static bool |
39 | udp_unique_tuple(struct nf_conntrack_tuple *tuple, | 23 | udp_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 | ||
88 | static int | 32 | static bool |
89 | udp_manip_pkt(struct sk_buff *skb, | 33 | udp_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 | ||
130 | const struct nf_nat_protocol nf_nat_protocol_udp = { | 74 | const 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 | |||
19 | static u_int16_t udplite_port_rover; | ||
20 | |||
21 | static bool | ||
22 | udplite_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 | |||
31 | static bool | ||
32 | udplite_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 | |||
72 | static 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 | |||
84 | static int __init nf_nat_proto_udplite_init(void) | ||
85 | { | ||
86 | return nf_nat_protocol_register(&nf_nat_protocol_udplite); | ||
87 | } | ||
88 | |||
89 | static void __exit nf_nat_proto_udplite_fini(void) | ||
90 | { | ||
91 | nf_nat_protocol_unregister(&nf_nat_protocol_udplite); | ||
92 | } | ||
93 | |||
94 | module_init(nf_nat_proto_udplite_init); | ||
95 | module_exit(nf_nat_proto_udplite_fini); | ||
96 | |||
97 | MODULE_LICENSE("GPL"); | ||
98 | MODULE_DESCRIPTION("UDP-Lite NAT protocol helper"); | ||
99 | MODULE_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 | ||
21 | static int unknown_in_range(const struct nf_conntrack_tuple *tuple, | 21 | static 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 | ||
29 | static int unknown_unique_tuple(struct nf_conntrack_tuple *tuple, | 29 | static 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 | ||
39 | static int | 39 | static bool |
40 | unknown_manip_pkt(struct sk_buff *skb, | 40 | unknown_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 | ||
48 | const struct nf_nat_protocol nf_nat_unknown_protocol = { | 48 | const 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 | |||
61 | static struct xt_table __nat_table = { | 61 | static 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 | ||
191 | unsigned int | ||
192 | alloc_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 | |||
210 | int nf_nat_rule_find(struct sk_buff *skb, | 191 | int 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 | ||
621 | static struct snmp_cnv snmp_conv [] = | 621 | static 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 | ||
1002 | static void hex_dump(unsigned char *buf, size_t len) | 1001 | static 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 |
31 | static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) | 31 | static 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 | ||
255 | static unsigned int | ||
256 | nf_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 | ||
276 | static struct nf_hook_ops nf_nat_ops[] __read_mostly = { | 250 | static 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 | ||
327 | static int __init nf_nat_standalone_init(void) | 285 | static 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 | |||
125 | EXPORT_SYMBOL(nf_ip6_checksum); | 124 | EXPORT_SYMBOL(nf_ip6_checksum); |
126 | 125 | ||
126 | static __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 | |||
127 | static const struct nf_afinfo nf_ip6_afinfo = { | 154 | static 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 | ||
136 | int __init ipv6_netfilter_init(void) | 164 | int __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 | ||
373 | static struct nf_loginfo default_loginfo = { | 377 | static 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 | |||
54 | static struct xt_table packet_filter = { | 54 | static 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 | |||
60 | static struct xt_table packet_mangler = { | 60 | static 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 | |||
38 | static struct xt_table packet_raw = { | 38 | static 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 | ||
30 | static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, | 30 | static 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 | ||
47 | static int ipv6_invert_tuple(struct nf_conntrack_tuple *tuple, | 47 | static 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 | ||
56 | static int ipv6_print_tuple(struct seq_file *s, | 56 | static 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 | ||
29 | static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ; | 29 | static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ; |
30 | 30 | ||
31 | static int icmpv6_pkt_to_tuple(const struct sk_buff *skb, | 31 | static 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 | ||
56 | static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, | 56 | static 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. */ |
105 | static int icmpv6_new(struct nf_conn *ct, | 105 | static 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 | ||
126 | static int | 125 | static 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 | ||
106 | static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, | 106 | static 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 | ||
133 | static unsigned int nf_hashfn(struct inet_frag_queue *q) | 133 | static 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 | ||
224 | static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, | 224 | static 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 | ||
89 | config 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 | |||
89 | config NF_CT_PROTO_GRE | 99 | config 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 | |||
13 | obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o | 13 | obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o |
14 | 14 | ||
15 | # SCTP protocol connection tracking | 15 | # SCTP protocol connection tracking |
16 | obj-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o | ||
16 | obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o | 17 | obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o |
17 | obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o | 18 | obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o |
18 | obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o | 19 | obj-$(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 | ||
55 | static struct { | 55 | static 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 | ||
97 | int | 97 | bool |
98 | nf_ct_get_tuple(const struct sk_buff *skb, | 98 | nf_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 | } |
118 | EXPORT_SYMBOL_GPL(nf_ct_get_tuple); | 118 | EXPORT_SYMBOL_GPL(nf_ct_get_tuple); |
119 | 119 | ||
120 | int nf_ct_get_tuplepr(const struct sk_buff *skb, | 120 | bool 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 | } |
148 | EXPORT_SYMBOL_GPL(nf_ct_get_tuplepr); | 146 | EXPORT_SYMBOL_GPL(nf_ct_get_tuplepr); |
149 | 147 | ||
150 | int | 148 | bool |
151 | nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, | 149 | nf_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 | } |
740 | EXPORT_SYMBOL_GPL(nf_conntrack_in); | 737 | EXPORT_SYMBOL_GPL(nf_conntrack_in); |
741 | 738 | ||
742 | int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, | 739 | bool 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 " | |||
50 | module_param(dcc_timeout, uint, 0400); | 50 | module_param(dcc_timeout, uint, 0400); |
51 | MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); | 51 | MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); |
52 | 52 | ||
53 | static const char *dccprotos[] = { | 53 | static 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 | */ |
68 | static int parse_dcc(char *data, char *data_end, u_int32_t *ip, | 68 | static 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 | ||
34 | static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, | 34 | static 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 | ||
43 | static int generic_invert_tuple(struct nf_conntrack_tuple *tuple, | 43 | static 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 | ||
52 | static int generic_print_tuple(struct seq_file *s, | 52 | static 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: | |||
145 | static inline int | 145 | static inline int |
146 | ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) | 146 | ctnetlink_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 | |||
540 | static int | 538 | static int |
541 | ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) | 539 | ctnetlink_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 | ||
723 | static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = { | 712 | static 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 | ||
147 | static int kill_l3proto(struct nf_conn *i, void *data) | 147 | static 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 | ||
153 | static int kill_l4proto(struct nf_conn *i, void *data) | 152 | static 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 | ||
163 | static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto) | 160 | static 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 | |||
24 | static DEFINE_RWLOCK(dccp_lock); | ||
25 | |||
26 | static 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 | |||
75 | static 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 | |||
85 | static 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 | */ | ||
141 | static const u_int8_t | ||
142 | dccp_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 | |||
396 | static 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 | |||
410 | static 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 | |||
418 | static 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 | |||
447 | out_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 | |||
453 | static 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 | |||
462 | static 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 | |||
549 | static 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 | |||
593 | out_invalid: | ||
594 | if (LOG_INVALID(IPPROTO_DCCP)) | ||
595 | nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg); | ||
596 | return -NF_ACCEPT; | ||
597 | } | ||
598 | |||
599 | static 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 | |||
607 | static 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) | ||
613 | static 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 | |||
627 | nla_put_failure: | ||
628 | read_unlock_bh(&dccp_lock); | ||
629 | return -1; | ||
630 | } | ||
631 | |||
632 | static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = { | ||
633 | [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 }, | ||
634 | }; | ||
635 | |||
636 | static 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 | ||
662 | static unsigned int dccp_sysctl_table_users; | ||
663 | static struct ctl_table_header *dccp_sysctl_header; | ||
664 | static 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 | |||
735 | static 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 | |||
760 | static 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 | |||
785 | static 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 | |||
798 | err2: | ||
799 | nf_conntrack_l4proto_unregister(&dccp_proto4); | ||
800 | err1: | ||
801 | return err; | ||
802 | } | ||
803 | |||
804 | static 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 | |||
810 | module_init(nf_conntrack_proto_dccp_init); | ||
811 | module_exit(nf_conntrack_proto_dccp_fini); | ||
812 | |||
813 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
814 | MODULE_DESCRIPTION("DCCP connection tracking protocol helper"); | ||
815 | MODULE_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 | ||
15 | static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; | 15 | static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; |
16 | 16 | ||
17 | static int generic_pkt_to_tuple(const struct sk_buff *skb, | 17 | static 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 | ||
27 | static int generic_invert_tuple(struct nf_conntrack_tuple *tuple, | 27 | static 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. */ |
56 | static int new(struct nf_conn *ct, const struct sk_buff *skb, | 56 | static 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 */ |
151 | static int gre_invert_tuple(struct nf_conntrack_tuple *tuple, | 151 | static 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 */ |
160 | static int gre_pkt_to_tuple(const struct sk_buff *skb, | 160 | static 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. */ |
238 | static int gre_new(struct nf_conn *ct, const struct sk_buff *skb, | 237 | static 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 | ||
36 | static const char *sctp_conntrack_names[] = { | 36 | static 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 | ||
133 | static int sctp_pkt_to_tuple(const struct sk_buff *skb, | 133 | static 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 | ||
149 | static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple, | 149 | static 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. */ |
393 | static int sctp_new(struct nf_conn *ct, const struct sk_buff *skb, | 395 | static 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 | ||
260 | static int tcp_pkt_to_tuple(const struct sk_buff *skb, | 260 | static 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 | ||
278 | static int tcp_invert_tuple(struct nf_conntrack_tuple *tuple, | 277 | static 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 | ||
481 | static int tcp_in_window(const struct nf_conn *ct, | 480 | static 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. */ |
985 | static int tcp_new(struct nf_conn *ct, | 984 | static 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 @@ | |||
26 | static unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ; | 26 | static unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ; |
27 | static unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ; | 27 | static unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ; |
28 | 28 | ||
29 | static int udp_pkt_to_tuple(const struct sk_buff *skb, | 29 | static 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 | ||
47 | static int udp_invert_tuple(struct nf_conntrack_tuple *tuple, | 47 | static 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. */ |
86 | static int udp_new(struct nf_conn *ct, const struct sk_buff *skb, | 86 | static 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 | ||
92 | static int udp_error(struct sk_buff *skb, unsigned int dataoff, | 92 | static 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 @@ | |||
27 | static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ; | 27 | static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ; |
28 | static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ; | 28 | static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ; |
29 | 29 | ||
30 | static int udplite_pkt_to_tuple(const struct sk_buff *skb, | 30 | static 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 | ||
46 | static int udplite_invert_tuple(struct nf_conntrack_tuple *tuple, | 46 | static 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. */ |
86 | static int udplite_new(struct nf_conn *ct, const struct sk_buff *skb, | 86 | static 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 | ||
92 | static int udplite_error(struct sk_buff *skb, unsigned int dataoff, | 92 | static 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 | |||
292 | static 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 | |||
306 | out_stat_nf_conntrack: | ||
307 | proc_net_remove(&init_net, "nf_conntrack"); | ||
308 | out_nf_conntrack: | ||
309 | return -ENOMEM; | ||
310 | } | ||
311 | |||
312 | static 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 | ||
318 | static int nf_conntrack_standalone_init_proc(void) | ||
319 | { | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static 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 | ||
392 | EXPORT_SYMBOL_GPL(nf_ct_log_invalid); | 420 | EXPORT_SYMBOL_GPL(nf_ct_log_invalid); |
421 | |||
422 | static 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 | |||
434 | static void nf_conntrack_standalone_fini_sysctl(void) | ||
435 | { | ||
436 | unregister_sysctl_table(nf_ct_sysctl_header); | ||
437 | } | ||
438 | #else | ||
439 | static int nf_conntrack_standalone_init_sysctl(void) | ||
440 | { | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static void nf_conntrack_standalone_fini_sysctl(void) | ||
445 | { | ||
446 | } | ||
393 | #endif /* CONFIG_SYSCTL */ | 447 | #endif /* CONFIG_SYSCTL */ |
394 | 448 | ||
395 | static int __init nf_conntrack_standalone_init(void) | 449 | static 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 | 464 | out_sysctl: |
426 | cleanup_proc_stat: | 465 | nf_conntrack_standalone_fini_proc(); |
427 | #endif | 466 | out_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(); |
468 | out: | ||
435 | return ret; | 469 | return ret; |
436 | } | 470 | } |
437 | 471 | ||
438 | static void __exit nf_conntrack_standalone_fini(void) | 472 | static 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 | ||
61 | static const char *xt_prefix[NPROTO] = { | 61 | static 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 | ||
249 | static int match_revfn(int af, const char *name, u8 revision, int *bestp) | 249 | static 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 | ||
265 | static int target_revfn(int af, const char *name, u8 revision, int *bestp) | 265 | static 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 | } |
386 | EXPORT_SYMBOL_GPL(xt_compat_calc_jump); | 386 | EXPORT_SYMBOL_GPL(xt_compat_calc_jump); |
387 | 387 | ||
388 | int xt_compat_match_offset(struct xt_match *match) | 388 | int 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); | |||
395 | int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr, | 395 | int 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); | |||
422 | int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr, | 422 | int 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, | |||
479 | EXPORT_SYMBOL_GPL(xt_check_target); | 479 | EXPORT_SYMBOL_GPL(xt_check_target); |
480 | 480 | ||
481 | #ifdef CONFIG_COMPAT | 481 | #ifdef CONFIG_COMPAT |
482 | int xt_compat_target_offset(struct xt_target *target) | 482 | int 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); | |||
489 | void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr, | 489 | void 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); | |||
515 | int xt_compat_target_to_user(struct xt_entry_target *t, void __user **dstptr, | 515 | int 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) | |||
55 | static void secmark_restore(struct sk_buff *skb) | 55 | static 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 | ||
73 | static inline bool already_closed(const struct nf_conn *conn) | 73 | static 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, | |||
256 | static void | 254 | static void |
257 | connlimit_mt_destroy(const struct xt_match *match, void *matchinfo) | 255 | connlimit_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: | |||
130 | static void xt_rateest_mt_destroy(const struct xt_match *match, | 130 | static 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) { |