: Handle NAT in IPsec policy checks
Subsystems (8)
PATCH 6/6 : Handle NAT in IPsec policy checks
[NETFILTER]: Handle NAT in IPsec policy checks
Signed-off-by Patrick McHardy <[email protected]>
---
commit 28bfee77b74d8e81c535735b8580a5a0b52a1ccf
tree 923eb3417866e8973f05a04988f5e871cd8e71b7
parent 373ca7e8b42cb5abbaf86e41a755363aa4029850
author Patrick McHardy <[email protected]> Mon, 17 Oct 2005 01:50:55 +0200 committer Patrick McHardy <[email protected]> Mon, 17 Oct 2005 01:50:55 +0200
include/linux/netfilter.h | 16 ++++++++++ net/dccp/ipv4.c | 2 + net/ipv4/ip_input.c | 14 ++++----- net/ipv4/netfilter.c | 3 ++ net/ipv4/netfilter/ip_nat_standalone.c | 50 +++++++++++++++++++++++++++++++- net/ipv4/raw.c | 1 + net/ipv4/tcp_ipv4.c | 3 ++ net/ipv4/udp.c | 2 + net/sctp/input.c | 1 + net/xfrm/xfrm_policy.c | 2 + 10 files changed, 84 insertions(+), 10 deletions(-)
include/linux/netfilter.h +16 -0
@@ -266,6 +266,20 @@ static inline int nf_defer_fragment(strureturn skb->nfct !=NULL ; } +#include <net/flow.h> +extern void (*ip_nat_decode_session)(struct sk_buff *,struct flowi *); + +static inline void +nf_nat_decode_session (struct sk_buff *skb,struct flowi *fl,int family) +{ +#ifdef CONFIG_IP_NF_NAT_NEEDED +void (*decodefn)(struct sk_buff *,struct flowi *); + +if (family ==AF_INET && (decodefn = ip_nat_decode_session) !=NULL ) +decodefn (skb, fl); +#endif +} +#ifdef CONFIG_PROC_FS #include <linux/proc_fs.h> extern struct proc_dir_entry *proc_net_netfilter;
@@ -275,6 +289,8 @@ extern struct proc_dir_entry *proc_net_n#define NF_HOOK (pf, hook, skb, indev, outdev, okfn) (okfn)(skb)static inline void nf_ct_attach (struct sk_buff *new,struct sk_buff *skb) {}static inline int nf_defer_fragment (struct sk_buff *skb) {return 0 ; } +static inline void +nf_nat_decode_session (struct sk_buff *skb,struct flowi *fl,int family) {}#endif /*CONFIG_NETFILTER*/ #endif /*__KERNEL__*/
net/dccp/ipv4.c +2 -0
@@ -1171,6 +1171,7 @@ int dccp_v4_rcv(struct sk_buff *skb)dccp_pr_debug ("xfrm4_policy_check failed\n" ); goto discard_and_relse; } +nf_reset (skb);if (sk_filter (sk, skb,0 )) {dccp_pr_debug ("sk_filter failed\n" );
@@ -1193,6 +1194,7 @@ int dccp_v4_rcv(struct sk_buff *skb) no_dccp_socket:if (!xfrm4_policy_check (NULL ,XFRM_POLICY_IN , skb)) goto discard_it; +nf_reset (skb);/* * Step 2: * Generate Reset(No Connection) unless P.type == Reset
net/ipv4/ip_input.c +6 -8
@@ -203,10 +203,6 @@ static inline int ip_local_deliver_finis__skb_pull (skb, ihl); -/* Free reference early: we don't need it any more, and it may -hold ip_conntrack module loaded indefinitely. */ -nf_reset (skb); -/* Point into the IP datagram, just past the header. */ skb->h.raw = skb->data;
@@ -231,10 +227,12 @@ static inline int ip_local_deliver_finisif ((ipprot =rcu_dereference (inet_protos[hash])) !=NULL ) {int ret; -if (!ipprot->no_policy && - !xfrm4_policy_check (NULL ,XFRM_POLICY_IN , skb)) { -kfree_skb (skb); - goto out; +if (!ipprot->no_policy) { +if (!xfrm4_policy_check (NULL ,XFRM_POLICY_IN , skb)) { +kfree_skb (skb); + goto out; + } +nf_reset (skb); } ret = ipprot->handler (skb);if (ret <0 ) {
net/ipv4/netfilter.c +3 -0
@@ -117,6 +117,9 @@ int ip_dst_output(struct sk_buff *skb)EXPORT_SYMBOL (ip_dst_output);#endif /* CONFIG_XFRM */ +void (*ip_nat_decode_session)(struct sk_buff *,struct flowi *); +EXPORT_SYMBOL (ip_nat_decode_session); +/* * Extra routing may needed on local out, as the QUEUE target never * returns control to the table.
net/ipv4/netfilter/ip_nat_standalone.c +48 -2
71 lines not on this page · raw message
net/ipv4/raw.c +1 -0
@@ -255,6 +255,7 @@ int raw_rcv(struct sock *sk, struct sk_bkfree_skb (skb);return NET_RX_DROP ; } +nf_reset (skb);skb_push (skb, skb->data - skb->nh.raw);
net/ipv4/tcp_ipv4.c +3 -0
@@ -1247,6 +1247,7 @@ process:if (!xfrm4_policy_check (sk,XFRM_POLICY_IN , skb)) goto discard_and_relse; +nf_reset (skb);if (sk_filter (sk, skb,0 )) goto discard_and_relse;
@@ -1269,6 +1270,7 @@ process: no_tcp_socket:if (!xfrm4_policy_check (NULL ,XFRM_POLICY_IN , skb)) goto discard_it; +nf_reset (skb);if (skb->len < (th->doff <<2 ) ||tcp_checksum_complete (skb)) { bad_packet:
@@ -1291,6 +1293,7 @@ do_time_wait:inet_twsk_put ((struct inet_timewait_sock *) sk); goto discard_it; } +nf_reset (skb);if (skb->len < (th->doff <<2 ) ||tcp_checksum_complete (skb)) {TCP_INC_STATS_BH (TCP_MIB_INERRS );
net/ipv4/udp.c +2 -0
@@ -1001,6 +1001,7 @@ static int udp_queue_rcv_skb(struct sockkfree_skb (skb);return -1 ; } +nf_reset (skb);if (up->encap_type) {/*
@@ -1166,6 +1167,7 @@ int udp_rcv(struct sk_buff *skb)if (!xfrm4_policy_check (NULL ,XFRM_POLICY_IN , skb)) goto drop; +nf_reset (skb);/* No socket. Drop packet silently, if checksum is wrong */ if (udp_checksum_complete (skb))
net/sctp/input.c +1 -0
@@ -243,6 +243,7 @@ int sctp_rcv(struct sk_buff *skb)if (!xfrm_policy_check (sk,XFRM_POLICY_IN , skb, family)) goto discard_release; +nf_reset (skb); ret =sk_filter (sk, skb,1 );if (ret)
net/xfrm/xfrm_policy.c +2 -0
@@ -22,6 +22,7 @@#include <linux/workqueue.h> #include <linux/notifier.h> #include <linux/netdevice.h> +#include <linux/netfilter.h> #include <linux/module.h> #include <net/xfrm.h> #include <net/ip.h>
@@ -937,6 +938,7 @@ int __xfrm_policy_check(struct sock *sk,if (xfrm_decode_session (skb, &fl, family) <0 )return 0 ; +nf_nat_decode_session (skb, &fl, family);/* First, check used SA against their selectors. */ if (skb->sp) {