Philip Bellino wrote:
> To all;
> Previously running Linux kernel 2.6.14.3:
> 
> In addrconf.c, in the function "ipv6_add_dev",(see below in bold).  
> "dev->ip6_ptr = ndev" is set, then "ipv6_mc_init_dev(ndev)" is called
> (mcast.c), which then calls "ipv6_dev_mc_inc" (mcast.c) for the "all
> nodes address".
> This sets "idev = in6_dev_get(dev)" and then tests if it is NULL.
> 
> 2.6.14.3 code:
> static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
> {
>       struct inet6_dev *ndev;
> ~~~~
> ~~~
> 
>               write_lock_bh(&addrconf_lock);
>               dev->ip6_ptr = ndev;
>               write_unlock_bh(&addrconf_lock);
> 
>               ipv6_mc_init_dev(ndev);
>               ndev->tstamp = jiffies;
> #ifdef CONFIG_SYSCTL
>               neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6, 
>                                     NET_IPV6_NEIGH, "ipv6",
>                                     &ndisc_ifinfo_sysctl_change,
>                                     NULL);
>               addrconf_sysctl_register(ndev, &ndev->cnf);
> #endif
>       }
>       return ndev;
> }
> 
> "Idev is not NULL, so the all nodes address (FF02::1) is added to the
> list and all is fine.
> 
> ************************************************************************
> *****************
> 
> 
> Now in the 2.6.19.2 linux kernel, the "ipv6_add_dev" routine has
> changed(see below). "dev->ip6_ptr = ndev" is no longer in the code.
> "ipv6_mc_init_dev(ndev)" is called and then a new function
> "rcu_assign_pointer(dev->ip6_ptr, ndev)" is used.
> When this occurs, the call to "ipv6_dev_mc_inc" (in mcast.c) will set
> "idev = in6_dev_get(dev)" and then test if it is NULL.
> It is NULL, so it returns -EINVAL.
> 
> 2.6.19.2 code:
> static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
> {
>       struct inet6_dev *ndev;
> 
> ~~~~  
> ~~~~  
> 
>       if (netif_carrier_ok(dev))
>               ndev->if_flags |= IF_READY;
> 
> 
>               ipv6_mc_init_dev(ndev);
>               ndev->tstamp = jiffies;
> #ifdef CONFIG_SYSCTL
>               neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6, 
>                                     NET_IPV6_NEIGH, "ipv6",
>                                     &ndisc_ifinfo_sysctl_change,
>                                     NULL);
>               addrconf_sysctl_register(ndev, &ndev->cnf);
> #endif
>       /* protected by rtnl_lock */
>       rcu_assign_pointer(dev->ip6_ptr, ndev);
>       return ndev;
> }
> 
> The all nodes address (FF02::1) is never added to the list.
> 
> I have worked around the problem by moving the
> "rcu_assign_pointer(dev->ip6_ptr, ndev)" before the call to
> "ipv6_mc_init_dev(ndev)".
> 
> Has anyone else seen this issue?
>

Yes.  It has been reported and fixed.

http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.19.y.git;a=commit;h=edfe21a29b1dca9ce5a938317868066d2e21c385

you may want to get a more recent version of the 2.6.19 stable kernel.

-vlad
_______________________________________________
Users mailing list
[email protected]
https://lists.ipv6.org/mailman/listinfo/users

Reply via email to