diff mbox

[v2] ipv4/ipv6: multicast api unappropriate errno fix.

Message ID 501B99E1.9090803@cn.fujitsu.com
State Rejected, archived
Delegated to: David Miller
Headers show

Commit Message

Wei Li Aug. 3, 2012, 9:29 a.m. UTC
commit 917f2f105([IPV4]: multicast API "join" issues) corrected
some errno values but also caused unappropriate errno returned.

With an unjoined group address, return -EADDRNOTAVAIL would be
much better than -EINVAL.

Also correct the errno when to join an source group which we have
already joined to -EADDRINUSE.

Signed-off-by: Li Wei <lw@cn.fujitsu.com>

--
V2: return -EADDRINUSE when join an already joined source group.
---
 net/ipv4/igmp.c  |    8 +++-----
 net/ipv6/mcast.c |   12 ++++++------
 2 files changed, 9 insertions(+), 11 deletions(-)

Comments

David Stevens Aug. 3, 2012, 12:09 p.m. UTC | #1
netdev-owner@vger.kernel.org wrote on 08/03/2012 05:29:05 AM:

> @@ -1933,10 +1933,8 @@ int ip_mc_source(int add, int omode, struct 
> sock *sk, struct
>            (pmc->multi.imr_ifindex == imr.imr_ifindex))
>           break;
>     }
> -   if (!pmc) {      /* must have a prior join */
> -      err = -EINVAL;
> -      goto done;
> -   }
> +   if (!pmc)      /* must have a prior join */
> +      goto done;   /* err = -EADDRNOTAVAIL */

RFC3678, section 4.1.3:
        "When the option itself is not legal on the group (i.e., when 
trying a
   Source-Specific option on a group after doing IP_ADD_MEMBERSHIP, or
   when trying an Any-Source option without doing IP_ADD_MEMBERSHIP) the
   error generated is EINVAL."

>     }
> -   if (rv == 0)      /* address already there is an error */
> +   if (rv == 0) {      /* address already there is an error */
> +      err = -EADDRINUSE;
>        goto done;
> +   }

EADDRINUSE is not one of the API's listed error codes. Section 4.1.3
of RFC3678 specifies:
  "When the option would be legal on the group, but an address is
   invalid (e.g., when trying to block a source that is already blocked
   by the socket, or when trying to drop an unjoined group) the error
   generated is EADDRNOTAVAIL."

At least some of this patch directly differs with RFC3678.

                                                        +-DLS

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wei Li Aug. 6, 2012, 1:19 a.m. UTC | #2
On 08/03/2012 08:09 PM, David Stevens wrote:
> netdev-owner@vger.kernel.org wrote on 08/03/2012 05:29:05 AM:
> 
>> @@ -1933,10 +1933,8 @@ int ip_mc_source(int add, int omode, struct 
>> sock *sk, struct
>>            (pmc->multi.imr_ifindex == imr.imr_ifindex))
>>           break;
>>     }
>> -   if (!pmc) {      /* must have a prior join */
>> -      err = -EINVAL;
>> -      goto done;
>> -   }
>> +   if (!pmc)      /* must have a prior join */
>> +      goto done;   /* err = -EADDRNOTAVAIL */
> 
> RFC3678, section 4.1.3:
>         "When the option itself is not legal on the group (i.e., when 
> trying a
>    Source-Specific option on a group after doing IP_ADD_MEMBERSHIP, or
>    when trying an Any-Source option without doing IP_ADD_MEMBERSHIP) the
>    error generated is EINVAL."
> 
>>     }
>> -   if (rv == 0)      /* address already there is an error */
>> +   if (rv == 0) {      /* address already there is an error */
>> +      err = -EADDRINUSE;
>>        goto done;
>> +   }
> 
> EADDRINUSE is not one of the API's listed error codes. Section 4.1.3
> of RFC3678 specifies:
>   "When the option would be legal on the group, but an address is
>    invalid (e.g., when trying to block a source that is already blocked
>    by the socket, or when trying to drop an unjoined group) the error
>    generated is EADDRNOTAVAIL."
> 
> At least some of this patch directly differs with RFC3678.

I read the RFC and found you are right, thanks :)

> 
>                                                         +-DLS
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 6699f23..c45c092 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1933,10 +1933,8 @@  int ip_mc_source(int add, int omode, struct sock *sk, struct
 		    (pmc->multi.imr_ifindex == imr.imr_ifindex))
 			break;
 	}
-	if (!pmc) {		/* must have a prior join */
-		err = -EINVAL;
-		goto done;
-	}
+	if (!pmc)		/* must have a prior join */
+		goto done;	/* err = -EADDRNOTAVAIL */
 	/* if a source filter was set, must be the same mode as before */
 	if (pmc->sflist) {
 		if (pmc->sfmode != omode) {
@@ -2076,7 +2074,7 @@  int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
 			break;
 	}
 	if (!pmc) {		/* must have a prior join */
-		err = -EINVAL;
+		err = -EADDRNOTAVAIL;
 		goto done;
 	}
 	if (msf->imsf_numsrc) {
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 92f8e48..dcd12c0 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -347,10 +347,8 @@  int ip6_mc_source(int add, int omode, struct sock *sk,
 		if (ipv6_addr_equal(&pmc->addr, group))
 			break;
 	}
-	if (!pmc) {		/* must have a prior join */
-		err = -EINVAL;
-		goto done;
-	}
+	if (!pmc)		/* must have a prior join */
+		goto done;	/* err = -EADDRNOTAVAIL */
 	/* if a source filter was set, must be the same mode as before */
 	if (pmc->sflist) {
 		if (pmc->sfmode != omode) {
@@ -428,8 +426,10 @@  int ip6_mc_source(int add, int omode, struct sock *sk,
 		if (rv == 0)
 			break;
 	}
-	if (rv == 0)		/* address already there is an error */
+	if (rv == 0) {		/* address already there is an error */
+		err = -EADDRINUSE;
 		goto done;
+	}
 	for (j=psl->sl_count-1; j>=i; j--)
 		psl->sl_addr[j+1] = psl->sl_addr[j];
 	psl->sl_addr[i] = *source;
@@ -488,7 +488,7 @@  int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf)
 			break;
 	}
 	if (!pmc) {		/* must have a prior join */
-		err = -EINVAL;
+		err = -EADDRNOTAVAIL;
 		goto done;
 	}
 	if (gsf->gf_numsrc) {