netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup
@ 2004-07-30  8:12 Kazunori Miyazawa
  2004-08-02  2:51 ` David S. Miller
  2004-08-02  7:41 ` [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Herbert Xu
  0 siblings, 2 replies; 19+ messages in thread
From: Kazunori Miyazawa @ 2004-07-30  8:12 UTC (permalink / raw)
  To: davem, herbert; +Cc: netdev, usagi-core, kazunori

Hello,

This patch separates xfrm_lookup from ip6_dst_lookup
to support srcrt correctly. ip6_dst_lookup should be
called with next hop. however xfrm_lookup should be
called with final destination. It fixes them.

This patch makes AH support routing header with
previous Mr Hervert's patch. Of course this fixes ESP and IPcomp.

I consider copying flowi(fl_rt) uses too much stack at the moment.
I'll re-send the fixed patch again.

Thank you,

--Kazunori Miyazawa


diff -ruNBE a/net/ipv6/datagram.c b/net/ipv6/datagram.c
--- a/net/ipv6/datagram.c	2004-07-28 10:07:16.000000000 +0900
+++ b/net/ipv6/datagram.c	2004-07-28 10:29:13.000000000 +0900
@@ -40,7 +40,7 @@
 	struct ipv6_pinfo      	*np = inet6_sk(sk);
 	struct in6_addr		*daddr;
 	struct dst_entry	*dst;
-	struct flowi		fl;
+	struct flowi		fl, fl_rt, *flp = &fl;
 	struct ip6_flowlabel	*flowlabel = NULL;
 	int			addr_type;
 	int			err;
@@ -157,17 +157,27 @@
 	if (flowlabel) {
 		if (flowlabel->opt && flowlabel->opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
-			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			memcpy(&fl_rt, &fl, sizeof(fl_rt));
+			ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+			flp = &fl_rt;
 		}
 	} else if (np->opt && np->opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
-		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		memcpy(&fl_rt, &fl, sizeof(fl_rt));
+		ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+		flp = &fl_rt;
 	}
 
-	err = ip6_dst_lookup(sk, &dst, &fl);
+	err = ip6_dst_lookup(sk, &dst, flp);
 	if (err)
 		goto out;
 
+	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+		dst_release(dst);
+		dst = NULL;
+		goto out;
+	}
+
 	/* source address lookup done in ip6_dst_lookup */
 
 	if (ipv6_addr_any(&np->saddr))
diff -ruNBE a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
--- a/net/ipv6/ip6_output.c	2004-07-28 10:07:09.000000000 +0900
+++ b/net/ipv6/ip6_output.c	2004-07-28 10:29:20.000000000 +0900
@@ -796,10 +796,6 @@
 			goto out_err_release;
 		}
 	}
-	if ((err = xfrm_lookup(dst, fl, sk, 0)) < 0) {
-		err = -ENETUNREACH;
-		goto out_err_release;
-        }
 
 	return 0;
 
diff -ruNBE a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c	2004-07-28 10:08:26.000000000 +0900
+++ b/net/ipv6/raw.c	2004-07-28 10:30:22.000000000 +0900
@@ -567,7 +567,7 @@
 	struct ipv6_txoptions *opt = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
 	struct dst_entry *dst = NULL;
-	struct flowi fl;
+	struct flowi fl, fl_rt, *flp = &fl;
 	int addr_len = msg->msg_namelen;
 	int hlimit = -1;
 	u16 proto;
@@ -674,6 +674,7 @@
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 
 	fl.proto = proto;
+ 
 	ipv6_addr_copy(&fl.fl6_dst, daddr);
 	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
 		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
@@ -681,16 +682,24 @@
 	/* merge ip6_build_xmit from ip6_output */
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		memcpy(&fl_rt, &fl, sizeof(fl_rt));
+		ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+		flp = &fl_rt;
 	}
 
 	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
 		fl.oif = np->mcast_oif;
 
-	err = ip6_dst_lookup(sk, &dst, &fl);
+	err = ip6_dst_lookup(sk, &dst, flp);
 	if (err)
 		goto out;
 
+	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+		dst_release(dst);
+		dst = NULL;
+		goto out;
+	}
+
 	if (hlimit < 0) {
 		if (ipv6_addr_is_multicast(&fl.fl6_dst))
 			hlimit = np->mcast_hops;
diff -ruNBE a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	2004-07-28 10:09:10.000000000 +0900
+++ b/net/ipv6/tcp_ipv6.c	2004-07-28 10:29:37.000000000 +0900
@@ -550,7 +550,7 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct tcp_opt *tp = tcp_sk(sk);
 	struct in6_addr *saddr = NULL;
-	struct flowi fl;
+	struct flowi fl, fl_rt, *flp = &fl;
 	struct dst_entry *dst;
 	int addr_type;
 	int err;
@@ -666,14 +666,21 @@
 
 	if (np->opt && np->opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
-		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		memcpy(&fl_rt, &fl, sizeof(fl_rt));
+		ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+		flp = &fl_rt;
 	}
 
-	err = ip6_dst_lookup(sk, &dst, &fl);
-
+	err = ip6_dst_lookup(sk, &dst, flp);
 	if (err)
 		goto failure;
 
+	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+		dst_release(dst);
+		dst = NULL;
+		goto failure;
+	}
+
 	if (saddr == NULL) {
 		saddr = &fl.fl6_src;
 		ipv6_addr_copy(&np->rcv_saddr, saddr);
@@ -793,6 +800,14 @@
 				sk->sk_err_soft = -err;
 				goto out;
 			}
+
+			if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+				sk->sk_err_soft = -err;
+				dst_release(dst);
+				dst = NULL;
+				goto out;
+			}
+
 		} else
 			dst_hold(dst);
 
@@ -863,7 +878,7 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff * skb;
 	struct ipv6_txoptions *opt = NULL;
-	struct flowi fl;
+	struct flowi fl, fl_rt, *flp = &fl;
 	int err = -1;
 
 	memset(&fl, 0, sizeof(fl));
@@ -888,12 +903,22 @@
 
 		if (opt && opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			memcpy(&fl_rt, &fl, sizeof(fl_rt));
+			ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+			flp = &fl_rt;
 		}
 
-		err = ip6_dst_lookup(sk, &dst, &fl);
+		err = ip6_dst_lookup(sk, &dst, flp);
 		if (err)
 			goto done;
+
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			dst_release(dst);
+			dst = NULL;
+			goto done;
+		}
+
+
 	}
 
 	skb = tcp_make_synack(sk, dst, req);
@@ -1021,6 +1046,12 @@
 
 	/* sk = NULL, but it is safe for now. RST socket required. */
 	if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
+
+		if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
+			dst_release(buff->dst);
+			return;
+		}
+
 		ip6_xmit(NULL, buff, &fl, NULL, 0);
 		TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
 		TCP_INC_STATS_BH(TCP_MIB_OUTRSTS);
@@ -1082,6 +1113,12 @@
 	fl.fl_ip_sport = t1->source;
 
 	if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
+
+		if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
+			dst_release(buff->dst);
+			return;
+		}
+
 		ip6_xmit(NULL, buff, &fl, NULL, 0);
 		TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
 		return;
@@ -1313,22 +1350,31 @@
 	}
 
 	if (dst == NULL) {
-		struct flowi fl;
+		struct flowi fl, fl_rt, *flp = &fl;
 
 		memset(&fl, 0, sizeof(fl));
 		fl.proto = IPPROTO_TCP;
 		ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
 		if (opt && opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			memcpy(&fl_rt, &fl, sizeof(fl_rt));
+			ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+			flp = &fl_rt;
 		}
 		ipv6_addr_copy(&fl.fl6_src, &req->af.v6_req.loc_addr);
 		fl.oif = sk->sk_bound_dev_if;
 		fl.fl_ip_dport = req->rmt_port;
 		fl.fl_ip_sport = inet_sk(sk)->sport;
 
-		if (ip6_dst_lookup(sk, &dst, &fl))
+		if (ip6_dst_lookup(sk, &dst, flp))
 			goto out;
+
+		if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			dst_release(dst);
+			dst = NULL;
+			goto out;
+		}
+
 	} 
 
 	newsk = tcp_create_openreq_child(sk, req, skb);
@@ -1710,7 +1756,7 @@
 
 	if (dst == NULL) {
 		struct inet_opt *inet = inet_sk(sk);
-		struct flowi fl;
+		struct flowi fl, fl_rt, *flp = &fl;
 
 		memset(&fl, 0, sizeof(fl));
 		fl.proto = IPPROTO_TCP;
@@ -1723,16 +1769,25 @@
 
 		if (np->opt && np->opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			memcpy(&fl_rt, &fl, sizeof(fl_rt));
+			ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+			flp = &fl_rt;
 		}
 
-		err = ip6_dst_lookup(sk, &dst, &fl);
+		err = ip6_dst_lookup(sk, &dst, flp);
 
 		if (err) {
 			sk->sk_route_caps = 0;
 			return err;
 		}
 
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			sk->sk_route_caps = 0;
+			dst_release(dst);
+			return err;
+		}
+
+
 		ip6_dst_store(sk, dst, NULL);
 		sk->sk_route_caps = dst->dev->features &
 			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
@@ -1747,7 +1802,7 @@
 	struct sock *sk = skb->sk;
 	struct inet_opt *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct flowi fl;
+	struct flowi fl, fl_rt, *flp = &fl;
 	struct dst_entry *dst;
 
 	memset(&fl, 0, sizeof(fl));
@@ -1762,19 +1817,27 @@
 
 	if (np->opt && np->opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		memcpy(&fl_rt, &fl, sizeof(fl_rt));
+		ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+		flp = &fl_rt;
 	}
 
 	dst = __sk_dst_check(sk, np->dst_cookie);
 
 	if (dst == NULL) {
-		int err = ip6_dst_lookup(sk, &dst, &fl);
+		int err = ip6_dst_lookup(sk, &dst, flp);
 
 		if (err) {
 			sk->sk_err_soft = -err;
 			return err;
 		}
 
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			sk->sk_err_soft = -err;
+			dst_release(dst);
+			return err;
+		}
+
 		ip6_dst_store(sk, dst, NULL);
 		sk->sk_route_caps = dst->dev->features &
 			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
diff -ruNBE a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	2004-07-28 10:10:23.000000000 +0900
+++ b/net/ipv6/udp.c	2004-07-28 10:29:41.000000000 +0900
@@ -630,13 +630,13 @@
 	struct in6_addr *daddr;
 	struct ipv6_txoptions *opt = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
-	struct flowi *fl = &inet->cork.fl;
-	struct dst_entry *dst;
+	struct flowi *fl = &inet->cork.fl, fl_rt, *flp = fl;
+	struct dst_entry *dst = NULL;
 	int addr_len = msg->msg_namelen;
 	int ulen = len;
 	int hlimit = -1;
 	int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
-	int err;
+	int err = 0;
 
 	/* destination address check */
 	if (sin6) {
@@ -779,20 +779,28 @@
 	if (ipv6_addr_any(&fl->fl6_src) && !ipv6_addr_any(&np->saddr))
 		ipv6_addr_copy(&fl->fl6_src, &np->saddr);
 	fl->fl_ip_sport = inet->sport;
-	
+
 	/* merge ip6_build_xmit from ip6_output */
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
+		memcpy(&fl_rt, &fl, sizeof(fl_rt));
+		ipv6_addr_copy(&fl_rt.fl6_dst, rt0->addr);
+		flp = &fl_rt;
 	}
 
 	if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst))
 		fl->oif = np->mcast_oif;
 
-	err = ip6_dst_lookup(sk, &dst, fl);
+	err = ip6_dst_lookup(sk, &dst, flp);
 	if (err)
 		goto out;
 
+	if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) {
+		dst_release(dst);
+		dst = NULL;
+		goto out;
+	}
+
 	if (hlimit < 0) {
 		if (ipv6_addr_is_multicast(&fl->fl6_dst))
 			hlimit = np->mcast_hops;

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2004-10-27 15:21 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-30  8:12 [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Kazunori Miyazawa
2004-08-02  2:51 ` David S. Miller
2004-08-03  9:00   ` YOSHIFUJI Hideaki / 吉藤英明
2004-08-03  9:21     ` Kazunori Miyazawa
2004-08-09 23:35     ` David S. Miller
2004-08-10  1:38       ` YOSHIFUJI Hideaki / 吉藤英明
2004-08-27 16:49   ` [PATCH, TAKE 2] [IPV6] XFRM: extract xfrm_lookup() from ip6_dst_lookup() (is Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup) YOSHIFUJI Hideaki / 吉藤英明
2004-08-28  0:02     ` David S. Miller
2004-10-25 21:27     ` Brian Haley
2004-10-26  3:55       ` YOSHIFUJI Hideaki / 吉藤英明
2004-10-26 14:29         ` Brian Haley
2004-10-26 15:43           ` YOSHIFUJI Hideaki / 吉藤英明
2004-10-26 18:09             ` Brian Haley
2004-10-27  0:10               ` YOSHIFUJI Hideaki / 吉藤英明
2004-10-27 15:21                 ` Brian Haley
2004-08-02  7:41 ` [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Herbert Xu
2004-08-03  2:09   ` David S. Miller
2004-08-03  8:19     ` YOSHIFUJI Hideaki / 吉藤英明
2004-08-03 10:55     ` Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).