Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 1593

kernel-2.6.18-128.1.10.el5.src.rpm

From: Eric Paris <eparis@redhat.com>
Subject: [RHEL 5.1 PATCH] BZ 225328 Always wait for IPSEC SA resolution in socket contexts.
Date: Wed, 28 Mar 2007 15:04:51 -0400
Bugzilla: 225328
Message-Id: <1175108691.16700.12.camel@localhost.localdomain>
Changelog: [net] wait for IPSEC SA resolution in socket contexts.


BZ 225328

The first packet sent for which an ipsec SA needed to be negotiated is
being dropped and -EAGAIN is being returned to the application.  This
causes problems for many applications which don't expect that error
code.  With the usage of labeled IPSec where every single network
connection is going to have an IPSec SA this becomes many packets
dropped for a machine and every application needs to be able to
handle/retry.  Thanks to David Miller the upstream solution was to just
block until the SA was ready even for non-blocking sockets in some
cases.

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=8eb9086f21c73b38b5ca27558db4c91d62d0e70b

Testing in the LSPP for quite some time has shown little trouble.  It is
noted in the BZ that this patch brought to the front issues where
multiple SAs were being created instead of just one.  These are not a
large issue and will mainly be just a memory hog until they time out.
However, further patches will be coming to solve these problems (aka
that's a different problem and so a different BZ(s))

-Eric

--- linux-2.6.18.i686/net/ipv6/datagram.c.pre.225328	2007-02-15 17:30:38.000000000 -0500
+++ linux-2.6.18.i686/net/ipv6/datagram.c	2007-02-16 13:39:47.000000000 -0500
@@ -178,7 +178,7 @@ ipv4_connected:
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+	if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
 		goto out;
 
 	/* source address lookup done in ip6_dst_lookup */
--- linux-2.6.18.i686/net/ipv6/tcp_ipv6.c.pre.225328	2007-02-15 17:30:38.000000000 -0500
+++ linux-2.6.18.i686/net/ipv6/tcp_ipv6.c	2007-02-16 13:39:47.000000000 -0500
@@ -259,7 +259,7 @@ static int tcp_v6_connect(struct sock *s
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+	if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
 		goto failure;
 
 	if (saddr == NULL) {
--- linux-2.6.18.i686/net/ipv6/raw.c.pre.225328	2007-02-15 17:30:34.000000000 -0500
+++ linux-2.6.18.i686/net/ipv6/raw.c	2007-02-16 13:39:47.000000000 -0500
@@ -767,7 +767,7 @@ static int rawv6_sendmsg(struct kiocb *i
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+	if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
 		goto out;
 
 	if (hlimit < 0) {
--- linux-2.6.18.i686/net/ipv6/udp.c.pre.225328	2007-02-15 17:30:42.000000000 -0500
+++ linux-2.6.18.i686/net/ipv6/udp.c	2007-02-16 13:43:51.000000000 -0500
@@ -790,7 +790,7 @@ do_udp_sendmsg:
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+	if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
 		goto out;
 
 	if (hlimit < 0) {
--- linux-2.6.18.i686/net/ipv4/tcp_ipv4.c.pre.225328	2007-02-15 17:30:34.000000000 -0500
+++ linux-2.6.18.i686/net/ipv4/tcp_ipv4.c	2007-02-16 13:39:47.000000000 -0500
@@ -179,7 +179,7 @@ int tcp_v4_connect(struct sock *sk, stru
 	tmp = ip_route_connect(&rt, nexthop, inet->saddr,
 			       RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
 			       IPPROTO_TCP,
-			       inet->sport, usin->sin_port, sk);
+			       inet->sport, usin->sin_port, sk, 1);
 	if (tmp < 0)
 		return tmp;
 
--- linux-2.6.18.i686/net/ipv4/datagram.c.pre.225328	2006-09-19 23:42:06.000000000 -0400
+++ linux-2.6.18.i686/net/ipv4/datagram.c	2007-02-16 13:39:47.000000000 -0500
@@ -49,7 +49,7 @@ int ip4_datagram_connect(struct sock *sk
 	err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr,
 			       RT_CONN_FLAGS(sk), oif,
 			       sk->sk_protocol,
-			       inet->sport, usin->sin_port, sk);
+			       inet->sport, usin->sin_port, sk, 1);
 	if (err)
 		return err;
 	if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) {
--- linux-2.6.18.i686/net/ipv4/af_inet.c.pre.225328	2007-02-15 17:30:46.000000000 -0500
+++ linux-2.6.18.i686/net/ipv4/af_inet.c	2007-02-16 13:39:47.000000000 -0500
@@ -1006,7 +1006,7 @@ static int inet_sk_reselect_saddr(struct
 			       RT_CONN_FLAGS(sk),
 			       sk->sk_bound_dev_if,
 			       sk->sk_protocol,
-			       inet->sport, inet->dport, sk);
+			       inet->sport, inet->dport, sk, 0);
 	if (err)
 		return err;
 
--- linux-2.6.18.i686/net/ipv4/raw.c.pre.225328	2007-02-15 17:30:34.000000000 -0500
+++ linux-2.6.18.i686/net/ipv4/raw.c	2007-02-16 13:39:47.000000000 -0500
@@ -484,7 +484,7 @@ static int raw_sendmsg(struct kiocb *ioc
 			raw_probe_proto_opt(&fl, msg);
 
 		security_sk_classify_flow(sk, &fl);
-		err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
+		err = ip_route_output_flow(&rt, &fl, sk, 1);
 	}
 	if (err)
 		goto done;
--- linux-2.6.18.i686/net/ipv4/udp.c.pre.225328	2007-02-15 17:30:34.000000000 -0500
+++ linux-2.6.18.i686/net/ipv4/udp.c	2007-02-16 13:39:47.000000000 -0500
@@ -604,7 +604,7 @@ int udp_sendmsg(struct kiocb *iocb, stru
 					       { .sport = inet->sport,
 						 .dport = dport } } };
 		security_sk_classify_flow(sk, &fl);
-		err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
+		err = ip_route_output_flow(&rt, &fl, sk, 1);
 		if (err)
 			goto out;
 
--- linux-2.6.18.i686/net/dccp/ipv4.c.pre.225328	2007-02-15 17:30:34.000000000 -0500
+++ linux-2.6.18.i686/net/dccp/ipv4.c	2007-02-16 13:39:47.000000000 -0500
@@ -75,7 +75,7 @@ int dccp_v4_connect(struct sock *sk, str
 	tmp = ip_route_connect(&rt, nexthop, inet->saddr,
 			       RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
 			       IPPROTO_DCCP,
-			       inet->sport, usin->sin_port, sk);
+			       inet->sport, usin->sin_port, sk, 1);
 	if (tmp < 0)
 		return tmp;
 
--- linux-2.6.18.i686/net/dccp/ipv6.c.pre.225328	2007-02-15 17:30:38.000000000 -0500
+++ linux-2.6.18.i686/net/dccp/ipv6.c	2007-02-16 13:39:47.000000000 -0500
@@ -218,7 +218,7 @@ static int dccp_v6_connect(struct sock *
 	if (final_p)
 		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	err = xfrm_lookup(&dst, &fl, sk, 0);
+	err = xfrm_lookup(&dst, &fl, sk, 1);
 	if (err < 0)
 		goto failure;
 
--- linux-2.6.18.i686/include/net/route.h.pre.225328	2007-02-15 17:30:33.000000000 -0500
+++ linux-2.6.18.i686/include/net/route.h	2007-02-16 13:41:37.000000000 -0500
@@ -146,7 +146,8 @@ static inline char rt_tos2priority(u8 to
 
 static inline int ip_route_connect(struct rtable **rp, u32 dst,
 				   u32 src, u32 tos, int oif, u8 protocol,
-				   u16 sport, u16 dport, struct sock *sk)
+				   u16 sport, u16 dport, struct sock *sk,
+				   int flags)
 {
 	struct flowi fl = { .oif = oif,
 			    .nl_u = { .ip4_u = { .daddr = dst,
@@ -168,7 +169,7 @@ static inline int ip_route_connect(struc
 		*rp = NULL;
 	}
 	security_sk_classify_flow(sk, &fl);
-	return ip_route_output_flow(rp, &fl, sk, 0);
+	return ip_route_output_flow(rp, &fl, sk, flags);
 }
 
 static inline int ip_route_newports(struct rtable **rp, u8 protocol,