From patchwork Fri Dec 21 12:59:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?TWljaGFsIFByw612b3puw61r?= X-Patchwork-Id: 207804 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 B379D2C007C for ; Fri, 21 Dec 2012 23:59:27 +1100 (EST) Received: from localhost ([::1]:48848 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tm2CD-0002kz-DE for incoming@patchwork.ozlabs.org; Fri, 21 Dec 2012 07:59:25 -0500 Received: from eggs.gnu.org ([208.118.235.92]:46848) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tm2C1-0002kr-TG for qemu-devel@nongnu.org; Fri, 21 Dec 2012 07:59:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tm2Bw-0005kW-FR for qemu-devel@nongnu.org; Fri, 21 Dec 2012 07:59:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:24136) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tm2Bw-0005kQ-7N for qemu-devel@nongnu.org; Fri, 21 Dec 2012 07:59:08 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qBLCx6W1005236 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 21 Dec 2012 07:59:07 -0500 Received: from bart.brq.redhat.com (dhcp-27-249.brq.redhat.com [10.34.27.249]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qBLCx5pj000415 for ; Fri, 21 Dec 2012 07:59:06 -0500 From: Michal Privoznik To: qemu-devel@nongnu.org Date: Fri, 21 Dec 2012 13:59:03 +0100 Message-Id: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH] qemu-ga: Extend guest-network-get-interfaces 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 Nowadays only basic information is reported. However, with the current implementation much more can be exposed to users. like broadcast/destination address (the former in case of standard ethernet device, the latter in case of PPP interface), if the interface is up, of type loopback, in promisc mode or capable of sending multicast. --- Based on getifaddrs manpage, interface can either has a PTP peer, or a broadcast. While it can has up to one peer address, it can has multiple broadcast addresses. Therefore the broadcast address needs to be within GuestIpAddress. qga/commands-posix.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ qga/qapi-schema.json | 37 +++++++++++++++++++++++++++--- 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index a657201..7717fbf 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -816,6 +816,11 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) } } + info->value->up = ifa->ifa_flags & IFF_UP; + info->value->loopback = ifa->ifa_flags & IFF_LOOPBACK; + info->value->promisc = ifa->ifa_flags & IFF_PROMISC; + info->value->multicast = ifa->ifa_flags & IFF_MULTICAST; + if (!info->value->has_hardware_address && ifa->ifa_flags & SIOCGIFHWADDR) { /* we haven't obtained HW address yet */ @@ -909,6 +914,66 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) continue; } + if (ifa->ifa_broadaddr && + ifa->ifa_flags & IFF_BROADCAST) { + /* interface has a broadcast address set */ + info->value->has_type = true; + info->value->type = GUEST_NETWORK_INTERFACE_TYPE_BROADCAST; + + if (ifa->ifa_addr->sa_family == AF_INET) { + /* and the broadcast is an IPv4 address */ + p = &((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr; + if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) { + snprintf(err_msg, sizeof(err_msg), + "inet_ntop failed : %s", strerror(errno)); + error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg); + goto error; + } + address_item->value->dest_address = g_strdup(addr4); + address_item->value->has_dest_address = true; + } else { + /* or it is an IPv6 address */ + p = &((struct sockaddr_in6 *)ifa->ifa_broadaddr)->sin6_addr; + if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) { + snprintf(err_msg, sizeof(err_msg), + "inet_ntop failed : %s", strerror(errno)); + error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg); + goto error; + } + address_item->value->dest_address = g_strdup(addr6); + address_item->value->has_dest_address = true; + } + } else if (ifa->ifa_dstaddr && + ifa->ifa_flags & IFF_POINTOPOINT) { + /* interface is point to point */ + info->value->has_type = true; + info->value->type = GUEST_NETWORK_INTERFACE_TYPE_PPP; + + if (ifa->ifa_addr->sa_family == AF_INET) { + /* and the peer has an IPv4 address */ + p = &((struct sockaddr_in *)ifa->ifa_dstaddr)->sin_addr; + if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) { + snprintf(err_msg, sizeof(err_msg), + "inet_ntop failed : %s", strerror(errno)); + error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg); + goto error; + } + address_item->value->dest_address = g_strdup(addr4); + address_item->value->has_dest_address = true; + } else { + /* or it has an IPv6 address */ + p = &((struct sockaddr_in6 *)ifa->ifa_dstaddr)->sin6_addr; + if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) { + snprintf(err_msg, sizeof(err_msg), + "inet_ntop failed : %s", strerror(errno)); + error_set(errp, QERR_QGA_COMMAND_FAILED, err_msg); + goto error; + } + address_item->value->dest_address = g_strdup(addr6); + address_item->value->has_dest_address = true; + } + } + address_list = &info->value->ip_addresses; while (*address_list && (*address_list)->next) { diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index ed0eb69..066e6aa 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -480,26 +480,57 @@ # # @prefix: Network prefix length of @ip-address # -# Since: 1.1 +# @dest-address: The broadcast or peer address. +# +# Since: 1.1, @dest-address since 1.3 ## { 'type': 'GuestIpAddress', 'data': {'ip-address': 'str', 'ip-address-type': 'GuestIpAddressType', - 'prefix': 'int'} } + 'prefix': 'int', + '*dest-address': 'str'} } ## +# @GuestNetworkInterfaceType: +# +# @broadcast: Interface has a broadcast address. In which case it is +# contained in @dest-address in @GuestIpAddress. +# +# @ppp: Interface is of point-to-point type. The peer address is then in +# @dest-address in @GuestIpAddress. +# +# Since: 1.3 +## +{ 'enum': 'GuestNetworkInterfaceType', + 'data': ['broadcast', 'ppp'] } +## # @GuestNetworkInterface: # # @name: The name of interface for which info are being delivered # +# @up: If the interface is up +# +# @loopback: If the interface is of loopback type +# +# @promisc: If the interface is in promiscuous mode +# +# @multicast: If the interface is cappable of multicast +# +# @type: If the interface has a broadcast address(-es) assigned, or is a PPP. +# # @hardware-address: Hardware address of @name # # @ip-addresses: List of addresses assigned to @name # -# Since: 1.1 +# Since: 1.1, @up, @loopback, @promisc, @multicast and @type since 1.3 ## { 'type': 'GuestNetworkInterface', 'data': {'name': 'str', + 'up': 'bool', + 'loopback': 'bool', + 'promisc': 'bool', + 'multicast': 'bool', + '*type': 'GuestNetworkInterfaceType', '*hardware-address': 'str', '*ip-addresses': ['GuestIpAddress'] } }