Later patches will add the possibility to define a network's netmask as a prefix (0-32, or 0-128 in the case of IPv6). To make it easier to deal with definition of both kinds (prefix or netmask), add two new functions: virNetworkDefNetmask: return a copy of the netmask into a virSocketAddr. If no netmask was specified in the XML, create a default netmask based on the network class of the virNetworkDef's IP address. virNetworkDefPrefix: return the netmask as numeric prefix (or the default prefix for the network class of the virNetworkDef's IP address, if no netmask was specified in the XML) --- V2 Changes: * expose the nitty-gritty of detecting class A-C networks, rather than using IN_CLASSx() macros (which aren't guaranteed to be on all platforms) src/conf/network_conf.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/conf/network_conf.h | 3 +++ src/libvirt_private.syms | 2 ++ 3 files changed, 51 insertions(+), 0 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index b469269..427b338 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -207,6 +207,52 @@ void virNetworkRemoveInactive(virNetworkObjListPtr nets, } } +/* return number of 1 bits in netmask for the network's ipAddress, + * or -1 on error + */ +int virNetworkDefPrefix(const virNetworkDefPtr def) +{ + if (VIR_SOCKET_HAS_ADDR(&def->netmask)) { + return virSocketGetNumNetmaskBits(&def->netmask); + } else if (VIR_SOCKET_IS_FAMILY(&def->ipAddress, AF_INET)) { + /* Return the natural prefix for the network's ip address. + * On Linux we could use the IN_CLASSx() macros, but those + * aren't guaranteed on all platforms, so we just deal with + * the bits ourselves. + */ + const unsigned char *octets + = (const unsigned char *)(&def->ipAddress.data.inet4.sin_addr.s_addr); + if ((octets[0] & 0x80) == 0) { + /* Class A network */ + return 8; + } else if ((octets[0] & 0xC0) == 0x80) { + /* Class B network */ + return 16; + } else if ((octets[0] & 0xE0) == 0xC0) { + /* Class C network */ + return 24; + } + return -1; + } + return -1; +} + +/* Fill in a virSocketAddr with the proper netmask for this + * definition, based on either the definition's netmask, or its + * prefix. Return -1 on error (and set the netmask family to AF_UNSPEC) + */ +int virNetworkDefNetmask(const virNetworkDefPtr def, + virSocketAddrPtr netmask) +{ + if (VIR_SOCKET_IS_FAMILY(&def->netmask, AF_INET)) { + *netmask = def->netmask; + return 0; + } + + return virSocketAddrPrefixToNetmask(virNetworkDefPrefix(def), netmask, + VIR_SOCKET_FAMILY(&def->ipAddress)); +} + static int virNetworkDHCPRangeDefParseXML(virNetworkDefPtr def, diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 7d31693..a922d28 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -133,6 +133,9 @@ virNetworkDefPtr virNetworkDefParseNode(xmlDocPtr xml, char *virNetworkDefFormat(const virNetworkDefPtr def); +int virNetworkDefPrefix(const virNetworkDefPtr def); +int virNetworkDefNetmask(const virNetworkDefPtr def, + virSocketAddrPtr netmask); int virNetworkSaveXML(const char *configDir, virNetworkDefPtr def, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 19841ef..d9ba7b1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -578,9 +578,11 @@ virNetworkAssignDef; virNetworkConfigFile; virNetworkDefFormat; virNetworkDefFree; +virNetworkDefNetmask; virNetworkDefParseFile; virNetworkDefParseNode; virNetworkDefParseString; +virNetworkDefPrefix; virNetworkDeleteConfig; virNetworkFindByName; virNetworkFindByUUID; -- 1.7.3.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list