===== include/linux/netfilter.h 1.6 vs edited ===== --- 1.6/include/linux/netfilter.h Wed Jun 25 00:36:10 2003 +++ edited/include/linux/netfilter.h Sun Feb 1 14:39:16 2004 @@ -166,5 +166,21 @@ #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) #endif /*CONFIG_NETFILTER*/ +#ifdef CONFIG_XFRM +#ifdef CONFIG_IP_NF_NAT_NEEDED +struct flowi; +extern void nf_nat_decode_session4(struct sk_buff *skb, struct flowi *fl); + +static inline void +nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) +{ + if (family == AF_INET) + nf_nat_decode_session4(skb, fl); +} +#else /* CONFIG_IP_NF_NAT_NEEDED */ +#define nf_nat_decode_session(skb, fl, family) +#endif /* CONFIG_IP_NF_NAT_NEEDED */ +#endif /* CONFIG_XFRM */ + #endif /*__KERNEL__*/ #endif /*__LINUX_NETFILTER_H*/ ===== net/core/netfilter.c 1.26 vs edited ===== --- 1.26/net/core/netfilter.c Sun Sep 28 18:34:18 2003 +++ edited/net/core/netfilter.c Sun Feb 1 14:39:46 2004 @@ -681,6 +695,49 @@ return 0; } + +#if defined(CONFIG_IP_NF_NAT_NEEDED) && defined(CONFIG_XFRM) +#include +#include + +void nf_nat_decode_session4(struct sk_buff *skb, struct flowi *fl) +{ + struct ip_conntrack *ct; + struct ip_nat_info_manip *m; + struct ip_conntrack_tuple *tuple; + unsigned int i; + + if (skb->nfct == NULL) + return; + ct = (struct ip_conntrack *)skb->nfct->master; + + for (i = 0; i < ct->nat.info.num_manips; i++) { + m = &ct->nat.info.manips[i]; + if (m->direction != IP_CT_DIR_REPLY) + continue; + tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; + + if (m->hooknum == NF_IP_PRE_ROUTING && + m->maniptype == IP_NAT_MANIP_DST) { + /* SNAT rule reply mangling */ + fl->fl4_dst = tuple->dst.ip; + if (tuple->dst.protonum == IPPROTO_TCP || + tuple->dst.protonum == IPPROTO_UDP) + fl->fl_ip_dport = tuple->dst.u.tcp.port; + } +#ifdef CONFIG_IP_NF_NAT_LOCAL + else if (m->hooknum == NF_IP_LOCAL_IN && + m->maniptype == IP_NAT_MANIP_SRC) { + /* DNAT rule reply mangling */ + fl->fl4_src = tuple->src.ip; + if (tuple->dst.protonum == IPPROTO_TCP || + tuple->dst.protonum == IPPROTO_UDP) + fl->fl_ip_sport = tuple->src.u.tcp.port; + } +#endif + } +} +#endif /* CONFIG_IP_NF_NAT_NEEDED && CONFIG_XFRM */ int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len) { ===== net/ipv4/ip_input.c 1.20 vs edited ===== --- 1.20/net/ipv4/ip_input.c Mon Sep 29 04:05:42 2003 +++ edited/net/ipv4/ip_input.c Sat Jan 31 21:30:52 2004 @@ -207,12 +207,14 @@ __skb_pull(skb, ihl); +#if 0 #ifdef CONFIG_NETFILTER /* Free reference early: we don't need it any more, and it may hold ip_conntrack module loaded indefinitely. */ nf_conntrack_put(skb->nfct); skb->nfct = NULL; #endif /*CONFIG_NETFILTER*/ +#endif /* Point into the IP datagram, just past the header. */ skb->h.raw = skb->data; ===== net/xfrm/xfrm_policy.c 1.47 vs edited ===== --- 1.47/net/xfrm/xfrm_policy.c Wed Jan 14 08:30:19 2004 +++ edited/net/xfrm/xfrm_policy.c Sun Feb 1 13:57:09 2004 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -908,6 +909,7 @@ if (_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) {