From patchwork Thu Aug 29 23:46:41 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 271007 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 416362C009A for ; Fri, 30 Aug 2013 09:47:59 +1000 (EST) Received: from localhost ([::1]:46442 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFBwT-0006mj-7h for incoming@patchwork.ozlabs.org; Thu, 29 Aug 2013 19:47:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43353) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFBvz-0006ey-CZ for qemu-devel@nongnu.org; Thu, 29 Aug 2013 19:47:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VFBvy-0005Q7-AT for qemu-devel@nongnu.org; Thu, 29 Aug 2013 19:47:27 -0400 Received: from smtp5-g21.free.fr ([2a01:e0c:1:1599::14]:42697) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFBvx-0005Pl-Mp for qemu-devel@nongnu.org; Thu, 29 Aug 2013 19:47:26 -0400 Received: from Quad (unknown [IPv6:2a01:e34:eeee:5240:9daa:7271:81b9:90fb]) by smtp5-g21.free.fr (Postfix) with ESMTP id AB9CED4808F; Fri, 30 Aug 2013 01:47:18 +0200 (CEST) Received: from laurent by Quad with local (Exim 4.80) (envelope-from ) id 1VFBvp-00010q-9i; Fri, 30 Aug 2013 01:47:17 +0200 From: Laurent Vivier To: Riku Voipio Date: Fri, 30 Aug 2013 01:46:41 +0200 Message-Id: <1377820005-3835-3-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1377820005-3835-1-git-send-email-laurent@vivier.eu> References: <1377820005-3835-1-git-send-email-laurent@vivier.eu> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a01:e0c:1:1599::14 Cc: qemu-devel@nongnu.org, Laurent Vivier Subject: [Qemu-devel] [PATCH 2/6] linux-user: Add setsockopt(SO_ATTACH_FILTER) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This is needed to be able to run dhclient. Signed-off-by: Laurent Vivier Reviewed-by: Peter Maydell --- linux-user/syscall.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ linux-user/syscall_defs.h | 12 ++++++++++++ 2 files changed, 56 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b19f712..9acc4f5 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -106,6 +106,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include #include #include +#include #include "linux_loop.h" #include "cpu-uname.h" @@ -1357,6 +1358,49 @@ set_timeout: case TARGET_SO_SNDTIMEO: optname = SO_SNDTIMEO; goto set_timeout; + case TARGET_SO_ATTACH_FILTER: + { + struct target_sock_fprog *tfprog; + struct target_sock_filter *tfilter; + struct sock_fprog fprog; + struct sock_filter *filter; + int i; + + if (optlen != sizeof(*tfprog)) { + return -TARGET_EINVAL; + } + if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) { + return -TARGET_EFAULT; + } + if (!lock_user_struct(VERIFY_READ, tfilter, + tswapal(tfprog->filter), 0)) { + unlock_user_struct(tfprog, optval_addr, 1); + return -TARGET_EFAULT; + } + + fprog.len = tswap16(tfprog->len); + filter = malloc(fprog.len * sizeof(*filter)); + if (filter == NULL) { + unlock_user_struct(tfilter, tfprog->filter, 1); + unlock_user_struct(tfprog, optval_addr, 1); + return -TARGET_ENOMEM; + } + for (i = 0; i < fprog.len; i++) { + filter[i].code = tswap16(tfilter[i].code); + filter[i].jt = tfilter[i].jt; + filter[i].jf = tfilter[i].jf; + filter[i].k = tswap32(tfilter[i].k); + } + fprog.filter = filter; + + ret = get_errno(setsockopt(sockfd, SOL_SOCKET, + SO_ATTACH_FILTER, &fprog, sizeof(fprog))); + free(filter); + + unlock_user_struct(tfilter, tfprog->filter, 1); + unlock_user_struct(tfprog, optval_addr, 1); + return ret; + } /* Options with 'int' argument. */ case TARGET_SO_DEBUG: optname = SO_DEBUG; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 086fbff..b0630ca 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -119,6 +119,18 @@ struct target_sockaddr { uint8_t sa_data[14]; }; +struct target_sock_filter { + abi_ushort code; + uint8_t jt; + uint8_t jf; + abi_uint k; +}; + +struct target_sock_fprog { + abi_ushort len; + abi_ulong filter; +}; + struct target_in_addr { uint32_t s_addr; /* big endian */ };