diff -Naur linux-2.6.23/include/linux/in.h linux-2.6.23-saref/include/linux/in.h
--- linux-2.6.23/include/linux/in.h	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/include/linux/in.h	2009-11-18 16:20:15.000000000 -0500
@@ -75,6 +75,7 @@
 #define IP_IPSEC_POLICY	16
 #define IP_XFRM_POLICY	17
 #define IP_PASSSEC	18
+#define IP_IPSEC_REFINFO 30
 
 /* BSD compatibility */
 #define IP_RECVRETOPTS	IP_RETOPTS
diff -Naur linux-2.6.23/include/linux/rtnetlink.h linux-2.6.23-saref/include/linux/rtnetlink.h
--- linux-2.6.23/include/linux/rtnetlink.h	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/include/linux/rtnetlink.h	2009-11-18 18:57:12.000000000 -0500
@@ -268,6 +268,9 @@
 
 #define RTA_MAX (__RTA_MAX - 1)
 
+#define RTA_FWMARK      RTA_PROTOINFO
+#define RTA_FWMARK_MASK RTA_CACHEINFO
+
 #define RTM_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
 #define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
 
diff -Naur linux-2.6.23/include/net/ip.h linux-2.6.23-saref/include/net/ip.h
--- linux-2.6.23/include/net/ip.h	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/include/net/ip.h	2009-11-18 16:20:15.000000000 -0500
@@ -54,6 +54,7 @@
 	__be32			addr;
 	int			oif;
 	struct ip_options	*opt;
+	struct sec_path         *sp;
 };
 
 #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
diff -Naur linux-2.6.23/include/net/xfrm.h linux-2.6.23-saref/include/net/xfrm.h
--- linux-2.6.23/include/net/xfrm.h	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/include/net/xfrm.h	2009-11-18 16:20:15.000000000 -0500
@@ -615,14 +615,19 @@
 }
 
 extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
+typedef unsigned int xfrm_sec_unique_t;
 
 struct sec_path
 {
 	atomic_t		refcnt;
+	xfrm_sec_unique_t       ref;       /*reference to high-level policy*/
 	int			len;
 	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
 };
 
+struct ipcm_cookie;
+extern int ip_cmsg_send_ipsec(struct cmsghdr *cmsg, struct ipcm_cookie *ipc);
+
 static inline struct sec_path *
 secpath_get(struct sec_path *sp)
 {
diff -Naur linux-2.6.23/net/ipv4/af_inet.c linux-2.6.23-saref/net/ipv4/af_inet.c
--- linux-2.6.23/net/ipv4/af_inet.c	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/net/ipv4/af_inet.c	2009-11-18 16:19:14.000000000 -0500
@@ -1424,6 +1424,18 @@
 #if defined(CONFIG_IP_MROUTE)
 	ip_mr_init();
 #endif
+
+#if defined(CONFIG_KLIPS)
+	{
+               extern int ipsec_klips_init(void);
+		/*
+		 *  Initialise AF_INET ESP and AH protocol support including 
+		 *  e-routing and SA tables
+		 */
+		ipsec_klips_init();
+	}
+#endif /* CONFIG_IPSEC */
+
 	/*
 	 *	Initialise per-cpu ipv4 mibs
 	 */
diff -Naur linux-2.6.23/net/ipv4/icmp.c linux-2.6.23-saref/net/ipv4/icmp.c
--- linux-2.6.23/net/ipv4/icmp.c	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/net/ipv4/icmp.c	2009-11-18 19:04:35.000000000 -0500
@@ -383,6 +383,8 @@
 	struct rtable *rt = (struct rtable *)skb->dst;
 	__be32 daddr;
 
+	memset(&ipc, 0, sizeof(ipc));
+
 	if (ip_options_echo(&icmp_param->replyopts, skb))
 		return;
 
@@ -440,6 +442,8 @@
 	__be32 saddr;
 	u8  tos;
 
+	memset(&ipc, 0, sizeof(ipc));
+
 	if (!rt)
 		goto out;
 
diff -Naur linux-2.6.23/net/ipv4/ip_output.c linux-2.6.23-saref/net/ipv4/ip_output.c
--- linux-2.6.23/net/ipv4/ip_output.c	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/net/ipv4/ip_output.c	2009-11-18 19:06:47.000000000 -0500
@@ -74,6 +74,7 @@
 #include <net/arp.h>
 #include <net/icmp.h>
 #include <net/checksum.h>
+#include <net/xfrm.h>
 #include <net/inetpeer.h>
 #include <linux/igmp.h>
 #include <linux/netfilter_ipv4.h>
@@ -394,6 +395,8 @@
 	/* Copy the flags to each fragment. */
 	IPCB(to)->flags = IPCB(from)->flags;
 
+	to->sp = secpath_get(from->sp);
+
 #ifdef CONFIG_NET_SCHED
 	to->tc_index = from->tc_index;
 #endif
@@ -930,6 +933,7 @@
 			 */
 			skb->ip_summed = csummode;
 			skb->csum = 0;
+			skb->sp = secpath_get(ipc->sp);
 			skb_reserve(skb, hh_len);
 
 			/*
@@ -1341,6 +1345,8 @@
 	__be32 daddr;
 	struct rtable *rt = (struct rtable*)skb->dst;
 
+	memset(&ipc, 0, sizeof(ipc));
+
 	if (ip_options_echo(&replyopts.opt, skb))
 		return;
 
diff -Naur linux-2.6.23/net/ipv4/ip_sockglue.c linux-2.6.23-saref/net/ipv4/ip_sockglue.c
--- linux-2.6.23/net/ipv4/ip_sockglue.c	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/net/ipv4/ip_sockglue.c	2009-11-18 23:03:09.000000000 -0500
@@ -49,6 +49,7 @@
 #define IP_CMSG_RECVOPTS	8
 #define IP_CMSG_RETOPTS		16
 #define IP_CMSG_PASSSEC		32
+#define IP_CMSG_IPSEC_REFINFO   64
 
 /*
  *	SOL_IP control messages.
@@ -130,6 +131,7 @@
 
 void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
 {
+	extern void ip_cmsg_recv_ipsec(struct msghdr *msg, struct sk_buff *skb);
 	struct inet_sock *inet = inet_sk(skb->sk);
 	unsigned flags = inet->cmsg_flags;
 
@@ -161,6 +163,13 @@
 
 	if (flags & 1)
 		ip_cmsg_recv_security(msg, skb);
+       if ((flags>>=1) == 0)
+               return;
+
+       /* IP_CMSG_IPSEC_REFINFO */
+       if (flags & 1)
+               ip_cmsg_recv_ipsec(msg, skb);
+
 }
 
 int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc)
@@ -190,6 +199,14 @@
 			ipc->addr = info->ipi_spec_dst.s_addr;
 			break;
 		}
+               case IP_IPSEC_REFINFO:
+               {
+                       err = ip_cmsg_send_ipsec(cmsg, ipc);
+                       if(err)
+                               return err;
+
+                       break;
+               }
 		default:
 			return -EINVAL;
 		}
@@ -415,6 +432,7 @@
 	int val=0,err;
 
 	if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
+			     (1<<IP_IPSEC_REFINFO) |
 			     (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
 			     (1<<IP_RETOPTS) | (1<<IP_TOS) |
 			     (1<<IP_TTL) | (1<<IP_HDRINCL) |
@@ -505,6 +523,13 @@
 		else
 			inet->cmsg_flags &= ~IP_CMSG_RETOPTS;
 		break;
+	case IP_IPSEC_REFINFO:
+		if (val)
+			inet->cmsg_flags |= IP_CMSG_IPSEC_REFINFO;
+		else
+			inet->cmsg_flags &= ~IP_CMSG_IPSEC_REFINFO;
+		break;
+
 	case IP_PASSSEC:
 		if (val)
 			inet->cmsg_flags |= IP_CMSG_PASSSEC;
@@ -909,7 +934,8 @@
 #ifdef CONFIG_NETFILTER
 	/* we need to exclude all possible ENOPROTOOPTs except default case */
 	if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
-		optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY
+		optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY &&
+		optname != IP_IPSEC_REFINFO
 #ifdef CONFIG_IP_MROUTE
 		&& (optname < MRT_BASE || optname > (MRT_BASE + 10))
 #endif
@@ -935,7 +961,8 @@
 #ifdef CONFIG_NETFILTER
 	/* we need to exclude all possible ENOPROTOOPTs except default case */
 	if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
-	    optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY
+	    optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY &&
+		optname != IP_IPSEC_REFINFO
 #ifdef CONFIG_IP_MROUTE
 	    && (optname < MRT_BASE || optname > (MRT_BASE + 10))
 #endif
@@ -1019,6 +1046,9 @@
 	case IP_RETOPTS:
 		val = (inet->cmsg_flags & IP_CMSG_RETOPTS) != 0;
 		break;
+	case IP_IPSEC_REFINFO:
+		val = (inet->cmsg_flags & IP_CMSG_IPSEC_REFINFO) != 0;
+		break;
 	case IP_PASSSEC:
 		val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
 		break;
@@ -1225,6 +1255,7 @@
 #endif
 
 EXPORT_SYMBOL(ip_cmsg_recv);
+EXPORT_SYMBOL(ip_cmsg_send);
 
 EXPORT_SYMBOL(ip_getsockopt);
 EXPORT_SYMBOL(ip_setsockopt);
diff -Naur linux-2.6.23/net/ipv4/raw.c linux-2.6.23-saref/net/ipv4/raw.c
--- linux-2.6.23/net/ipv4/raw.c	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/net/ipv4/raw.c	2009-11-18 16:20:15.000000000 -0500
@@ -390,6 +390,8 @@
 	u8  tos;
 	int err;
 
+	memset(&ipc, 0, sizeof(ipc));
+
 	err = -EMSGSIZE;
 	if (len > 0xFFFF)
 		goto out;
diff -Naur linux-2.6.23/net/ipv4/udp.c linux-2.6.23-saref/net/ipv4/udp.c
--- linux-2.6.23/net/ipv4/udp.c	2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23-saref/net/ipv4/udp.c	2009-11-18 19:13:41.000000000 -0500
@@ -102,6 +102,7 @@
 #include <net/route.h>
 #include <net/checksum.h>
 #include <net/xfrm.h>
+#include <net/xfrmudp.h>
 #include "udp_impl.h"
 
 /*
@@ -527,6 +528,8 @@
 	int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
 	int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 
+	memset(&ipc, 0, sizeof(ipc));
+
 	if (len > 0xFFFF)
 		return -EMSGSIZE;
 
@@ -695,6 +698,11 @@
 	ip_rt_put(rt);
 	if (free)
 		kfree(ipc.opt);
+	if(ipc.sp) {
+		secpath_put(ipc.sp);
+		ipc.sp=NULL;
+	}
+
 	if (!err)
 		return len;
 	/*
