From patchwork Mon May 27 18:48:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 246637 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C9B172C0085 for ; Tue, 28 May 2013 04:49:24 +1000 (EST) Received: from localhost ([::1]:57727 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uh2Tz-0004pA-3m for incoming@patchwork.ozlabs.org; Mon, 27 May 2013 14:49:23 -0400 Received: from eggs.gnu.org ([208.118.235.92]:47260) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uh2Tb-0004oy-I7 for qemu-devel@nongnu.org; Mon, 27 May 2013 14:49:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uh2TS-0006Yv-Om for qemu-devel@nongnu.org; Mon, 27 May 2013 14:48:59 -0400 Received: from smtp1-g21.free.fr ([2a01:e0c:1:1599::10]:41618) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uh2TS-0006Y6-63 for qemu-devel@nongnu.org; Mon, 27 May 2013 14:48:50 -0400 Received: from Quad (unknown [IPv6:2a01:e34:eeee:5240:55a5:f281:64b1:317a]) by smtp1-g21.free.fr (Postfix) with ESMTP id EF03F94009F; Mon, 27 May 2013 20:48:39 +0200 (CEST) Received: from laurent by Quad with local (Exim 4.80) (envelope-from ) id 1Uh2TG-0004pf-EG; Mon, 27 May 2013 20:48:38 +0200 From: Laurent Vivier To: Riku Voipio Date: Mon, 27 May 2013 20:48:36 +0200 Message-Id: <1369680516-18544-1-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 1.8.1.2 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a01:e0c:1:1599::10 Cc: qemu-devel@nongnu.org, Laurent Vivier Subject: [Qemu-devel] [PATCH] linux-user: add SIOCADDRT/SIOCDELRT support 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 allows to pass the device name. You can test this with the "route" command. WITHOUT this patch: $ sudo route add -net default gw 10.0.3.1 eth0 SIOCADDRT: Bad address $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Ifa 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth WITH this patch: $ sudo route add -net default gw 10.0.3.1 eth0 $ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Ifa 0.0.0.0 10.0.3.1 0.0.0.0 UG 0 0 0 eth 10.0.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth Signed-off-by: Laurent Vivier Reviewed-by: Peter Maydell --- linux-user/ioctls.h | 6 +++-- linux-user/syscall.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 8a47767..439c2a9 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -88,8 +88,6 @@ #endif IOCTL(SIOCATMARK, 0, TYPE_NULL) - IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry))) - IOCTL(SIOCDELRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry))) IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT)) IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq))) IOCTL(SIOCSIFFLAGS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_short_ifreq))) @@ -379,3 +377,7 @@ MK_PTR(MK_STRUCT(STRUCT_dm_ioctl))) IOCTL_SPECIAL(DM_DEV_SET_GEOMETRY, IOC_RW, do_ioctl_dm, MK_PTR(MK_STRUCT(STRUCT_dm_ioctl))) + IOCTL_SPECIAL(SIOCADDRT, IOC_W, do_ioctl_rt, + MK_PTR(MK_STRUCT(STRUCT_rtentry))) + IOCTL_SPECIAL(SIOCDELRT, IOC_W, do_ioctl_rt, + MK_PTR(MK_STRUCT(STRUCT_rtentry))) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 1b3c0ed..a5cd166 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -105,6 +105,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include #include #include +#include #include "linux_loop.h" #include "cpu-uname.h" @@ -3714,6 +3715,69 @@ out: return ret; } +static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, abi_long cmd, abi_long arg) +{ + const argtype *arg_type = ie->arg_type; + const StructEntry *se; + const argtype *field_types; + const int *dst_offsets, *src_offsets; + int target_size; + void *argptr; + abi_ulong *target_rt_dev_ptr; + unsigned long *host_rt_dev_ptr; + abi_long ret; + int i; + + assert(ie->access == IOC_W); + assert(*arg_type == TYPE_PTR); + arg_type++; + assert(*arg_type == TYPE_STRUCT); + target_size = thunk_type_size(arg_type, 0); + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) { + return -TARGET_EFAULT; + } + arg_type++; + assert(*arg_type == (int)STRUCT_rtentry); + se = struct_entries + *arg_type++; + assert(se->convert[0] == NULL); + /* convert struct here to be able to catch rt_dev string */ + field_types = se->field_types; + dst_offsets = se->field_offsets[THUNK_HOST]; + src_offsets = se->field_offsets[THUNK_TARGET]; + for (i = 0; i < se->nb_fields; i++) { + if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) { + assert(*field_types == TYPE_PTRVOID); + target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]); + host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]); + if (*target_rt_dev_ptr != 0) { + *host_rt_dev_ptr = (unsigned long)lock_user_string( + tswapal(*target_rt_dev_ptr)); + if (!*host_rt_dev_ptr) { + unlock_user(argptr, arg, 0); + return -TARGET_EFAULT; + } + } else { + *host_rt_dev_ptr = 0; + } + field_types++; + continue; + } + field_types = thunk_convert(buf_temp + dst_offsets[i], + argptr + src_offsets[i], + field_types, THUNK_HOST); + } + unlock_user(argptr, arg, 0); + + ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); + if (*host_rt_dev_ptr != 0) { + unlock_user((void *)*host_rt_dev_ptr, + *target_rt_dev_ptr, 0); + } + return ret; +} + static IOCTLEntry ioctl_entries[] = { #define IOCTL(cmd, access, ...) \ { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },