diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ip_output.c | 30 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_core.c | 5 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_est.c | 1 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_sched.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_amanda.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_ftp.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_irc.c | 10 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_netbios_ns.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_netlink.c | 36 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_icmp.c | 47 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_standalone.c | 26 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 17 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_REJECT.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 10 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_recent.c | 20 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 74 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 97 |
17 files changed, 206 insertions, 176 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 2a830de3a699..71da31818cfc 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -202,13 +202,11 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
202 | 202 | ||
203 | static inline int ip_finish_output(struct sk_buff *skb) | 203 | static inline int ip_finish_output(struct sk_buff *skb) |
204 | { | 204 | { |
205 | struct net_device *dev = skb->dst->dev; | 205 | if (skb->len > dst_mtu(skb->dst) && |
206 | 206 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) | |
207 | skb->dev = dev; | 207 | return ip_fragment(skb, ip_finish_output2); |
208 | skb->protocol = htons(ETH_P_IP); | 208 | else |
209 | 209 | return ip_finish_output2(skb); | |
210 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, | ||
211 | ip_finish_output2); | ||
212 | } | 210 | } |
213 | 211 | ||
214 | int ip_mc_output(struct sk_buff *skb) | 212 | int ip_mc_output(struct sk_buff *skb) |
@@ -265,21 +263,21 @@ int ip_mc_output(struct sk_buff *skb) | |||
265 | newskb->dev, ip_dev_loopback_xmit); | 263 | newskb->dev, ip_dev_loopback_xmit); |
266 | } | 264 | } |
267 | 265 | ||
268 | if (skb->len > dst_mtu(&rt->u.dst)) | 266 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, |
269 | return ip_fragment(skb, ip_finish_output); | 267 | ip_finish_output); |
270 | else | ||
271 | return ip_finish_output(skb); | ||
272 | } | 268 | } |
273 | 269 | ||
274 | int ip_output(struct sk_buff *skb) | 270 | int ip_output(struct sk_buff *skb) |
275 | { | 271 | { |
272 | struct net_device *dev = skb->dst->dev; | ||
273 | |||
276 | IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); | 274 | IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); |
277 | 275 | ||
278 | if (skb->len > dst_mtu(skb->dst) && | 276 | skb->dev = dev; |
279 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) | 277 | skb->protocol = htons(ETH_P_IP); |
280 | return ip_fragment(skb, ip_finish_output); | 278 | |
281 | else | 279 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, |
282 | return ip_finish_output(skb); | 280 | ip_finish_output); |
283 | } | 281 | } |
284 | 282 | ||
285 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | 283 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) |
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index 1aca94a9fd8b..3f47ad8e1cad 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c | |||
@@ -532,11 +532,8 @@ static unsigned int ip_vs_post_routing(unsigned int hooknum, | |||
532 | { | 532 | { |
533 | if (!((*pskb)->ipvs_property)) | 533 | if (!((*pskb)->ipvs_property)) |
534 | return NF_ACCEPT; | 534 | return NF_ACCEPT; |
535 | |||
536 | /* The packet was sent from IPVS, exit this chain */ | 535 | /* The packet was sent from IPVS, exit this chain */ |
537 | (*okfn)(*pskb); | 536 | return NF_STOP; |
538 | |||
539 | return NF_STOLEN; | ||
540 | } | 537 | } |
541 | 538 | ||
542 | u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) | 539 | u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) |
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c index e7004741ac73..c453e1e57f4b 100644 --- a/net/ipv4/ipvs/ip_vs_est.c +++ b/net/ipv4/ipvs/ip_vs_est.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/interrupt.h> | ||
21 | 22 | ||
22 | #include <net/ip_vs.h> | 23 | #include <net/ip_vs.h> |
23 | 24 | ||
diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c index 0f7c56a225bd..8bc42b76223d 100644 --- a/net/ipv4/ipvs/ip_vs_sched.c +++ b/net/ipv4/ipvs/ip_vs_sched.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/interrupt.h> | ||
25 | #include <asm/string.h> | 26 | #include <asm/string.h> |
26 | #include <linux/kmod.h> | 27 | #include <linux/kmod.h> |
27 | 28 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index 0366eedb4d70..84e4f79b7ffa 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c | |||
@@ -36,7 +36,7 @@ static unsigned int master_timeout = 300; | |||
36 | MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>"); | 36 | MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>"); |
37 | MODULE_DESCRIPTION("Amanda connection tracking module"); | 37 | MODULE_DESCRIPTION("Amanda connection tracking module"); |
38 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
39 | module_param(master_timeout, int, 0600); | 39 | module_param(master_timeout, uint, 0600); |
40 | MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); | 40 | MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); |
41 | 41 | ||
42 | static const char *conns[] = { "DATA ", "MESG ", "INDEX " }; | 42 | static const char *conns[] = { "DATA ", "MESG ", "INDEX " }; |
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index 68b173bcda60..e627e5856172 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c | |||
@@ -34,7 +34,7 @@ static int ports_c; | |||
34 | module_param_array(ports, ushort, &ports_c, 0400); | 34 | module_param_array(ports, ushort, &ports_c, 0400); |
35 | 35 | ||
36 | static int loose; | 36 | static int loose; |
37 | module_param(loose, int, 0600); | 37 | module_param(loose, bool, 0600); |
38 | 38 | ||
39 | unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb, | 39 | unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb, |
40 | enum ip_conntrack_info ctinfo, | 40 | enum ip_conntrack_info ctinfo, |
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index d7c40421d0d1..c51a2cf71b4b 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #define MAX_PORTS 8 | 36 | #define MAX_PORTS 8 |
37 | static unsigned short ports[MAX_PORTS]; | 37 | static unsigned short ports[MAX_PORTS]; |
38 | static int ports_c; | 38 | static int ports_c; |
39 | static int max_dcc_channels = 8; | 39 | static unsigned int max_dcc_channels = 8; |
40 | static unsigned int dcc_timeout = 300; | 40 | static unsigned int dcc_timeout = 300; |
41 | /* This is slow, but it's simple. --RR */ | 41 | /* This is slow, but it's simple. --RR */ |
42 | static char *irc_buffer; | 42 | static char *irc_buffer; |
@@ -54,9 +54,9 @@ MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); | |||
54 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
55 | module_param_array(ports, ushort, &ports_c, 0400); | 55 | module_param_array(ports, ushort, &ports_c, 0400); |
56 | MODULE_PARM_DESC(ports, "port numbers of IRC servers"); | 56 | MODULE_PARM_DESC(ports, "port numbers of IRC servers"); |
57 | module_param(max_dcc_channels, int, 0400); | 57 | module_param(max_dcc_channels, uint, 0400); |
58 | MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session"); | 58 | MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session"); |
59 | module_param(dcc_timeout, int, 0400); | 59 | module_param(dcc_timeout, uint, 0400); |
60 | MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); | 60 | MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); |
61 | 61 | ||
62 | static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; | 62 | static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; |
@@ -254,10 +254,6 @@ static int __init init(void) | |||
254 | printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n"); | 254 | printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n"); |
255 | return -EBUSY; | 255 | return -EBUSY; |
256 | } | 256 | } |
257 | if (dcc_timeout < 0) { | ||
258 | printk("ip_conntrack_irc: dcc_timeout must be a positive integer\n"); | ||
259 | return -EBUSY; | ||
260 | } | ||
261 | 257 | ||
262 | irc_buffer = kmalloc(65536, GFP_KERNEL); | 258 | irc_buffer = kmalloc(65536, GFP_KERNEL); |
263 | if (!irc_buffer) | 259 | if (!irc_buffer) |
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c index 186646eb249f..4e68e16a2612 100644 --- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c +++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c | |||
@@ -37,7 +37,7 @@ MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper"); | |||
37 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
38 | 38 | ||
39 | static unsigned int timeout = 3; | 39 | static unsigned int timeout = 3; |
40 | module_param(timeout, int, 0600); | 40 | module_param(timeout, uint, 0400); |
41 | MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds"); | 41 | MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds"); |
42 | 42 | ||
43 | static int help(struct sk_buff **pskb, | 43 | static int help(struct sk_buff **pskb, |
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 91fe8f2e38ff..c9ebbe0d2d9c 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
@@ -79,6 +79,7 @@ ctnetlink_dump_tuples(struct sk_buff *skb, | |||
79 | const struct ip_conntrack_tuple *tuple) | 79 | const struct ip_conntrack_tuple *tuple) |
80 | { | 80 | { |
81 | struct nfattr *nest_parms; | 81 | struct nfattr *nest_parms; |
82 | int ret; | ||
82 | 83 | ||
83 | nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); | 84 | nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); |
84 | NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip); | 85 | NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip); |
@@ -86,10 +87,10 @@ ctnetlink_dump_tuples(struct sk_buff *skb, | |||
86 | NFA_NEST_END(skb, nest_parms); | 87 | NFA_NEST_END(skb, nest_parms); |
87 | 88 | ||
88 | nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); | 89 | nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); |
89 | ctnetlink_dump_tuples_proto(skb, tuple); | 90 | ret = ctnetlink_dump_tuples_proto(skb, tuple); |
90 | NFA_NEST_END(skb, nest_parms); | 91 | NFA_NEST_END(skb, nest_parms); |
91 | 92 | ||
92 | return 0; | 93 | return ret; |
93 | 94 | ||
94 | nfattr_failure: | 95 | nfattr_failure: |
95 | return -1; | 96 | return -1; |
@@ -160,7 +161,7 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct ip_conntrack *ct) | |||
160 | return 0; | 161 | return 0; |
161 | 162 | ||
162 | nest_helper = NFA_NEST(skb, CTA_HELP); | 163 | nest_helper = NFA_NEST(skb, CTA_HELP); |
163 | NFA_PUT(skb, CTA_HELP_NAME, CTA_HELP_MAXNAMESIZE, &ct->helper->name); | 164 | NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name); |
164 | 165 | ||
165 | if (ct->helper->to_nfattr) | 166 | if (ct->helper->to_nfattr) |
166 | ct->helper->to_nfattr(skb, ct); | 167 | ct->helper->to_nfattr(skb, ct); |
@@ -229,7 +230,7 @@ nfattr_failure: | |||
229 | static inline int | 230 | static inline int |
230 | ctnetlink_dump_use(struct sk_buff *skb, const struct ip_conntrack *ct) | 231 | ctnetlink_dump_use(struct sk_buff *skb, const struct ip_conntrack *ct) |
231 | { | 232 | { |
232 | unsigned int use = htonl(atomic_read(&ct->ct_general.use)); | 233 | u_int32_t use = htonl(atomic_read(&ct->ct_general.use)); |
233 | 234 | ||
234 | NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); | 235 | NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); |
235 | return 0; | 236 | return 0; |
@@ -311,29 +312,22 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, | |||
311 | if (events & IPCT_DESTROY) { | 312 | if (events & IPCT_DESTROY) { |
312 | type = IPCTNL_MSG_CT_DELETE; | 313 | type = IPCTNL_MSG_CT_DELETE; |
313 | group = NFNLGRP_CONNTRACK_DESTROY; | 314 | group = NFNLGRP_CONNTRACK_DESTROY; |
314 | goto alloc_skb; | 315 | } else if (events & (IPCT_NEW | IPCT_RELATED)) { |
315 | } | ||
316 | if (events & (IPCT_NEW | IPCT_RELATED)) { | ||
317 | type = IPCTNL_MSG_CT_NEW; | 316 | type = IPCTNL_MSG_CT_NEW; |
318 | flags = NLM_F_CREATE|NLM_F_EXCL; | 317 | flags = NLM_F_CREATE|NLM_F_EXCL; |
319 | /* dump everything */ | 318 | /* dump everything */ |
320 | events = ~0UL; | 319 | events = ~0UL; |
321 | group = NFNLGRP_CONNTRACK_NEW; | 320 | group = NFNLGRP_CONNTRACK_NEW; |
322 | goto alloc_skb; | 321 | } else if (events & (IPCT_STATUS | |
323 | } | ||
324 | if (events & (IPCT_STATUS | | ||
325 | IPCT_PROTOINFO | | 322 | IPCT_PROTOINFO | |
326 | IPCT_HELPER | | 323 | IPCT_HELPER | |
327 | IPCT_HELPINFO | | 324 | IPCT_HELPINFO | |
328 | IPCT_NATINFO)) { | 325 | IPCT_NATINFO)) { |
329 | type = IPCTNL_MSG_CT_NEW; | 326 | type = IPCTNL_MSG_CT_NEW; |
330 | group = NFNLGRP_CONNTRACK_UPDATE; | 327 | group = NFNLGRP_CONNTRACK_UPDATE; |
331 | goto alloc_skb; | 328 | } else |
332 | } | 329 | return NOTIFY_DONE; |
333 | 330 | ||
334 | return NOTIFY_DONE; | ||
335 | |||
336 | alloc_skb: | ||
337 | /* FIXME: Check if there are any listeners before, don't hurt performance */ | 331 | /* FIXME: Check if there are any listeners before, don't hurt performance */ |
338 | 332 | ||
339 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); | 333 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); |
@@ -1037,6 +1031,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
1037 | return err; | 1031 | return err; |
1038 | } | 1032 | } |
1039 | 1033 | ||
1034 | #if defined(CONFIG_IP_NF_CONNTRACK_MARK) | ||
1035 | if (cda[CTA_MARK-1]) | ||
1036 | ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); | ||
1037 | #endif | ||
1038 | |||
1040 | ct->helper = ip_conntrack_helper_find_get(rtuple); | 1039 | ct->helper = ip_conntrack_helper_find_get(rtuple); |
1041 | 1040 | ||
1042 | add_timer(&ct->timeout); | 1041 | add_timer(&ct->timeout); |
@@ -1045,11 +1044,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
1045 | if (ct->helper) | 1044 | if (ct->helper) |
1046 | ip_conntrack_helper_put(ct->helper); | 1045 | ip_conntrack_helper_put(ct->helper); |
1047 | 1046 | ||
1048 | #if defined(CONFIG_IP_NF_CONNTRACK_MARK) | ||
1049 | if (cda[CTA_MARK-1]) | ||
1050 | ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); | ||
1051 | #endif | ||
1052 | |||
1053 | DEBUGP("conntrack with id %u inserted\n", ct->id); | 1047 | DEBUGP("conntrack with id %u inserted\n", ct->id); |
1054 | return 0; | 1048 | return 0; |
1055 | 1049 | ||
@@ -1209,7 +1203,6 @@ static int ctnetlink_expect_event(struct notifier_block *this, | |||
1209 | unsigned int type; | 1203 | unsigned int type; |
1210 | unsigned char *b; | 1204 | unsigned char *b; |
1211 | int flags = 0; | 1205 | int flags = 0; |
1212 | u16 proto; | ||
1213 | 1206 | ||
1214 | if (events & IPEXP_NEW) { | 1207 | if (events & IPEXP_NEW) { |
1215 | type = IPCTNL_MSG_EXP_NEW; | 1208 | type = IPCTNL_MSG_EXP_NEW; |
@@ -1236,7 +1229,6 @@ static int ctnetlink_expect_event(struct notifier_block *this, | |||
1236 | goto nfattr_failure; | 1229 | goto nfattr_failure; |
1237 | 1230 | ||
1238 | nlh->nlmsg_len = skb->tail - b; | 1231 | nlh->nlmsg_len = skb->tail - b; |
1239 | proto = exp->tuple.dst.protonum; | ||
1240 | nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); | 1232 | nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); |
1241 | return NOTIFY_DONE; | 1233 | return NOTIFY_DONE; |
1242 | 1234 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index 5f9925db608e..30fc21d6165a 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c | |||
@@ -47,20 +47,21 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb, | |||
47 | return 1; | 47 | return 1; |
48 | } | 48 | } |
49 | 49 | ||
50 | /* Add 1; spaces filled with 0. */ | ||
51 | static const u_int8_t invmap[] = { | ||
52 | [ICMP_ECHO] = ICMP_ECHOREPLY + 1, | ||
53 | [ICMP_ECHOREPLY] = ICMP_ECHO + 1, | ||
54 | [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, | ||
55 | [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, | ||
56 | [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, | ||
57 | [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, | ||
58 | [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, | ||
59 | [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 | ||
60 | }; | ||
61 | |||
50 | static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple, | 62 | static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple, |
51 | const struct ip_conntrack_tuple *orig) | 63 | const struct ip_conntrack_tuple *orig) |
52 | { | 64 | { |
53 | /* Add 1; spaces filled with 0. */ | ||
54 | static const u_int8_t invmap[] | ||
55 | = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, | ||
56 | [ICMP_ECHOREPLY] = ICMP_ECHO + 1, | ||
57 | [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, | ||
58 | [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, | ||
59 | [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, | ||
60 | [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, | ||
61 | [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, | ||
62 | [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1}; | ||
63 | |||
64 | if (orig->dst.u.icmp.type >= sizeof(invmap) | 65 | if (orig->dst.u.icmp.type >= sizeof(invmap) |
65 | || !invmap[orig->dst.u.icmp.type]) | 66 | || !invmap[orig->dst.u.icmp.type]) |
66 | return 0; | 67 | return 0; |
@@ -110,17 +111,17 @@ static int icmp_packet(struct ip_conntrack *ct, | |||
110 | return NF_ACCEPT; | 111 | return NF_ACCEPT; |
111 | } | 112 | } |
112 | 113 | ||
113 | static const u_int8_t valid_new[] = { | ||
114 | [ICMP_ECHO] = 1, | ||
115 | [ICMP_TIMESTAMP] = 1, | ||
116 | [ICMP_INFO_REQUEST] = 1, | ||
117 | [ICMP_ADDRESS] = 1 | ||
118 | }; | ||
119 | |||
120 | /* Called when a new connection for this protocol found. */ | 114 | /* Called when a new connection for this protocol found. */ |
121 | static int icmp_new(struct ip_conntrack *conntrack, | 115 | static int icmp_new(struct ip_conntrack *conntrack, |
122 | const struct sk_buff *skb) | 116 | const struct sk_buff *skb) |
123 | { | 117 | { |
118 | static const u_int8_t valid_new[] = { | ||
119 | [ICMP_ECHO] = 1, | ||
120 | [ICMP_TIMESTAMP] = 1, | ||
121 | [ICMP_INFO_REQUEST] = 1, | ||
122 | [ICMP_ADDRESS] = 1 | ||
123 | }; | ||
124 | |||
124 | if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) | 125 | if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) |
125 | || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { | 126 | || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { |
126 | /* Can't create a new ICMP `conn' with this. */ | 127 | /* Can't create a new ICMP `conn' with this. */ |
@@ -279,10 +280,6 @@ static int icmp_tuple_to_nfattr(struct sk_buff *skb, | |||
279 | NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t), | 280 | NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t), |
280 | &t->dst.u.icmp.code); | 281 | &t->dst.u.icmp.code); |
281 | 282 | ||
282 | if (t->dst.u.icmp.type >= sizeof(valid_new) | ||
283 | || !valid_new[t->dst.u.icmp.type]) | ||
284 | return -EINVAL; | ||
285 | |||
286 | return 0; | 283 | return 0; |
287 | 284 | ||
288 | nfattr_failure: | 285 | nfattr_failure: |
@@ -295,7 +292,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[], | |||
295 | if (!tb[CTA_PROTO_ICMP_TYPE-1] | 292 | if (!tb[CTA_PROTO_ICMP_TYPE-1] |
296 | || !tb[CTA_PROTO_ICMP_CODE-1] | 293 | || !tb[CTA_PROTO_ICMP_CODE-1] |
297 | || !tb[CTA_PROTO_ICMP_ID-1]) | 294 | || !tb[CTA_PROTO_ICMP_ID-1]) |
298 | return -1; | 295 | return -EINVAL; |
299 | 296 | ||
300 | tuple->dst.u.icmp.type = | 297 | tuple->dst.u.icmp.type = |
301 | *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]); | 298 | *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]); |
@@ -304,6 +301,10 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[], | |||
304 | tuple->src.u.icmp.id = | 301 | tuple->src.u.icmp.id = |
305 | *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); | 302 | *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); |
306 | 303 | ||
304 | if (tuple->dst.u.icmp.type >= sizeof(invmap) | ||
305 | || !invmap[tuple->dst.u.icmp.type]) | ||
306 | return -EINVAL; | ||
307 | |||
307 | return 0; | 308 | return 0; |
308 | } | 309 | } |
309 | #endif | 310 | #endif |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index a88bcc551244..7ba97783e741 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -451,30 +451,6 @@ static unsigned int ip_conntrack_defrag(unsigned int hooknum, | |||
451 | return NF_ACCEPT; | 451 | return NF_ACCEPT; |
452 | } | 452 | } |
453 | 453 | ||
454 | static unsigned int ip_refrag(unsigned int hooknum, | ||
455 | struct sk_buff **pskb, | ||
456 | const struct net_device *in, | ||
457 | const struct net_device *out, | ||
458 | int (*okfn)(struct sk_buff *)) | ||
459 | { | ||
460 | struct rtable *rt = (struct rtable *)(*pskb)->dst; | ||
461 | |||
462 | /* We've seen it coming out the other side: confirm */ | ||
463 | if (ip_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT) | ||
464 | return NF_DROP; | ||
465 | |||
466 | /* Local packets are never produced too large for their | ||
467 | interface. We degfragment them at LOCAL_OUT, however, | ||
468 | so we have to refragment them here. */ | ||
469 | if ((*pskb)->len > dst_mtu(&rt->u.dst) && | ||
470 | !skb_shinfo(*pskb)->tso_size) { | ||
471 | /* No hook can be after us, so this should be OK. */ | ||
472 | ip_fragment(*pskb, okfn); | ||
473 | return NF_STOLEN; | ||
474 | } | ||
475 | return NF_ACCEPT; | ||
476 | } | ||
477 | |||
478 | static unsigned int ip_conntrack_local(unsigned int hooknum, | 454 | static unsigned int ip_conntrack_local(unsigned int hooknum, |
479 | struct sk_buff **pskb, | 455 | struct sk_buff **pskb, |
480 | const struct net_device *in, | 456 | const struct net_device *in, |
@@ -544,7 +520,7 @@ static struct nf_hook_ops ip_conntrack_helper_in_ops = { | |||
544 | 520 | ||
545 | /* Refragmenter; last chance. */ | 521 | /* Refragmenter; last chance. */ |
546 | static struct nf_hook_ops ip_conntrack_out_ops = { | 522 | static struct nf_hook_ops ip_conntrack_out_ops = { |
547 | .hook = ip_refrag, | 523 | .hook = ip_confirm, |
548 | .owner = THIS_MODULE, | 524 | .owner = THIS_MODULE, |
549 | .pf = PF_INET, | 525 | .pf = PF_INET, |
550 | .hooknum = NF_IP_POST_ROUTING, | 526 | .hooknum = NF_IP_POST_ROUTING, |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 30cd4e18c129..f04111f74e09 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -190,23 +190,6 @@ ip_nat_out(unsigned int hooknum, | |||
190 | || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) | 190 | || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) |
191 | return NF_ACCEPT; | 191 | return NF_ACCEPT; |
192 | 192 | ||
193 | /* We can hit fragment here; forwarded packets get | ||
194 | defragmented by connection tracking coming in, then | ||
195 | fragmented (grr) by the forward code. | ||
196 | |||
197 | In future: If we have nfct != NULL, AND we have NAT | ||
198 | initialized, AND there is no helper, then we can do full | ||
199 | NAPT on the head, and IP-address-only NAT on the rest. | ||
200 | |||
201 | I'm starting to have nightmares about fragments. */ | ||
202 | |||
203 | if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { | ||
204 | *pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT); | ||
205 | |||
206 | if (!*pskb) | ||
207 | return NF_STOLEN; | ||
208 | } | ||
209 | |||
210 | return ip_nat_fn(hooknum, pskb, in, out, okfn); | 193 | return ip_nat_fn(hooknum, pskb, in, out, okfn); |
211 | } | 194 | } |
212 | 195 | ||
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index f057025a719e..6693526ae128 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -203,7 +203,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
203 | sizeof(struct tcphdr), 0)); | 203 | sizeof(struct tcphdr), 0)); |
204 | 204 | ||
205 | /* Adjust IP TTL, DF */ | 205 | /* Adjust IP TTL, DF */ |
206 | nskb->nh.iph->ttl = MAXTTL; | 206 | nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); |
207 | /* Set DF, id = 0 */ | 207 | /* Set DF, id = 0 */ |
208 | nskb->nh.iph->frag_off = htons(IP_DF); | 208 | nskb->nh.iph->frag_off = htons(IP_DF); |
209 | nskb->nh.iph->id = 0; | 209 | nskb->nh.iph->id = 0; |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 2883ccd8a91d..38641cd06123 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -77,15 +77,15 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG); | |||
77 | #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) | 77 | #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) |
78 | 78 | ||
79 | static unsigned int nlbufsiz = 4096; | 79 | static unsigned int nlbufsiz = 4096; |
80 | module_param(nlbufsiz, uint, 0600); /* FIXME: Check size < 128k --RR */ | 80 | module_param(nlbufsiz, uint, 0400); |
81 | MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); | 81 | MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); |
82 | 82 | ||
83 | static unsigned int flushtimeout = 10; | 83 | static unsigned int flushtimeout = 10; |
84 | module_param(flushtimeout, int, 0600); | 84 | module_param(flushtimeout, uint, 0600); |
85 | MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)"); | 85 | MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)"); |
86 | 86 | ||
87 | static unsigned int nflog = 1; | 87 | static int nflog = 1; |
88 | module_param(nflog, int, 0400); | 88 | module_param(nflog, bool, 0400); |
89 | MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); | 89 | MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); |
90 | 90 | ||
91 | /* global data structures */ | 91 | /* global data structures */ |
@@ -376,7 +376,7 @@ static int __init init(void) | |||
376 | 376 | ||
377 | DEBUGP("ipt_ULOG: init module\n"); | 377 | DEBUGP("ipt_ULOG: init module\n"); |
378 | 378 | ||
379 | if (nlbufsiz >= 128*1024) { | 379 | if (nlbufsiz > 128*1024) { |
380 | printk("Netlink buffer has to be <= 128kB\n"); | 380 | printk("Netlink buffer has to be <= 128kB\n"); |
381 | return -EINVAL; | 381 | return -EINVAL; |
382 | } | 382 | } |
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 261cbb4d4c49..5ddccb18c65e 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c | |||
@@ -24,10 +24,10 @@ | |||
24 | #define HASH_LOG 9 | 24 | #define HASH_LOG 9 |
25 | 25 | ||
26 | /* Defaults, these can be overridden on the module command-line. */ | 26 | /* Defaults, these can be overridden on the module command-line. */ |
27 | static int ip_list_tot = 100; | 27 | static unsigned int ip_list_tot = 100; |
28 | static int ip_pkt_list_tot = 20; | 28 | static unsigned int ip_pkt_list_tot = 20; |
29 | static int ip_list_hash_size = 0; | 29 | static unsigned int ip_list_hash_size = 0; |
30 | static int ip_list_perms = 0644; | 30 | static unsigned int ip_list_perms = 0644; |
31 | #ifdef DEBUG | 31 | #ifdef DEBUG |
32 | static int debug = 1; | 32 | static int debug = 1; |
33 | #endif | 33 | #endif |
@@ -38,13 +38,13 @@ KERN_INFO RECENT_NAME " " RECENT_VER ": Stephen Frost <sfrost@snowman.net>. htt | |||
38 | MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>"); | 38 | MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>"); |
39 | MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER); | 39 | MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER); |
40 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
41 | module_param(ip_list_tot, int, 0400); | 41 | module_param(ip_list_tot, uint, 0400); |
42 | module_param(ip_pkt_list_tot, int, 0400); | 42 | module_param(ip_pkt_list_tot, uint, 0400); |
43 | module_param(ip_list_hash_size, int, 0400); | 43 | module_param(ip_list_hash_size, uint, 0400); |
44 | module_param(ip_list_perms, int, 0400); | 44 | module_param(ip_list_perms, uint, 0400); |
45 | #ifdef DEBUG | 45 | #ifdef DEBUG |
46 | module_param(debug, int, 0600); | 46 | module_param(debug, bool, 0600); |
47 | MODULE_PARM_DESC(debug,"debugging level, defaults to 1"); | 47 | MODULE_PARM_DESC(debug,"enable debugging output"); |
48 | #endif | 48 | #endif |
49 | MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list"); | 49 | MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list"); |
50 | MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember"); | 50 | MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember"); |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 8202c1c0afad..9bdbb7793971 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/skbuff.h> | 22 | #include <linux/skbuff.h> |
23 | #include <linux/icmp.h> | 23 | #include <linux/icmp.h> |
24 | #include <linux/sysctl.h> | 24 | #include <linux/sysctl.h> |
25 | #include <net/route.h> | ||
25 | #include <net/ip.h> | 26 | #include <net/ip.h> |
26 | 27 | ||
27 | #include <linux/netfilter_ipv4.h> | 28 | #include <linux/netfilter_ipv4.h> |
@@ -180,30 +181,6 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | |||
180 | return NF_ACCEPT; | 181 | return NF_ACCEPT; |
181 | } | 182 | } |
182 | 183 | ||
183 | static unsigned int ipv4_refrag(unsigned int hooknum, | ||
184 | struct sk_buff **pskb, | ||
185 | const struct net_device *in, | ||
186 | const struct net_device *out, | ||
187 | int (*okfn)(struct sk_buff *)) | ||
188 | { | ||
189 | struct rtable *rt = (struct rtable *)(*pskb)->dst; | ||
190 | |||
191 | /* We've seen it coming out the other side: confirm */ | ||
192 | if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT) | ||
193 | return NF_DROP; | ||
194 | |||
195 | /* Local packets are never produced too large for their | ||
196 | interface. We degfragment them at LOCAL_OUT, however, | ||
197 | so we have to refragment them here. */ | ||
198 | if ((*pskb)->len > dst_mtu(&rt->u.dst) && | ||
199 | !skb_shinfo(*pskb)->tso_size) { | ||
200 | /* No hook can be after us, so this should be OK. */ | ||
201 | ip_fragment(*pskb, okfn); | ||
202 | return NF_STOLEN; | ||
203 | } | ||
204 | return NF_ACCEPT; | ||
205 | } | ||
206 | |||
207 | static unsigned int ipv4_conntrack_in(unsigned int hooknum, | 184 | static unsigned int ipv4_conntrack_in(unsigned int hooknum, |
208 | struct sk_buff **pskb, | 185 | struct sk_buff **pskb, |
209 | const struct net_device *in, | 186 | const struct net_device *in, |
@@ -283,7 +260,7 @@ static struct nf_hook_ops ipv4_conntrack_helper_in_ops = { | |||
283 | 260 | ||
284 | /* Refragmenter; last chance. */ | 261 | /* Refragmenter; last chance. */ |
285 | static struct nf_hook_ops ipv4_conntrack_out_ops = { | 262 | static struct nf_hook_ops ipv4_conntrack_out_ops = { |
286 | .hook = ipv4_refrag, | 263 | .hook = ipv4_confirm, |
287 | .owner = THIS_MODULE, | 264 | .owner = THIS_MODULE, |
288 | .pf = PF_INET, | 265 | .pf = PF_INET, |
289 | .hooknum = NF_IP_POST_ROUTING, | 266 | .hooknum = NF_IP_POST_ROUTING, |
@@ -392,6 +369,48 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) | |||
392 | return -ENOENT; | 369 | return -ENOENT; |
393 | } | 370 | } |
394 | 371 | ||
372 | #if defined(CONFIG_NF_CT_NETLINK) || \ | ||
373 | defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
374 | |||
375 | #include <linux/netfilter/nfnetlink.h> | ||
376 | #include <linux/netfilter/nfnetlink_conntrack.h> | ||
377 | |||
378 | static int ipv4_tuple_to_nfattr(struct sk_buff *skb, | ||
379 | const struct nf_conntrack_tuple *tuple) | ||
380 | { | ||
381 | NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), | ||
382 | &tuple->src.u3.ip); | ||
383 | NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), | ||
384 | &tuple->dst.u3.ip); | ||
385 | return 0; | ||
386 | |||
387 | nfattr_failure: | ||
388 | return -1; | ||
389 | } | ||
390 | |||
391 | static const size_t cta_min_ip[CTA_IP_MAX] = { | ||
392 | [CTA_IP_V4_SRC-1] = sizeof(u_int32_t), | ||
393 | [CTA_IP_V4_DST-1] = sizeof(u_int32_t), | ||
394 | }; | ||
395 | |||
396 | static int ipv4_nfattr_to_tuple(struct nfattr *tb[], | ||
397 | struct nf_conntrack_tuple *t) | ||
398 | { | ||
399 | if (!tb[CTA_IP_V4_SRC-1] || !tb[CTA_IP_V4_DST-1]) | ||
400 | return -EINVAL; | ||
401 | |||
402 | if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) | ||
403 | return -EINVAL; | ||
404 | |||
405 | t->src.u3.ip = | ||
406 | *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]); | ||
407 | t->dst.u3.ip = | ||
408 | *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | #endif | ||
413 | |||
395 | static struct nf_sockopt_ops so_getorigdst = { | 414 | static struct nf_sockopt_ops so_getorigdst = { |
396 | .pf = PF_INET, | 415 | .pf = PF_INET, |
397 | .get_optmin = SO_ORIGINAL_DST, | 416 | .get_optmin = SO_ORIGINAL_DST, |
@@ -408,6 +427,11 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = { | |||
408 | .print_conntrack = ipv4_print_conntrack, | 427 | .print_conntrack = ipv4_print_conntrack, |
409 | .prepare = ipv4_prepare, | 428 | .prepare = ipv4_prepare, |
410 | .get_features = ipv4_get_features, | 429 | .get_features = ipv4_get_features, |
430 | #if defined(CONFIG_NF_CT_NETLINK) || \ | ||
431 | defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
432 | .tuple_to_nfattr = ipv4_tuple_to_nfattr, | ||
433 | .nfattr_to_tuple = ipv4_nfattr_to_tuple, | ||
434 | #endif | ||
411 | .me = THIS_MODULE, | 435 | .me = THIS_MODULE, |
412 | }; | 436 | }; |
413 | 437 | ||
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 7ddb5c08f7b8..52dc175be39a 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -50,20 +50,21 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb, | |||
50 | return 1; | 50 | return 1; |
51 | } | 51 | } |
52 | 52 | ||
53 | /* Add 1; spaces filled with 0. */ | ||
54 | static const u_int8_t invmap[] = { | ||
55 | [ICMP_ECHO] = ICMP_ECHOREPLY + 1, | ||
56 | [ICMP_ECHOREPLY] = ICMP_ECHO + 1, | ||
57 | [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, | ||
58 | [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, | ||
59 | [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, | ||
60 | [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, | ||
61 | [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, | ||
62 | [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 | ||
63 | }; | ||
64 | |||
53 | static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple, | 65 | static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple, |
54 | const struct nf_conntrack_tuple *orig) | 66 | const struct nf_conntrack_tuple *orig) |
55 | { | 67 | { |
56 | /* Add 1; spaces filled with 0. */ | ||
57 | static u_int8_t invmap[] | ||
58 | = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, | ||
59 | [ICMP_ECHOREPLY] = ICMP_ECHO + 1, | ||
60 | [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, | ||
61 | [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, | ||
62 | [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, | ||
63 | [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, | ||
64 | [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, | ||
65 | [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1}; | ||
66 | |||
67 | if (orig->dst.u.icmp.type >= sizeof(invmap) | 68 | if (orig->dst.u.icmp.type >= sizeof(invmap) |
68 | || !invmap[orig->dst.u.icmp.type]) | 69 | || !invmap[orig->dst.u.icmp.type]) |
69 | return 0; | 70 | return 0; |
@@ -120,11 +121,12 @@ static int icmp_packet(struct nf_conn *ct, | |||
120 | static int icmp_new(struct nf_conn *conntrack, | 121 | static int icmp_new(struct nf_conn *conntrack, |
121 | const struct sk_buff *skb, unsigned int dataoff) | 122 | const struct sk_buff *skb, unsigned int dataoff) |
122 | { | 123 | { |
123 | static u_int8_t valid_new[] | 124 | static const u_int8_t valid_new[] = { |
124 | = { [ICMP_ECHO] = 1, | 125 | [ICMP_ECHO] = 1, |
125 | [ICMP_TIMESTAMP] = 1, | 126 | [ICMP_TIMESTAMP] = 1, |
126 | [ICMP_INFO_REQUEST] = 1, | 127 | [ICMP_INFO_REQUEST] = 1, |
127 | [ICMP_ADDRESS] = 1 }; | 128 | [ICMP_ADDRESS] = 1 |
129 | }; | ||
128 | 130 | ||
129 | if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) | 131 | if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) |
130 | || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { | 132 | || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { |
@@ -168,7 +170,7 @@ icmp_error_message(struct sk_buff *skb, | |||
168 | return -NF_ACCEPT; | 170 | return -NF_ACCEPT; |
169 | } | 171 | } |
170 | 172 | ||
171 | innerproto = nf_ct_find_proto(PF_INET, inside->ip.protocol); | 173 | innerproto = __nf_ct_proto_find(PF_INET, inside->ip.protocol); |
172 | dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp); | 174 | dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp); |
173 | /* Are they talking about one of our connections? */ | 175 | /* Are they talking about one of our connections? */ |
174 | if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET, | 176 | if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET, |
@@ -281,6 +283,60 @@ checksum_skipped: | |||
281 | return icmp_error_message(skb, ctinfo, hooknum); | 283 | return icmp_error_message(skb, ctinfo, hooknum); |
282 | } | 284 | } |
283 | 285 | ||
286 | #if defined(CONFIG_NF_CT_NETLINK) || \ | ||
287 | defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
288 | |||
289 | #include <linux/netfilter/nfnetlink.h> | ||
290 | #include <linux/netfilter/nfnetlink_conntrack.h> | ||
291 | |||
292 | static int icmp_tuple_to_nfattr(struct sk_buff *skb, | ||
293 | const struct nf_conntrack_tuple *t) | ||
294 | { | ||
295 | NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t), | ||
296 | &t->src.u.icmp.id); | ||
297 | NFA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t), | ||
298 | &t->dst.u.icmp.type); | ||
299 | NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t), | ||
300 | &t->dst.u.icmp.code); | ||
301 | |||
302 | return 0; | ||
303 | |||
304 | nfattr_failure: | ||
305 | return -1; | ||
306 | } | ||
307 | |||
308 | static const size_t cta_min_proto[CTA_PROTO_MAX] = { | ||
309 | [CTA_PROTO_ICMP_TYPE-1] = sizeof(u_int8_t), | ||
310 | [CTA_PROTO_ICMP_CODE-1] = sizeof(u_int8_t), | ||
311 | [CTA_PROTO_ICMP_ID-1] = sizeof(u_int16_t) | ||
312 | }; | ||
313 | |||
314 | static int icmp_nfattr_to_tuple(struct nfattr *tb[], | ||
315 | struct nf_conntrack_tuple *tuple) | ||
316 | { | ||
317 | if (!tb[CTA_PROTO_ICMP_TYPE-1] | ||
318 | || !tb[CTA_PROTO_ICMP_CODE-1] | ||
319 | || !tb[CTA_PROTO_ICMP_ID-1]) | ||
320 | return -EINVAL; | ||
321 | |||
322 | if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) | ||
323 | return -EINVAL; | ||
324 | |||
325 | tuple->dst.u.icmp.type = | ||
326 | *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]); | ||
327 | tuple->dst.u.icmp.code = | ||
328 | *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]); | ||
329 | tuple->src.u.icmp.id = | ||
330 | *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); | ||
331 | |||
332 | if (tuple->dst.u.icmp.type >= sizeof(invmap) | ||
333 | || !invmap[tuple->dst.u.icmp.type]) | ||
334 | return -EINVAL; | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | #endif | ||
339 | |||
284 | struct nf_conntrack_protocol nf_conntrack_protocol_icmp = | 340 | struct nf_conntrack_protocol nf_conntrack_protocol_icmp = |
285 | { | 341 | { |
286 | .list = { NULL, NULL }, | 342 | .list = { NULL, NULL }, |
@@ -295,7 +351,12 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmp = | |||
295 | .new = icmp_new, | 351 | .new = icmp_new, |
296 | .error = icmp_error, | 352 | .error = icmp_error, |
297 | .destroy = NULL, | 353 | .destroy = NULL, |
298 | .me = NULL | 354 | .me = NULL, |
355 | #if defined(CONFIG_NF_CT_NETLINK) || \ | ||
356 | defined(CONFIG_NF_CT_NETLINK_MODULE) | ||
357 | .tuple_to_nfattr = icmp_tuple_to_nfattr, | ||
358 | .nfattr_to_tuple = icmp_nfattr_to_tuple, | ||
359 | #endif | ||
299 | }; | 360 | }; |
300 | 361 | ||
301 | EXPORT_SYMBOL(nf_conntrack_protocol_icmp); | 362 | EXPORT_SYMBOL(nf_conntrack_protocol_icmp); |