* [BUG] ipv6: all routes share same inetpeer @ 2011-07-19 17:23 Eric Dumazet 2011-07-19 17:37 ` David Miller 0 siblings, 1 reply; 9+ messages in thread From: Eric Dumazet @ 2011-07-19 17:23 UTC (permalink / raw) To: David Miller; +Cc: netdev Hi David While polishing a patch and testing it, I found that all ipv6 routes shared the same inetpeer ! Oh well... Apparently we call rt6_bind_peer() at wrong time, providing NULL addresses. Maybe you can find the bug before me ? With following quick/dirty/debugging patch : diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 39d1230..f24391c 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -88,6 +88,7 @@ static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, ipv6_addr_copy((struct in6_addr *)daddr.addr.a6, v6daddr); daddr.family = AF_INET6; + WARN_ON(daddr.addr.a6[0] == 0 && daddr.addr.a6[1] == 0 && daddr.addr.a6[2] == 0 && daddr.addr.a6[3] == 0); return inet_getpeer(&daddr, create); } I get for example : [ 299.024117] ------------[ cut here ]------------ [ 299.024176] WARNING: at include/net/inetpeer.h:91 rt6_bind_peer+0x84/0xb0() [ 299.024234] Hardware name: ProLiant BL460c G1 [ 299.024287] Modules linked in: xt_hashlimit ipmi_devintf ipmi_si ipmi_msghandler tg3 bonding [ 299.024583] Pid: 7119, comm: ping6 Tainted: G W 3.0.0-rc7-03555-ge798b6e-dirty #1048 [ 299.024657] Call Trace: [ 299.024709] [<c1042b4d>] warn_slowpath_common+0x6d/0xa0 [ 299.024765] [<c1373104>] ? rt6_bind_peer+0x84/0xb0 [ 299.024820] [<c1373104>] ? rt6_bind_peer+0x84/0xb0 [ 299.024875] [<c1042b9d>] warn_slowpath_null+0x1d/0x20 [ 299.024931] [<c1373104>] rt6_bind_peer+0x84/0xb0 [ 299.024985] [<c13731ec>] ipv6_cow_metrics+0xbc/0xe0 [ 299.025046] [<c13722a8>] ip6_rt_copy+0x1e8/0x210 [ 299.025101] [<c1372a70>] rt6_alloc_cow.isra.32+0x10/0x1d0 [ 299.025158] [<c1048fb9>] ? local_bh_enable_ip+0x59/0xc0 [ 299.025213] [<c137356b>] ip6_pol_route.isra.37+0x29b/0x2a0 [ 299.025270] [<c13735a1>] ip6_pol_route_output+0x31/0x40 [ 299.025325] [<c1376277>] fib6_rule_lookup+0x17/0x20 [ 299.025380] [<c137238c>] ip6_route_output+0x5c/0xa0 [ 299.025436] [<c1373570>] ? ip6_pol_route.isra.37+0x2a0/0x2a0 [ 299.025492] [<c1365004>] ip6_dst_lookup_tail+0xd4/0xe0 [ 299.025548] [<c136519f>] ip6_dst_lookup_flow+0x2f/0x90 [ 299.025604] [<c1048fb9>] ? local_bh_enable_ip+0x59/0xc0 [ 299.025660] [<c1390ef4>] ip6_datagram_connect+0x174/0x490 [ 299.025717] [<c12bdd42>] ? release_sock+0xf2/0x150 [ 299.025772] [<c137d9a7>] ? udp_v6_get_port+0x47/0x60 [ 299.025829] [<c132f838>] inet_dgram_connect+0x28/0x70 [ 299.025884] [<c12bc5c0>] sys_connect+0x60/0xa0 [ 299.025939] [<c10d239e>] ? might_fault+0x2e/0x80 [ 299.026001] [<c13c438d>] ? _raw_spin_unlock+0x1d/0x20 [ 299.026057] [<c10d239e>] ? might_fault+0x2e/0x80 [ 299.026117] [<c10d23e4>] ? might_fault+0x74/0x80 [ 299.026172] [<c12bcfeb>] sys_socketcall+0xbb/0x2e0 [ 299.026227] [<c13c4fc3>] ? sysenter_exit+0xf/0x18 [ 299.026282] [<c11a3ec0>] ? trace_hardirqs_on_thunk+0xc/0x10 [ 299.026338] [<c13c4f90>] sysenter_do_call+0x12/0x36 [ 299.026393] ---[ end trace 53d11c892332cf99 ]--- or : [ 299.032017] ------------[ cut here ]------------ [ 299.032072] WARNING: at include/net/inetpeer.h:91 rt6_bind_peer+0x84/0xb0() [ 299.032130] Hardware name: ProLiant BL460c G1 [ 299.032183] Modules linked in: xt_hashlimit ipmi_devintf ipmi_si ipmi_msghandler tg3 bonding [ 299.032482] Pid: 0, comm: kworker/0:1 Tainted: G W 3.0.0-rc7-03555-ge798b6e-dirty #1048 [ 299.032557] Call Trace: [ 299.032614] [<c1042b4d>] warn_slowpath_common+0x6d/0xa0 [ 299.032671] [<c1373104>] ? rt6_bind_peer+0x84/0xb0 [ 299.032725] [<c1373104>] ? rt6_bind_peer+0x84/0xb0 [ 299.032780] [<c1042b9d>] warn_slowpath_null+0x1d/0x20 [ 299.032835] [<c1373104>] rt6_bind_peer+0x84/0xb0 [ 299.032890] [<c13731ec>] ipv6_cow_metrics+0xbc/0xe0 [ 299.032945] [<c1373a90>] icmp6_dst_alloc+0x1a0/0x2a0 [ 299.033001] [<c13738f0>] ? ip6_blackhole_route+0x240/0x240 [ 299.033058] [<c137a0bf>] ndisc_send_skb+0x4f/0x310 [ 299.033113] [<c137957b>] ? ndisc_fill_addr_option+0x5b/0x90 [ 299.033169] [<c137a3d2>] __ndisc_send+0x52/0x60 [ 299.033224] [<c137ad5d>] ndisc_send_ns+0x5d/0x90 [ 299.033279] [<c136b559>] ? ipv6_chk_addr+0x119/0x130 [ 299.033335] [<c137ae2f>] ndisc_solicit+0x9f/0x130 [ 299.033391] [<c12d8b8e>] neigh_timer_handler+0x10e/0x2a0 [ 299.033447] [<c105168a>] run_timer_softirq+0x13a/0x370 [ 299.033503] [<c1051608>] ? run_timer_softirq+0xb8/0x370 [ 299.033558] [<c12d8a80>] ? neigh_update+0x4c0/0x4c0 [ 299.033614] [<c1049577>] __do_softirq+0x97/0x1f0 [ 299.033674] [<c10494e0>] ? remote_softirq_receive+0x60/0x60 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [BUG] ipv6: all routes share same inetpeer 2011-07-19 17:23 [BUG] ipv6: all routes share same inetpeer Eric Dumazet @ 2011-07-19 17:37 ` David Miller 2011-07-19 18:20 ` Eric Dumazet 0 siblings, 1 reply; 9+ messages in thread From: David Miller @ 2011-07-19 17:37 UTC (permalink / raw) To: eric.dumazet; +Cc: netdev From: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue, 19 Jul 2011 19:23:49 +0200 > Maybe you can find the bug before me ? I think when we add the route we cow the metrics almost immediately. The daddr is, unfortunately, fully prefixed at that point. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] ipv6: all routes share same inetpeer 2011-07-19 17:37 ` David Miller @ 2011-07-19 18:20 ` Eric Dumazet 2011-07-19 18:57 ` Eric Dumazet 0 siblings, 1 reply; 9+ messages in thread From: Eric Dumazet @ 2011-07-19 18:20 UTC (permalink / raw) To: David Miller; +Cc: netdev Le mardi 19 juillet 2011 à 10:37 -0700, David Miller a écrit : > From: Eric Dumazet <eric.dumazet@gmail.com> > Date: Tue, 19 Jul 2011 19:23:49 +0200 > > > Maybe you can find the bug before me ? > > I think when we add the route we cow the metrics almost immediately. > The daddr is, unfortunately, fully prefixed at that point. Yes, we shall provide a second ip6_rt_copy() argument, with the destination address. I am testing : diff --git a/net/ipv6/route.c b/net/ipv6/route.c index ddef80f..2a6d70a 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -72,7 +72,7 @@ #define RT6_TRACE(x...) do { ; } while (0) #endif -static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); +static struct rt6_info * ip6_rt_copy(struct rt6_info *ort, const struct in6_addr *dest); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); static unsigned int ip6_default_mtu(const struct dst_entry *dst); @@ -699,7 +699,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add * Clone the route. */ - rt = ip6_rt_copy(ort); + rt = ip6_rt_copy(ort, daddr); if (rt) { struct neighbour *neigh; @@ -712,7 +712,6 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add ipv6_addr_copy(&rt->rt6i_gateway, daddr); } - ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; @@ -761,9 +760,9 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_addr *daddr) { - struct rt6_info *rt = ip6_rt_copy(ort); + struct rt6_info *rt = ip6_rt_copy(ort, daddr); + if (rt) { - ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; @@ -1584,7 +1583,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, if (neigh == dst_get_neighbour(&rt->dst)) goto out; - nrt = ip6_rt_copy(rt); + nrt = ip6_rt_copy(rt, dest); if (nrt == NULL) goto out; @@ -1592,7 +1591,6 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, if (on_link) nrt->rt6i_flags &= ~RTF_GATEWAY; - ipv6_addr_copy(&nrt->rt6i_dst.addr, dest); nrt->rt6i_dst.plen = 128; nrt->dst.flags |= DST_HOST; @@ -1730,7 +1728,7 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad * Misc support functions */ -static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) +static struct rt6_info * ip6_rt_copy(struct rt6_info *ort, const struct in6_addr *dest) { struct net *net = dev_net(ort->rt6i_dev); struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, @@ -1740,6 +1738,8 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->dst.input = ort->dst.input; rt->dst.output = ort->dst.output; + ipv6_addr_copy(&rt->rt6i_dst.addr, dest); + rt->rt6i_dst.plen = ort->rt6i_dst.plen; dst_copy_metrics(&rt->dst, &ort->dst); rt->dst.error = ort->dst.error; rt->rt6i_idev = ort->rt6i_idev; @@ -1752,7 +1752,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; rt->rt6i_metric = 0; - memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); #ifdef CONFIG_IPV6_SUBTREES memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); #endif ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [BUG] ipv6: all routes share same inetpeer 2011-07-19 18:20 ` Eric Dumazet @ 2011-07-19 18:57 ` Eric Dumazet 2011-07-19 18:59 ` David Miller 0 siblings, 1 reply; 9+ messages in thread From: Eric Dumazet @ 2011-07-19 18:57 UTC (permalink / raw) To: David Miller; +Cc: netdev Le mardi 19 juillet 2011 à 20:20 +0200, Eric Dumazet a écrit : > Le mardi 19 juillet 2011 à 10:37 -0700, David Miller a écrit : > > From: Eric Dumazet <eric.dumazet@gmail.com> > > Date: Tue, 19 Jul 2011 19:23:49 +0200 > > > > > Maybe you can find the bug before me ? > > > > I think when we add the route we cow the metrics almost immediately. > > The daddr is, unfortunately, fully prefixed at that point. > > Yes, we shall provide a second ip6_rt_copy() argument, with the > destination address. > Hmm, or maybe just change the dst_copy_metrics(&rt->dst, &ort->dst); call done from ip6_rt_copy(), to avoid doing the COW if not really needed ? diff --git a/net/ipv6/route.c b/net/ipv6/route.c index ddef80f..5403cea 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1740,7 +1740,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->dst.input = ort->dst.input; rt->dst.output = ort->dst.output; - dst_copy_metrics(&rt->dst, &ort->dst); + rt->dst._metrics = ort->dst._metrics; rt->dst.error = ort->dst.error; rt->rt6i_idev = ort->rt6i_idev; if (rt->rt6i_idev) ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [BUG] ipv6: all routes share same inetpeer 2011-07-19 18:57 ` Eric Dumazet @ 2011-07-19 18:59 ` David Miller 2011-07-20 5:29 ` Eric Dumazet 0 siblings, 1 reply; 9+ messages in thread From: David Miller @ 2011-07-19 18:59 UTC (permalink / raw) To: eric.dumazet; +Cc: netdev From: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue, 19 Jul 2011 20:57:50 +0200 > Le mardi 19 juillet 2011 à 20:20 +0200, Eric Dumazet a écrit : >> Le mardi 19 juillet 2011 à 10:37 -0700, David Miller a écrit : >> > From: Eric Dumazet <eric.dumazet@gmail.com> >> > Date: Tue, 19 Jul 2011 19:23:49 +0200 >> > >> > > Maybe you can find the bug before me ? >> > >> > I think when we add the route we cow the metrics almost immediately. >> > The daddr is, unfortunately, fully prefixed at that point. >> >> Yes, we shall provide a second ip6_rt_copy() argument, with the >> destination address. >> > > Hmm, or maybe just change the dst_copy_metrics(&rt->dst, &ort->dst); > call done from ip6_rt_copy(), to avoid doing the COW if not really > needed ? This is ok if it handles the case where ort's metrics point to writable inetpeer memory. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] ipv6: all routes share same inetpeer 2011-07-19 18:59 ` David Miller @ 2011-07-20 5:29 ` Eric Dumazet 2011-07-20 6:18 ` Eric Dumazet 2011-07-22 0:18 ` David Miller 0 siblings, 2 replies; 9+ messages in thread From: Eric Dumazet @ 2011-07-20 5:29 UTC (permalink / raw) To: David Miller; +Cc: netdev Le mardi 19 juillet 2011 à 11:59 -0700, David Miller a écrit : > From: Eric Dumazet <eric.dumazet@gmail.com> > Date: Tue, 19 Jul 2011 20:57:50 +0200 > > > Le mardi 19 juillet 2011 à 20:20 +0200, Eric Dumazet a écrit : > >> Le mardi 19 juillet 2011 à 10:37 -0700, David Miller a écrit : > >> > From: Eric Dumazet <eric.dumazet@gmail.com> > >> > Date: Tue, 19 Jul 2011 19:23:49 +0200 > >> > > >> > > Maybe you can find the bug before me ? > >> > > >> > I think when we add the route we cow the metrics almost immediately. > >> > The daddr is, unfortunately, fully prefixed at that point. > >> > >> Yes, we shall provide a second ip6_rt_copy() argument, with the > >> destination address. > >> > > > > Hmm, or maybe just change the dst_copy_metrics(&rt->dst, &ort->dst); > > call done from ip6_rt_copy(), to avoid doing the COW if not really > > needed ? > > This is ok if it handles the case where ort's metrics point to > writable inetpeer memory. OK but if ort's metrics are writeable we must perform the dst_copy_metrics() and therefore fill rt6i_dst before ? My first patch had an issue in rt6_alloc_cow(), line 710, where ipv6_addr_equal(&rt->rt6i_dst.addr, daddr) becomes always true. I guess I can replace it by ipv6_addr_equal(&ort->rt6i_dst.addr, daddr) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] ipv6: all routes share same inetpeer 2011-07-20 5:29 ` Eric Dumazet @ 2011-07-20 6:18 ` Eric Dumazet 2011-07-22 4:25 ` David Miller 2011-07-22 0:18 ` David Miller 1 sibling, 1 reply; 9+ messages in thread From: Eric Dumazet @ 2011-07-20 6:18 UTC (permalink / raw) To: David Miller; +Cc: netdev Le mercredi 20 juillet 2011 à 07:29 +0200, Eric Dumazet a écrit : > My first patch had an issue in rt6_alloc_cow(), line 710, where > ipv6_addr_equal(&rt->rt6i_dst.addr, daddr) becomes always true. > > I guess I can replace it by ipv6_addr_equal(&ort->rt6i_dst.addr, daddr) > > Here the combo patch I tested : I also had to solve the icmp6_dst_alloc() problem [it uses dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);] Note : this is based on net-2.6, but I really tested it on net-next-2.6 (with the frag ident patch applied too) [PATCH] ipv6: unshare inetpeers We currently cow metrics a bit too soon in IPv6 case : All routes are tied to a single inetpeer entry. Change ip6_rt_copy() to get destination address as second argument, so that we fill rt6i_dst before the dst_copy_metrics() call. icmp6_dst_alloc() must set rt6i_dst before calling dst_metric_set(), or else the cow is done while rt6i_dst is still NULL. If orig route points to readonly metrics, we can share the pointer instead of performing the memory allocation and copy. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> --- net/ipv6/route.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 0ef1f08..5b5a32d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -72,7 +72,8 @@ #define RT6_TRACE(x...) do { ; } while (0) #endif -static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); +static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, + const struct in6_addr *dest); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); static unsigned int ip6_default_mtu(const struct dst_entry *dst); @@ -683,7 +684,8 @@ int ip6_ins_rt(struct rt6_info *rt) return __ip6_ins_rt(rt, &info); } -static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_addr *daddr, +static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, + const struct in6_addr *daddr, const struct in6_addr *saddr) { struct rt6_info *rt; @@ -692,7 +694,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add * Clone the route. */ - rt = ip6_rt_copy(ort); + rt = ip6_rt_copy(ort, daddr); if (rt) { struct neighbour *neigh; @@ -700,12 +702,11 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add if (!(rt->rt6i_flags&RTF_GATEWAY)) { if (rt->rt6i_dst.plen != 128 && - ipv6_addr_equal(&rt->rt6i_dst.addr, daddr)) + ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) rt->rt6i_flags |= RTF_ANYCAST; ipv6_addr_copy(&rt->rt6i_gateway, daddr); } - ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; @@ -752,11 +753,12 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, const struct in6_add return rt; } -static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, const struct in6_addr *daddr) +static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, + const struct in6_addr *daddr) { - struct rt6_info *rt = ip6_rt_copy(ort); + struct rt6_info *rt = ip6_rt_copy(ort, daddr); + if (rt) { - ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; @@ -900,7 +902,10 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori new->input = dst_discard; new->output = dst_discard; - dst_copy_metrics(new, &ort->dst); + if (dst_metrics_read_only(&ort->dst)) + new->_metrics = ort->dst._metrics; + else + dst_copy_metrics(new, &ort->dst); rt->rt6i_idev = ort->rt6i_idev; if (rt->rt6i_idev) in6_dev_hold(rt->rt6i_idev); @@ -1060,6 +1065,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, rt->rt6i_idev = idev; rt->rt6i_nexthop = neigh; atomic_set(&rt->dst.__refcnt, 1); + ipv6_addr_copy(&rt->rt6i_dst.addr, addr); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); rt->dst.output = ip6_output; @@ -1577,7 +1583,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, if (neigh == rt->dst.neighbour) goto out; - nrt = ip6_rt_copy(rt); + nrt = ip6_rt_copy(rt, dest); if (nrt == NULL) goto out; @@ -1585,7 +1591,6 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, if (on_link) nrt->rt6i_flags &= ~RTF_GATEWAY; - ipv6_addr_copy(&nrt->rt6i_dst.addr, dest); nrt->rt6i_dst.plen = 128; nrt->dst.flags |= DST_HOST; @@ -1723,7 +1728,8 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad * Misc support functions */ -static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) +static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, + const struct in6_addr *dest) { struct net *net = dev_net(ort->rt6i_dev); struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, @@ -1733,6 +1739,8 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->dst.input = ort->dst.input; rt->dst.output = ort->dst.output; + ipv6_addr_copy(&rt->rt6i_dst.addr, dest); + rt->rt6i_dst.plen = ort->rt6i_dst.plen; dst_copy_metrics(&rt->dst, &ort->dst); rt->dst.error = ort->dst.error; rt->rt6i_idev = ort->rt6i_idev; @@ -1745,7 +1753,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; rt->rt6i_metric = 0; - memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); #ifdef CONFIG_IPV6_SUBTREES memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); #endif ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [BUG] ipv6: all routes share same inetpeer 2011-07-20 6:18 ` Eric Dumazet @ 2011-07-22 4:25 ` David Miller 0 siblings, 0 replies; 9+ messages in thread From: David Miller @ 2011-07-22 4:25 UTC (permalink / raw) To: eric.dumazet; +Cc: netdev From: Eric Dumazet <eric.dumazet@gmail.com> Date: Wed, 20 Jul 2011 08:18:36 +0200 > Le mercredi 20 juillet 2011 à 07:29 +0200, Eric Dumazet a écrit : > >> My first patch had an issue in rt6_alloc_cow(), line 710, where >> ipv6_addr_equal(&rt->rt6i_dst.addr, daddr) becomes always true. >> >> I guess I can replace it by ipv6_addr_equal(&ort->rt6i_dst.addr, daddr) >> >> > > Here the combo patch I tested : > > I also had to solve the icmp6_dst_alloc() problem > [it uses dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);] > > Note : this is based on net-2.6, but I really tested it on net-next-2.6 > (with the frag ident patch applied too) > > [PATCH] ipv6: unshare inetpeers I applied this to net-next and queued it up for -stable, thanks! ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] ipv6: all routes share same inetpeer 2011-07-20 5:29 ` Eric Dumazet 2011-07-20 6:18 ` Eric Dumazet @ 2011-07-22 0:18 ` David Miller 1 sibling, 0 replies; 9+ messages in thread From: David Miller @ 2011-07-22 0:18 UTC (permalink / raw) To: eric.dumazet; +Cc: netdev From: Eric Dumazet <eric.dumazet@gmail.com> Date: Wed, 20 Jul 2011 07:29:34 +0200 > Le mardi 19 juillet 2011 à 11:59 -0700, David Miller a écrit : >> From: Eric Dumazet <eric.dumazet@gmail.com> >> Date: Tue, 19 Jul 2011 20:57:50 +0200 >> >> > Le mardi 19 juillet 2011 à 20:20 +0200, Eric Dumazet a écrit : >> >> Le mardi 19 juillet 2011 à 10:37 -0700, David Miller a écrit : >> >> > From: Eric Dumazet <eric.dumazet@gmail.com> >> >> > Date: Tue, 19 Jul 2011 19:23:49 +0200 >> >> > >> >> > > Maybe you can find the bug before me ? >> >> > >> >> > I think when we add the route we cow the metrics almost immediately. >> >> > The daddr is, unfortunately, fully prefixed at that point. >> >> >> >> Yes, we shall provide a second ip6_rt_copy() argument, with the >> >> destination address. >> >> >> > >> > Hmm, or maybe just change the dst_copy_metrics(&rt->dst, &ort->dst); >> > call done from ip6_rt_copy(), to avoid doing the COW if not really >> > needed ? >> >> This is ok if it handles the case where ort's metrics point to >> writable inetpeer memory. > > OK but if ort's metrics are writeable we must perform the dst_copy_metrics() > and therefore fill rt6i_dst before ? If it's writable, then there are no problems. Oh actually, I see what you mean. This is a mess. I'll try to think about this some more and look at your most recent patches. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-07-22 4:25 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-07-19 17:23 [BUG] ipv6: all routes share same inetpeer Eric Dumazet 2011-07-19 17:37 ` David Miller 2011-07-19 18:20 ` Eric Dumazet 2011-07-19 18:57 ` Eric Dumazet 2011-07-19 18:59 ` David Miller 2011-07-20 5:29 ` Eric Dumazet 2011-07-20 6:18 ` Eric Dumazet 2011-07-22 4:25 ` David Miller 2011-07-22 0:18 ` David Miller
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).