diff options
author | Patrick McHardy <kaber@trash.net> | 2006-01-07 02:06:30 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-07 15:57:37 -0500 |
commit | eb9c7ebe6980c41cf6ae889e301c3b49f473ee9f (patch) | |
tree | 419103d15b9de9c26c8400c698625231df55da91 /net/ipv4 | |
parent | b59c270104f03960069596722fea70340579244d (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.c | 3 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 50 |
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 | } |
87 | EXPORT_SYMBOL(ip_route_me_harder); | 87 | EXPORT_SYMBOL(ip_route_me_harder); |
88 | 88 | ||
89 | void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); | ||
90 | EXPORT_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 | ||
59 | static 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 | |||
58 | static unsigned int | 96 | static unsigned int |
59 | ip_nat_fn(unsigned int hooknum, | 97 | ip_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 | ||