All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
@ 2016-05-22 16:56 Laurent Vivier
  2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 1/3] linux-user: add rtnetlink(7) support Laurent Vivier
                   ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Laurent Vivier @ 2016-05-22 16:56 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel, Peter Maydell, Laurent Vivier

Since commit:
e36800c linux-user: add signalfd/signalfd4 syscalls

It is now possible to register handlers to a file descriptor
to translate a data stream transiting by this file descriptor.

We can now decode netlink information coming from the guest
and inject a translated one into the host, and vice-versa.

This series is an "RFC" because it works (we can boot a
container using systemd and use iproute tools) but some
problems remain.

Some results (x86_64 host) with some guests:

* ppc: it can boot a debian 8.2/8.3 (Jessie) LXC container
  and networking works fine (dhcp and "apt-get upgrade").

  "ip link" generates some traces in the kernel log:
  "netlink: 8 bytes leftover after parsing attributes in process `ip'."

* ppc64: it can boot a fedora 21 LXC container.

  Some issues with dhclient and "dnf update"
  -> missing netlink nested types 18 and 26
  -> uniplemented instruction "evmheumiaaw"

  "ip link" generates some traces in the kernel log:
  "netlink: 8 bytes leftover after parsing attributes in process `ip'."

* ppc64le: Debian 8.3 (Jessie).

  ip commands work fine, but "apt-get update" generates some netlink
  invalid types (and fails):
    Unknown target IFA type: 130
    Unknown target IFA type: 59722
    Unknown target IFA type: 59657
    Unknown target IFA type: 15648
    Unknown target IFA type: 32008
    Unknown target IFA type: 16590

* sh4: container doesn't work but 'ip' in a chroot works well.

* arm: Raspbian 8.3 (Jessie) works fine.

* s390x: container Debian 8.1 boots well, but "apt-get" hangs on
  networking (name resolution?).

  "ip link" generates some traces in the kernel log:
  "netlink: 8 bytes leftover after parsing attributes in process `ip'."

v2:

Check domain before opening socket
Remove cast to int of sizeof()
Move NLMSG_DONE into the switch()
Fix '{' in 'case:'
Reorder data types by type size
Add new conversions (IFLA_STATS, IFLA_STATS64, IFLA_MAP)
Add warning for nested type (not supported)
Add logs with gemu_log()
Don't convert rta_len and rta_type in the error case

Laurent Vivier (3):
  linux-user: add rtnetlink(7) support
  linux-user: support netlink protocol NETLINK_KOBJECT_UEVENT
  linux-user: add netlink audit

 linux-user/syscall.c | 643 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 637 insertions(+), 6 deletions(-)

-- 
2.5.5

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v2 1/3] linux-user: add rtnetlink(7) support
  2016-05-22 16:56 [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Laurent Vivier
@ 2016-05-22 16:56 ` Laurent Vivier
  2016-06-14  9:34   ` Peter Maydell
  2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 2/3] linux-user: support netlink protocol NETLINK_KOBJECT_UEVENT Laurent Vivier
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 20+ messages in thread
From: Laurent Vivier @ 2016-05-22 16:56 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel, Peter Maydell, Laurent Vivier

rtnetlink is needed to use iproute package (ip addr, ip route)
and dhcp client.

Examples:

Without this patch:
    # ip link
    Cannot open netlink socket: Address family not supported by protocol
    # ip addr
    Cannot open netlink socket: Address family not supported by protocol
    # ip route
    Cannot open netlink socket: Address family not supported by protocol
    # dhclient eth0
    Cannot open netlink socket: Address family not supported by protocol
    Cannot open netlink socket: Address family not supported by protocol

With this patch:
    # ip link
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    51: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT qlen 1000
        link/ether 00:16:3e:89:6b:d7 brd ff:ff:ff:ff:ff:ff
    # ip addr show eth0
    51: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
        link/ether 00:16:3e:89:6b:d7 brd ff:ff:ff:ff:ff:ff
        inet 192.168.122.197/24 brd 192.168.122.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::216:3eff:fe89:6bd7/64 scope link
           valid_lft forever preferred_lft forever
    # ip route
    default via 192.168.122.1 dev eth0
    192.168.122.0/24 dev eth0  proto kernel  scope link  src 192.168.122.197
    # ip addr flush eth0
    # ip addr add 192.168.122.10 dev eth0
    # ip addr show eth0
    51: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
        link/ether 00:16:3e:89:6b:d7 brd ff:ff:ff:ff:ff:ff
        inet 192.168.122.10/32 scope global eth0
           valid_lft forever preferred_lft forever
    # ip route add 192.168.122.0/24 via 192.168.122.10
    # ip route
        192.168.122.0/24 via 192.168.122.10 dev eth0

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
v2:
Check domain before opening socket
Remove cast to int of sizeof()
Move NLMSG_DONE into the switch()
Fix '{' in 'case:'
Reorder data types by type size
Add new conversions (IFLA_STATS, IFLA_STATS64, IFLA_MAP)
Add warning for nested type (not supported)
Add logs with gemu_log()
Don't convert rta_len and rta_type in the error case

 linux-user/syscall.c | 581 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 575 insertions(+), 6 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d1f4f0e..3f1b2cc 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -103,6 +103,8 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <linux/blkpg.h>
 #include "linux_loop.h"
 #include <linux/if_packet.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
 #include "uname.h"
 
 #include "qemu.h"
@@ -301,6 +303,14 @@ static TargetFdTrans **target_fd_trans;
 
 static unsigned int target_fd_max;
 
+static TargetFdDataFunc fd_trans_target_to_host_data(int fd)
+{
+    if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
+        return target_fd_trans[fd]->target_to_host_data;
+    }
+    return NULL;
+}
+
 static TargetFdDataFunc fd_trans_host_to_target_data(int fd)
 {
     if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
@@ -1205,7 +1215,13 @@ static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
 
     memcpy(addr, target_saddr, len);
     addr->sa_family = sa_family;
-    if (sa_family == AF_PACKET) {
+    if (sa_family == AF_NETLINK) {
+        struct sockaddr_nl *nladdr;
+
+        nladdr = (struct sockaddr_nl *)addr;
+        nladdr->nl_pid = tswap32(nladdr->nl_pid);
+        nladdr->nl_groups = tswap32(nladdr->nl_groups);
+    } else if (sa_family == AF_PACKET) {
 	struct target_sockaddr_ll *lladdr;
 
 	lladdr = (struct target_sockaddr_ll *)addr;
@@ -1228,6 +1244,11 @@ static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
         return -TARGET_EFAULT;
     memcpy(target_saddr, addr, len);
     target_saddr->sa_family = tswap16(addr->sa_family);
+    if (addr->sa_family == AF_NETLINK) {
+        struct sockaddr_nl *target_nl = (struct sockaddr_nl *)target_saddr;
+        target_nl->nl_pid = tswap32(target_nl->nl_pid);
+        target_nl->nl_groups = tswap32(target_nl->nl_groups);
+    }
     unlock_user(target_saddr, target_addr, len);
 
     return 0;
@@ -1459,6 +1480,511 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
     return 0;
 }
 
+static void tswap_nlmsghdr(struct nlmsghdr *nlh)
+{
+    nlh->nlmsg_len = tswap32(nlh->nlmsg_len);
+    nlh->nlmsg_type = tswap16(nlh->nlmsg_type);
+    nlh->nlmsg_flags = tswap16(nlh->nlmsg_flags);
+    nlh->nlmsg_seq = tswap32(nlh->nlmsg_seq);
+    nlh->nlmsg_pid = tswap32(nlh->nlmsg_pid);
+}
+
+static abi_long host_to_target_for_each_nlmsg(struct nlmsghdr *nlh,
+                                              size_t len,
+                                              abi_long (*host_to_target_nlmsg)
+                                                       (struct nlmsghdr *))
+{
+    uint32_t nlmsg_len;
+    abi_long ret;
+
+    while (len > sizeof(struct nlmsghdr)) {
+
+        nlmsg_len = nlh->nlmsg_len;
+        if (nlmsg_len < sizeof(struct nlmsghdr) ||
+            nlmsg_len > len) {
+            break;
+        }
+
+        switch (nlh->nlmsg_type) {
+        case NLMSG_DONE:
+            tswap_nlmsghdr(nlh);
+            return 0;
+        case NLMSG_NOOP:
+            break;
+        case NLMSG_ERROR:
+        {
+            struct nlmsgerr *e = NLMSG_DATA(nlh);
+            e->error = tswap32(e->error);
+            tswap_nlmsghdr(&e->msg);
+            tswap_nlmsghdr(nlh);
+            return 0;
+        }
+        default:
+            ret = host_to_target_nlmsg(nlh);
+            if (ret < 0) {
+                tswap_nlmsghdr(nlh);
+                return ret;
+            }
+            break;
+        }
+        tswap_nlmsghdr(nlh);
+        len -= NLMSG_ALIGN(nlmsg_len);
+        nlh = (struct nlmsghdr *)(((char*)nlh) + NLMSG_ALIGN(nlmsg_len));
+    }
+    return 0;
+}
+
+static abi_long target_to_host_for_each_nlmsg(struct nlmsghdr *nlh,
+                                              size_t len,
+                                              abi_long (*target_to_host_nlmsg)
+                                                       (struct nlmsghdr *))
+{
+    int ret;
+
+    while (len > sizeof(struct nlmsghdr)) {
+        if (tswap32(nlh->nlmsg_len) < sizeof(struct nlmsghdr) ||
+            tswap32(nlh->nlmsg_len) > len) {
+            break;
+        }
+        tswap_nlmsghdr(nlh);
+        switch (nlh->nlmsg_type) {
+        case NLMSG_DONE:
+            return 0;
+        case NLMSG_NOOP:
+            break;
+        case NLMSG_ERROR:
+        {
+            struct nlmsgerr *e = NLMSG_DATA(nlh);
+            e->error = tswap32(e->error);
+            tswap_nlmsghdr(&e->msg);
+        }
+        default:
+            ret = target_to_host_nlmsg(nlh);
+            if (ret < 0) {
+                return ret;
+            }
+        }
+        len -= NLMSG_ALIGN(nlh->nlmsg_len);
+        nlh = (struct nlmsghdr *)(((char *)nlh) + NLMSG_ALIGN(nlh->nlmsg_len));
+    }
+    return 0;
+}
+
+static abi_long host_to_target_for_each_rtattr(struct rtattr *rtattr,
+                                               size_t len,
+                                               abi_long (*host_to_target_rtattr)
+                                                        (struct rtattr *))
+{
+    unsigned short rta_len;
+    abi_long ret;
+
+    while (len > sizeof(struct rtattr)) {
+        rta_len = rtattr->rta_len;
+        if (rta_len < sizeof(struct rtattr) ||
+            rta_len > len) {
+            break;
+        }
+        ret = host_to_target_rtattr(rtattr);
+        rtattr->rta_len = tswap16(rtattr->rta_len);
+        rtattr->rta_type = tswap16(rtattr->rta_type);
+        if (ret < 0) {
+            return ret;
+        }
+        len -= RTA_ALIGN(rta_len);
+        rtattr = (struct rtattr *)(((char *)rtattr) + RTA_ALIGN(rta_len));
+    }
+    return 0;
+}
+
+static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
+{
+    uint32_t *u32;
+    struct rtnl_link_stats *st;
+    struct rtnl_link_stats64 *st64;
+    struct rtnl_link_ifmap *map;
+
+    switch (rtattr->rta_type) {
+    /* binary stream */
+    case IFLA_ADDRESS:
+    case IFLA_BROADCAST:
+    /* string */
+    case IFLA_IFNAME:
+    case IFLA_QDISC:
+        break;
+    /* uin8_t */
+    case IFLA_OPERSTATE:
+    case IFLA_LINKMODE:
+    case IFLA_CARRIER:
+    case IFLA_PROTO_DOWN:
+        break;
+    /* uint32_t */
+    case IFLA_MTU:
+    case IFLA_LINK:
+    case IFLA_WEIGHT:
+    case IFLA_TXQLEN:
+    case IFLA_CARRIER_CHANGES:
+    case IFLA_NUM_RX_QUEUES:
+    case IFLA_NUM_TX_QUEUES:
+    case IFLA_PROMISCUITY:
+    case IFLA_EXT_MASK:
+    case IFLA_LINK_NETNSID:
+    case IFLA_GROUP:
+    case IFLA_MASTER:
+    case IFLA_NUM_VF:
+        u32 = RTA_DATA(rtattr);
+        *u32 = tswap32(*u32);
+        break;
+    /* struct rtnl_link_stats */
+    case IFLA_STATS:
+        st = RTA_DATA(rtattr);
+        st->rx_packets = tswap32(st->rx_packets);
+        st->tx_packets = tswap32(st->tx_packets);
+        st->rx_bytes = tswap32(st->rx_bytes);
+        st->tx_bytes = tswap32(st->tx_bytes);
+        st->rx_errors = tswap32(st->rx_errors);
+        st->tx_errors = tswap32(st->tx_errors);
+        st->rx_dropped = tswap32(st->rx_dropped);
+        st->tx_dropped = tswap32(st->tx_dropped);
+        st->multicast = tswap32(st->multicast);
+        st->collisions = tswap32(st->collisions);
+
+        /* detailed rx_errors: */
+        st->rx_length_errors = tswap32(st->rx_length_errors);
+        st->rx_over_errors = tswap32(st->rx_over_errors);
+        st->rx_crc_errors = tswap32(st->rx_crc_errors);
+        st->rx_frame_errors = tswap32(st->rx_frame_errors);
+        st->rx_fifo_errors = tswap32(st->rx_fifo_errors);
+        st->rx_missed_errors = tswap32(st->rx_missed_errors);
+
+        /* detailed tx_errors */
+        st->tx_aborted_errors = tswap32(st->tx_aborted_errors);
+        st->tx_carrier_errors = tswap32(st->tx_carrier_errors);
+        st->tx_fifo_errors = tswap32(st->tx_fifo_errors);
+        st->tx_heartbeat_errors = tswap32(st->tx_heartbeat_errors);
+        st->tx_window_errors = tswap32(st->tx_window_errors);
+
+        /* for cslip etc */
+        st->rx_compressed = tswap32(st->rx_compressed);
+        st->tx_compressed = tswap32(st->tx_compressed);
+        break;
+    /* struct rtnl_link_stats64 */
+    case IFLA_STATS64:
+        st64 = RTA_DATA(rtattr);
+        st64->rx_packets = tswap64(st64->rx_packets);
+        st64->tx_packets = tswap64(st64->tx_packets);
+        st64->rx_bytes = tswap64(st64->rx_bytes);
+        st64->tx_bytes = tswap64(st64->tx_bytes);
+        st64->rx_errors = tswap64(st64->rx_errors);
+        st64->tx_errors = tswap64(st64->tx_errors);
+        st64->rx_dropped = tswap64(st64->rx_dropped);
+        st64->tx_dropped = tswap64(st64->tx_dropped);
+        st64->multicast = tswap64(st64->multicast);
+        st64->collisions = tswap64(st64->collisions);
+
+        /* detailed rx_errors: */
+        st64->rx_length_errors = tswap64(st64->rx_length_errors);
+        st64->rx_over_errors = tswap64(st64->rx_over_errors);
+        st64->rx_crc_errors = tswap64(st64->rx_crc_errors);
+        st64->rx_frame_errors = tswap64(st64->rx_frame_errors);
+        st64->rx_fifo_errors = tswap64(st64->rx_fifo_errors);
+        st64->rx_missed_errors = tswap64(st64->rx_missed_errors);
+
+        /* detailed tx_errors */
+        st64->tx_aborted_errors = tswap64(st64->tx_aborted_errors);
+        st64->tx_carrier_errors = tswap64(st64->tx_carrier_errors);
+        st64->tx_fifo_errors = tswap64(st64->tx_fifo_errors);
+        st64->tx_heartbeat_errors = tswap64(st64->tx_heartbeat_errors);
+        st64->tx_window_errors = tswap64(st64->tx_window_errors);
+
+        /* for cslip etc */
+        st64->rx_compressed = tswap64(st64->rx_compressed);
+        st64->tx_compressed = tswap64(st64->tx_compressed);
+        break;
+    /* struct rtnl_link_ifmap */
+    case IFLA_MAP:
+        map = RTA_DATA(rtattr);
+        map->mem_start = tswap64(map->mem_start);
+        map->mem_end = tswap64(map->mem_end);
+        map->base_addr = tswap64(map->base_addr);
+        map->irq = tswap16(map->irq);
+        break;
+    /* nested */
+    case IFLA_AF_SPEC:
+    case IFLA_LINKINFO:
+        /* FIXME: implement nested type */
+        gemu_log("Unimplemented nested type %d\n", rtattr->rta_type);
+        break;
+    default:
+        gemu_log("Unknown host IFLA type: %d\n", rtattr->rta_type);
+        break;
+    }
+    return 0;
+}
+
+static abi_long host_to_target_data_addr_rtattr(struct rtattr *rtattr)
+{
+    uint32_t *u32;
+    struct ifa_cacheinfo *ci;
+
+    switch (rtattr->rta_type) {
+    /* binary: depends on family type */
+    case IFA_ADDRESS:
+    case IFA_LOCAL:
+        break;
+    /* string */
+    case IFA_LABEL:
+        break;
+    /* u32 */
+    case IFA_FLAGS:
+    case IFA_BROADCAST:
+        u32 = RTA_DATA(rtattr);
+        *u32 = tswap32(*u32);
+        break;
+    /* struct ifa_cacheinfo */
+    case IFA_CACHEINFO:
+        ci = RTA_DATA(rtattr);
+        ci->ifa_prefered = tswap32(ci->ifa_prefered);
+        ci->ifa_valid = tswap32(ci->ifa_valid);
+        ci->cstamp = tswap32(ci->cstamp);
+        ci->tstamp = tswap32(ci->tstamp);
+        break;
+    default:
+        gemu_log("Unknown host IFA type: %d\n", rtattr->rta_type);
+        break;
+    }
+    return 0;
+}
+
+static abi_long host_to_target_data_route_rtattr(struct rtattr *rtattr)
+{
+    uint32_t *u32;
+    switch (rtattr->rta_type) {
+    /* binary: depends on family type */
+    case RTA_GATEWAY:
+    case RTA_DST:
+    case RTA_PREFSRC:
+        break;
+    /* u32 */
+    case RTA_PRIORITY:
+    case RTA_TABLE:
+    case RTA_OIF:
+        u32 = RTA_DATA(rtattr);
+        *u32 = tswap32(*u32);
+        break;
+    default:
+        gemu_log("Unknown host RTA type: %d\n", rtattr->rta_type);
+        break;
+    }
+    return 0;
+}
+
+static abi_long host_to_target_link_rtattr(struct rtattr *rtattr,
+                                         uint32_t rtattr_len)
+{
+    return host_to_target_for_each_rtattr(rtattr, rtattr_len,
+                                          host_to_target_data_link_rtattr);
+}
+
+static abi_long host_to_target_addr_rtattr(struct rtattr *rtattr,
+                                         uint32_t rtattr_len)
+{
+    return host_to_target_for_each_rtattr(rtattr, rtattr_len,
+                                          host_to_target_data_addr_rtattr);
+}
+
+static abi_long host_to_target_route_rtattr(struct rtattr *rtattr,
+                                         uint32_t rtattr_len)
+{
+    return host_to_target_for_each_rtattr(rtattr, rtattr_len,
+                                          host_to_target_data_route_rtattr);
+}
+
+static abi_long host_to_target_data_route(struct nlmsghdr *nlh)
+{
+    uint32_t nlmsg_len;
+    struct ifinfomsg *ifi;
+    struct ifaddrmsg *ifa;
+    struct rtmsg *rtm;
+
+    nlmsg_len = nlh->nlmsg_len;
+    switch (nlh->nlmsg_type) {
+    case RTM_NEWLINK:
+    case RTM_DELLINK:
+    case RTM_GETLINK:
+        ifi = NLMSG_DATA(nlh);
+        ifi->ifi_type = tswap16(ifi->ifi_type);
+        ifi->ifi_index = tswap32(ifi->ifi_index);
+        ifi->ifi_flags = tswap32(ifi->ifi_flags);
+        ifi->ifi_change = tswap32(ifi->ifi_change);
+        host_to_target_link_rtattr(IFLA_RTA(ifi),
+                                   nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
+        break;
+    case RTM_NEWADDR:
+    case RTM_DELADDR:
+    case RTM_GETADDR:
+        ifa = NLMSG_DATA(nlh);
+        ifa->ifa_index = tswap32(ifa->ifa_index);
+        host_to_target_addr_rtattr(IFA_RTA(ifa),
+                                   nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
+        break;
+    case RTM_NEWROUTE:
+    case RTM_DELROUTE:
+    case RTM_GETROUTE:
+        rtm = NLMSG_DATA(nlh);
+        rtm->rtm_flags = tswap32(rtm->rtm_flags);
+        host_to_target_route_rtattr(RTM_RTA(rtm),
+                                    nlmsg_len - NLMSG_LENGTH(sizeof(*rtm)));
+        break;
+    default:
+        return -TARGET_EINVAL;
+    }
+    return 0;
+}
+
+static inline abi_long host_to_target_nlmsg_route(struct nlmsghdr *nlh,
+                                                  size_t len)
+{
+    return host_to_target_for_each_nlmsg(nlh, len, host_to_target_data_route);
+}
+
+static abi_long target_to_host_for_each_rtattr(struct rtattr *rtattr,
+                                               size_t len,
+                                               abi_long (*target_to_host_rtattr)
+                                                        (struct rtattr *))
+{
+    abi_long ret;
+
+    while (len >= sizeof(struct rtattr)) {
+        if (tswap16(rtattr->rta_len) < sizeof(struct rtattr) ||
+            tswap16(rtattr->rta_len) > len) {
+            break;
+        }
+        rtattr->rta_len = tswap16(rtattr->rta_len);
+        rtattr->rta_type = tswap16(rtattr->rta_type);
+        ret = target_to_host_rtattr(rtattr);
+        if (ret < 0) {
+            return ret;
+        }
+        len -= RTA_ALIGN(rtattr->rta_len);
+        rtattr = (struct rtattr *)(((char *)rtattr) +
+                 RTA_ALIGN(rtattr->rta_len));
+    }
+    return 0;
+}
+
+static abi_long target_to_host_data_link_rtattr(struct rtattr *rtattr)
+{
+    switch (rtattr->rta_type) {
+    default:
+        gemu_log("Unknown target IFLA type: %d\n", rtattr->rta_type);
+        break;
+    }
+    return 0;
+}
+
+static abi_long target_to_host_data_addr_rtattr(struct rtattr *rtattr)
+{
+    switch (rtattr->rta_type) {
+    /* binary: depends on family type */
+    case IFA_LOCAL:
+    case IFA_ADDRESS:
+        break;
+    default:
+        gemu_log("Unknown target IFA type: %d\n", rtattr->rta_type);
+        break;
+    }
+    return 0;
+}
+
+static abi_long target_to_host_data_route_rtattr(struct rtattr *rtattr)
+{
+    uint32_t *u32;
+    switch (rtattr->rta_type) {
+    /* binary: depends on family type */
+    case RTA_DST:
+    case RTA_SRC:
+    case RTA_GATEWAY:
+        break;
+    /* u32 */
+    case RTA_OIF:
+        u32 = RTA_DATA(rtattr);
+        *u32 = tswap32(*u32);
+        break;
+    default:
+        gemu_log("Unknown target RTA type: %d\n", rtattr->rta_type);
+        break;
+    }
+    return 0;
+}
+
+static void target_to_host_link_rtattr(struct rtattr *rtattr,
+                                       uint32_t rtattr_len)
+{
+    target_to_host_for_each_rtattr(rtattr, rtattr_len,
+                                   target_to_host_data_link_rtattr);
+}
+
+static void target_to_host_addr_rtattr(struct rtattr *rtattr,
+                                     uint32_t rtattr_len)
+{
+    target_to_host_for_each_rtattr(rtattr, rtattr_len,
+                                   target_to_host_data_addr_rtattr);
+}
+
+static void target_to_host_route_rtattr(struct rtattr *rtattr,
+                                     uint32_t rtattr_len)
+{
+    target_to_host_for_each_rtattr(rtattr, rtattr_len,
+                                   target_to_host_data_route_rtattr);
+}
+
+static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
+{
+    struct ifinfomsg *ifi;
+    struct ifaddrmsg *ifa;
+    struct rtmsg *rtm;
+
+    switch (nlh->nlmsg_type) {
+    case RTM_GETLINK:
+        break;
+    case RTM_NEWLINK:
+    case RTM_DELLINK:
+        ifi = NLMSG_DATA(nlh);
+        ifi->ifi_type = tswap16(ifi->ifi_type);
+        ifi->ifi_index = tswap32(ifi->ifi_index);
+        ifi->ifi_flags = tswap32(ifi->ifi_flags);
+        ifi->ifi_change = tswap32(ifi->ifi_change);
+        target_to_host_link_rtattr(IFLA_RTA(ifi), nlh->nlmsg_len -
+                                   NLMSG_LENGTH(sizeof(*ifi)));
+        break;
+    case RTM_GETADDR:
+    case RTM_NEWADDR:
+    case RTM_DELADDR:
+        ifa = NLMSG_DATA(nlh);
+        ifa->ifa_index = tswap32(ifa->ifa_index);
+        target_to_host_addr_rtattr(IFA_RTA(ifa), nlh->nlmsg_len -
+                                   NLMSG_LENGTH(sizeof(*ifa)));
+        break;
+    case RTM_GETROUTE:
+        break;
+    case RTM_NEWROUTE:
+    case RTM_DELROUTE:
+        rtm = NLMSG_DATA(nlh);
+        rtm->rtm_flags = tswap32(rtm->rtm_flags);
+        target_to_host_route_rtattr(RTM_RTA(rtm), nlh->nlmsg_len -
+                                    NLMSG_LENGTH(sizeof(*rtm)));
+        break;
+    default:
+        return -TARGET_EOPNOTSUPP;
+    }
+    return 0;
+}
+
+static abi_long target_to_host_nlmsg_route(struct nlmsghdr *nlh, size_t len)
+{
+    return target_to_host_for_each_nlmsg(nlh, len, target_to_host_data_route);
+}
+
 /* do_setsockopt() Must return target values and target errnos. */
 static abi_long do_setsockopt(int sockfd, int level, int optname,
                               abi_ulong optval_addr, socklen_t optlen)
@@ -2126,6 +2652,21 @@ static TargetFdTrans target_packet_trans = {
     .target_to_host_addr = packet_target_to_host_sockaddr,
 };
 
+static abi_long netlink_route_target_to_host(void *buf, size_t len)
+{
+    return target_to_host_nlmsg_route(buf, len);
+}
+
+static abi_long netlink_route_host_to_target(void *buf, size_t len)
+{
+    return host_to_target_nlmsg_route(buf, len);
+}
+
+static TargetFdTrans target_netlink_route_trans = {
+    .target_to_host_data = netlink_route_target_to_host,
+    .host_to_target_data = netlink_route_host_to_target,
+};
+
 /* do_socket() Must return target values and target errnos. */
 static abi_long do_socket(int domain, int type, int protocol)
 {
@@ -2137,8 +2678,10 @@ static abi_long do_socket(int domain, int type, int protocol)
         return ret;
     }
 
-    if (domain == PF_NETLINK)
-        return -TARGET_EAFNOSUPPORT;
+    if (domain == PF_NETLINK &&
+        protocol != NETLINK_ROUTE) {
+        return -EPFNOSUPPORT;
+    }
 
     if (domain == AF_PACKET ||
         (domain == AF_INET && type == SOCK_PACKET)) {
@@ -2153,6 +2696,14 @@ static abi_long do_socket(int domain, int type, int protocol)
              * if socket type is SOCK_PACKET, bind by name
              */
             fd_trans_register(ret, &target_packet_trans);
+        } else if (domain == PF_NETLINK) {
+            switch (protocol) {
+            case NETLINK_ROUTE:
+                fd_trans_register(ret, &target_netlink_route_trans);
+                break;
+            default:
+                g_assert_not_reached();
+            }
         }
     }
     return ret;
@@ -2237,14 +2788,25 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
     msg.msg_iov = vec;
 
     if (send) {
-        ret = target_to_host_cmsg(&msg, msgp);
-        if (ret == 0)
+        if (fd_trans_target_to_host_data(fd)) {
+            ret = fd_trans_target_to_host_data(fd)(msg.msg_iov->iov_base,
+                                                   msg.msg_iov->iov_len);
+        } else {
+            ret = target_to_host_cmsg(&msg, msgp);
+        }
+        if (ret == 0) {
             ret = get_errno(sendmsg(fd, &msg, flags));
+        }
     } else {
         ret = get_errno(recvmsg(fd, &msg, flags));
         if (!is_error(ret)) {
             len = ret;
-            ret = host_to_target_cmsg(msgp, &msg);
+            if (fd_trans_host_to_target_data(fd)) {
+                ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base,
+                                                       msg.msg_iov->iov_len);
+            } else {
+                ret = host_to_target_cmsg(msgp, &msg);
+            }
             if (!is_error(ret)) {
                 msgp->msg_namelen = tswap32(msg.msg_namelen);
                 if (msg.msg_name != NULL) {
@@ -2471,6 +3033,13 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
     host_msg = lock_user(VERIFY_READ, msg, len, 1);
     if (!host_msg)
         return -TARGET_EFAULT;
+    if (fd_trans_target_to_host_data(fd)) {
+        ret = fd_trans_target_to_host_data(fd)(host_msg, len);
+        if (ret < 0) {
+            unlock_user(host_msg, msg, 0);
+            return ret;
+        }
+    }
     if (target_addr) {
         addr = alloca(addrlen+1);
         ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v2 2/3] linux-user: support netlink protocol NETLINK_KOBJECT_UEVENT
  2016-05-22 16:56 [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Laurent Vivier
  2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 1/3] linux-user: add rtnetlink(7) support Laurent Vivier
@ 2016-05-22 16:56 ` Laurent Vivier
  2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 3/3] linux-user: add netlink audit Laurent Vivier
  2016-05-24  8:29 ` [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Riku Voipio
  3 siblings, 0 replies; 20+ messages in thread
From: Laurent Vivier @ 2016-05-22 16:56 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel, Peter Maydell, Laurent Vivier

This is the protocol used by udevd to manage kernel events.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
v2: Check domain before opening socket

 linux-user/syscall.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3f1b2cc..ff63bf5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2679,7 +2679,8 @@ static abi_long do_socket(int domain, int type, int protocol)
     }
 
     if (domain == PF_NETLINK &&
-        protocol != NETLINK_ROUTE) {
+        !(protocol == NETLINK_ROUTE ||
+          protocol == NETLINK_KOBJECT_UEVENT)) {
         return -EPFNOSUPPORT;
     }
 
@@ -2701,6 +2702,9 @@ static abi_long do_socket(int domain, int type, int protocol)
             case NETLINK_ROUTE:
                 fd_trans_register(ret, &target_netlink_route_trans);
                 break;
+            case NETLINK_KOBJECT_UEVENT:
+                /* nothing to do: messages are strings */
+                break;
             default:
                 g_assert_not_reached();
             }
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [Qemu-devel] [PATCH v2 3/3] linux-user: add netlink audit
  2016-05-22 16:56 [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Laurent Vivier
  2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 1/3] linux-user: add rtnetlink(7) support Laurent Vivier
  2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 2/3] linux-user: support netlink protocol NETLINK_KOBJECT_UEVENT Laurent Vivier
@ 2016-05-22 16:56 ` Laurent Vivier
  2016-05-24  8:29 ` [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Riku Voipio
  3 siblings, 0 replies; 20+ messages in thread
From: Laurent Vivier @ 2016-05-22 16:56 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel, Peter Maydell, Laurent Vivier

This is, for instance, needed to log in a container.

Without this, the user cannot be identified and the console login
fails with "Login incorrect".

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
v2: Check domain before opening socket
    Use gemu_log()

 linux-user/syscall.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ff63bf5..8160374 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 <linux/if_packet.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <linux/audit.h>
 #include "uname.h"
 
 #include "qemu.h"
@@ -1985,6 +1986,44 @@ static abi_long target_to_host_nlmsg_route(struct nlmsghdr *nlh, size_t len)
     return target_to_host_for_each_nlmsg(nlh, len, target_to_host_data_route);
 }
 
+static abi_long host_to_target_data_audit(struct nlmsghdr *nlh)
+{
+    switch (nlh->nlmsg_type) {
+    default:
+        gemu_log("Unknown host audit message type %d\n",
+                 nlh->nlmsg_type);
+        return -TARGET_EINVAL;
+    }
+    return 0;
+}
+
+static inline abi_long host_to_target_nlmsg_audit(struct nlmsghdr *nlh,
+                                                  size_t len)
+{
+    return host_to_target_for_each_nlmsg(nlh, len, host_to_target_data_audit);
+}
+
+static abi_long target_to_host_data_audit(struct nlmsghdr *nlh)
+{
+    switch (nlh->nlmsg_type) {
+    case AUDIT_USER:
+    case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
+    case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
+        break;
+    default:
+        gemu_log("Unknown target audit message type %d\n",
+                 nlh->nlmsg_type);
+        return -TARGET_EINVAL;
+    }
+
+    return 0;
+}
+
+static abi_long target_to_host_nlmsg_audit(struct nlmsghdr *nlh, size_t len)
+{
+    return target_to_host_for_each_nlmsg(nlh, len, target_to_host_data_audit);
+}
+
 /* do_setsockopt() Must return target values and target errnos. */
 static abi_long do_setsockopt(int sockfd, int level, int optname,
                               abi_ulong optval_addr, socklen_t optlen)
@@ -2667,6 +2706,21 @@ static TargetFdTrans target_netlink_route_trans = {
     .host_to_target_data = netlink_route_host_to_target,
 };
 
+static abi_long netlink_audit_target_to_host(void *buf, size_t len)
+{
+    return target_to_host_nlmsg_audit(buf, len);
+}
+
+static abi_long netlink_audit_host_to_target(void *buf, size_t len)
+{
+    return host_to_target_nlmsg_audit(buf, len);
+}
+
+static TargetFdTrans target_netlink_audit_trans = {
+    .target_to_host_data = netlink_audit_target_to_host,
+    .host_to_target_data = netlink_audit_host_to_target,
+};
+
 /* do_socket() Must return target values and target errnos. */
 static abi_long do_socket(int domain, int type, int protocol)
 {
@@ -2680,7 +2734,8 @@ static abi_long do_socket(int domain, int type, int protocol)
 
     if (domain == PF_NETLINK &&
         !(protocol == NETLINK_ROUTE ||
-          protocol == NETLINK_KOBJECT_UEVENT)) {
+          protocol == NETLINK_KOBJECT_UEVENT ||
+          protocol == NETLINK_AUDIT)) {
         return -EPFNOSUPPORT;
     }
 
@@ -2705,6 +2760,9 @@ static abi_long do_socket(int domain, int type, int protocol)
             case NETLINK_KOBJECT_UEVENT:
                 /* nothing to do: messages are strings */
                 break;
+            case NETLINK_AUDIT:
+                fd_trans_register(ret, &target_netlink_audit_trans);
+                break;
             default:
                 g_assert_not_reached();
             }
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-22 16:56 [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Laurent Vivier
                   ` (2 preceding siblings ...)
  2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 3/3] linux-user: add netlink audit Laurent Vivier
@ 2016-05-24  8:29 ` Riku Voipio
  2016-05-24  8:34   ` Peter Maydell
  2016-05-24  8:42   ` Laurent Vivier
  3 siblings, 2 replies; 20+ messages in thread
From: Riku Voipio @ 2016-05-24  8:29 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-devel, Peter Maydell

On Sun, May 22, 2016 at 06:56:18PM +0200, Laurent Vivier wrote:
> It is now possible to register handlers to a file descriptor
> to translate a data stream transiting by this file descriptor.
> 
> We can now decode netlink information coming from the guest
> and inject a translated one into the host, and vice-versa.
> 
> This series is an "RFC" because it works (we can boot a
> container using systemd and use iproute tools) but some
> problems remain.

Ok, I can wait for V3.

> Some results (x86_64 host) with some guests:
> 
> * ppc: it can boot a debian 8.2/8.3 (Jessie) LXC container
>   and networking works fine (dhcp and "apt-get upgrade").
> 
>   "ip link" generates some traces in the kernel log:
>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
> 
> * ppc64: it can boot a fedora 21 LXC container.
> 
>   Some issues with dhclient and "dnf update"
>   -> missing netlink nested types 18 and 26
>   -> uniplemented instruction "evmheumiaaw"
> 
>   "ip link" generates some traces in the kernel log:
>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
> 
> * ppc64le: Debian 8.3 (Jessie).
> 
>   ip commands work fine, but "apt-get update" generates some netlink
>   invalid types (and fails):
>     Unknown target IFA type: 130
>     Unknown target IFA type: 59722
>     Unknown target IFA type: 59657
>     Unknown target IFA type: 15648
>     Unknown target IFA type: 32008
>     Unknown target IFA type: 16590
> 
> * sh4: container doesn't work but 'ip' in a chroot works well.
> 
> * arm: Raspbian 8.3 (Jessie) works fine.

Tested on arm64 and seems to work fine (didn't test dhcp).

> * s390x: container Debian 8.1 boots well, but "apt-get" hangs on
>   networking (name resolution?).
> 
>   "ip link" generates some traces in the kernel log:
>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
> 
> v2:
> 
> Check domain before opening socket
> Remove cast to int of sizeof()
> Move NLMSG_DONE into the switch()
> Fix '{' in 'case:'
> Reorder data types by type size
> Add new conversions (IFLA_STATS, IFLA_STATS64, IFLA_MAP)
> Add warning for nested type (not supported)
> Add logs with gemu_log()
> Don't convert rta_len and rta_type in the error case
> 
> Laurent Vivier (3):
>   linux-user: add rtnetlink(7) support
>   linux-user: support netlink protocol NETLINK_KOBJECT_UEVENT
>   linux-user: add netlink audit
> 
>  linux-user/syscall.c | 643 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 637 insertions(+), 6 deletions(-)
> 
> -- 
> 2.5.5
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-24  8:29 ` [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Riku Voipio
@ 2016-05-24  8:34   ` Peter Maydell
  2016-05-24  8:50     ` Laurent Vivier
  2016-05-24  8:42   ` Laurent Vivier
  1 sibling, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2016-05-24  8:34 UTC (permalink / raw)
  To: Riku Voipio; +Cc: Laurent Vivier, QEMU Developers

On 24 May 2016 at 09:29, Riku Voipio <riku.voipio@iki.fi> wrote:
> On Sun, May 22, 2016 at 06:56:18PM +0200, Laurent Vivier wrote:
>> It is now possible to register handlers to a file descriptor
>> to translate a data stream transiting by this file descriptor.
>>
>> We can now decode netlink information coming from the guest
>> and inject a translated one into the host, and vice-versa.
>>
>> This series is an "RFC" because it works (we can boot a
>> container using systemd and use iproute tools) but some
>> problems remain.
>
> Ok, I can wait for V3.

Well, this version of the patchset isn't marked RFC -- did you
forget to edit the cover letter, Laurent?

>> Some results (x86_64 host) with some guests:
>>
>> * ppc: it can boot a debian 8.2/8.3 (Jessie) LXC container
>>   and networking works fine (dhcp and "apt-get upgrade").
>>
>>   "ip link" generates some traces in the kernel log:
>>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."

I guess we should track down what this 8-bytes-leftover
stuff is...

thanks
-- PMM

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-24  8:29 ` [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Riku Voipio
  2016-05-24  8:34   ` Peter Maydell
@ 2016-05-24  8:42   ` Laurent Vivier
  2016-05-24 12:05     ` Riku Voipio
  1 sibling, 1 reply; 20+ messages in thread
From: Laurent Vivier @ 2016-05-24  8:42 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel, Peter Maydell



Le 24/05/2016 à 10:29, Riku Voipio a écrit :
> On Sun, May 22, 2016 at 06:56:18PM +0200, Laurent Vivier wrote:
>> It is now possible to register handlers to a file descriptor
>> to translate a data stream transiting by this file descriptor.
>>
>> We can now decode netlink information coming from the guest
>> and inject a translated one into the host, and vice-versa.
>>
>> This series is an "RFC" because it works (we can boot a
>> container using systemd and use iproute tools) but some
>> problems remain.
> 
> Ok, I can wait for V3.

Well, I've forgotten to remove this part from the first series version :)

So, if it doesn't break anything and bring some improvements, I think
you can apply it.

There are two remaining problems:
- missing nested types on ppc64
- some unknown IFA types on ppc64le/debian 8.3 (could be unimplemented
flags management)

But I think this can wait.

ppc64/ppc64le can also be broken because of missing instructions, not
because netlink implementation.

> 
>> Some results (x86_64 host) with some guests:
>>
>> * ppc: it can boot a debian 8.2/8.3 (Jessie) LXC container
>>   and networking works fine (dhcp and "apt-get upgrade").
>>
>>   "ip link" generates some traces in the kernel log:
>>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
>>
>> * ppc64: it can boot a fedora 21 LXC container.
>>
>>   Some issues with dhclient and "dnf update"
>>   -> missing netlink nested types 18 and 26
>>   -> uniplemented instruction "evmheumiaaw"
>>
>>   "ip link" generates some traces in the kernel log:
>>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
>>
>> * ppc64le: Debian 8.3 (Jessie).
>>
>>   ip commands work fine, but "apt-get update" generates some netlink
>>   invalid types (and fails):
>>     Unknown target IFA type: 130
>>     Unknown target IFA type: 59722
>>     Unknown target IFA type: 59657
>>     Unknown target IFA type: 15648
>>     Unknown target IFA type: 32008
>>     Unknown target IFA type: 16590
>>
>> * sh4: container doesn't work but 'ip' in a chroot works well.
>>
>> * arm: Raspbian 8.3 (Jessie) works fine.
> 
> Tested on arm64 and seems to work fine (didn't test dhcp).

Thanks

> 
>> * s390x: container Debian 8.1 boots well, but "apt-get" hangs on
>>   networking (name resolution?).
>>
>>   "ip link" generates some traces in the kernel log:
>>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
>>
>> v2:
>>
>> Check domain before opening socket
>> Remove cast to int of sizeof()
>> Move NLMSG_DONE into the switch()
>> Fix '{' in 'case:'
>> Reorder data types by type size
>> Add new conversions (IFLA_STATS, IFLA_STATS64, IFLA_MAP)
>> Add warning for nested type (not supported)
>> Add logs with gemu_log()
>> Don't convert rta_len and rta_type in the error case
>>
>> Laurent Vivier (3):
>>   linux-user: add rtnetlink(7) support
>>   linux-user: support netlink protocol NETLINK_KOBJECT_UEVENT
>>   linux-user: add netlink audit
>>
>>  linux-user/syscall.c | 643 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 637 insertions(+), 6 deletions(-)
>>
>> -- 
>> 2.5.5
>>
Laurent

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-24  8:34   ` Peter Maydell
@ 2016-05-24  8:50     ` Laurent Vivier
  0 siblings, 0 replies; 20+ messages in thread
From: Laurent Vivier @ 2016-05-24  8:50 UTC (permalink / raw)
  To: Peter Maydell, Riku Voipio; +Cc: QEMU Developers



Le 24/05/2016 à 10:34, Peter Maydell a écrit :
> On 24 May 2016 at 09:29, Riku Voipio <riku.voipio@iki.fi> wrote:
>> On Sun, May 22, 2016 at 06:56:18PM +0200, Laurent Vivier wrote:
>>> It is now possible to register handlers to a file descriptor
>>> to translate a data stream transiting by this file descriptor.
>>>
>>> We can now decode netlink information coming from the guest
>>> and inject a translated one into the host, and vice-versa.
>>>
>>> This series is an "RFC" because it works (we can boot a
>>> container using systemd and use iproute tools) but some
>>> problems remain.
>>
>> Ok, I can wait for V3.
> 
> Well, this version of the patchset isn't marked RFC -- did you
> forget to edit the cover letter, Laurent?

Yes, sorry...

>>> Some results (x86_64 host) with some guests:
>>>
>>> * ppc: it can boot a debian 8.2/8.3 (Jessie) LXC container
>>>   and networking works fine (dhcp and "apt-get upgrade").
>>>
>>>   "ip link" generates some traces in the kernel log:
>>>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
> 
> I guess we should track down what this 8-bytes-leftover
> stuff is...

OK, I will...

Laurent

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-24  8:42   ` Laurent Vivier
@ 2016-05-24 12:05     ` Riku Voipio
  2016-05-24 12:54       ` Riku Voipio
  0 siblings, 1 reply; 20+ messages in thread
From: Riku Voipio @ 2016-05-24 12:05 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-devel, Peter Maydell

On Tue, May 24, 2016 at 10:42:01AM +0200, Laurent Vivier wrote:
> Le 24/05/2016 à 10:29, Riku Voipio a écrit :
> > On Sun, May 22, 2016 at 06:56:18PM +0200, Laurent Vivier wrote:
> >> It is now possible to register handlers to a file descriptor
> >> to translate a data stream transiting by this file descriptor.
> >>
> >> We can now decode netlink information coming from the guest
> >> and inject a translated one into the host, and vice-versa.
> >>
> >> This series is an "RFC" because it works (we can boot a
> >> container using systemd and use iproute tools) but some
> >> problems remain.
> > 
> > Ok, I can wait for V3.
> 
> Well, I've forgotten to remove this part from the first series version :)
 
> So, if it doesn't break anything and bring some improvements, I think
> you can apply it.

Ok, fair enough, applied.

> There are two remaining problems:
> - missing nested types on ppc64
> - some unknown IFA types on ppc64le/debian 8.3 (could be unimplemented
> flags management)
>
> But I think this can wait.

Since it's new stuff, I agree

> ppc64/ppc64le can also be broken because of missing instructions, not
> because netlink implementation.
> 
> > 
> >> Some results (x86_64 host) with some guests:
> >>
> >> * ppc: it can boot a debian 8.2/8.3 (Jessie) LXC container
> >>   and networking works fine (dhcp and "apt-get upgrade").
> >>
> >>   "ip link" generates some traces in the kernel log:
> >>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
> >>
> >> * ppc64: it can boot a fedora 21 LXC container.
> >>
> >>   Some issues with dhclient and "dnf update"
> >>   -> missing netlink nested types 18 and 26
> >>   -> uniplemented instruction "evmheumiaaw"
> >>
> >>   "ip link" generates some traces in the kernel log:
> >>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
> >>
> >> * ppc64le: Debian 8.3 (Jessie).
> >>
> >>   ip commands work fine, but "apt-get update" generates some netlink
> >>   invalid types (and fails):
> >>     Unknown target IFA type: 130
> >>     Unknown target IFA type: 59722
> >>     Unknown target IFA type: 59657
> >>     Unknown target IFA type: 15648
> >>     Unknown target IFA type: 32008
> >>     Unknown target IFA type: 16590
> >>
> >> * sh4: container doesn't work but 'ip' in a chroot works well.
> >>
> >> * arm: Raspbian 8.3 (Jessie) works fine.
> > 
> > Tested on arm64 and seems to work fine (didn't test dhcp).
> 
> Thanks
> 
> > 
> >> * s390x: container Debian 8.1 boots well, but "apt-get" hangs on
> >>   networking (name resolution?).
> >>
> >>   "ip link" generates some traces in the kernel log:
> >>   "netlink: 8 bytes leftover after parsing attributes in process `ip'."
> >>
> >> v2:
> >>
> >> Check domain before opening socket
> >> Remove cast to int of sizeof()
> >> Move NLMSG_DONE into the switch()
> >> Fix '{' in 'case:'
> >> Reorder data types by type size
> >> Add new conversions (IFLA_STATS, IFLA_STATS64, IFLA_MAP)
> >> Add warning for nested type (not supported)
> >> Add logs with gemu_log()
> >> Don't convert rta_len and rta_type in the error case
> >>
> >> Laurent Vivier (3):
> >>   linux-user: add rtnetlink(7) support
> >>   linux-user: support netlink protocol NETLINK_KOBJECT_UEVENT
> >>   linux-user: add netlink audit
> >>
> >>  linux-user/syscall.c | 643 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> >>  1 file changed, 637 insertions(+), 6 deletions(-)
> >>
> >> -- 
> >> 2.5.5
> >>
> Laurent

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-24 12:05     ` Riku Voipio
@ 2016-05-24 12:54       ` Riku Voipio
  2016-05-24 13:08         ` Peter Maydell
  2016-06-02 15:34         ` Laurent Vivier
  0 siblings, 2 replies; 20+ messages in thread
From: Riku Voipio @ 2016-05-24 12:54 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: Peter Maydell, qemu-devel

On tiistaina 24. toukokuuta 2016 15.05.08 EEST, Riku Voipio wrote:
> Ok, fair enough, applied.

dropped since the build failed on squeeze. I take the simplest fix is to 
wrap all nl support #ifdef IFLA_PROTO_DOWN since that is the newest define 
available.

/squeeze-container/qemu/linux-user/syscall.c: In function 
'host_to_target_data_link_rtattr':
/squeeze-container/qemu/linux-user/syscall.c:1674: error: 'IFLA_CARRIER' 
undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1674: error: (Each undeclared 
identifier is reported only once
/squeeze-container/qemu/linux-user/syscall.c:1674: error: for each function 
it appears in.)
/squeeze-container/qemu/linux-user/syscall.c:1675: error: 'IFLA_PROTO_DOWN' 
undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1682: error: 
'IFLA_CARRIER_CHANGES' undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1683: error: 
'IFLA_NUM_RX_QUEUES' undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1684: error: 
'IFLA_NUM_TX_QUEUES' undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1685: error: 
'IFLA_PROMISCUITY' undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1686: error: 'IFLA_EXT_MASK' 
undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1687: error: 
'IFLA_LINK_NETNSID' undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1688: error: 'IFLA_GROUP' 
undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1690: error: 'IFLA_NUM_VF' 
undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1728: error: 'IFLA_STATS64' 
undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c:1730: error: dereferencing 
pointer to incomplete type
/squeeze-container/qemu/linux-user/syscall.c:1730: error: dereferencing 
pointer to incomplete type
/squeeze-container/qemu/linux-user/syscall.c:1731: error: dereferencing 
pointer to incomplete type
....
/squeeze-container/qemu/linux-user/syscall.c:1758: error: dereferencing 
pointer to incomplete type
/squeeze-container/qemu/linux-user/syscall.c:1769: error: 'IFLA_AF_SPEC' 
undeclared (first use in this function)
/squeeze-container/qemu/linux-user/syscall.c: In function 
'host_to_target_data_addr_rtattr':
/squeeze-container/qemu/linux-user/syscall.c:1795: error: 'IFA_FLAGS' 
undeclared (first use in this function)
make[1]: *** [linux-user/syscall.o] Error 1
make: *** [subdir-aarch64-linux-user] Error 2

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-24 12:54       ` Riku Voipio
@ 2016-05-24 13:08         ` Peter Maydell
  2016-05-25 11:06           ` Riku Voipio
  2016-06-02 15:34         ` Laurent Vivier
  1 sibling, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2016-05-24 13:08 UTC (permalink / raw)
  To: Riku Voipio; +Cc: Laurent Vivier, QEMU Developers

On 24 May 2016 at 13:54, Riku Voipio <riku.voipio@iki.fi> wrote:
> On tiistaina 24. toukokuuta 2016 15.05.08 EEST, Riku Voipio wrote:
>>
>> Ok, fair enough, applied.
>
>
> dropped since the build failed on squeeze. I take the simplest fix is to
> wrap all nl support #ifdef IFLA_PROTO_DOWN since that is the newest define
> available.
>
> /squeeze-container/qemu/linux-user/syscall.c

Tangentially, are your containers here chroots, ad-hoc containers,
docker images, or something else? I was thinking about trying to
sort out a more self-contained and reproducible LTP setup than the
chroot I have at the moment, but perhaps you've already gone down
that path ?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-24 13:08         ` Peter Maydell
@ 2016-05-25 11:06           ` Riku Voipio
  2016-05-25 12:31             ` Peter Maydell
  0 siblings, 1 reply; 20+ messages in thread
From: Riku Voipio @ 2016-05-25 11:06 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Laurent Vivier, QEMU Developers

On Tue, May 24, 2016 at 02:08:14PM +0100, Peter Maydell wrote:
> On 24 May 2016 at 13:54, Riku Voipio <riku.voipio@iki.fi> wrote:
> > On tiistaina 24. toukokuuta 2016 15.05.08 EEST, Riku Voipio wrote:
> >>
> >> Ok, fair enough, applied.
> >
> >
> > dropped since the build failed on squeeze. I take the simplest fix is to
> > wrap all nl support #ifdef IFLA_PROTO_DOWN since that is the newest define
> > available.
> >
> > /squeeze-container/qemu/linux-user/syscall.c
 
> Tangentially, are your containers here chroots, ad-hoc containers,
> docker images, or something else? I was thinking about trying to
> sort out a more self-contained and reproducible LTP setup than the
> chroot I have at the moment, but perhaps you've already gone down
> that path ?

Local docker images - these aren't exactly clean yet. But if people want
I can look at publishing them in dockerhub. That said, for build testing
docker images don't add much to plain chroots.

Riku

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-25 11:06           ` Riku Voipio
@ 2016-05-25 12:31             ` Peter Maydell
  2016-05-25 13:25               ` Laurent Vivier
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2016-05-25 12:31 UTC (permalink / raw)
  To: Riku Voipio; +Cc: Laurent Vivier, QEMU Developers

On 25 May 2016 at 12:06, Riku Voipio <riku.voipio@iki.fi> wrote:
> Local docker images - these aren't exactly clean yet. But if people want
> I can look at publishing them in dockerhub. That said, for build testing
> docker images don't add much to plain chroots.

It would be nice to, for instance, run the LTP tests that
try to restart syslogd or the ones that add/remove swap,
without doing weird things to my actual host. IIRC there
are a few that mess with the system clock too. But maybe
you need a real VM for that.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-25 12:31             ` Peter Maydell
@ 2016-05-25 13:25               ` Laurent Vivier
  0 siblings, 0 replies; 20+ messages in thread
From: Laurent Vivier @ 2016-05-25 13:25 UTC (permalink / raw)
  To: Peter Maydell, Riku Voipio; +Cc: QEMU Developers



Le 25/05/2016 à 14:31, Peter Maydell a écrit :
> On 25 May 2016 at 12:06, Riku Voipio <riku.voipio@iki.fi> wrote:
>> Local docker images - these aren't exactly clean yet. But if people want
>> I can look at publishing them in dockerhub. That said, for build testing
>> docker images don't add much to plain chroots.
> 
> It would be nice to, for instance, run the LTP tests that
> try to restart syslogd or the ones that add/remove swap,
> without doing weird things to my actual host. IIRC there
> are a few that mess with the system clock too. But maybe
> you need a real VM for that.

I think there is no namespace for time and date functions, so even in a
linux container, changing the date in the container changes the date in
the host.

Laurent

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-05-24 12:54       ` Riku Voipio
  2016-05-24 13:08         ` Peter Maydell
@ 2016-06-02 15:34         ` Laurent Vivier
  2016-06-02 15:39           ` Peter Maydell
  1 sibling, 1 reply; 20+ messages in thread
From: Laurent Vivier @ 2016-06-02 15:34 UTC (permalink / raw)
  To: Riku Voipio; +Cc: Peter Maydell, qemu-devel



Le 24/05/2016 à 14:54, Riku Voipio a écrit :
> On tiistaina 24. toukokuuta 2016 15.05.08 EEST, Riku Voipio wrote:
>> Ok, fair enough, applied.
> 
> dropped since the build failed on squeeze. I take the simplest fix is to
> wrap all nl support #ifdef IFLA_PROTO_DOWN since that is the newest
> define available.
> 
> /squeeze-container/qemu/linux-user/syscall.c: In function
> 'host_to_target_data_link_rtattr':
> /squeeze-container/qemu/linux-user/syscall.c:1674: error: 'IFLA_CARRIER'
> undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1674: error: (Each
> undeclared identifier is reported only once
> /squeeze-container/qemu/linux-user/syscall.c:1674: error: for each
> function it appears in.)
> /squeeze-container/qemu/linux-user/syscall.c:1675: error:
> 'IFLA_PROTO_DOWN' undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1682: error:
> 'IFLA_CARRIER_CHANGES' undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1683: error:
> 'IFLA_NUM_RX_QUEUES' undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1684: error:
> 'IFLA_NUM_TX_QUEUES' undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1685: error:
> 'IFLA_PROMISCUITY' undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1686: error:
> 'IFLA_EXT_MASK' undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1687: error:
> 'IFLA_LINK_NETNSID' undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1688: error: 'IFLA_GROUP'
> undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1690: error: 'IFLA_NUM_VF'
> undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1728: error: 'IFLA_STATS64'
> undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c:1730: error: dereferencing
> pointer to incomplete type
> /squeeze-container/qemu/linux-user/syscall.c:1730: error: dereferencing
> pointer to incomplete type
> /squeeze-container/qemu/linux-user/syscall.c:1731: error: dereferencing
> pointer to incomplete type
> ....
> /squeeze-container/qemu/linux-user/syscall.c:1758: error: dereferencing
> pointer to incomplete type
> /squeeze-container/qemu/linux-user/syscall.c:1769: error: 'IFLA_AF_SPEC'
> undeclared (first use in this function)
> /squeeze-container/qemu/linux-user/syscall.c: In function
> 'host_to_target_data_addr_rtattr':
> /squeeze-container/qemu/linux-user/syscall.c:1795: error: 'IFA_FLAGS'
> undeclared (first use in this function)
> make[1]: *** [linux-user/syscall.o] Error 1
> make: *** [subdir-aarch64-linux-user] Error 2

What do you think if instead I add a "--disable-netlink" (enabled by
default) in configure?

Laurent

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-06-02 15:34         ` Laurent Vivier
@ 2016-06-02 15:39           ` Peter Maydell
  2016-06-02 15:45             ` Laurent Vivier
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2016-06-02 15:39 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: Riku Voipio, QEMU Developers

On 2 June 2016 at 16:34, Laurent Vivier <laurent@vivier.eu> wrote:
> Le 24/05/2016 à 14:54, Riku Voipio a écrit :
>> dropped since the build failed on squeeze. I take the simplest fix is to
>> wrap all nl support #ifdef IFLA_PROTO_DOWN since that is the newest
>> define available.

> What do you think if instead I add a "--disable-netlink" (enabled by
> default) in configure?

I don't think we need a command line switch for this -- we should only
have those for cases where there's a reasonable user decision to
say "I don't want feature X (even if my host might support it)".
For this kind of thing we should just have a configure test for
"do the host headers support feature X" and unconditionally use it
if present. That's what we do for things like CONFIG_FIEMAP, for instance.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-06-02 15:39           ` Peter Maydell
@ 2016-06-02 15:45             ` Laurent Vivier
  2016-06-02 15:49               ` Peter Maydell
  0 siblings, 1 reply; 20+ messages in thread
From: Laurent Vivier @ 2016-06-02 15:45 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Riku Voipio, QEMU Developers



Le 02/06/2016 à 17:39, Peter Maydell a écrit :
> On 2 June 2016 at 16:34, Laurent Vivier <laurent@vivier.eu> wrote:
>> Le 24/05/2016 à 14:54, Riku Voipio a écrit :
>>> dropped since the build failed on squeeze. I take the simplest fix is to
>>> wrap all nl support #ifdef IFLA_PROTO_DOWN since that is the newest
>>> define available.
> 
>> What do you think if instead I add a "--disable-netlink" (enabled by
>> default) in configure?
> 
> I don't think we need a command line switch for this -- we should only
> have those for cases where there's a reasonable user decision to
> say "I don't want feature X (even if my host might support it)".
> For this kind of thing we should just have a configure test for
> "do the host headers support feature X" and unconditionally use it
> if present. That's what we do for things like CONFIG_FIEMAP, for instance.

ok, but in this case what is the best solution:
1- to check the host environment in configure and define (or not) a
CONFIG_NETLINK,
2- Add a "#ifdef IFLA_PROTO_DOWN" directly in the code?

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support
  2016-06-02 15:45             ` Laurent Vivier
@ 2016-06-02 15:49               ` Peter Maydell
  0 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2016-06-02 15:49 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: Riku Voipio, QEMU Developers

On 2 June 2016 at 16:45, Laurent Vivier <laurent@vivier.eu> wrote:
> Le 02/06/2016 à 17:39, Peter Maydell a écrit :
>> I don't think we need a command line switch for this -- we should only
>> have those for cases where there's a reasonable user decision to
>> say "I don't want feature X (even if my host might support it)".
>> For this kind of thing we should just have a configure test for
>> "do the host headers support feature X" and unconditionally use it
>> if present. That's what we do for things like CONFIG_FIEMAP, for instance.
>
> ok, but in this case what is the best solution:
> 1- to check the host environment in configure and define (or not) a
> CONFIG_NETLINK,
> 2- Add a "#ifdef IFLA_PROTO_DOWN" directly in the code?

I don't have a strong preference.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/3] linux-user: add rtnetlink(7) support
  2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 1/3] linux-user: add rtnetlink(7) support Laurent Vivier
@ 2016-06-14  9:34   ` Peter Maydell
  2016-06-14 10:03     ` Laurent Vivier
  0 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2016-06-14  9:34 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: Riku Voipio, QEMU Developers

On 22 May 2016 at 17:56, Laurent Vivier <laurent@vivier.eu> wrote:
> rtnetlink is needed to use iproute package (ip addr, ip route)
> and dhcp client.
>
> +static abi_long target_to_host_for_each_nlmsg(struct nlmsghdr *nlh,
> +                                              size_t len,
> +                                              abi_long (*target_to_host_nlmsg)
> +                                                       (struct nlmsghdr *))
> +{
> +    int ret;
> +
> +    while (len > sizeof(struct nlmsghdr)) {
> +        if (tswap32(nlh->nlmsg_len) < sizeof(struct nlmsghdr) ||
> +            tswap32(nlh->nlmsg_len) > len) {
> +            break;
> +        }
> +        tswap_nlmsghdr(nlh);
> +        switch (nlh->nlmsg_type) {
> +        case NLMSG_DONE:
> +            return 0;
> +        case NLMSG_NOOP:
> +            break;
> +        case NLMSG_ERROR:
> +        {
> +            struct nlmsgerr *e = NLMSG_DATA(nlh);
> +            e->error = tswap32(e->error);
> +            tswap_nlmsghdr(&e->msg);
> +        }
> +        default:
> +            ret = target_to_host_nlmsg(nlh);
> +            if (ret < 0) {
> +                return ret;
> +            }
> +        }

Coverity points out that the NLMSG_ERROR case falls
through into the default. Missing "break" or missing
"/* fallthrough */" comment?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/3] linux-user: add rtnetlink(7) support
  2016-06-14  9:34   ` Peter Maydell
@ 2016-06-14 10:03     ` Laurent Vivier
  0 siblings, 0 replies; 20+ messages in thread
From: Laurent Vivier @ 2016-06-14 10:03 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Riku Voipio, QEMU Developers



Le 14/06/2016 à 11:34, Peter Maydell a écrit :
> On 22 May 2016 at 17:56, Laurent Vivier <laurent@vivier.eu> wrote:
>> rtnetlink is needed to use iproute package (ip addr, ip route)
>> and dhcp client.
>>
>> +static abi_long target_to_host_for_each_nlmsg(struct nlmsghdr *nlh,
>> +                                              size_t len,
>> +                                              abi_long (*target_to_host_nlmsg)
>> +                                                       (struct nlmsghdr *))
>> +{
>> +    int ret;
>> +
>> +    while (len > sizeof(struct nlmsghdr)) {
>> +        if (tswap32(nlh->nlmsg_len) < sizeof(struct nlmsghdr) ||
>> +            tswap32(nlh->nlmsg_len) > len) {
>> +            break;
>> +        }
>> +        tswap_nlmsghdr(nlh);
>> +        switch (nlh->nlmsg_type) {
>> +        case NLMSG_DONE:
>> +            return 0;
>> +        case NLMSG_NOOP:
>> +            break;
>> +        case NLMSG_ERROR:
>> +        {
>> +            struct nlmsgerr *e = NLMSG_DATA(nlh);
>> +            e->error = tswap32(e->error);
>> +            tswap_nlmsghdr(&e->msg);
>> +        }
>> +        default:
>> +            ret = target_to_host_nlmsg(nlh);
>> +            if (ret < 0) {
>> +                return ret;
>> +            }
>> +        }
> 
> Coverity points out that the NLMSG_ERROR case falls
> through into the default. Missing "break" or missing
> "/* fallthrough */" comment?

I think like in host_to_target_for_each_nlmsg() we need:

        case NLMSG_ERROR:
        {
            struct nlmsgerr *e = NLMSG_DATA(nlh);
            e->error = tswap32(e->error);
            tswap_nlmsghdr(&e->msg);
            tswap_nlmsghdr(nlh);
            return 0;
        }

I'm going to have a deeper look at this and send a patch.

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2016-06-14 10:03 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-22 16:56 [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Laurent Vivier
2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 1/3] linux-user: add rtnetlink(7) support Laurent Vivier
2016-06-14  9:34   ` Peter Maydell
2016-06-14 10:03     ` Laurent Vivier
2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 2/3] linux-user: support netlink protocol NETLINK_KOBJECT_UEVENT Laurent Vivier
2016-05-22 16:56 ` [Qemu-devel] [PATCH v2 3/3] linux-user: add netlink audit Laurent Vivier
2016-05-24  8:29 ` [Qemu-devel] [PATCH v2 0/3] linux-user: netlink support Riku Voipio
2016-05-24  8:34   ` Peter Maydell
2016-05-24  8:50     ` Laurent Vivier
2016-05-24  8:42   ` Laurent Vivier
2016-05-24 12:05     ` Riku Voipio
2016-05-24 12:54       ` Riku Voipio
2016-05-24 13:08         ` Peter Maydell
2016-05-25 11:06           ` Riku Voipio
2016-05-25 12:31             ` Peter Maydell
2016-05-25 13:25               ` Laurent Vivier
2016-06-02 15:34         ` Laurent Vivier
2016-06-02 15:39           ` Peter Maydell
2016-06-02 15:45             ` Laurent Vivier
2016-06-02 15:49               ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.