linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / ipv4 / igmp.c
index 8e8117c..64ce52b 100644 (file)
@@ -72,6 +72,7 @@
  *                                     Vinay Kulkarni
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -1028,9 +1029,10 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
         * for deleted items allows change reports to use common code with
         * non-deleted or query-response MCA's.
         */
-       pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
+       pmc = kmalloc(sizeof(*pmc), GFP_KERNEL);
        if (!pmc)
                return;
+       memset(pmc, 0, sizeof(*pmc));
        spin_lock_bh(&im->lock);
        pmc->interface = im->interface;
        in_dev_hold(in_dev);
@@ -1380,7 +1382,7 @@ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
                dev = ip_dev_find(imr->imr_address.s_addr);
                if (!dev)
                        return NULL;
-               dev_put(dev);
+               __dev_put(dev);
        }
 
        if (!dev && !ip_route_output_key(&rt, &fl)) {
@@ -1528,9 +1530,10 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
                psf_prev = psf;
        }
        if (!psf) {
-               psf = kzalloc(sizeof(*psf), GFP_ATOMIC);
+               psf = kmalloc(sizeof(*psf), GFP_ATOMIC);
                if (!psf)
                        return -ENOBUFS;
+               memset(psf, 0, sizeof(*psf));
                psf->sf_inaddr = *psfsrc;
                if (psf_prev) {
                        psf_prev->sf_next = psf;
@@ -1727,7 +1730,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
        if (!MULTICAST(addr))
                return -EINVAL;
 
-       rtnl_lock();
+       rtnl_shlock();
 
        in_dev = ip_mc_find_dev(imr);
 
@@ -1760,7 +1763,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
        ip_mc_inc_group(in_dev, addr);
        err = 0;
 done:
-       rtnl_unlock();
+       rtnl_shunlock();
        return err;
 }
 
@@ -1793,35 +1796,29 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
        struct in_device *in_dev;
        u32 group = imr->imr_multiaddr.s_addr;
        u32 ifindex;
-       int ret = -EADDRNOTAVAIL;
 
        rtnl_lock();
        in_dev = ip_mc_find_dev(imr);
+       if (!in_dev) {
+               rtnl_unlock();
+               return -ENODEV;
+       }
        ifindex = imr->imr_ifindex;
        for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) {
-               if (iml->multi.imr_multiaddr.s_addr != group)
-                       continue;
-               if (ifindex) {
-                       if (iml->multi.imr_ifindex != ifindex)
-                               continue;
-               } else if (imr->imr_address.s_addr && imr->imr_address.s_addr !=
-                               iml->multi.imr_address.s_addr)
-                       continue;
+               if (iml->multi.imr_multiaddr.s_addr == group &&
+                   iml->multi.imr_ifindex == ifindex) {
+                       (void) ip_mc_leave_src(sk, iml, in_dev);
 
-               (void) ip_mc_leave_src(sk, iml, in_dev);
+                       *imlp = iml->next;
 
-               *imlp = iml->next;
-
-               if (in_dev)
                        ip_mc_dec_group(in_dev, group);
-               rtnl_unlock();
-               sock_kfree_s(sk, iml, sizeof(*iml));
-               return 0;
+                       rtnl_unlock();
+                       sock_kfree_s(sk, iml, sizeof(*iml));
+                       return 0;
+               }
        }
-       if (!in_dev)
-               ret = -ENODEV;
        rtnl_unlock();
-       return ret;
+       return -EADDRNOTAVAIL;
 }
 
 int ip_mc_source(int add, int omode, struct sock *sk, struct
@@ -1840,7 +1837,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
        if (!MULTICAST(addr))
                return -EINVAL;
 
-       rtnl_lock();
+       rtnl_shlock();
 
        imr.imr_multiaddr.s_addr = mreqs->imr_multiaddr;
        imr.imr_address.s_addr = mreqs->imr_interface;
@@ -1950,7 +1947,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
        ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1, 
                &mreqs->imr_sourceaddr, 1);
 done:
-       rtnl_unlock();
+       rtnl_shunlock();
        if (leavegroup)
                return ip_mc_leave_group(sk, &imr);
        return err;
@@ -1973,7 +1970,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
            msf->imsf_fmode != MCAST_EXCLUDE)
                return -EINVAL;
 
-       rtnl_lock();
+       rtnl_shlock();
 
        imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
        imr.imr_address.s_addr = msf->imsf_interface;
@@ -2033,7 +2030,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
        pmc->sfmode = msf->imsf_fmode;
        err = 0;
 done:
-       rtnl_unlock();
+       rtnl_shunlock();
        if (leavegroup)
                err = ip_mc_leave_group(sk, &imr);
        return err;
@@ -2053,7 +2050,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
        if (!MULTICAST(addr))
                return -EINVAL;
 
-       rtnl_lock();
+       rtnl_shlock();
 
        imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
        imr.imr_address.s_addr = msf->imsf_interface;
@@ -2075,7 +2072,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
                goto done;
        msf->imsf_fmode = pmc->sfmode;
        psl = pmc->sflist;
-       rtnl_unlock();
+       rtnl_shunlock();
        if (!psl) {
                len = 0;
                count = 0;
@@ -2094,7 +2091,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
                return -EFAULT;
        return 0;
 done:
-       rtnl_unlock();
+       rtnl_shunlock();
        return err;
 }
 
@@ -2115,7 +2112,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
        if (!MULTICAST(addr))
                return -EINVAL;
 
-       rtnl_lock();
+       rtnl_shlock();
 
        err = -EADDRNOTAVAIL;
 
@@ -2128,7 +2125,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
                goto done;
        gsf->gf_fmode = pmc->sfmode;
        psl = pmc->sflist;
-       rtnl_unlock();
+       rtnl_shunlock();
        count = psl ? psl->sl_count : 0;
        copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
        gsf->gf_numsrc = count;
@@ -2149,7 +2146,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
        }
        return 0;
 done:
-       rtnl_unlock();
+       rtnl_shunlock();
        return err;
 }
 
@@ -2205,13 +2202,13 @@ void ip_mc_drop_socket(struct sock *sk)
                struct in_device *in_dev;
                inet->mc_list = iml->next;
 
-               in_dev = inetdev_by_index(iml->multi.imr_ifindex);
-               (void) ip_mc_leave_src(sk, iml, in_dev);
-               if (in_dev != NULL) {
+               if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) {
+                       (void) ip_mc_leave_src(sk, iml, in_dev);
                        ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
                        in_dev_put(in_dev);
                }
                sock_kfree_s(sk, iml, sizeof(*iml));
+
        }
        rtnl_unlock();
 }
@@ -2364,7 +2361,7 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
                }
 
                seq_printf(seq,
-                          "\t\t\t\t%08X %5d %d:%08lX\t\t%d\n",
+                          "\t\t\t\t%08lX %5d %d:%08lX\t\t%d\n",
                           im->multiaddr, im->users,
                           im->tm_running, im->tm_running ?
                           jiffies_to_clock_t(im->timer.expires-jiffies) : 0,
@@ -2384,7 +2381,7 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct igmp_mc_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
+       struct igmp_mc_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
 
        if (!s)
                goto out;
@@ -2394,6 +2391,7 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file)
 
        seq = file->private_data;
        seq->private = s;
+       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree:
@@ -2558,7 +2556,7 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        int rc = -ENOMEM;
-       struct igmp_mcf_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
+       struct igmp_mcf_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
 
        if (!s)
                goto out;
@@ -2568,6 +2566,7 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
 
        seq = file->private_data;
        seq->private = s;
+       memset(s, 0, sizeof(*s));
 out:
        return rc;
 out_kfree: