qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v4 4/5] linux-user: Add support for setsockopt()


From: Laurent Vivier
Subject: Re: [Qemu-devel] [PATCH v4 4/5] linux-user: Add support for setsockopt() options IPV6_<ADD|DROP>_MEMBERSHIP
Date: Mon, 13 May 2019 14:00:48 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0

On 03/05/2019 19:50, Aleksandar Markovic wrote:
From: Neng Chen <address@hidden>

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 <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 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]