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 #include #include +#include #include #include #include @@ -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<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 #include #include +#include #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; /*