mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 23:23:03 +00:00
ipv6: take handling of group_source_req options into a helper
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
2bbf8c1ead
commit
fcfa0b09d3
@ -136,6 +136,41 @@ static bool setsockopt_needs_rtnl(int optname)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int do_ipv6_mcast_group_source(struct sock *sk, int optname,
|
||||
struct group_source_req *greqs)
|
||||
{
|
||||
int omode, add;
|
||||
|
||||
if (greqs->gsr_group.ss_family != AF_INET6 ||
|
||||
greqs->gsr_source.ss_family != AF_INET6)
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
if (optname == MCAST_BLOCK_SOURCE) {
|
||||
omode = MCAST_EXCLUDE;
|
||||
add = 1;
|
||||
} else if (optname == MCAST_UNBLOCK_SOURCE) {
|
||||
omode = MCAST_EXCLUDE;
|
||||
add = 0;
|
||||
} else if (optname == MCAST_JOIN_SOURCE_GROUP) {
|
||||
struct sockaddr_in6 *psin6;
|
||||
int retv;
|
||||
|
||||
psin6 = (struct sockaddr_in6 *)&greqs->gsr_group;
|
||||
retv = ipv6_sock_mc_join_ssm(sk, greqs->gsr_interface,
|
||||
&psin6->sin6_addr,
|
||||
MCAST_INCLUDE);
|
||||
/* prior join w/ different source is ok */
|
||||
if (retv && retv != -EADDRINUSE)
|
||||
return retv;
|
||||
omode = MCAST_INCLUDE;
|
||||
add = 1;
|
||||
} else /* MCAST_LEAVE_SOURCE_GROUP */ {
|
||||
omode = MCAST_INCLUDE;
|
||||
add = 0;
|
||||
}
|
||||
return ip6_mc_source(add, omode, sk, greqs);
|
||||
}
|
||||
|
||||
static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, unsigned int optlen)
|
||||
{
|
||||
@ -715,7 +750,6 @@ done:
|
||||
case MCAST_UNBLOCK_SOURCE:
|
||||
{
|
||||
struct group_source_req greqs;
|
||||
int omode, add;
|
||||
|
||||
if (optlen < sizeof(struct group_source_req))
|
||||
goto e_inval;
|
||||
@ -723,34 +757,7 @@ done:
|
||||
retv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (greqs.gsr_group.ss_family != AF_INET6 ||
|
||||
greqs.gsr_source.ss_family != AF_INET6) {
|
||||
retv = -EADDRNOTAVAIL;
|
||||
break;
|
||||
}
|
||||
if (optname == MCAST_BLOCK_SOURCE) {
|
||||
omode = MCAST_EXCLUDE;
|
||||
add = 1;
|
||||
} else if (optname == MCAST_UNBLOCK_SOURCE) {
|
||||
omode = MCAST_EXCLUDE;
|
||||
add = 0;
|
||||
} else if (optname == MCAST_JOIN_SOURCE_GROUP) {
|
||||
struct sockaddr_in6 *psin6;
|
||||
|
||||
psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
|
||||
retv = ipv6_sock_mc_join_ssm(sk, greqs.gsr_interface,
|
||||
&psin6->sin6_addr,
|
||||
MCAST_INCLUDE);
|
||||
/* prior join w/ different source is ok */
|
||||
if (retv && retv != -EADDRINUSE)
|
||||
break;
|
||||
omode = MCAST_INCLUDE;
|
||||
add = 1;
|
||||
} else /* MCAST_LEAVE_SOURCE_GROUP */ {
|
||||
omode = MCAST_INCLUDE;
|
||||
add = 0;
|
||||
}
|
||||
retv = ip6_mc_source(add, omode, sk, &greqs);
|
||||
retv = do_ipv6_mcast_group_source(sk, optname, &greqs);
|
||||
break;
|
||||
}
|
||||
case MCAST_MSFILTER:
|
||||
|
Loading…
Reference in New Issue
Block a user