[netfilter-cvslog] r4006 - in trunk/patch-o-matic-ng:
ipsec-01-output-hooks ipsec-02-input-hooks
ipsec-03-policy-lookup ipsec-04-policy-checks
laforge at netfilter.org
laforge at netfilter.org
Mon Jun 27 10:26:21 CEST 2005
Author: laforge at netfilter.org
Date: 2005-06-27 10:26:20 +0200 (Mon, 27 Jun 2005)
New Revision: 4006
Added:
trunk/patch-o-matic-ng/ipsec-01-output-hooks/linux-2.6.12.patch
trunk/patch-o-matic-ng/ipsec-02-input-hooks/linux-2.6.12.patch
trunk/patch-o-matic-ng/ipsec-03-policy-lookup/linux-2.6.12.patch
trunk/patch-o-matic-ng/ipsec-04-policy-checks/linux-2.6.12.patch
Log:
add 2.6.12 port by Christophe Saout <christophe at saout.de>
Added: trunk/patch-o-matic-ng/ipsec-01-output-hooks/linux-2.6.12.patch
===================================================================
--- trunk/patch-o-matic-ng/ipsec-01-output-hooks/linux-2.6.12.patch 2005-06-26 12:50:26 UTC (rev 4005)
+++ trunk/patch-o-matic-ng/ipsec-01-output-hooks/linux-2.6.12.patch 2005-06-27 08:26:20 UTC (rev 4006)
@@ -0,0 +1,222 @@
+diff -Nurp linux-2.6.12.orig/include/linux/netfilter.h linux-2.6.12/include/linux/netfilter.h
+--- linux-2.6.12.orig/include/linux/netfilter.h 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/include/linux/netfilter.h 2005-06-19 18:12:33.000000000 +0200
+@@ -139,9 +139,10 @@ void nf_log_packet(int pf,
+ /* This is gross, but inline doesn't cut it for avoiding the function
+ call in fast path: gcc doesn't inline (needs value tracking?). --RR */
+ #ifdef CONFIG_NETFILTER_DEBUG
+-#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
++#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) \
+ ({int __ret; \
+-if ((__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \
++if (!(cond) || \
++ (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \
+ __ret = (okfn)(skb); \
+ __ret;})
+ #define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
+@@ -150,9 +151,9 @@ if ((__ret=nf_hook_slow(pf, hook, &(skb)
+ __ret = (okfn)(skb); \
+ __ret;})
+ #else
+-#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
++#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) \
+ ({int __ret; \
+-if (list_empty(&nf_hooks[pf][hook]) || \
++if (!(cond) || list_empty(&nf_hooks[pf][hook]) || \
+ (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \
+ __ret = (okfn)(skb); \
+ __ret;})
+@@ -163,6 +164,8 @@ if (list_empty(&nf_hooks[pf][hook]) ||
+ __ret = (okfn)(skb); \
+ __ret;})
+ #endif
++#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
++ NF_HOOK_COND((pf), (hook), (skb), (indev), (outdev), (okfn), 1)
+
+ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
+ struct net_device *indev, struct net_device *outdev,
+@@ -192,6 +195,7 @@ extern void nf_invalidate_cache(int pf);
+
+ #else /* !CONFIG_NETFILTER */
+ #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
++#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
+ static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
+ #endif /*CONFIG_NETFILTER*/
+
+diff -Nurp linux-2.6.12.orig/include/net/ip.h linux-2.6.12/include/net/ip.h
+--- linux-2.6.12.orig/include/net/ip.h 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/include/net/ip.h 2005-06-19 18:12:33.000000000 +0200
+@@ -30,6 +30,8 @@
+ #include <linux/netdevice.h>
+ #include <linux/inetdevice.h>
+ #include <linux/in_route.h>
++#include <linux/netfilter.h>
++#include <linux/netfilter_ipv4.h>
+ #include <net/route.h>
+ #include <net/arp.h>
+ #include <net/snmp.h>
+@@ -45,6 +47,7 @@ struct inet_skb_parm
+ #define IPSKB_TRANSLATED 2
+ #define IPSKB_FORWARDED 4
+ #define IPSKB_XFRM_TUNNEL_SIZE 8
++#define IPSKB_XFRM_TRANSFORMED 16
+ };
+
+ struct ipcm_cookie
+@@ -213,6 +216,16 @@ static inline void ip_select_ident_more(
+ __ip_select_ident(iph, dst, more);
+ }
+
++#ifdef CONFIG_NETFILTER
++extern int ip_dst_output(struct sk_buff *skb);
++#else
++static inline int ip_dst_output(struct sk_buff *skb)
++{
++ return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
++ skb->dst->dev, dst_output, skb->dst->xfrm != NULL);
++}
++#endif
++
+ /*
+ * Map a multicast IP onto multicast MAC for type ethernet.
+ */
+diff -Nurp linux-2.6.12.orig/net/ipv4/igmp.c linux-2.6.12/net/ipv4/igmp.c
+--- linux-2.6.12.orig/net/ipv4/igmp.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/igmp.c 2005-06-19 18:12:33.000000000 +0200
+@@ -343,7 +343,7 @@ static int igmpv3_sendpack(struct sk_buf
+ pig->csum = ip_compute_csum((void *)skb->h.igmph, igmplen);
+
+ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dev,
+- dst_output);
++ ip_dst_output);
+ }
+
+ static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
+@@ -674,7 +674,7 @@ static int igmp_send_report(struct in_de
+ ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
+
+ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+- dst_output);
++ ip_dst_output);
+ }
+
+ static void igmp_gq_timer_expire(unsigned long data)
+diff -Nurp linux-2.6.12.orig/net/ipv4/ip_forward.c linux-2.6.12/net/ipv4/ip_forward.c
+--- linux-2.6.12.orig/net/ipv4/ip_forward.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/ip_forward.c 2005-06-19 18:12:33.000000000 +0200
+@@ -51,7 +51,7 @@ static inline int ip_forward_finish(stru
+ if (unlikely(opt->optlen))
+ ip_forward_options(skb);
+
+- return dst_output(skb);
++ return ip_dst_output(skb);
+ }
+
+ int ip_forward(struct sk_buff *skb)
+diff -Nurp linux-2.6.12.orig/net/ipv4/ipmr.c linux-2.6.12/net/ipv4/ipmr.c
+--- linux-2.6.12.orig/net/ipv4/ipmr.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/ipmr.c 2005-06-19 18:12:32.000000000 +0200
+@@ -1119,7 +1119,7 @@ static inline int ipmr_forward_finish(st
+ if (unlikely(opt->optlen))
+ ip_forward_options(skb);
+
+- return dst_output(skb);
++ return ip_dst_output(skb);
+ }
+
+ /*
+diff -Nurp linux-2.6.12.orig/net/ipv4/ip_output.c linux-2.6.12/net/ipv4/ip_output.c
+--- linux-2.6.12.orig/net/ipv4/ip_output.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/ip_output.c 2005-06-19 18:12:33.000000000 +0200
+@@ -125,6 +125,15 @@ static inline int ip_select_ttl(struct i
+ return ttl;
+ }
+
++#ifdef CONFIG_NETFILTER
++/* out-of-line copy is only required with netfilter */
++int ip_dst_output(struct sk_buff *skb)
++{
++ return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
++ skb->dst->dev, dst_output, skb->dst->xfrm != NULL);
++}
++#endif
++
+ /*
+ * Add an ip header to a skbuff and send it out.
+ *
+@@ -167,7 +176,7 @@ int ip_build_and_send_pkt(struct sk_buff
+
+ /* Send it out. */
+ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+- dst_output);
++ ip_dst_output);
+ }
+
+ static inline int ip_finish_output2(struct sk_buff *skb)
+@@ -287,7 +296,7 @@ int ip_mc_output(struct sk_buff *skb)
+ return ip_finish_output(skb);
+ }
+
+-int ip_output(struct sk_buff *skb)
++static inline int ip_output2(struct sk_buff *skb)
+ {
+ IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
+
+@@ -297,6 +306,16 @@ int ip_output(struct sk_buff *skb)
+ return ip_finish_output(skb);
+ }
+
++int ip_output(struct sk_buff *skb)
++{
++ int transformed = IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED;
++
++ if (transformed)
++ nf_reset(skb);
++ return NF_HOOK_COND(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
++ skb->dst->dev, ip_output2, transformed);
++}
++
+ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
+ {
+ struct sock *sk = skb->sk;
+@@ -377,7 +396,7 @@ packet_routed:
+ skb->priority = sk->sk_priority;
+
+ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+- dst_output);
++ ip_dst_output);
+
+ no_route:
+ IP_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
+@@ -1201,7 +1220,7 @@ int ip_push_pending_frames(struct sock *
+
+ /* Netfilter gets whole the not fragmented skb. */
+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
+- skb->dst->dev, dst_output);
++ skb->dst->dev, ip_dst_output);
+ if (err) {
+ if (err > 0)
+ err = inet->recverr ? net_xmit_errno(err) : 0;
+diff -Nurp linux-2.6.12.orig/net/ipv4/raw.c linux-2.6.12/net/ipv4/raw.c
+--- linux-2.6.12.orig/net/ipv4/raw.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/raw.c 2005-06-19 18:12:32.000000000 +0200
+@@ -310,7 +310,7 @@ static int raw_send_hdrinc(struct sock *
+ }
+
+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+- dst_output);
++ ip_dst_output);
+ if (err > 0)
+ err = inet->recverr ? net_xmit_errno(err) : 0;
+ if (err)
+diff -Nurp linux-2.6.12.orig/net/ipv4/xfrm4_output.c linux-2.6.12/net/ipv4/xfrm4_output.c
+--- linux-2.6.12.orig/net/ipv4/xfrm4_output.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/xfrm4_output.c 2005-06-19 18:12:32.000000000 +0200
+@@ -129,6 +129,7 @@ int xfrm4_output(struct sk_buff *skb)
+ err = -EHOSTUNREACH;
+ goto error_nolock;
+ }
++ IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
+ err = NET_XMIT_BYPASS;
+
+ out_exit:
Added: trunk/patch-o-matic-ng/ipsec-02-input-hooks/linux-2.6.12.patch
===================================================================
--- trunk/patch-o-matic-ng/ipsec-02-input-hooks/linux-2.6.12.patch 2005-06-26 12:50:26 UTC (rev 4005)
+++ trunk/patch-o-matic-ng/ipsec-02-input-hooks/linux-2.6.12.patch 2005-06-27 08:26:20 UTC (rev 4006)
@@ -0,0 +1,268 @@
+diff -Nurp linux-2.6.12.orig/include/linux/netfilter_ipv4.h linux-2.6.12/include/linux/netfilter_ipv4.h
+--- linux-2.6.12.orig/include/linux/netfilter_ipv4.h 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/include/linux/netfilter_ipv4.h 2005-06-19 18:17:34.000000000 +0200
+@@ -7,6 +7,8 @@
+
+ #include <linux/config.h>
+ #include <linux/netfilter.h>
++#include <linux/netdevice.h>
++#include <net/protocol.h>
+
+ /* IP Cache bits. */
+ /* Src IP address. */
+@@ -88,6 +90,58 @@ extern int ip_route_me_harder(struct sk_
+ Returns true or false. */
+ extern int skb_ip_make_writable(struct sk_buff **pskb,
+ unsigned int writable_len);
++
++#if defined(CONFIG_XFRM) && defined(CONFIG_NETFILTER)
++#include <net/route.h>
++#include <net/xfrm.h>
++
++static inline int nf_hook_input_cond(struct sk_buff *skb)
++{
++ return !skb->sp || skb->sp->decap_done;
++}
++
++static inline int
++nf_xfrm_local_done(struct sk_buff *skb, struct net_protocol *ipprot)
++{
++ return skb->sp && !skb->sp->decap_done
++ && (!ipprot || !ipprot->xfrm_prot);
++}
++
++static inline int nf_xfrm_nonlocal_done(struct sk_buff *skb)
++{
++ return skb->sp && !skb->sp->decap_done
++ && !(((struct rtable *)skb->dst)->rt_flags & RTCF_LOCAL);
++}
++
++extern int nf_rcv_postxfrm_local(struct sk_buff *skb);
++extern int nf_rcv_postxfrm_nonlocal(struct sk_buff *skb);
++#else /* CONFIG_XFRM */
++static inline int nf_hook_input_cond(struct sk_buff *skb)
++{
++ return 1;
++}
++
++static inline int
++nf_xfrm_local_done(struct sk_buff *skb, struct net_protocol *ipprot)
++{
++ return 0;
++}
++
++static inline int nf_xfrm_nonlocal_done(struct sk_buff *skb)
++{
++ return 0;
++}
++
++static inline int nf_rcv_postxfrm_local(struct sk_buff *skb)
++{
++ return 0;
++}
++
++static inline int nf_rcv_postxfrm_nonlocal(struct sk_buff *skb)
++{
++ return 0;
++}
++#endif /* CONFIG_XFRM */
+ #endif /*__KERNEL__*/
+
+ #endif /*__LINUX_IP_NETFILTER_H*/
+diff -Nurp linux-2.6.12.orig/include/net/protocol.h linux-2.6.12/include/net/protocol.h
+--- linux-2.6.12.orig/include/net/protocol.h 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/include/net/protocol.h 2005-06-19 18:17:34.000000000 +0200
+@@ -38,6 +38,7 @@ struct net_protocol {
+ int (*handler)(struct sk_buff *skb);
+ void (*err_handler)(struct sk_buff *skb, u32 info);
+ int no_policy;
++ int xfrm_prot;
+ };
+
+ #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+diff -Nurp linux-2.6.12.orig/include/net/xfrm.h linux-2.6.12/include/net/xfrm.h
+--- linux-2.6.12.orig/include/net/xfrm.h 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/include/net/xfrm.h 2005-06-19 18:17:34.000000000 +0200
+@@ -546,6 +546,9 @@ struct sec_path
+ {
+ atomic_t refcnt;
+ int len;
++#ifdef CONFIG_NETFILTER
++ int decap_done;
++#endif
+ struct sec_decap_state x[XFRM_MAX_DEPTH];
+ };
+
+diff -Nurp linux-2.6.12.orig/net/core/netfilter.c linux-2.6.12/net/core/netfilter.c
+--- linux-2.6.12.orig/net/core/netfilter.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/core/netfilter.c 2005-06-19 18:17:34.000000000 +0200
+@@ -27,6 +27,7 @@
+ #include <linux/icmp.h>
+ #include <net/sock.h>
+ #include <net/route.h>
++#include <net/xfrm.h>
+ #include <linux/ip.h>
+
+ /* In this code, we can be waiting indefinitely for userspace to
+@@ -651,6 +652,27 @@ int ip_route_me_harder(struct sk_buff **
+ }
+ EXPORT_SYMBOL(ip_route_me_harder);
+
++#ifdef CONFIG_XFRM
++inline int nf_rcv_postxfrm_nonlocal(struct sk_buff *skb)
++{
++ skb->sp->decap_done = 1;
++ dst_release(skb->dst);
++ skb->dst = NULL;
++ nf_reset(skb);
++ return netif_rx(skb);
++}
++
++int nf_rcv_postxfrm_local(struct sk_buff *skb)
++{
++ __skb_push(skb, skb->data - skb->nh.raw);
++ /* Fix header len and checksum if last xfrm was transport mode */
++ if (!skb->sp->x[skb->sp->len - 1].xvec->props.mode) {
++ skb->nh.iph->tot_len = htons(skb->len);
++ ip_send_check(skb->nh.iph);
++ }
++ return nf_rcv_postxfrm_nonlocal(skb);
++}
++
+ int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len)
+ {
+ struct sk_buff *nskb;
+@@ -784,3 +806,4 @@ EXPORT_SYMBOL(nf_setsockopt);
+ EXPORT_SYMBOL(nf_unregister_hook);
+ EXPORT_SYMBOL(nf_unregister_queue_handler);
+ EXPORT_SYMBOL(nf_unregister_sockopt);
++EXPORT_SYMBOL(nf_rcv_postxfrm_local);
+diff -Nurp linux-2.6.12.orig/net/ipv4/ah4.c linux-2.6.12/net/ipv4/ah4.c
+--- linux-2.6.12.orig/net/ipv4/ah4.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/ah4.c 2005-06-19 18:17:34.000000000 +0200
+@@ -306,6 +306,7 @@ static struct net_protocol ah4_protocol
+ .handler = xfrm4_rcv,
+ .err_handler = ah4_err,
+ .no_policy = 1,
++ .xfrm_prot = 1,
+ };
+
+ static int __init ah4_init(void)
+diff -Nurp linux-2.6.12.orig/net/ipv4/esp4.c linux-2.6.12/net/ipv4/esp4.c
+--- linux-2.6.12.orig/net/ipv4/esp4.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/esp4.c 2005-06-19 18:17:34.000000000 +0200
+@@ -472,6 +472,7 @@ static struct net_protocol esp4_protocol
+ .handler = xfrm4_rcv,
+ .err_handler = esp4_err,
+ .no_policy = 1,
++ .xfrm_prot = 1,
+ };
+
+ static int __init esp4_init(void)
+diff -Nurp linux-2.6.12.orig/net/ipv4/ipcomp.c linux-2.6.12/net/ipv4/ipcomp.c
+--- linux-2.6.12.orig/net/ipv4/ipcomp.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/ipcomp.c 2005-06-19 18:17:34.000000000 +0200
+@@ -491,6 +491,7 @@ static struct net_protocol ipcomp4_proto
+ .handler = xfrm4_rcv,
+ .err_handler = ipcomp4_err,
+ .no_policy = 1,
++ .xfrm_prot = 1,
+ };
+
+ static int __init ipcomp4_init(void)
+diff -Nurp linux-2.6.12.orig/net/ipv4/ip_input.c linux-2.6.12/net/ipv4/ip_input.c
+--- linux-2.6.12.orig/net/ipv4/ip_input.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/ip_input.c 2005-06-19 18:17:34.000000000 +0200
+@@ -224,6 +224,12 @@ static inline int ip_local_deliver_finis
+ resubmit:
+ hash = protocol & (MAX_INET_PROTOS - 1);
+ raw_sk = sk_head(&raw_v4_htable[hash]);
++ ipprot = rcu_dereference(inet_protos[hash]);
++
++ if (nf_xfrm_local_done(skb, ipprot)) {
++ nf_rcv_postxfrm_local(skb);
++ goto out;
++ }
+
+ /* If there maybe a raw socket we must check - if not we
+ * don't care less
+@@ -231,7 +237,7 @@ static inline int ip_local_deliver_finis
+ if (raw_sk)
+ raw_v4_input(skb, skb->nh.iph, hash);
+
+- if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
++ if (ipprot != NULL) {
+ int ret;
+
+ if (!ipprot->no_policy &&
+@@ -278,8 +284,8 @@ int ip_local_deliver(struct sk_buff *skb
+ return 0;
+ }
+
+- return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,
+- ip_local_deliver_finish);
++ return NF_HOOK_COND(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,
++ ip_local_deliver_finish, nf_hook_input_cond(skb));
+ }
+
+ static inline int ip_rcv_finish(struct sk_buff *skb)
+@@ -296,6 +302,9 @@ static inline int ip_rcv_finish(struct s
+ goto drop;
+ }
+
++ if (nf_xfrm_nonlocal_done(skb))
++ return nf_rcv_postxfrm_nonlocal(skb);
++
+ #ifdef CONFIG_NET_CLS_ROUTE
+ if (skb->dst->tclassid) {
+ struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id();
+@@ -416,8 +425,8 @@ int ip_rcv(struct sk_buff *skb, struct n
+ }
+ }
+
+- return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
+- ip_rcv_finish);
++ return NF_HOOK_COND(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
++ ip_rcv_finish, nf_hook_input_cond(skb));
+
+ inhdr_error:
+ IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
+diff -Nurp linux-2.6.12.orig/net/ipv4/ipip.c linux-2.6.12/net/ipv4/ipip.c
+--- linux-2.6.12.orig/net/ipv4/ipip.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/ipip.c 2005-06-19 18:17:34.000000000 +0200
+@@ -476,6 +476,11 @@ static int ipip_rcv(struct sk_buff *skb)
+
+ read_lock(&ipip_lock);
+ if ((tunnel = ipip_tunnel_lookup(iph->saddr, iph->daddr)) != NULL) {
++ /* IPIP packets decapsulated by IPsec missed netfilter hooks */
++ if (nf_xfrm_local_done(skb, NULL)) {
++ nf_rcv_postxfrm_local(skb);
++ return 0;
++ }
+ if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+ read_unlock(&ipip_lock);
+ kfree_skb(skb);
+diff -Nurp linux-2.6.12.orig/net/ipv4/xfrm4_tunnel.c linux-2.6.12/net/ipv4/xfrm4_tunnel.c
+--- linux-2.6.12.orig/net/ipv4/xfrm4_tunnel.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/xfrm4_tunnel.c 2005-06-19 18:17:34.000000000 +0200
+@@ -115,6 +115,7 @@ static struct net_protocol ipip_protocol
+ .handler = ipip_rcv,
+ .err_handler = ipip_err,
+ .no_policy = 1,
++ .xfrm_prot = 1,
+ };
+
+ static int __init ipip_init(void)
+diff -Nurp linux-2.6.12.orig/net/xfrm/xfrm_input.c linux-2.6.12/net/xfrm/xfrm_input.c
+--- linux-2.6.12.orig/net/xfrm/xfrm_input.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/xfrm/xfrm_input.c 2005-06-19 18:17:34.000000000 +0200
+@@ -31,6 +31,9 @@ struct sec_path *secpath_dup(struct sec_
+ if (!sp)
+ return NULL;
+
++#ifdef CONFIG_NETFILTER
++ sp->decap_done = 0;
++#endif
+ sp->len = 0;
+ if (src) {
+ int i;
Added: trunk/patch-o-matic-ng/ipsec-03-policy-lookup/linux-2.6.12.patch
===================================================================
--- trunk/patch-o-matic-ng/ipsec-03-policy-lookup/linux-2.6.12.patch 2005-06-26 12:50:26 UTC (rev 4005)
+++ trunk/patch-o-matic-ng/ipsec-03-policy-lookup/linux-2.6.12.patch 2005-06-27 08:26:20 UTC (rev 4006)
@@ -0,0 +1,173 @@
+diff -Nurp linux-2.6.12.orig/net/core/netfilter.c linux-2.6.12/net/core/netfilter.c
+--- linux-2.6.12.orig/net/core/netfilter.c 2005-06-19 18:22:57.000000000 +0200
++++ linux-2.6.12/net/core/netfilter.c 2005-06-19 18:23:03.000000000 +0200
+@@ -28,6 +28,7 @@
+ #include <net/sock.h>
+ #include <net/route.h>
+ #include <net/xfrm.h>
++#include <net/ip.h>
+ #include <linux/ip.h>
+
+ /* In this code, we can be waiting indefinitely for userspace to
+@@ -607,7 +608,6 @@ int ip_route_me_harder(struct sk_buff **
+ #ifdef CONFIG_IP_ROUTE_FWMARK
+ fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark;
+ #endif
+- fl.proto = iph->protocol;
+ if (ip_route_output_key(&rt, &fl) != 0)
+ return -1;
+
+@@ -634,6 +634,20 @@ int ip_route_me_harder(struct sk_buff **
+ if ((*pskb)->dst->error)
+ return -1;
+
++#ifdef CONFIG_XFRM
++ if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED)) {
++ struct xfrm_policy_afinfo *afinfo;
++
++ afinfo = xfrm_policy_get_afinfo(AF_INET);
++ if (afinfo != NULL) {
++ afinfo->decode_session(*pskb, &fl);
++ xfrm_policy_put_afinfo(afinfo);
++ if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0) != 0)
++ return -1;
++ }
++ }
++#endif
++
+ /* Change in oif may mean change in hh_len. */
+ hh_len = (*pskb)->dst->dev->hard_header_len;
+ if (skb_headroom(*pskb) < hh_len) {
+diff -Nurp linux-2.6.12.orig/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.12/net/ipv4/netfilter/ip_conntrack_standalone.c
+--- linux-2.6.12.orig/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-06-19 18:23:03.000000000 +0200
+@@ -970,6 +970,7 @@ EXPORT_SYMBOL(ip_ct_get_tuple);
+ EXPORT_SYMBOL(invert_tuplepr);
+ EXPORT_SYMBOL(ip_conntrack_alter_reply);
+ EXPORT_SYMBOL(ip_conntrack_destroyed);
++EXPORT_SYMBOL(__ip_conntrack_confirm);
+ EXPORT_SYMBOL(need_ip_conntrack);
+ EXPORT_SYMBOL(ip_conntrack_helper_register);
+ EXPORT_SYMBOL(ip_conntrack_helper_unregister);
+diff -Nurp linux-2.6.12.orig/net/ipv4/netfilter/ip_nat_standalone.c linux-2.6.12/net/ipv4/netfilter/ip_nat_standalone.c
+--- linux-2.6.12.orig/net/ipv4/netfilter/ip_nat_standalone.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/netfilter/ip_nat_standalone.c 2005-06-19 18:23:03.000000000 +0200
+@@ -172,6 +172,47 @@ ip_nat_in(unsigned int hooknum,
+ return ret;
+ }
+
++struct nat_route_key
++{
++ u_int32_t addr;
++#ifdef CONFIG_XFRM
++ u_int16_t port;
++#endif
++};
++
++static inline void
++nat_route_key_get(struct sk_buff *skb, struct nat_route_key *key, int which)
++{
++ struct iphdr *iph = skb->nh.iph;
++
++ key->addr = which ? iph->daddr : iph->saddr;
++#ifdef CONFIG_XFRM
++ key->port = 0;
++ if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP) {
++ u_int16_t *ports = (u_int16_t *)(skb->nh.raw + iph->ihl*4);
++ key->port = ports[which];
++ }
++#endif
++}
++
++static inline int
++nat_route_key_compare(struct sk_buff *skb, struct nat_route_key *key, int which)
++{
++ struct iphdr *iph = skb->nh.iph;
++
++ if (key->addr != (which ? iph->daddr : iph->saddr))
++ return 1;
++#ifdef CONFIG_XFRM
++ if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP) {
++ u_int16_t *ports = (u_int16_t *)(skb->nh.raw + iph->ihl*4);
++ if (key->port != ports[which])
++ return 1;
++ }
++#endif
++
++ return 0;
++}
++
+ static unsigned int
+ ip_nat_out(unsigned int hooknum,
+ struct sk_buff **pskb,
+@@ -179,6 +220,9 @@ ip_nat_out(unsigned int hooknum,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ struct nat_route_key key;
++ unsigned int ret;
++
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
+@@ -201,7 +245,29 @@ ip_nat_out(unsigned int hooknum,
+ return NF_STOLEN;
+ }
+
+- return ip_nat_fn(hooknum, pskb, in, out, okfn);
++ nat_route_key_get(*pskb, &key, 0);
++ ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
++
++ if (ret != NF_DROP && ret != NF_STOLEN
++ && nat_route_key_compare(*pskb, &key, 0)) {
++ if (ip_route_me_harder(pskb) != 0)
++ ret = NF_DROP;
++#ifdef CONFIG_XFRM
++ /*
++ * POST_ROUTING hook is called with fixed outfn, we need
++ * to manually confirm the packet and direct it to the
++ * transformers if a policy matches.
++ */
++ else if ((*pskb)->dst->xfrm != NULL) {
++ ret = ip_conntrack_confirm(pskb);
++ if (ret != NF_DROP) {
++ dst_output(*pskb);
++ ret = NF_STOLEN;
++ }
++ }
++#endif
++ }
++ return ret;
+ }
+
+ static unsigned int
+@@ -211,7 +277,7 @@ ip_nat_local_fn(unsigned int hooknum,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
+- u_int32_t saddr, daddr;
++ struct nat_route_key key;
+ unsigned int ret;
+
+ /* root is playing with raw sockets. */
+@@ -219,14 +285,14 @@ ip_nat_local_fn(unsigned int hooknum,
+ || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
+ return NF_ACCEPT;
+
+- saddr = (*pskb)->nh.iph->saddr;
+- daddr = (*pskb)->nh.iph->daddr;
+-
++ nat_route_key_get(*pskb, &key, 1);
+ ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
++
+ if (ret != NF_DROP && ret != NF_STOLEN
+- && ((*pskb)->nh.iph->saddr != saddr
+- || (*pskb)->nh.iph->daddr != daddr))
+- return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
++ && nat_route_key_compare(*pskb, &key, 1)) {
++ if (ip_route_me_harder(pskb) != 0)
++ ret = NF_DROP;
++ }
+ return ret;
+ }
+
Added: trunk/patch-o-matic-ng/ipsec-04-policy-checks/linux-2.6.12.patch
===================================================================
--- trunk/patch-o-matic-ng/ipsec-04-policy-checks/linux-2.6.12.patch 2005-06-26 12:50:26 UTC (rev 4005)
+++ trunk/patch-o-matic-ng/ipsec-04-policy-checks/linux-2.6.12.patch 2005-06-27 08:26:20 UTC (rev 4006)
@@ -0,0 +1,209 @@
+diff -Nurp linux-2.6.12.orig/include/linux/netfilter.h linux-2.6.12/include/linux/netfilter.h
+--- linux-2.6.12.orig/include/linux/netfilter.h 2005-06-19 18:17:27.000000000 +0200
++++ linux-2.6.12/include/linux/netfilter.h 2005-06-19 18:28:33.000000000 +0200
+@@ -199,5 +199,21 @@ extern void nf_invalidate_cache(int pf);
+ static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *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*/
+diff -Nurp linux-2.6.12.orig/include/net/xfrm.h linux-2.6.12/include/net/xfrm.h
+--- linux-2.6.12.orig/include/net/xfrm.h 2005-06-19 18:22:57.000000000 +0200
++++ linux-2.6.12/include/net/xfrm.h 2005-06-19 18:28:33.000000000 +0200
+@@ -179,6 +179,8 @@ struct xfrm_policy_afinfo {
+
+ extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
+ extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
++extern struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
++extern void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
+
+ #define XFRM_ACQ_EXPIRES 30
+
+diff -Nurp linux-2.6.12.orig/net/core/netfilter.c linux-2.6.12/net/core/netfilter.c
+--- linux-2.6.12.orig/net/core/netfilter.c 2005-06-19 18:28:27.000000000 +0200
++++ linux-2.6.12/net/core/netfilter.c 2005-06-19 18:28:33.000000000 +0200
+@@ -687,6 +687,48 @@ int nf_rcv_postxfrm_local(struct sk_buff
+ return nf_rcv_postxfrm_nonlocal(skb);
+ }
+
++#ifdef CONFIG_IP_NF_NAT_NEEDED
++#include <linux/netfilter_ipv4/ip_conntrack.h>
++#include <linux/netfilter_ipv4/ip_nat.h>
++
++void nf_nat_decode_session4(struct sk_buff *skb, struct flowi *fl)
++{
++ struct ip_conntrack *ct;
++ struct ip_conntrack_tuple *t;
++ enum ip_conntrack_info ctinfo;
++ enum ip_conntrack_dir dir;
++ int known_proto;
++ int statusbit;
++
++ ct = ip_conntrack_get(skb, &ctinfo);
++ if (ct == NULL || !(ct->status & IPS_NAT_MASK))
++ return;
++
++ dir = CTINFO2DIR(ctinfo);
++ t = &ct->tuplehash[dir].tuple;
++ known_proto = t->dst.protonum == IPPROTO_TCP ||
++ t->dst.protonum == IPPROTO_UDP;
++
++ if (dir == IP_CT_DIR_REPLY)
++ statusbit = IPS_SRC_NAT;
++ else
++ statusbit = IPS_DST_NAT;
++ if (ct->status & statusbit) {
++ fl->fl4_dst = t->dst.ip;
++ if (known_proto)
++ fl->fl_ip_dport = t->dst.u.tcp.port;
++ }
++
++ statusbit ^= IPS_NAT_MASK;
++ if (ct->status & statusbit) {
++ fl->fl4_src = t->src.ip;
++ if (known_proto)
++ fl->fl_ip_sport = t->src.u.tcp.port;
++ }
++}
++#endif /* CONFIG_IP_NF_NAT_NEEDED */
++#endif
++
+ int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len)
+ {
+ struct sk_buff *nskb;
+diff -Nurp linux-2.6.12.orig/net/ipv4/ip_input.c linux-2.6.12/net/ipv4/ip_input.c
+--- linux-2.6.12.orig/net/ipv4/ip_input.c 2005-06-19 18:22:57.000000000 +0200
++++ linux-2.6.12/net/ipv4/ip_input.c 2005-06-19 18:28:33.000000000 +0200
+@@ -206,10 +206,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;
+
+@@ -240,10 +236,12 @@ static inline int ip_local_deliver_finis
+ if (ipprot != 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) {
+diff -Nurp linux-2.6.12.orig/net/ipv4/raw.c linux-2.6.12/net/ipv4/raw.c
+--- linux-2.6.12.orig/net/ipv4/raw.c 2005-06-19 18:17:27.000000000 +0200
++++ linux-2.6.12/net/ipv4/raw.c 2005-06-19 18:28:33.000000000 +0200
+@@ -252,6 +252,7 @@ int raw_rcv(struct sock *sk, struct sk_b
+ kfree_skb(skb);
+ return NET_RX_DROP;
+ }
++ nf_reset(skb);
+
+ skb_push(skb, skb->data - skb->nh.raw);
+
+diff -Nurp linux-2.6.12.orig/net/ipv4/tcp_ipv4.c linux-2.6.12/net/ipv4/tcp_ipv4.c
+--- linux-2.6.12.orig/net/ipv4/tcp_ipv4.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/tcp_ipv4.c 2005-06-19 18:28:33.000000000 +0200
+@@ -1772,6 +1772,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;
+diff -Nurp linux-2.6.12.orig/net/ipv4/udp.c linux-2.6.12/net/ipv4/udp.c
+--- linux-2.6.12.orig/net/ipv4/udp.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/ipv4/udp.c 2005-06-19 18:28:33.000000000 +0200
+@@ -1000,6 +1000,7 @@ static int udp_queue_rcv_skb(struct sock
+ kfree_skb(skb);
+ return -1;
+ }
++ nf_reset(skb);
+
+ if (up->encap_type) {
+ /*
+@@ -1165,6 +1166,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))
+diff -Nurp linux-2.6.12.orig/net/xfrm/xfrm_policy.c linux-2.6.12/net/xfrm/xfrm_policy.c
+--- linux-2.6.12.orig/net/xfrm/xfrm_policy.c 2005-06-17 21:48:29.000000000 +0200
++++ linux-2.6.12/net/xfrm/xfrm_policy.c 2005-06-19 18:28:33.000000000 +0200
+@@ -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>
+@@ -44,8 +45,8 @@ static struct list_head xfrm_policy_gc_l
+ LIST_HEAD_INIT(xfrm_policy_gc_list);
+ static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
+
+-static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
+-static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
++struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
++void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
+
+ int xfrm_register_type(struct xfrm_type *type, unsigned short family)
+ {
+@@ -936,6 +937,7 @@ int __xfrm_policy_check(struct sock *sk,
+
+ 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) {
+@@ -1289,7 +1291,7 @@ int xfrm_policy_unregister_afinfo(struct
+ }
+ EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
+
+-static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family)
++struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family)
+ {
+ struct xfrm_policy_afinfo *afinfo;
+ if (unlikely(family >= NPROTO))
+@@ -1302,7 +1304,7 @@ static struct xfrm_policy_afinfo *xfrm_p
+ return afinfo;
+ }
+
+-static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo)
++void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo)
+ {
+ if (unlikely(afinfo == NULL))
+ return;
More information about the netfilter-cvslog
mailing list