aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter_ipv4.h3
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c51
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c54
4 files changed, 101 insertions, 16 deletions
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index c9bacf9b2431..9e5750079e09 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -62,6 +62,9 @@ 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_LAST = INT_MAX, 68 NF_IP_PRI_LAST = INT_MAX,
66}; 69};
67 70
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 80a7bde2a57a..0c29ccf62a89 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -401,6 +401,16 @@ static unsigned int ip_confirm(unsigned int hooknum,
401 const struct net_device *out, 401 const struct net_device *out,
402 int (*okfn)(struct sk_buff *)) 402 int (*okfn)(struct sk_buff *))
403{ 403{
404 /* We've seen it coming out the other side: confirm it */
405 return ip_conntrack_confirm(pskb);
406}
407
408static unsigned int ip_conntrack_help(unsigned int hooknum,
409 struct sk_buff **pskb,
410 const struct net_device *in,
411 const struct net_device *out,
412 int (*okfn)(struct sk_buff *))
413{
404 struct ip_conntrack *ct; 414 struct ip_conntrack *ct;
405 enum ip_conntrack_info ctinfo; 415 enum ip_conntrack_info ctinfo;
406 416
@@ -412,9 +422,7 @@ static unsigned int ip_confirm(unsigned int hooknum,
412 if (ret != NF_ACCEPT) 422 if (ret != NF_ACCEPT)
413 return ret; 423 return ret;
414 } 424 }
415 425 return NF_ACCEPT;
416 /* We've seen it coming out the other side: confirm it */
417 return ip_conntrack_confirm(pskb);
418} 426}
419 427
420static unsigned int ip_conntrack_defrag(unsigned int hooknum, 428static unsigned int ip_conntrack_defrag(unsigned int hooknum,
@@ -516,13 +524,30 @@ static struct nf_hook_ops ip_conntrack_local_out_ops = {
516 .priority = NF_IP_PRI_CONNTRACK, 524 .priority = NF_IP_PRI_CONNTRACK,
517}; 525};
518 526
527/* helpers */
528static struct nf_hook_ops ip_conntrack_helper_out_ops = {
529 .hook = ip_conntrack_help,
530 .owner = THIS_MODULE,
531 .pf = PF_INET,
532 .hooknum = NF_IP_POST_ROUTING,
533 .priority = NF_IP_PRI_CONNTRACK_HELPER,
534};
535
536static struct nf_hook_ops ip_conntrack_helper_in_ops = {
537 .hook = ip_conntrack_help,
538 .owner = THIS_MODULE,
539 .pf = PF_INET,
540 .hooknum = NF_IP_LOCAL_IN,
541 .priority = NF_IP_PRI_CONNTRACK_HELPER,
542};
543
519/* Refragmenter; last chance. */ 544/* Refragmenter; last chance. */
520static struct nf_hook_ops ip_conntrack_out_ops = { 545static struct nf_hook_ops ip_conntrack_out_ops = {
521 .hook = ip_refrag, 546 .hook = ip_refrag,
522 .owner = THIS_MODULE, 547 .owner = THIS_MODULE,
523 .pf = PF_INET, 548 .pf = PF_INET,
524 .hooknum = NF_IP_POST_ROUTING, 549 .hooknum = NF_IP_POST_ROUTING,
525 .priority = NF_IP_PRI_LAST, 550 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
526}; 551};
527 552
528static struct nf_hook_ops ip_conntrack_local_in_ops = { 553static struct nf_hook_ops ip_conntrack_local_in_ops = {
@@ -530,7 +555,7 @@ static struct nf_hook_ops ip_conntrack_local_in_ops = {
530 .owner = THIS_MODULE, 555 .owner = THIS_MODULE,
531 .pf = PF_INET, 556 .pf = PF_INET,
532 .hooknum = NF_IP_LOCAL_IN, 557 .hooknum = NF_IP_LOCAL_IN,
533 .priority = NF_IP_PRI_LAST-1, 558 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
534}; 559};
535 560
536/* Sysctl support */ 561/* Sysctl support */
@@ -831,10 +856,20 @@ static int init_or_cleanup(int init)
831 printk("ip_conntrack: can't register local out hook.\n"); 856 printk("ip_conntrack: can't register local out hook.\n");
832 goto cleanup_inops; 857 goto cleanup_inops;
833 } 858 }
859 ret = nf_register_hook(&ip_conntrack_helper_in_ops);
860 if (ret < 0) {
861 printk("ip_conntrack: can't register local in helper hook.\n");
862 goto cleanup_inandlocalops;
863 }
864 ret = nf_register_hook(&ip_conntrack_helper_out_ops);
865 if (ret < 0) {
866 printk("ip_conntrack: can't register postrouting helper hook.\n");
867 goto cleanup_helperinops;
868 }
834 ret = nf_register_hook(&ip_conntrack_out_ops); 869 ret = nf_register_hook(&ip_conntrack_out_ops);
835 if (ret < 0) { 870 if (ret < 0) {
836 printk("ip_conntrack: can't register post-routing hook.\n"); 871 printk("ip_conntrack: can't register post-routing hook.\n");
837 goto cleanup_inandlocalops; 872 goto cleanup_helperoutops;
838 } 873 }
839 ret = nf_register_hook(&ip_conntrack_local_in_ops); 874 ret = nf_register_hook(&ip_conntrack_local_in_ops);
840 if (ret < 0) { 875 if (ret < 0) {
@@ -860,6 +895,10 @@ static int init_or_cleanup(int init)
860 nf_unregister_hook(&ip_conntrack_local_in_ops); 895 nf_unregister_hook(&ip_conntrack_local_in_ops);
861 cleanup_inoutandlocalops: 896 cleanup_inoutandlocalops:
862 nf_unregister_hook(&ip_conntrack_out_ops); 897 nf_unregister_hook(&ip_conntrack_out_ops);
898 cleanup_helperoutops:
899 nf_unregister_hook(&ip_conntrack_helper_out_ops);
900 cleanup_helperinops:
901 nf_unregister_hook(&ip_conntrack_helper_in_ops);
863 cleanup_inandlocalops: 902 cleanup_inandlocalops:
864 nf_unregister_hook(&ip_conntrack_local_out_ops); 903 nf_unregister_hook(&ip_conntrack_local_out_ops);
865 cleanup_inops: 904 cleanup_inops:
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 162ceacfc29a..9fc6f93af0dd 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -356,15 +356,6 @@ unsigned int nat_packet(struct ip_conntrack *ct,
356 unsigned long statusbit; 356 unsigned long statusbit;
357 enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum); 357 enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum);
358 358
359 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
360 && (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP_LOCAL_IN)) {
361 DEBUGP("ip_nat_core: adjusting sequence number\n");
362 /* future: put this in a l4-proto specific function,
363 * and call this function here. */
364 if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
365 return NF_DROP;
366 }
367
368 if (mtype == IP_NAT_MANIP_SRC) 359 if (mtype == IP_NAT_MANIP_SRC)
369 statusbit = IPS_SRC_NAT; 360 statusbit = IPS_SRC_NAT;
370 else 361 else
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index dec4a74212cd..79f56f662b33 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -230,6 +230,25 @@ ip_nat_local_fn(unsigned int hooknum,
230 return ret; 230 return ret;
231} 231}
232 232
233static unsigned int
234ip_nat_adjust(unsigned int hooknum,
235 struct sk_buff **pskb,
236 const struct net_device *in,
237 const struct net_device *out,
238 int (*okfn)(struct sk_buff *))
239{
240 struct ip_conntrack *ct;
241 enum ip_conntrack_info ctinfo;
242
243 ct = ip_conntrack_get(*pskb, &ctinfo);
244 if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
245 DEBUGP("ip_nat_standalone: adjusting sequence number\n");
246 if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
247 return NF_DROP;
248 }
249 return NF_ACCEPT;
250}
251
233/* We must be after connection tracking and before packet filtering. */ 252/* We must be after connection tracking and before packet filtering. */
234 253
235/* Before packet filtering, change destination */ 254/* Before packet filtering, change destination */
@@ -250,6 +269,15 @@ static struct nf_hook_ops ip_nat_out_ops = {
250 .priority = NF_IP_PRI_NAT_SRC, 269 .priority = NF_IP_PRI_NAT_SRC,
251}; 270};
252 271
272/* After conntrack, adjust sequence number */
273static struct nf_hook_ops ip_nat_adjust_out_ops = {
274 .hook = ip_nat_adjust,
275 .owner = THIS_MODULE,
276 .pf = PF_INET,
277 .hooknum = NF_IP_POST_ROUTING,
278 .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
279};
280
253/* Before packet filtering, change destination */ 281/* Before packet filtering, change destination */
254static struct nf_hook_ops ip_nat_local_out_ops = { 282static struct nf_hook_ops ip_nat_local_out_ops = {
255 .hook = ip_nat_local_fn, 283 .hook = ip_nat_local_fn,
@@ -268,6 +296,16 @@ static struct nf_hook_ops ip_nat_local_in_ops = {
268 .priority = NF_IP_PRI_NAT_SRC, 296 .priority = NF_IP_PRI_NAT_SRC,
269}; 297};
270 298
299/* After conntrack, adjust sequence number */
300static struct nf_hook_ops ip_nat_adjust_in_ops = {
301 .hook = ip_nat_adjust,
302 .owner = THIS_MODULE,
303 .pf = PF_INET,
304 .hooknum = NF_IP_LOCAL_IN,
305 .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
306};
307
308
271static int init_or_cleanup(int init) 309static int init_or_cleanup(int init)
272{ 310{
273 int ret = 0; 311 int ret = 0;
@@ -296,10 +334,20 @@ static int init_or_cleanup(int init)
296 printk("ip_nat_init: can't register out hook.\n"); 334 printk("ip_nat_init: can't register out hook.\n");
297 goto cleanup_inops; 335 goto cleanup_inops;
298 } 336 }
337 ret = nf_register_hook(&ip_nat_adjust_in_ops);
338 if (ret < 0) {
339 printk("ip_nat_init: can't register adjust in hook.\n");
340 goto cleanup_outops;
341 }
342 ret = nf_register_hook(&ip_nat_adjust_out_ops);
343 if (ret < 0) {
344 printk("ip_nat_init: can't register adjust out hook.\n");
345 goto cleanup_adjustin_ops;
346 }
299 ret = nf_register_hook(&ip_nat_local_out_ops); 347 ret = nf_register_hook(&ip_nat_local_out_ops);
300 if (ret < 0) { 348 if (ret < 0) {
301 printk("ip_nat_init: can't register local out hook.\n"); 349 printk("ip_nat_init: can't register local out hook.\n");
302 goto cleanup_outops; 350 goto cleanup_adjustout_ops;;
303 } 351 }
304 ret = nf_register_hook(&ip_nat_local_in_ops); 352 ret = nf_register_hook(&ip_nat_local_in_ops);
305 if (ret < 0) { 353 if (ret < 0) {
@@ -312,6 +360,10 @@ static int init_or_cleanup(int init)
312 nf_unregister_hook(&ip_nat_local_in_ops); 360 nf_unregister_hook(&ip_nat_local_in_ops);
313 cleanup_localoutops: 361 cleanup_localoutops:
314 nf_unregister_hook(&ip_nat_local_out_ops); 362 nf_unregister_hook(&ip_nat_local_out_ops);
363 cleanup_adjustout_ops:
364 nf_unregister_hook(&ip_nat_adjust_out_ops);
365 cleanup_adjustin_ops:
366 nf_unregister_hook(&ip_nat_adjust_in_ops);
315 cleanup_outops: 367 cleanup_outops:
316 nf_unregister_hook(&ip_nat_out_ops); 368 nf_unregister_hook(&ip_nat_out_ops);
317 cleanup_inops: 369 cleanup_inops: