qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qemu-ga: Extend guest-network-get-interfaces
@ 2012-12-21 12:59 Michal Privoznik
  2012-12-21 18:43 ` Eric Blake
  0 siblings, 1 reply; 3+ messages in thread
From: Michal Privoznik @ 2012-12-21 12:59 UTC (permalink / raw)
  To: qemu-devel

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'] } }
 
-- 
1.8.0.2

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

* Re: [Qemu-devel] [PATCH] qemu-ga: Extend guest-network-get-interfaces
  2012-12-21 12:59 [Qemu-devel] [PATCH] qemu-ga: Extend guest-network-get-interfaces Michal Privoznik
@ 2012-12-21 18:43 ` Eric Blake
  2013-01-02  8:28   ` Michal Privoznik
  0 siblings, 1 reply; 3+ messages in thread
From: Eric Blake @ 2012-12-21 18:43 UTC (permalink / raw)
  To: Michal Privoznik; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2716 bytes --]

On 12/21/2012 05:59 AM, Michal Privoznik wrote:
> 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.
> ---
> 

> +++ 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

Actually, since 1.4 now (1.3 is already out).

>  ##
>  { 'type': 'GuestIpAddress',
>    'data': {'ip-address': 'str',
>             'ip-address-type': 'GuestIpAddressType',
> -           'prefix': 'int'} }
> +           'prefix': 'int',
> +           '*dest-address': 'str'} }

Is this field always going to be present in 1.4?  If so, then it doesn't
need to be marked optional (even though it wasn't present in 1.3).

>  ##
> +# @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

1.4

> +##
> +{ '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

s/cappable/capable/

> +#
> +# @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

1.4

>  ##
>  { 'type': 'GuestNetworkInterface',
>    'data': {'name': 'str',
> +           'up': 'bool',
> +           'loopback': 'bool',
> +           'promisc': 'bool',
> +           'multicast': 'bool',
> +           '*type': 'GuestNetworkInterfaceType',

Again, is this field optional?

>             '*hardware-address': 'str',
>             '*ip-addresses': ['GuestIpAddress'] } }
>  
> 

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

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

* Re: [Qemu-devel] [PATCH] qemu-ga: Extend guest-network-get-interfaces
  2012-12-21 18:43 ` Eric Blake
@ 2013-01-02  8:28   ` Michal Privoznik
  0 siblings, 0 replies; 3+ messages in thread
From: Michal Privoznik @ 2013-01-02  8:28 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel

On 21.12.2012 19:43, Eric Blake wrote:
> On 12/21/2012 05:59 AM, Michal Privoznik wrote:
>> 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.
>> ---
>>
> 
>> +++ 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
> 
> Actually, since 1.4 now (1.3 is already out).
> 
>>  ##
>>  { 'type': 'GuestIpAddress',
>>    'data': {'ip-address': 'str',
>>             'ip-address-type': 'GuestIpAddressType',
>> -           'prefix': 'int'} }
>> +           'prefix': 'int',
>> +           '*dest-address': 'str'} }
> 
> Is this field always going to be present in 1.4?  If so, then it doesn't
> need to be marked optional (even though it wasn't present in 1.3).

Not really. This field is gonna be there iff guest agent is able to dig
the info out. For instance, for PPP interfaces, I was unable to get
peer's address via getifaddrs(). Other utilities use netlink for that.
However, if interface has an broadcast address, this can be easily
obtained via getifaddrs(). That's why I am making this optional for now.

> 
>>  ##
>> +# @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
> 
> 1.4
> 
>> +##
>> +{ '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
> 
> s/cappable/capable/
> 
>> +#
>> +# @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
> 
> 1.4
> 
>>  ##
>>  { 'type': 'GuestNetworkInterface',
>>    'data': {'name': 'str',
>> +           'up': 'bool',
>> +           'loopback': 'bool',
>> +           'promisc': 'bool',
>> +           'multicast': 'bool',
>> +           '*type': 'GuestNetworkInterfaceType',
> 
> Again, is this field optional?

Yes. Because this actually tells type of 'dest-address' field which is
optional I think this one should be optional as well.

> 
>>             '*hardware-address': 'str',
>>             '*ip-addresses': ['GuestIpAddress'] } }
>>  
>>
> 

Michal

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

end of thread, other threads:[~2013-01-02  8:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-21 12:59 [Qemu-devel] [PATCH] qemu-ga: Extend guest-network-get-interfaces Michal Privoznik
2012-12-21 18:43 ` Eric Blake
2013-01-02  8:28   ` Michal Privoznik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).