aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2015-04-10 19:09:51 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2015-04-10 19:09:51 +0000
commite2956804dd07dfc341e820df5b1e91854ecdd3bc (patch)
tree20a7f4e73b1b98b5c3be5003b01611280d97e5c2 /sys
parentb7ba1c08fe2e48cfe45448f7a79d385f311ad51a (diff)
downloadsrc-e2956804dd07dfc341e820df5b1e91854ecdd3bc.tar.gz
src-e2956804dd07dfc341e820df5b1e91854ecdd3bc.zip
Fix the IPV6_MULTICAST_IF sockopt handling. RFC 3493 says when the
interface index is specified as zero, the system should select the interface to use for outgoing multicast packets. Even the comment for the in6p_set_multicast_if() function says about index of zero. But in fact for zero index the function just returns EADDRNOTAVAIL. I.e. if you first set some interface and then will try reset it with zero ifindex, you will get EADDRNOTAVAIL. Reset im6o_multicast_ifp to NULL when interface index specified as zero. Also return EINVAL in case when ifnet_byindex() returns NULL. This will be the same behaviour as when ifindex is bigger than V_if_index. And return EADDRNOTAVAIL only when interface is not multicast capable. Reported by: Olivier Cochard-Labbé MFC after: 2 weeks Sponsored by: Yandex LLC
Notes
Notes: svn path=/head/; revision=281380
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet6/in6_mcast.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c
index d872b8767a5a..4bc66e67b0e8 100644
--- a/sys/netinet6/in6_mcast.c
+++ b/sys/netinet6/in6_mcast.c
@@ -2348,11 +2348,15 @@ in6p_set_multicast_if(struct inpcb *inp, struct sockopt *sopt)
return (error);
if (V_if_index < ifindex)
return (EINVAL);
-
- ifp = ifnet_byindex(ifindex);
- if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0)
- return (EADDRNOTAVAIL);
-
+ if (ifindex == 0)
+ ifp = NULL;
+ else {
+ ifp = ifnet_byindex(ifindex);
+ if (ifp == NULL)
+ return (EINVAL);
+ if ((ifp->if_flags & IFF_MULTICAST) == 0)
+ return (EADDRNOTAVAIL);
+ }
imo = in6p_findmoptions(inp);
imo->im6o_multicast_ifp = ifp;
INP_WUNLOCK(inp);