On 03/05/2019 19:50, Aleksandar Markovic wrote:
> From: Neng Chen <nchen@wavecomp.com>
>
> Add support for options IPV6_ADD_MEMBERSHIP and IPV6_DROP_MEMPEMBERSHIP
> of the syscall setsockopt(). These options control membership in
> multicast groups. Their argument is a pointer to a struct ipv6_mreq,
> which is in turn defined as:
>
> struct ipv6_mreq {
> /* IPv6 multicast address of group */
> struct in6_addr ipv6mr_multiaddr;
> /* local IPv6 address of interface */
> int ipv6mr_interface;
> };
>
> The in6_addr structure consists of fields that are always big-endian
> (on host of any endian), so the ipv6_mreq's field ipv6mr_multiaddr
> doesn't need any endian conversion, whereas ipv6mr_interface does.
>
> Signed-off-by: Neng Chen <nchen@wavecomp.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> ---
> linux-user/syscall.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 96cd4bf..b7eb4b7 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -1892,6 +1892,25 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
> &pki, sizeof(pki)));
> break;
> }
> + case IPV6_ADD_MEMBERSHIP:
> + case IPV6_DROP_MEMBERSHIP:
> + {
> + struct ipv6_mreq ipv6mreq;
> +
> + if (optlen < sizeof(ipv6mreq)) {
> + return -TARGET_EINVAL;
> + }
> +
> + if (copy_from_user(&ipv6mreq, optval_addr, sizeof(ipv6mreq))) {
> + return -TARGET_EFAULT;
> + }
> +
> + ipv6mreq.ipv6mr_interface = tswap32(ipv6mreq.ipv6mr_interface);
The name of this field seems to depend on where it is defined: in
netinet/in.h, it's ipv6mr_interface, but in linux/in6.h it's
ipv6mr_ifindex. I think you should check "__UAPI_DEF_IPV6_MREQ" to use
the good one.
> +
> + ret = get_errno(setsockopt(sockfd, level, optname,
> + &ipv6mreq, sizeof(ipv6mreq)));
> + break;
> + }
> default:
> goto unimplemented;
> }
>
Thanks,
Laurent