Re: [PATCH] source ip selection for ipv6

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Did anyone have a look at this / will it be included soon?

Nico

Bastian Blank [Fri, Apr 16, 2004 at 10:33:28PM +0200]:
> Hi folks
> 
> The attached patch implements source ip selection in routes for ipv6.
> 
> There a some issues left, which I can't solve:
> - the route add code for ipv4 includes a check for loopback ips or so, I
>   don't understand them and therefor can't convert it for ipv6.
> - there is no check if the ip is local.
> 
> Bastian
> 
> Please cc.
> 
> -- 
> Captain's Log, star date 21:34.5...

> diff -ur linux-2.6.5.orig/include/linux/ipv6_route.h linux-2.6.5/include/linux/ipv6_route.h
> --- linux-2.6.5.orig/include/linux/ipv6_route.h	2004-03-11 03:55:23.000000000 +0100
> +++ linux-2.6.5/include/linux/ipv6_route.h	2004-04-16 19:17:26.000000000 +0200
> @@ -30,6 +30,7 @@
>  struct in6_rtmsg {
>  	struct in6_addr		rtmsg_dst;
>  	struct in6_addr		rtmsg_src;
> +	struct in6_addr		rtmsg_prefsrc;
>  	struct in6_addr		rtmsg_gateway;
>  	__u32			rtmsg_type;
>  	__u16			rtmsg_dst_len;
> diff -ur linux-2.6.5.orig/include/net/ip6_fib.h linux-2.6.5/include/net/ip6_fib.h
> --- linux-2.6.5.orig/include/net/ip6_fib.h	2004-03-11 03:55:37.000000000 +0100
> +++ linux-2.6.5/include/net/ip6_fib.h	2004-04-16 19:53:08.000000000 +0200
> @@ -71,6 +71,7 @@
>  
>  	struct rt6key			rt6i_dst;
>  	struct rt6key			rt6i_src;
> +	struct rt6key			rt6i_prefsrc;
>  
>  	u8				rt6i_protocol;
>  };
> diff -ur linux-2.6.5.orig/net/ipv6/ip6_output.c linux-2.6.5/net/ipv6/ip6_output.c
> --- linux-2.6.5.orig/net/ipv6/ip6_output.c	2004-04-16 22:25:17.000000000 +0200
> +++ linux-2.6.5/net/ipv6/ip6_output.c	2004-04-16 21:04:04.000000000 +0200
> @@ -768,8 +768,13 @@
>  	if ((err = (*dst)->error))
>  		goto out_err_release;
>  
>  	if (ipv6_addr_any(&fl->fl6_src)) {
> -		err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
> +		struct rt6_info *rt = (struct rt6_info*)*dst;
> +		/* XXX needs to check */
> +		if (rt->rt6i_prefsrc.plen)
> +			ipv6_addr_copy(&fl->fl6_src, &rt->rt6i_prefsrc.addr);
> +		else
> +			err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
>  
>  		if (err) {
>  #if IP6_DEBUG >= 2
> diff -ur linux-2.6.5.orig/net/ipv6/route.c linux-2.6.5/net/ipv6/route.c
> --- linux-2.6.5.orig/net/ipv6/route.c	2004-03-11 03:55:37.000000000 +0100
> +++ linux-2.6.5/net/ipv6/route.c	2004-04-16 21:40:42.000000000 +0200
> @@ -702,7 +708,7 @@
>  	struct rtattr **rta;
>  	struct rt6_info *rt;
>  	struct net_device *dev = NULL;
> -	int addr_type;
> +	int addr_type, i, j;
>  
>  	rta = (struct rtattr **) _rtattr;
>  
> @@ -758,6 +764,17 @@
>  
>  	rt->rt6i_metric = rtmsg->rtmsg_metric;
>  
> +	/* XXX is there another way to compare ipv6 addresses? */
> +	for (i = 0, j = 0; i < 4; i++)
> +		if (rtmsg->rtmsg_prefsrc.s6_addr32[i] != in6addr_any.s6_addr32[i])
> +			j = 1;
> +	if (j) {
> +		memcpy(&rt->rt6i_prefsrc.addr, &rtmsg->rtmsg_prefsrc, 16);
> +		rt->rt6i_prefsrc.plen = 128;
> +	}
> +	else
> +		rt->rt6i_prefsrc.plen = 0;
> +
>  	/* We cannot add true routes via loopback here,
>  	   they would result in kernel looping; promote them to reject routes
>  	 */
> @@ -837,6 +854,16 @@
>  
>  	rt->rt6i_flags = rtmsg->rtmsg_flags;
>  
> +	/* XXX: I don't understand this check */
> +#if 0
> +	if (rt->rt6i_prefsrc) {
> +		if (r->rtm_type != RTN_LOCAL || rta->rta_dst == NULL ||
> +				memcmp(&fi->fib_prefsrc, rta->rta_dst, 4))
> +			if (inet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
> +				goto err_inval;
> +	}
> +#endif
> +
>  install_route:
>  	if (rta && rta[RTA_METRICS-1]) {
>  		int attrlen = RTA_PAYLOAD(rta[RTA_METRICS-1]);
> @@ -1147,6 +1174,7 @@
>  #ifdef CONFIG_IPV6_SUBTREES
>  		memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
>  #endif
> +		memcpy(&rt->rt6i_prefsrc, &ort->rt6i_prefsrc, sizeof(struct rt6key));
>  	}
>  	return rt;
>  }
> @@ -1431,6 +1459,9 @@
>  			return -EINVAL;
>  		memcpy(&rtmsg->rtmsg_metric, RTA_DATA(rta[RTA_PRIORITY-1]), 4);
>  	}
> +	if (rta[RTA_PREFSRC-1]) {
> +		memcpy(&rtmsg->rtmsg_prefsrc, RTA_DATA(rta[RTA_PREFSRC-1]), 16);
> +	}
>  	return 0;
>  }
>  
> @@ -1523,11 +1554,9 @@
>  #endif
>  	if (iif)
>  		RTA_PUT(skb, RTA_IIF, 4, &iif);
> -	else if (dst) {
> -		struct in6_addr saddr_buf;
> -		if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
> -			RTA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
> -	}
> +	if (rt->rt6i_prefsrc.plen)
> +		RTA_PUT(skb, RTA_PREFSRC, 16, &rt->rt6i_prefsrc);
> +
>  	if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
>  		goto rtattr_failure;
>  	if (rt->u.dst.neighbour)




-- 
Keep it simple & stupid, use what's available.
pgp: 8D0E E27A          | Nico Schottelius
http://nerd-hosting.net | http://linux.schottelius.org

Attachment: pgp00167.pgp
Description: PGP signature


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux