[libvirt] Report guest IPs as XML or struct?

I've proposed both approaches in the past. However, none of them was accepted as we ought to agree on $subj first. Frankly, both makes sense to me, both has advantages and disadvantages. XML - keeps things more consistent as libvirt is tied to XML, right? Pros: - can add items over the time Cons: - more complicated to parse and dump info (apps would have to query multiple XPATHs to get answer - at least with my implementation I've sent) struct - it would be a linked list or array of structs in fact Pros: - easier to dump useful data Cons: - once struct is released we cannot change it if we don't want to break ABI. What things do we want to expose for now? qemu guest agent reports: - type of IP address (v4/v6) - prefix length - actual address (string) (these can repeat multiple times, since there's 1:* relationship between interface an IP addresses) - hw address - name as seen within guest (HW address can be omitted - not all interfaces must have one). The only element that will be there for sure is name then. The whole QAPI schema can be found in qapi-schema-guest.json [1]. Suggestions are welcome. Michal 1: http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema-guest.json;h=ed0eb698c6...

On Wed, Nov 14, 2012 at 05:06:08PM +0100, Michal Privoznik wrote:
I've proposed both approaches in the past. However, none of them was accepted as we ought to agree on $subj first. Frankly, both makes sense to me, both has advantages and disadvantages.
XML - keeps things more consistent as libvirt is tied to XML, right? Pros: - can add items over the time Cons: - more complicated to parse and dump info (apps would have to query multiple XPATHs to get answer - at least with my implementation I've sent)
struct - it would be a linked list or array of structs in fact Pros: - easier to dump useful data Cons: - once struct is released we cannot change it if we don't want to break ABI.
What things do we want to expose for now? qemu guest agent reports: - type of IP address (v4/v6) - prefix length - actual address (string) (these can repeat multiple times, since there's 1:* relationship between interface an IP addresses)
- hw address - name as seen within guest (HW address can be omitted - not all interfaces must have one). The only element that will be there for sure is name then.
The whole QAPI schema can be found in qapi-schema-guest.json [1].
Suggestions are welcome.
I believe I said in the past, the answer depends on what we consider the scope of the APIs to be. If we consider this to be solely about network interface address configuration, then I think a struct is the most appropriate. If we consider this to be about guest network configuration in general,then XML is the most appropriate, and we should use the virInterface XML schema and not invent a new one. IMHO, we should focus solely on interface address configuration and aim to provide an API equivalent to getifaddrs(3). This means - Name - Type - Prefix - Address - Broadcast addresss or P2p destination address - Hardware address and nothing more, in a fixed struct. Specifically out of scope would be - Routing information. - Type of interface config (bridging/bonding/vlans/etc) - NIC config parameters/state (MTU, etc) Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 11/14/2012 09:25 AM, Daniel P. Berrange wrote:
On Wed, Nov 14, 2012 at 05:06:08PM +0100, Michal Privoznik wrote:
I've proposed both approaches in the past. However, none of them was accepted as we ought to agree on $subj first. Frankly, both makes sense to me, both has advantages and disadvantages.
IMHO, we should focus solely on interface address configuration and aim to provide an API equivalent to getifaddrs(3). This means
- Name - Type - Prefix - Address - Broadcast addresss or P2p destination address - Hardware address
and nothing more, in a fixed struct.
Using a fixed-size struct works for me as well. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 14.11.2012 17:25, Daniel P. Berrange wrote:
On Wed, Nov 14, 2012 at 05:06:08PM +0100, Michal Privoznik wrote:
I've proposed both approaches in the past. However, none of them was accepted as we ought to agree on $subj first. Frankly, both makes sense to me, both has advantages and disadvantages.
XML - keeps things more consistent as libvirt is tied to XML, right? Pros: - can add items over the time Cons: - more complicated to parse and dump info (apps would have to query multiple XPATHs to get answer - at least with my implementation I've sent)
struct - it would be a linked list or array of structs in fact Pros: - easier to dump useful data Cons: - once struct is released we cannot change it if we don't want to break ABI.
What things do we want to expose for now? qemu guest agent reports: - type of IP address (v4/v6) - prefix length - actual address (string) (these can repeat multiple times, since there's 1:* relationship between interface an IP addresses)
- hw address - name as seen within guest (HW address can be omitted - not all interfaces must have one). The only element that will be there for sure is name then.
The whole QAPI schema can be found in qapi-schema-guest.json [1].
Suggestions are welcome.
I believe I said in the past, the answer depends on what we consider the scope of the APIs to be. If we consider this to be solely about network interface address configuration, then I think a struct is the most appropriate. If we consider this to be about guest network configuration in general,then XML is the most appropriate, and we should use the virInterface XML schema and not invent a new one.
IMHO, we should focus solely on interface address configuration and aim to provide an API equivalent to getifaddrs(3). This means
- Name - Type - Prefix - Address - Broadcast addresss or P2p destination address - Hardware address
and nothing more, in a fixed struct. Specifically out of scope would be
- Routing information. - Type of interface config (bridging/bonding/vlans/etc) - NIC config parameters/state (MTU, etc)
Regards, Daniel
Okay, I lean towards struct as well. But just to make things a slightly more complicated; In general there is no connection between host part and guest of NIC. IOW, the host vnet0 interface can be eth0 within guest, vnet1 can be eth1 as well as vice versa (vnet0 being eth1 and vnet1 being eth0). The only link is HW address, which can be changed though. Moreover, users can create virtual interfaces within guest itself. Should we care about this? The second thought, we already have ip address learning code (in nwfilter). I think this could be exposed as well and users would choose which method they want to use (guest agent or nwfilter). But then on second thought, when choosing the nwfilter learning method, even though info would fit into the struct, some fields will be missing (e.g. prefix) and some will be totally different (e.g. name because this is from host POV). Not to mention that learning code doesn't necessarily have to have desired info (e.g. guest hasn't sent any packet or is sending spoofed ones). Michal

On Fri, Nov 16, 2012 at 10:47:40AM +0100, Michal Privoznik wrote:
On 14.11.2012 17:25, Daniel P. Berrange wrote:
On Wed, Nov 14, 2012 at 05:06:08PM +0100, Michal Privoznik wrote:
I've proposed both approaches in the past. However, none of them was accepted as we ought to agree on $subj first. Frankly, both makes sense to me, both has advantages and disadvantages.
XML - keeps things more consistent as libvirt is tied to XML, right? Pros: - can add items over the time Cons: - more complicated to parse and dump info (apps would have to query multiple XPATHs to get answer - at least with my implementation I've sent)
struct - it would be a linked list or array of structs in fact Pros: - easier to dump useful data Cons: - once struct is released we cannot change it if we don't want to break ABI.
What things do we want to expose for now? qemu guest agent reports: - type of IP address (v4/v6) - prefix length - actual address (string) (these can repeat multiple times, since there's 1:* relationship between interface an IP addresses)
- hw address - name as seen within guest (HW address can be omitted - not all interfaces must have one). The only element that will be there for sure is name then.
The whole QAPI schema can be found in qapi-schema-guest.json [1].
Suggestions are welcome.
I believe I said in the past, the answer depends on what we consider the scope of the APIs to be. If we consider this to be solely about network interface address configuration, then I think a struct is the most appropriate. If we consider this to be about guest network configuration in general,then XML is the most appropriate, and we should use the virInterface XML schema and not invent a new one.
IMHO, we should focus solely on interface address configuration and aim to provide an API equivalent to getifaddrs(3). This means
- Name - Type - Prefix - Address - Broadcast addresss or P2p destination address - Hardware address
and nothing more, in a fixed struct. Specifically out of scope would be
- Routing information. - Type of interface config (bridging/bonding/vlans/etc) - NIC config parameters/state (MTU, etc)
Regards, Daniel
Okay, I lean towards struct as well. But just to make things a slightly more complicated; In general there is no connection between host part and guest of NIC. IOW, the host vnet0 interface can be eth0 within guest, vnet1 can be eth1 as well as vice versa (vnet0 being eth1 and vnet1 being eth0). The only link is HW address, which can be changed though. Moreover, users can create virtual interfaces within guest itself. Should we care about this?
No, that's just life, and users have to live with it.
The second thought, we already have ip address learning code (in nwfilter). I think this could be exposed as well and users would choose which method they want to use (guest agent or nwfilter). But then on second thought, when choosing the nwfilter learning method, even though info would fit into the struct, some fields will be missing (e.g. prefix) and some will be totally different (e.g. name because this is from host POV). Not to mention that learning code doesn't necessarily have to have desired info (e.g. guest hasn't sent any packet or is sending spoofed ones).
There are multiple ways to obtain the IP address info, so we should support a flag to control which is used. So we can either query the libvirt IP learning code, or we can query the guest agent, or we can directly grab it from the container. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Seems like we agree on struct. So this is my proposal: typedef enum { VIR_INTERFACE_TYPE_UNKNOWN = 0, VIR_INTERFACE_TYPE_ETHER = 1, VIR_INTERFACE_TYPE_PPP = 2, /* we can add things here */ #idef VIR_ENUM_SENTINELS VIR_INTERFACE_TYPE_LAST #endif } virDomainInterfaceType; typedef enum { VIR_IP_ADDR_TYPE_IPV4, VIR_IP_ADDR_TYPE_IPV6, #ifdef VIR_ENUM_SENTINELS VIR_IP_ADDR_TYPE_LAST #endif } virIPAddrType; typedef struct _virDomainInterfaceIPAddress virDomainIPAddress; typedef virDomainIPAddress *virDomainIPAddressPtr; struct _virDomainInterfaceIPAddress { int type; /* virIPAddrType */ char *addr; /* IP address */ int prefix; /* IP address prefix */ }; typedef struct _virDomainInterface virDomainInterface; typedef virDomainInterface *virDomainInterfacePtr; struct _virDomainInterface { char *name; /* interface name */ int type; /* virDomainInterfaceType */ char *hwaddr; /* hardware address */ unsigned int ip_addrs_count; /* number of items in @ip_addr */ virDomainIPAddressPtr ip_addrs; /* array of IP addresses */ void *padding[20]; /* maybe we need this? */ }; typedef enum { VIR_DOMAIN_INTERFACE_ADDRS_DEFAULT = 0, /* hypervisor choice */ VIR_DOMAIN_INTERFACE_ADDRS_GUEST_AGENT = 1, /* use guest agent */ VIR_DOMAIN_INTERFACE_ADDRS_NWFILTER = 2, /* use nwfilter learning code */ /* etc ... */ } virDomainInterfacesAddressesMethod; int virDomainInterfacesAddresses(virDomainPtr dom, virDomainInterfacePtr ifaces, unsigned int method unsigned int flags); This API would dynamically allocate return array for all interfaces presented in @dom. We are already doing this in some places, so I think it's okay. With @method users can choose desired way to get info. I guess if we misuse @flags for that it would be just a waste of space, since methods are mutually exclusive. Hence, @flags are currently unused. Michal
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Michal Privoznik