From patchwork Fri Sep 27 12:09:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Riku Voipio X-Patchwork-Id: 278557 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 083042C00B7 for ; Fri, 27 Sep 2013 22:11:15 +1000 (EST) Received: from localhost ([::1]:35921 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPWt6-00060d-RS for incoming@patchwork.ozlabs.org; Fri, 27 Sep 2013 08:11:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59617) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPWsH-0005ru-DA for qemu-devel@nongnu.org; Fri, 27 Sep 2013 08:10:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VPWs8-00085U-HS for qemu-devel@nongnu.org; Fri, 27 Sep 2013 08:10:21 -0400 Received: from afflict.kos.to ([92.243.29.197]:51420) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPWs8-00083V-6x for qemu-devel@nongnu.org; Fri, 27 Sep 2013 08:10:12 -0400 Received: from kos.to (a91-156-63-85.elisa-laajakaista.fi [91.156.63.85]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by afflict.kos.to (Postfix) with ESMTPSA id A189A26558 for ; Fri, 27 Sep 2013 14:10:09 +0200 (CEST) Received: from voipio (uid 1000) (envelope-from voipio@kos.to) id 5e0a58 by kos.to (DragonFly Mail Agent); Fri, 27 Sep 2013 15:10:07 +0300 From: riku.voipio@linaro.org To: qemu-devel@nongnu.org Date: Fri, 27 Sep 2013 15:09:59 +0300 Message-Id: X-Mailer: git-send-email 1.8.1.2 In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 92.243.29.197 Cc: Laurent Vivier Subject: [Qemu-devel] [PATCH 04/11] 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 From: Laurent Vivier This is needed to be able to run dhclient. Signed-off-by: Laurent Vivier Reviewed-by: Peter Maydell Signed-off-by: Riku Voipio --- 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 251c116..505031b 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 2ebe356..5f53a28 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 */ };