mirror of https://gitee.com/openkylin/qemu.git
linux-user: add SIOCADDRT/SIOCDELRT support
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 <laurent@vivier.eu> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
463d8e7393
commit
7ff7b66618
|
@ -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)))
|
||||
|
|
|
@ -105,6 +105,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
|
|||
#include <linux/vt.h>
|
||||
#include <linux/dm-ioctl.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/route.h>
|
||||
#include "linux_loop.h"
|
||||
#include "cpu-uname.h"
|
||||
|
||||
|
@ -3551,6 +3552,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__ } },
|
||||
|
|
Loading…
Reference in New Issue