diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 18a7d575fd..e56e575e5e 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -582,33 +582,9 @@ virNetworkDefGetIpByIndex(const virNetworkDefPtr def, */ int virNetworkIpDefPrefix(const virNetworkIpDefPtr def) { - if (def->prefix > 0) { - return def->prefix; - } else if (VIR_SOCKET_ADDR_VALID(&def->netmask)) { - return virSocketAddrGetNumNetmaskBits(&def->netmask); - } else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, 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. - */ - unsigned char octet - = ntohl(def->address.data.inet4.sin_addr.s_addr) >> 24; - if ((octet & 0x80) == 0) { - /* Class A network */ - return 8; - } else if ((octet & 0xC0) == 0x80) { - /* Class B network */ - return 16; - } else if ((octet & 0xE0) == 0xC0) { - /* Class C network */ - return 24; - } - return -1; - } else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) { - return 64; - } - return -1; + return virSocketAddrGetIpPrefix(&def->address, + &def->netmask, + def->prefix); } /* Fill in a virSocketAddr with the proper netmask for this diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f778e9cd38..9f3a597a55 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1700,6 +1700,7 @@ virSocketAddrCheckNetmask; virSocketAddrEqual; virSocketAddrFormat; virSocketAddrFormatFull; +virSocketAddrGetIpPrefix; virSocketAddrGetPort; virSocketAddrGetRange; virSocketAddrIsNetmask; diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c index 3dfa3fb7ce..7ee450bb9e 100644 --- a/src/util/virsocketaddr.c +++ b/src/util/virsocketaddr.c @@ -754,4 +754,53 @@ virSocketAddrPrefixToNetmask(unsigned int prefix, error: return result; + } + +/** + * virSocketAddrGetIpPrefix: + * @address: network address + * @netmask: netmask for this network + * @prefix: prefix if specified instead of netmask + * + * Returns prefix value on success or -1 on error. + */ + +int +virSocketAddrGetIpPrefix(const virSocketAddrPtr address, + const virSocketAddrPtr netmask, + int prefix) +{ + if (prefix > 0) { + return prefix; + } else if (VIR_SOCKET_ADDR_VALID(netmask)) { + return virSocketAddrGetNumNetmaskBits(netmask); + } else if (VIR_SOCKET_ADDR_IS_FAMILY(address, 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. + */ + unsigned char octet + = ntohl(address->data.inet4.sin_addr.s_addr) >> 24; + if ((octet & 0x80) == 0) { + /* Class A network */ + return 8; + } else if ((octet & 0xC0) == 0x80) { + /* Class B network */ + return 16; + } else if ((octet & 0xE0) == 0xC0) { + /* Class C network */ + return 24; + } + return -1; + } else if (VIR_SOCKET_ADDR_IS_FAMILY(address, AF_INET6)) { + return 64; + } + + /* When none of the three (address/netmask/prefix) is given, 0 is + * returned rather than error, because this is a valid + * expectation, e.g. for the address/prefix used for a default + * route (the destination of a default route is 0.0.0.0/0). + */ + return 0; } diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h index 8993f7b81d..1c9e54a441 100644 --- a/src/util/virsocketaddr.h +++ b/src/util/virsocketaddr.h @@ -116,6 +116,9 @@ int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask); int virSocketAddrPrefixToNetmask(unsigned int prefix, virSocketAddrPtr netmask, int family); +int virSocketAddrGetIpPrefix(const virSocketAddrPtr address, + const virSocketAddrPtr netmask, + int prefix); bool virSocketAddrEqual(const virSocketAddrPtr s1, const virSocketAddrPtr s2); bool virSocketAddrIsPrivate(const virSocketAddrPtr addr);