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.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index e21ebe759907..dbbfa09de4e8 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1748,12 +1748,16 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1748 && pmc->multi.imr_ifindex == imr.imr_ifindex) 1748 && pmc->multi.imr_ifindex == imr.imr_ifindex)
1749 break; 1749 break;
1750 } 1750 }
1751 if (!pmc) /* must have a prior join */ 1751 if (!pmc) { /* must have a prior join */
1752 err = -EINVAL;
1752 goto done; 1753 goto done;
1754 }
1753 /* if a source filter was set, must be the same mode as before */ 1755 /* if a source filter was set, must be the same mode as before */
1754 if (pmc->sflist) { 1756 if (pmc->sflist) {
1755 if (pmc->sfmode != omode) 1757 if (pmc->sfmode != omode) {
1758 err = -EINVAL;
1756 goto done; 1759 goto done;
1760 }
1757 } else if (pmc->sfmode != omode) { 1761 } else if (pmc->sfmode != omode) {
1758 /* allow mode switches for empty-set filters */ 1762 /* allow mode switches for empty-set filters */
1759 ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 0, NULL, 0); 1763 ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 0, NULL, 0);
@@ -1765,7 +1769,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1765 psl = pmc->sflist; 1769 psl = pmc->sflist;
1766 if (!add) { 1770 if (!add) {
1767 if (!psl) 1771 if (!psl)
1768 goto done; 1772 goto done; /* err = -EADDRNOTAVAIL */
1769 rv = !0; 1773 rv = !0;
1770 for (i=0; i<psl->sl_count; i++) { 1774 for (i=0; i<psl->sl_count; i++) {
1771 rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr, 1775 rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
@@ -1774,7 +1778,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
1774 break; 1778 break;
1775 } 1779 }
1776 if (rv) /* source not found */ 1780 if (rv) /* source not found */
1777 goto done; 1781 goto done; /* err = -EADDRNOTAVAIL */
1778 1782
1779 /* special case - (INCLUDE, empty) == LEAVE_GROUP */ 1783 /* special case - (INCLUDE, empty) == LEAVE_GROUP */
1780 if (psl->sl_count == 1 && omode == MCAST_INCLUDE) { 1784 if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
@@ -1870,15 +1874,16 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
1870 err = -ENODEV; 1874 err = -ENODEV;
1871 goto done; 1875 goto done;
1872 } 1876 }
1873 err = -EADDRNOTAVAIL;
1874 1877
1875 for (pmc=inet->mc_list; pmc; pmc=pmc->next) { 1878 for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
1876 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && 1879 if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
1877 pmc->multi.imr_ifindex == imr.imr_ifindex) 1880 pmc->multi.imr_ifindex == imr.imr_ifindex)
1878 break; 1881 break;
1879 } 1882 }
1880 if (!pmc) /* must have a prior join */ 1883 if (!pmc) { /* must have a prior join */
1884 err = -EINVAL;
1881 goto done; 1885 goto done;
1886 }
1882 if (msf->imsf_numsrc) { 1887 if (msf->imsf_numsrc) {
1883 newpsl = (struct ip_sf_socklist *)sock_kmalloc(sk, 1888 newpsl = (struct ip_sf_socklist *)sock_kmalloc(sk,
1884 IP_SFLSIZE(msf->imsf_numsrc), GFP_KERNEL); 1889 IP_SFLSIZE(msf->imsf_numsrc), GFP_KERNEL);
@@ -1907,6 +1912,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
1907 0, NULL, 0); 1912 0, NULL, 0);
1908 pmc->sflist = newpsl; 1913 pmc->sflist = newpsl;
1909 pmc->sfmode = msf->imsf_fmode; 1914 pmc->sfmode = msf->imsf_fmode;
1915 err = 0;
1910done: 1916done:
1911 rtnl_shunlock(); 1917 rtnl_shunlock();
1912 return err; 1918 return err;