aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-01-07 02:06:30 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-01-07 15:57:37 -0500
commiteb9c7ebe6980c41cf6ae889e301c3b49f473ee9f (patch)
tree419103d15b9de9c26c8400c698625231df55da91 /net/ipv4
parentb59c270104f03960069596722fea70340579244d (diff)
[NETFILTER]: Handle NAT in IPsec policy checks
Handle NAT of decapsulated IPsec packets by reconstructing the struct flowi of the original packet from the conntrack information for IPsec policy checks. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter.c3
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c50
2 files changed, 51 insertions, 2 deletions
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 4c637a1cbd23..3321092b0914 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -86,6 +86,9 @@ int ip_route_me_harder(struct sk_buff **pskb)
86} 86}
87EXPORT_SYMBOL(ip_route_me_harder); 87EXPORT_SYMBOL(ip_route_me_harder);
88 88
89void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
90EXPORT_SYMBOL(ip_nat_decode_session);
91
89/* 92/*
90 * Extra routing may needed on local out, as the QUEUE target never 93 * Extra routing may needed on local out, as the QUEUE target never
91 * returns control to the table. 94 * returns control to the table.
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index b518697af4db..8b8a1f00bbf4 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -55,6 +55,44 @@
55 : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \ 55 : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \
56 : "*ERROR*"))) 56 : "*ERROR*")))
57 57
58#ifdef CONFIG_XFRM
59static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
60{
61 struct ip_conntrack *ct;
62 struct ip_conntrack_tuple *t;
63 enum ip_conntrack_info ctinfo;
64 enum ip_conntrack_dir dir;
65 unsigned long statusbit;
66
67 ct = ip_conntrack_get(skb, &ctinfo);
68 if (ct == NULL)
69 return;
70 dir = CTINFO2DIR(ctinfo);
71 t = &ct->tuplehash[dir].tuple;
72
73 if (dir == IP_CT_DIR_ORIGINAL)
74 statusbit = IPS_DST_NAT;
75 else
76 statusbit = IPS_SRC_NAT;
77
78 if (ct->status & statusbit) {
79 fl->fl4_dst = t->dst.ip;
80 if (t->dst.protonum == IPPROTO_TCP ||
81 t->dst.protonum == IPPROTO_UDP)
82 fl->fl_ip_dport = t->dst.u.tcp.port;
83 }
84
85 statusbit ^= IPS_NAT_MASK;
86
87 if (ct->status & statusbit) {
88 fl->fl4_src = t->src.ip;
89 if (t->dst.protonum == IPPROTO_TCP ||
90 t->dst.protonum == IPPROTO_UDP)
91 fl->fl_ip_sport = t->src.u.tcp.port;
92 }
93}
94#endif
95
58static unsigned int 96static unsigned int
59ip_nat_fn(unsigned int hooknum, 97ip_nat_fn(unsigned int hooknum,
60 struct sk_buff **pskb, 98 struct sk_buff **pskb,
@@ -330,10 +368,14 @@ static int init_or_cleanup(int init)
330 368
331 if (!init) goto cleanup; 369 if (!init) goto cleanup;
332 370
371#ifdef CONFIG_XFRM
372 BUG_ON(ip_nat_decode_session != NULL);
373 ip_nat_decode_session = nat_decode_session;
374#endif
333 ret = ip_nat_rule_init(); 375 ret = ip_nat_rule_init();
334 if (ret < 0) { 376 if (ret < 0) {
335 printk("ip_nat_init: can't setup rules.\n"); 377 printk("ip_nat_init: can't setup rules.\n");
336 goto cleanup_nothing; 378 goto cleanup_decode_session;
337 } 379 }
338 ret = nf_register_hook(&ip_nat_in_ops); 380 ret = nf_register_hook(&ip_nat_in_ops);
339 if (ret < 0) { 381 if (ret < 0) {
@@ -381,7 +423,11 @@ static int init_or_cleanup(int init)
381 nf_unregister_hook(&ip_nat_in_ops); 423 nf_unregister_hook(&ip_nat_in_ops);
382 cleanup_rule_init: 424 cleanup_rule_init:
383 ip_nat_rule_cleanup(); 425 ip_nat_rule_cleanup();
384 cleanup_nothing: 426 cleanup_decode_session:
427#ifdef CONFIG_XFRM
428 ip_nat_decode_session = NULL;
429 synchronize_net();
430#endif
385 return ret; 431 return ret;
386} 432}
387 433