aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/igmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r--net/ipv4/igmp.c125
1 files changed, 63 insertions, 62 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index ab680c851aa2..6eee71647b7c 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -72,7 +72,6 @@
72 * Vinay Kulkarni 72 * Vinay Kulkarni
73 */ 73 */
74 74
75#include <linux/config.h>
76#include <linux/module.h> 75#include <linux/module.h>
77#include <asm/uaccess.h> 76#include <asm/uaccess.h>
78#include <asm/system.h> 77#include <asm/system.h>
@@ -139,14 +138,14 @@
139 time_before(jiffies, (in_dev)->mr_v2_seen))) 138 time_before(jiffies, (in_dev)->mr_v2_seen)))
140 139
141static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); 140static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im);
142static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr); 141static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr);
143static void igmpv3_clear_delrec(struct in_device *in_dev); 142static void igmpv3_clear_delrec(struct in_device *in_dev);
144static int sf_setstate(struct ip_mc_list *pmc); 143static int sf_setstate(struct ip_mc_list *pmc);
145static void sf_markstate(struct ip_mc_list *pmc); 144static void sf_markstate(struct ip_mc_list *pmc);
146#endif 145#endif
147static void ip_mc_clear_src(struct ip_mc_list *pmc); 146static void ip_mc_clear_src(struct ip_mc_list *pmc);
148static int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode, 147static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
149 int sfcount, __u32 *psfsrc, int delta); 148 int sfcount, __be32 *psfsrc, int delta);
150 149
151static void ip_ma_put(struct ip_mc_list *im) 150static void ip_ma_put(struct ip_mc_list *im)
152{ 151{
@@ -427,7 +426,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
427 first = 1; 426 first = 1;
428 psf_prev = NULL; 427 psf_prev = NULL;
429 for (psf=*psf_list; psf; psf=psf_next) { 428 for (psf=*psf_list; psf; psf=psf_next) {
430 u32 *psrc; 429 __be32 *psrc;
431 430
432 psf_next = psf->sf_next; 431 psf_next = psf->sf_next;
433 432
@@ -440,7 +439,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
440 if (isquery) 439 if (isquery)
441 psf->sf_gsresp = 0; 440 psf->sf_gsresp = 0;
442 441
443 if (AVAILABLE(skb) < sizeof(u32) + 442 if (AVAILABLE(skb) < sizeof(__be32) +
444 first*sizeof(struct igmpv3_grec)) { 443 first*sizeof(struct igmpv3_grec)) {
445 if (truncate && !first) 444 if (truncate && !first)
446 break; /* truncate these */ 445 break; /* truncate these */
@@ -456,7 +455,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
456 skb = add_grhead(skb, pmc, type, &pgr); 455 skb = add_grhead(skb, pmc, type, &pgr);
457 first = 0; 456 first = 0;
458 } 457 }
459 psrc = (u32 *)skb_put(skb, sizeof(u32)); 458 psrc = (__be32 *)skb_put(skb, sizeof(__be32));
460 *psrc = psf->sf_inaddr; 459 *psrc = psf->sf_inaddr;
461 scount++; stotal++; 460 scount++; stotal++;
462 if ((type == IGMPV3_ALLOW_NEW_SOURCES || 461 if ((type == IGMPV3_ALLOW_NEW_SOURCES ||
@@ -631,8 +630,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
631 struct igmphdr *ih; 630 struct igmphdr *ih;
632 struct rtable *rt; 631 struct rtable *rt;
633 struct net_device *dev = in_dev->dev; 632 struct net_device *dev = in_dev->dev;
634 u32 group = pmc ? pmc->multiaddr : 0; 633 __be32 group = pmc ? pmc->multiaddr : 0;
635 u32 dst; 634 __be32 dst;
636 635
637 if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) 636 if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
638 return igmpv3_send_report(in_dev, pmc); 637 return igmpv3_send_report(in_dev, pmc);
@@ -749,7 +748,7 @@ static void igmp_timer_expire(unsigned long data)
749} 748}
750 749
751/* mark EXCLUDE-mode sources */ 750/* mark EXCLUDE-mode sources */
752static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs) 751static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
753{ 752{
754 struct ip_sf_list *psf; 753 struct ip_sf_list *psf;
755 int i, scount; 754 int i, scount;
@@ -776,7 +775,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
776 return 1; 775 return 1;
777} 776}
778 777
779static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs) 778static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
780{ 779{
781 struct ip_sf_list *psf; 780 struct ip_sf_list *psf;
782 int i, scount; 781 int i, scount;
@@ -804,7 +803,7 @@ static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __u32 *srcs)
804 return 1; 803 return 1;
805} 804}
806 805
807static void igmp_heard_report(struct in_device *in_dev, u32 group) 806static void igmp_heard_report(struct in_device *in_dev, __be32 group)
808{ 807{
809 struct ip_mc_list *im; 808 struct ip_mc_list *im;
810 809
@@ -829,7 +828,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
829 struct igmphdr *ih = skb->h.igmph; 828 struct igmphdr *ih = skb->h.igmph;
830 struct igmpv3_query *ih3 = (struct igmpv3_query *)ih; 829 struct igmpv3_query *ih3 = (struct igmpv3_query *)ih;
831 struct ip_mc_list *im; 830 struct ip_mc_list *im;
832 u32 group = ih->group; 831 __be32 group = ih->group;
833 int max_delay; 832 int max_delay;
834 int mark = 0; 833 int mark = 0;
835 834
@@ -863,7 +862,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
863 ih3 = (struct igmpv3_query *) skb->h.raw; 862 ih3 = (struct igmpv3_query *) skb->h.raw;
864 if (ih3->nsrcs) { 863 if (ih3->nsrcs) {
865 if (!pskb_may_pull(skb, sizeof(struct igmpv3_query) 864 if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)
866 + ntohs(ih3->nsrcs)*sizeof(__u32))) 865 + ntohs(ih3->nsrcs)*sizeof(__be32)))
867 return; 866 return;
868 ih3 = (struct igmpv3_query *) skb->h.raw; 867 ih3 = (struct igmpv3_query *) skb->h.raw;
869 } 868 }
@@ -932,7 +931,7 @@ int igmp_rcv(struct sk_buff *skb)
932 goto drop; 931 goto drop;
933 932
934 switch (skb->ip_summed) { 933 switch (skb->ip_summed) {
935 case CHECKSUM_HW: 934 case CHECKSUM_COMPLETE:
936 if (!(u16)csum_fold(skb->csum)) 935 if (!(u16)csum_fold(skb->csum))
937 break; 936 break;
938 /* fall through */ 937 /* fall through */
@@ -986,7 +985,7 @@ drop:
986 * Add a filter to a device 985 * Add a filter to a device
987 */ 986 */
988 987
989static void ip_mc_filter_add(struct in_device *in_dev, u32 addr) 988static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr)
990{ 989{
991 char buf[MAX_ADDR_LEN]; 990 char buf[MAX_ADDR_LEN];
992 struct net_device *dev = in_dev->dev; 991 struct net_device *dev = in_dev->dev;
@@ -1006,7 +1005,7 @@ static void ip_mc_filter_add(struct in_device *in_dev, u32 addr)
1006 * Remove a filter from a device 1005 * Remove a filter from a device
1007 */ 1006 */
1008 1007
1009static void ip_mc_filter_del(struct in_device *in_dev, u32 addr) 1008static void ip_mc_filter_del(struct in_device *in_dev, __be32 addr)
1010{ 1009{
1011 char buf[MAX_ADDR_LEN]; 1010 char buf[MAX_ADDR_LEN];
1012 struct net_device *dev = in_dev->dev; 1011 struct net_device *dev = in_dev->dev;
@@ -1029,10 +1028,9 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
1029 * for deleted items allows change reports to use common code with 1028 * for deleted items allows change reports to use common code with
1030 * non-deleted or query-response MCA's. 1029 * non-deleted or query-response MCA's.
1031 */ 1030 */
1032 pmc = kmalloc(sizeof(*pmc), GFP_KERNEL); 1031 pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
1033 if (!pmc) 1032 if (!pmc)
1034 return; 1033 return;
1035 memset(pmc, 0, sizeof(*pmc));
1036 spin_lock_bh(&im->lock); 1034 spin_lock_bh(&im->lock);
1037 pmc->interface = im->interface; 1035 pmc->interface = im->interface;
1038 in_dev_hold(in_dev); 1036 in_dev_hold(in_dev);
@@ -1057,7 +1055,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im)
1057 spin_unlock_bh(&in_dev->mc_tomb_lock); 1055 spin_unlock_bh(&in_dev->mc_tomb_lock);
1058} 1056}
1059 1057
1060static void igmpv3_del_delrec(struct in_device *in_dev, __u32 multiaddr) 1058static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr)
1061{ 1059{
1062 struct ip_mc_list *pmc, *pmc_prev; 1060 struct ip_mc_list *pmc, *pmc_prev;
1063 struct ip_sf_list *psf, *psf_next; 1061 struct ip_sf_list *psf, *psf_next;
@@ -1195,7 +1193,7 @@ static void igmp_group_added(struct ip_mc_list *im)
1195 * A socket has joined a multicast group on device dev. 1193 * A socket has joined a multicast group on device dev.
1196 */ 1194 */
1197 1195
1198void ip_mc_inc_group(struct in_device *in_dev, u32 addr) 1196void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
1199{ 1197{
1200 struct ip_mc_list *im; 1198 struct ip_mc_list *im;
1201 1199
@@ -1254,7 +1252,7 @@ out:
1254 * A socket has left a multicast group on device dev 1252 * A socket has left a multicast group on device dev
1255 */ 1253 */
1256 1254
1257void ip_mc_dec_group(struct in_device *in_dev, u32 addr) 1255void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
1258{ 1256{
1259 struct ip_mc_list *i, **ip; 1257 struct ip_mc_list *i, **ip;
1260 1258
@@ -1399,12 +1397,12 @@ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
1399/* 1397/*
1400 * Join a socket to a group 1398 * Join a socket to a group
1401 */ 1399 */
1402int sysctl_igmp_max_memberships = IP_MAX_MEMBERSHIPS; 1400int sysctl_igmp_max_memberships __read_mostly = IP_MAX_MEMBERSHIPS;
1403int sysctl_igmp_max_msf = IP_MAX_MSF; 1401int sysctl_igmp_max_msf __read_mostly = IP_MAX_MSF;
1404 1402
1405 1403
1406static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, 1404static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
1407 __u32 *psfsrc) 1405 __be32 *psfsrc)
1408{ 1406{
1409 struct ip_sf_list *psf, *psf_prev; 1407 struct ip_sf_list *psf, *psf_prev;
1410 int rv = 0; 1408 int rv = 0;
@@ -1452,8 +1450,8 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
1452#define igmp_ifc_event(x) do { } while (0) 1450#define igmp_ifc_event(x) do { } while (0)
1453#endif 1451#endif
1454 1452
1455static int ip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode, 1453static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
1456 int sfcount, __u32 *psfsrc, int delta) 1454 int sfcount, __be32 *psfsrc, int delta)
1457{ 1455{
1458 struct ip_mc_list *pmc; 1456 struct ip_mc_list *pmc;
1459 int changerec = 0; 1457 int changerec = 0;
@@ -1519,7 +1517,7 @@ out_unlock:
1519 * Add multicast single-source filter to the interface list 1517 * Add multicast single-source filter to the interface list
1520 */ 1518 */
1521static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode, 1519static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
1522 __u32 *psfsrc, int delta) 1520 __be32 *psfsrc, int delta)
1523{ 1521{
1524 struct ip_sf_list *psf, *psf_prev; 1522 struct ip_sf_list *psf, *psf_prev;
1525 1523
@@ -1530,10 +1528,9 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
1530 psf_prev = psf; 1528 psf_prev = psf;
1531 } 1529 }
1532 if (!psf) { 1530 if (!psf) {
1533 psf = kmalloc(sizeof(*psf), GFP_ATOMIC); 1531 psf = kzalloc(sizeof(*psf), GFP_ATOMIC);
1534 if (!psf) 1532 if (!psf)
1535 return -ENOBUFS; 1533 return -ENOBUFS;
1536 memset(psf, 0, sizeof(*psf));
1537 psf->sf_inaddr = *psfsrc; 1534 psf->sf_inaddr = *psfsrc;
1538 if (psf_prev) { 1535 if (psf_prev) {
1539 psf_prev->sf_next = psf; 1536 psf_prev->sf_next = psf;
@@ -1626,8 +1623,8 @@ static int sf_setstate(struct ip_mc_list *pmc)
1626/* 1623/*
1627 * Add multicast source filter list to the interface list 1624 * Add multicast source filter list to the interface list
1628 */ 1625 */
1629static int ip_mc_add_src(struct in_device *in_dev, __u32 *pmca, int sfmode, 1626static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
1630 int sfcount, __u32 *psfsrc, int delta) 1627 int sfcount, __be32 *psfsrc, int delta)
1631{ 1628{
1632 struct ip_mc_list *pmc; 1629 struct ip_mc_list *pmc;
1633 int isexclude; 1630 int isexclude;
@@ -1720,7 +1717,7 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc)
1720int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) 1717int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
1721{ 1718{
1722 int err; 1719 int err;
1723 u32 addr = imr->imr_multiaddr.s_addr; 1720 __be32 addr = imr->imr_multiaddr.s_addr;
1724 struct ip_mc_socklist *iml=NULL, *i; 1721 struct ip_mc_socklist *iml=NULL, *i;
1725 struct in_device *in_dev; 1722 struct in_device *in_dev;
1726 struct inet_sock *inet = inet_sk(sk); 1723 struct inet_sock *inet = inet_sk(sk);
@@ -1794,31 +1791,37 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
1794 struct inet_sock *inet = inet_sk(sk); 1791 struct inet_sock *inet = inet_sk(sk);
1795 struct ip_mc_socklist *iml, **imlp; 1792 struct ip_mc_socklist *iml, **imlp;
1796 struct in_device *in_dev; 1793 struct in_device *in_dev;
1797 u32 group = imr->imr_multiaddr.s_addr; 1794 __be32 group = imr->imr_multiaddr.s_addr;
1798 u32 ifindex; 1795 u32 ifindex;
1796 int ret = -EADDRNOTAVAIL;
1799 1797
1800 rtnl_lock(); 1798 rtnl_lock();
1801 in_dev = ip_mc_find_dev(imr); 1799 in_dev = ip_mc_find_dev(imr);
1802 if (!in_dev) {
1803 rtnl_unlock();
1804 return -ENODEV;
1805 }
1806 ifindex = imr->imr_ifindex; 1800 ifindex = imr->imr_ifindex;
1807 for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) { 1801 for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) {
1808 if (iml->multi.imr_multiaddr.s_addr == group && 1802 if (iml->multi.imr_multiaddr.s_addr != group)
1809 iml->multi.imr_ifindex == ifindex) { 1803 continue;
1810 (void) ip_mc_leave_src(sk, iml, in_dev); 1804 if (ifindex) {
1805 if (iml->multi.imr_ifindex != ifindex)
1806 continue;
1807 } else if (imr->imr_address.s_addr && imr->imr_address.s_addr !=
1808 iml->multi.imr_address.s_addr)
1809 continue;
1810
1811 (void) ip_mc_leave_src(sk, iml, in_dev);
1811 1812
1812 *imlp = iml->next; 1813 *imlp = iml->next;
1813 1814
1815 if (in_dev)
1814 ip_mc_dec_group(in_dev, group); 1816 ip_mc_dec_group(in_dev, group);
1815 rtnl_unlock(); 1817 rtnl_unlock();
1816 sock_kfree_s(sk, iml, sizeof(*iml)); 1818 sock_kfree_s(sk, iml, sizeof(*iml));
1817 return 0; 1819 return 0;
1818 }
1819 } 1820 }
1821 if (!in_dev)
1822 ret = -ENODEV;
1820 rtnl_unlock(); 1823 rtnl_unlock();
1821 return -EADDRNOTAVAIL; 1824 return ret;
1822} 1825}
1823 1826
1824int ip_mc_source(int add, int omode, struct sock *sk, struct 1827int ip_mc_source(int add, int omode, struct sock *sk, struct
@@ -1826,7 +1829,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1826{ 1829{
1827 int err; 1830 int err;
1828 struct ip_mreqn imr; 1831 struct ip_mreqn imr;
1829 u32 addr = mreqs->imr_multiaddr; 1832 __be32 addr = mreqs->imr_multiaddr;
1830 struct ip_mc_socklist *pmc; 1833 struct ip_mc_socklist *pmc;
1831 struct in_device *in_dev = NULL; 1834 struct in_device *in_dev = NULL;
1832 struct inet_sock *inet = inet_sk(sk); 1835 struct inet_sock *inet = inet_sk(sk);
@@ -1880,7 +1883,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1880 rv = !0; 1883 rv = !0;
1881 for (i=0; i<psl->sl_count; i++) { 1884 for (i=0; i<psl->sl_count; i++) {
1882 rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr, 1885 rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
1883 sizeof(__u32)); 1886 sizeof(__be32));
1884 if (rv == 0) 1887 if (rv == 0)
1885 break; 1888 break;
1886 } 1889 }
@@ -1932,7 +1935,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1932 rv = 1; /* > 0 for insert logic below if sl_count is 0 */ 1935 rv = 1; /* > 0 for insert logic below if sl_count is 0 */
1933 for (i=0; i<psl->sl_count; i++) { 1936 for (i=0; i<psl->sl_count; i++) {
1934 rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr, 1937 rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
1935 sizeof(__u32)); 1938 sizeof(__be32));
1936 if (rv == 0) 1939 if (rv == 0)
1937 break; 1940 break;
1938 } 1941 }
@@ -1957,7 +1960,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
1957{ 1960{
1958 int err = 0; 1961 int err = 0;
1959 struct ip_mreqn imr; 1962 struct ip_mreqn imr;
1960 u32 addr = msf->imsf_multiaddr; 1963 __be32 addr = msf->imsf_multiaddr;
1961 struct ip_mc_socklist *pmc; 1964 struct ip_mc_socklist *pmc;
1962 struct in_device *in_dev; 1965 struct in_device *in_dev;
1963 struct inet_sock *inet = inet_sk(sk); 1966 struct inet_sock *inet = inet_sk(sk);
@@ -2041,7 +2044,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
2041{ 2044{
2042 int err, len, count, copycount; 2045 int err, len, count, copycount;
2043 struct ip_mreqn imr; 2046 struct ip_mreqn imr;
2044 u32 addr = msf->imsf_multiaddr; 2047 __be32 addr = msf->imsf_multiaddr;
2045 struct ip_mc_socklist *pmc; 2048 struct ip_mc_socklist *pmc;
2046 struct in_device *in_dev; 2049 struct in_device *in_dev;
2047 struct inet_sock *inet = inet_sk(sk); 2050 struct inet_sock *inet = inet_sk(sk);
@@ -2100,7 +2103,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
2100{ 2103{
2101 int err, i, count, copycount; 2104 int err, i, count, copycount;
2102 struct sockaddr_in *psin; 2105 struct sockaddr_in *psin;
2103 u32 addr; 2106 __be32 addr;
2104 struct ip_mc_socklist *pmc; 2107 struct ip_mc_socklist *pmc;
2105 struct inet_sock *inet = inet_sk(sk); 2108 struct inet_sock *inet = inet_sk(sk);
2106 struct ip_sf_socklist *psl; 2109 struct ip_sf_socklist *psl;
@@ -2153,7 +2156,7 @@ done:
2153/* 2156/*
2154 * check if a multicast source filter allows delivery for a given <src,dst,intf> 2157 * check if a multicast source filter allows delivery for a given <src,dst,intf>
2155 */ 2158 */
2156int ip_mc_sf_allow(struct sock *sk, u32 loc_addr, u32 rmt_addr, int dif) 2159int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
2157{ 2160{
2158 struct inet_sock *inet = inet_sk(sk); 2161 struct inet_sock *inet = inet_sk(sk);
2159 struct ip_mc_socklist *pmc; 2162 struct ip_mc_socklist *pmc;
@@ -2202,18 +2205,18 @@ void ip_mc_drop_socket(struct sock *sk)
2202 struct in_device *in_dev; 2205 struct in_device *in_dev;
2203 inet->mc_list = iml->next; 2206 inet->mc_list = iml->next;
2204 2207
2205 if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) { 2208 in_dev = inetdev_by_index(iml->multi.imr_ifindex);
2206 (void) ip_mc_leave_src(sk, iml, in_dev); 2209 (void) ip_mc_leave_src(sk, iml, in_dev);
2210 if (in_dev != NULL) {
2207 ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); 2211 ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
2208 in_dev_put(in_dev); 2212 in_dev_put(in_dev);
2209 } 2213 }
2210 sock_kfree_s(sk, iml, sizeof(*iml)); 2214 sock_kfree_s(sk, iml, sizeof(*iml));
2211
2212 } 2215 }
2213 rtnl_unlock(); 2216 rtnl_unlock();
2214} 2217}
2215 2218
2216int ip_check_mc(struct in_device *in_dev, u32 mc_addr, u32 src_addr, u16 proto) 2219int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 proto)
2217{ 2220{
2218 struct ip_mc_list *im; 2221 struct ip_mc_list *im;
2219 struct ip_sf_list *psf; 2222 struct ip_sf_list *psf;
@@ -2381,7 +2384,7 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file)
2381{ 2384{
2382 struct seq_file *seq; 2385 struct seq_file *seq;
2383 int rc = -ENOMEM; 2386 int rc = -ENOMEM;
2384 struct igmp_mc_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); 2387 struct igmp_mc_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
2385 2388
2386 if (!s) 2389 if (!s)
2387 goto out; 2390 goto out;
@@ -2391,7 +2394,6 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file)
2391 2394
2392 seq = file->private_data; 2395 seq = file->private_data;
2393 seq->private = s; 2396 seq->private = s;
2394 memset(s, 0, sizeof(*s));
2395out: 2397out:
2396 return rc; 2398 return rc;
2397out_kfree: 2399out_kfree:
@@ -2556,7 +2558,7 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
2556{ 2558{
2557 struct seq_file *seq; 2559 struct seq_file *seq;
2558 int rc = -ENOMEM; 2560 int rc = -ENOMEM;
2559 struct igmp_mcf_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); 2561 struct igmp_mcf_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
2560 2562
2561 if (!s) 2563 if (!s)
2562 goto out; 2564 goto out;
@@ -2566,7 +2568,6 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
2566 2568
2567 seq = file->private_data; 2569 seq = file->private_data;
2568 seq->private = s; 2570 seq->private = s;
2569 memset(s, 0, sizeof(*s));
2570out: 2571out:
2571 return rc; 2572 return rc;
2572out_kfree: 2573out_kfree: