diff -ru a/include/linux/in.h b/include/linux/in.h
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -77,6 +77,7 @@
 #define IP_PASSSEC	18
 #define IP_TRANSPARENT	19
 #define IP_IPSEC_REFINFO 30 /* used with CONFIG_INET_IPSEC_SAREF */
+#define IP_IPSEC_BINDREF 31
 
 /* BSD compatibility */
 #define IP_RECVRETOPTS	IP_RETOPTS
diff -ru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -369,6 +369,7 @@
 #endif
 	__u32			sk_mark;
 	u32			sk_classid;
+    __u32           sk_saref;
 	struct cg_proto		*sk_cgrp;
 	void			(*sk_state_change)(struct sock *sk);
 	void			(*sk_data_ready)(struct sock *sk, int bytes);
diff -ru a/include/net/xfrm.h b/include/net/xfrm.h
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1015,6 +1015,21 @@
 
 extern struct sec_path *secpath_dup(struct sec_path *src);
 
+/*
+ * Attach IPsec SAref value to skb, if appropriate.
+ */
+static inline void skb_sec_assign_sk_saref(struct sk_buff *skb, struct sock *sk)
+{
+#if defined(CONFIG_XFRM)
+    if (sk->sk_saref) {
+        if (!skb->sp)
+            skb->sp = secpath_dup(NULL);
+        if (skb->sp)
+            skb->sp->ref = sk->sk_saref;
+    }
+#endif
+}
+
 static inline void
 secpath_reset(struct sk_buff *skb)
 {
diff -ru a/net/core/sock.c b/net/core/sock.c
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1627,6 +1627,9 @@
 			if (skb) {
 				int i;
 
+                /* associate the skb with the socket's SAref */
+                skb_sec_assign_sk_saref(skb, sk);
+
 				/* No pages, we're done... */
 				if (!data_len)
 					break;
diff -ru a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -556,6 +556,7 @@
 	case IP_RECVORIGDSTADDR:
 #ifdef CONFIG_INET_IPSEC_SAREF
     case IP_IPSEC_REFINFO:
+    case IP_IPSEC_BINDREF:
 #endif
 		if (optlen >= sizeof(int)) {
 			if (get_user(val, (int __user *) optval))
@@ -662,6 +661,9 @@
         else
             inet->cmsg_flags &= ~IP_CMSG_IPSEC_REFINFO;
         break;
+    case IP_IPSEC_BINDREF:
+        sk->sk_saref = val;
+        break;
 #endif
 	case IP_TOS:	/* This sets both TOS and Precedence */
 		if (sk->sk_type == SOCK_STREAM) {
@@ -1149,6 +1145,7 @@
 			optname != IP_XFRM_POLICY &&
 #ifdef CONFIG_INET_IPSEC_SAREF
             optname != IP_IPSEC_REFINFO &&
+            optname != IP_IPSEC_BINDREF &&
 #endif
 			!ip_mroute_opt(optname)) {
 		lock_sock(sk);
@@ -1182,6 +1177,7 @@
 			optname != IP_XFRM_POLICY &&
 #ifdef CONFIG_INET_IPSEC_SAREF
             optname != IP_IPSEC_REFINFO &&
+            optname != IP_IPSEC_BINDREF &&
 #endif
 			!ip_mroute_opt(optname)) {
 		lock_sock(sk);
@@ -1271,6 +1265,9 @@
 	case IP_IPSEC_REFINFO:
 		val = (inet->cmsg_flags & IP_CMSG_IPSEC_REFINFO) != 0;
 		break;
+    case IP_IPSEC_BINDREF:
+        val = sk->sk_saref;
+        break;
 #endif
 	case IP_RECVORIGDSTADDR:
 		val = (inet->cmsg_flags & IP_CMSG_ORIGDSTADDR) != 0;
diff -ru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -699,6 +699,9 @@
 	skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
 	if (skb) {
 		if (sk_wmem_schedule(sk, skb->truesize)) {
+            /* associate the skb with the socket's SAref */
+            skb_sec_assign_sk_saref(skb, sk);
+
 			skb_reserve(skb, sk->sk_prot->max_header);
 			/*
 			 * Make sure that we have exactly size bytes
diff -ru a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -35,6 +35,7 @@
  */
 
 #include <net/tcp.h>
+#include <net/xfrm.h>
 
 #include <linux/compiler.h>
 #include <linux/gfp.h>
@@ -824,6 +823,9 @@
 			return -ENOBUFS;
 	}
 
+    /* associate the skb with the socket's SAref */
+    skb_sec_assign_sk_saref(skb, sk);
+
 	inet = inet_sk(sk);
 	tp = tcp_sk(sk);
 	tcb = TCP_SKB_CB(skb);
@@ -2648,6 +2644,9 @@
 	if (unlikely(buff == NULL))
 		return -ENOBUFS;
 
+    /* associate the skb with the socket's SAref */
+    skb_sec_assign_sk_saref(buff, sk);
+
 	/* Reserve space for headers. */
 	skb_reserve(buff, MAX_TCP_HEADER);
 
