(usagi-users 03398) Re: MLDv2 linux implementation questions

Hoerdt Mickael <[email protected]>
Newsgroups gmane.linux.ipv6.usagi.users
Message-ID <[email protected]>
David,

Thanks for the quick fixup, but this patch causes a kernel panic on my i386
architecture after the first SSM calls. Also, would it be possible to
fix the IPv4 code
too ?

To reproduce :

./test_msf ff3e::1234

>p 2001:6::1 0
>r 2001:6::1 0
=> kernel panic.

Hoerdt Mickaël

David Stevens wrote:

>Hoerdt,
>        Here's the complete patch, which should
>fix the problem you've seen. Please let me know if
>you turn up anything else, of course. :-)
>
>                                +-DLS
>diff -ruNp linux-2.6.11.12/net/ipv6/ipv6_sockglue.c 
>linux-2.6.11.12MCT/net/ipv6/ipv6_sockglue.c
>--- linux-2.6.11.12/net/ipv6/ipv6_sockglue.c    2005-03-01 
>23:37:48.000000000 -0800
>+++ linux-2.6.11.12MCT/net/ipv6/ipv6_sockglue.c 2005-06-15 
>14:17:46.000000000 -0700
>@@ -423,11 +423,12 @@ done:
>                        psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
>                        retv = ipv6_sock_mc_join(sk, greqs.gsr_interface,
>                                &psin6->sin6_addr);
>-                       if (retv)
>+                       /* prior join w/ different source is ok */
>+                       if (retv && retv != -EADDRINUSE)
>                                break;
>                        omode = MCAST_INCLUDE;
>                        add = 1;
>-               } else /*IP_DROP_SOURCE_MEMBERSHIP */ {
>+               } else /* MCAST_LEAVE_SOURCE_GROUP */ {
>                        omode = MCAST_INCLUDE;
>                        add = 0;
>                }
>diff -ruNp linux-2.6.11.12/net/ipv6/mcast.c 
>linux-2.6.11.12MCT/net/ipv6/mcast.c
>--- linux-2.6.11.12/net/ipv6/mcast.c    2005-03-01 23:38:25.000000000 
>-0800
>+++ linux-2.6.11.12MCT/net/ipv6/mcast.c 2005-06-14 16:37:22.000000000 
>-0700
>@@ -188,6 +188,16 @@ int ipv6_sock_mc_join(struct sock *sk, i
>        if (!ipv6_addr_is_multicast(addr))
>                return -EINVAL;
> 
>+       read_lock_bh(&ipv6_sk_mc_lock);
>+       for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) {
>+               if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
>+                   ipv6_addr_equal(&mc_lst->addr, addr)) {
>+                       read_unlock_bh(&ipv6_sk_mc_lock);
>+                       return -EADDRINUSE;
>+               }
>+       }
>+       read_unlock_bh(&ipv6_sk_mc_lock);
>+
>        mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), 
>GFP_KERNEL);
> 
>        if (mc_lst == NULL)
>@@ -241,19 +251,18 @@ int ipv6_sock_mc_join(struct sock *sk, i
> /*
>  *     socket leave on multicast group
>  */
>-int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr 
>*addr)
>+static int __ipv6_sock_mc_drop(struct sock *sk, int ifindex,
>+       struct in6_addr *addr)
> {
>        struct ipv6_pinfo *np = inet6_sk(sk);
>        struct ipv6_mc_socklist *mc_lst, **lnk;
> 
>-       write_lock_bh(&ipv6_sk_mc_lock);
>        for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = 
>&mc_lst->next) {
>                if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
>                    ipv6_addr_equal(&mc_lst->addr, addr)) {
>                        struct net_device *dev;
> 
>                        *lnk = mc_lst->next;
>-                       write_unlock_bh(&ipv6_sk_mc_lock);
> 
>                        if ((dev = dev_get_by_index(mc_lst->ifindex)) != 
>NULL) {
>                                struct inet6_dev *idev = in6_dev_get(dev);
>@@ -269,11 +278,21 @@ int ipv6_sock_mc_drop(struct sock *sk, i
>                        return 0;
>                }
>        }
>-       write_unlock_bh(&ipv6_sk_mc_lock);
> 
>        return -ENOENT;
> }
> 
>+int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr 
>*addr)
>+{
>+       int rv;
>+
>+       write_lock_bh(&ipv6_sk_mc_lock);
>+       rv = __ipv6_sock_mc_drop(sk, ifindex, addr);
>+       write_unlock_bh(&ipv6_sk_mc_lock);
>+       return rv;
>+}
>+
>+
> static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int 
>ifindex)
> {
>        struct net_device *dev = NULL;
>@@ -368,6 +387,7 @@ int ip6_mc_source(int add, int omode, st
> 
>        err = -EADDRNOTAVAIL;
> 
>+       write_lock_bh(&ipv6_sk_mc_lock);
>        for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
>                if (pgsr->gsr_interface && pmc->ifindex != 
>pgsr->gsr_interface)
>                        continue;
>@@ -401,6 +421,13 @@ int ip6_mc_source(int add, int omode, st
>                if (rv)         /* source not found */
>                        goto done;
> 
>+               /* special case - (INCLUDE, empty) == LEAVE_GROUP */
>+               if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
>+                       err = __ipv6_sock_mc_drop(sk, pgsr->gsr_interface,
>+                               group);
>+                       goto done;
>+               }
>+
>                /* update the interface filter */
>                ip6_mc_del_src(idev, group, omode, 1, source, 1);
> 
>@@ -453,6 +480,7 @@ int ip6_mc_source(int add, int omode, st
>        /* update the interface list */
>        ip6_mc_add_src(idev, group, omode, 1, source, 1);
> done:
>+       write_unlock_bh(&ipv6_sk_mc_lock);
>        read_unlock_bh(&idev->lock);
>        in6_dev_put(idev);
>        dev_put(dev);
>
>
>  
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.