[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v12 1/5] linux-user: Add support for setsockopt(
From: |
Laurent Vivier |
Subject: |
Re: [Qemu-devel] [PATCH v12 1/5] linux-user: Add support for setsockopt() options IPV6_<ADD|DROP>_MEMBERSHIP |
Date: |
Wed, 19 Jun 2019 18:08:21 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 |
Le 19/06/2019 à 16:17, Aleksandar Markovic a écrit :
> From: Neng Chen <address@hidden>
>
> Add support for the option IPV6_<ADD|DROP>_MEMBERSHIP of the syscall
> setsockopt(). This option controls membership in multicast groups.
> Argument is a pointer to a struct ipv6_mreq.
>
> The glibc <netinet/in.h> header defines the ipv6_mreq structure,
> which includes the following members:
>
> struct in6_addr ipv6mr_multiaddr;
> unsigned int ipv6mr_interface;
>
> Whereas the kernel in its <linux/in6.h> header defines following
> members of the same structure:
>
> struct in6_addr ipv6mr_multiaddr;
> int ipv6mr_ifindex;
>
> POSIX defines ipv6mr_interface [1].
>
> __UAPI_DEF_IVP6_MREQ appears in kernel headers with v3.12:
>
> cfd280c91253 net: sync some IP headers with glibc
>
> Without __UAPI_DEF_IVP6_MREQ, kernel defines ipv6mr_ifindex, and
> this is explained in cfd280c91253:
>
> "If you include the kernel headers first you get those,
> and if you include the glibc headers first you get those,
> and the following patch arranges a coordination and
> synchronization between the two."
>
> So before 3.12, a program can't include both <netinet/in.h> and
> <linux/in6.h>.
>
> In linux-user/syscall.c, we only include <netinet/in.h> (glibc) and
> not <linux/in6.h> (kernel headers), so ipv6mr_interface is the one
> to use.
>
> [1] http://pubs.opengroup.org/onlinepubs/009695399/basedefs/netinet/in.h.html
>
> Signed-off-by: Neng Chen <address@hidden>
> Signed-off-by: Aleksandar Markovic <address@hidden>
> ---
> linux-user/syscall.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index b187c12..f267ad0 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -1920,6 +1920,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);
> +
> + ret = get_errno(setsockopt(sockfd, level, optname,
> + &ipv6mreq, sizeof(ipv6mreq)));
> + break;
> + }
> default:
> goto unimplemented;
> }
>
Reviewed-by: Laurent Vivier <address@hidden>