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