Subject: Re: [PATCH, TAKE 2] [IPV6] XFRM: extract xfrm_lookup() from ip6_dst_lookup() (is Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup)

From: Brian Haley <[email-masked]>
Date: Mon, 25 Oct 2004 17:27:44 -0400

YOSHIFUJI Hideaki / 吉藤英明 wrote:

> Here's the updated patch.

<snip>

Hi,

I finally tracked-down the patch that fixed the IPv6 routing header 
problems I'd been seeing :)  But I think you missed one code path from 
the original patch Kazunori posted in tcp_v6_xmit(), which I think is 
only called from the ND code.

Attached is a patch that fixes that and also brings the rt0_hdr struct 
in-line with RFC 3542 by removing the "bitmap" field.

Thanks,

-Brian

--
Brian Haley, HP Linux and Open Source Lab
Signed-off-by: [email-masked]

--- linux-2.6.9.orig/include/linux/ipv6.h	2004-10-18 17:54:39.000000000 -0400
+++ linux-2.6.9.rt0/include/linux/ipv6.h	2004-10-22 17:15:52.000000000 -0400
@@ -68,7 +68,7 @@
 
 struct rt0_hdr {
 	struct ipv6_rt_hdr	rt_hdr;
-	__u32			bitmap;		/* strict/loose bit map */
+	__u32			reserved;
 	struct in6_addr		addr[0];
 
 #define rt0_type		rt_hdr.type
--- linux-2.6.9.orig/net/ipv6/netfilter/ip6t_rt.c	2004-10-22 16:09:32.000000000 -0400
+++ linux-2.6.9.rt0/net/ipv6/netfilter/ip6t_rt.c	2004-10-22 17:14:55.410800617 -0400
@@ -159,8 +159,8 @@
                            ((rtinfo->hdrlen == hdrlen) ^
                            !!(rtinfo->invflags & IP6T_RT_INV_LEN))));
        DEBUGP("res %02X %02X %02X ", 
-       		(rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)route)->bitmap,
-       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->bitmap)));
+       		(rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)route)->reserved,
+       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->reserved)));
 
        ret = (route != NULL)
        		&&
@@ -176,7 +176,7 @@
                            ((rtinfo->rt_type == route->type) ^
                            !!(rtinfo->invflags & IP6T_RT_INV_TYP)))
 		&&
-       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->bitmap));
+       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->reserved));
 
 	DEBUGP("#%d ",rtinfo->addrnr);
        temp = len = ptr = 0;
--- linux-2.6.9.orig/net/ipv6/tcp_ipv6.c	2004-10-18 17:54:32.000000000 -0400
+++ linux-2.6.9.rt0/net/ipv6/tcp_ipv6.c	2004-10-22 17:13:43.386387437 -0400
@@ -1802,6 +1802,7 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct flowi fl;
 	struct dst_entry *dst;
+	struct in6_addr *final_p = NULL, final;
 
 	memset(&fl, 0, sizeof(fl));
 	fl.proto = IPPROTO_TCP;
@@ -1815,7 +1816,9 @@
 
 	if (np->opt && np->opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
+		ipv6_addr_copy(&final, &fl.fl6_dst);
 		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		final_p = &final;
 	}
 
 	dst = __sk_dst_check(sk, np->dst_cookie);
@@ -1828,6 +1831,9 @@
 			return err;
 		}
 
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+
 		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
 			sk->sk_route_caps = 0;
 			dst_release(dst);
--- linux-2.6.9.orig/net/ipv6/exthdrs.c	2004-10-18 17:53:07.000000000 -0400
+++ linux-2.6.9.rt0/net/ipv6/exthdrs.c	2004-10-22 17:14:12.413730831 -0400
@@ -404,8 +404,7 @@
 
 	memcpy(opt->srcrt, hdr, sizeof(*hdr));
 	irthdr = (struct rt0_hdr*)opt->srcrt;
-	/* Obsolete field, MBZ, when originated by us */
-	irthdr->bitmap = 0;
+	irthdr->reserved = 0;
 	opt->srcrt->segments_left = n;
 	for (i=0; i<n; i++)
 		memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);