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?

Thanks,
Phil Bellino

============================ 
Phil Bellino 
MRV Communications, Inc. 
Boston Product Division 
295 Foster St. 
Littleton,MA 01460 
Tel: (978)952-4807 
Email: [EMAIL PROTECTED] 
============================ 

_______________________________________________
Users mailing list
Users@ipv6.org
https://lists.ipv6.org/mailman/listinfo/users

Reply via email to