mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-27 09:57:43 +03:00
migration: add migration_host support for IPv6 address without brackets
if specifying migration_host to an Ipv6 address without brackets, it was resolved to an incorrect address, such as: tcp:2001:0DB8::1428:4444, but the correct address should be: tcp:[2001:0DB8::1428]:4444 so we should add brackets when parsing it. Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>
This commit is contained in:
parent
6c31911a96
commit
69f7b67d55
@ -1916,11 +1916,11 @@ virSocketAddrGetIpPrefix;
|
|||||||
virSocketAddrGetPort;
|
virSocketAddrGetPort;
|
||||||
virSocketAddrGetRange;
|
virSocketAddrGetRange;
|
||||||
virSocketAddrIsNetmask;
|
virSocketAddrIsNetmask;
|
||||||
virSocketAddrIsNumeric;
|
|
||||||
virSocketAddrIsPrivate;
|
virSocketAddrIsPrivate;
|
||||||
virSocketAddrIsWildcard;
|
virSocketAddrIsWildcard;
|
||||||
virSocketAddrMask;
|
virSocketAddrMask;
|
||||||
virSocketAddrMaskByPrefix;
|
virSocketAddrMaskByPrefix;
|
||||||
|
virSocketAddrNumericFamily;
|
||||||
virSocketAddrParse;
|
virSocketAddrParse;
|
||||||
virSocketAddrParseIPv4;
|
virSocketAddrParseIPv4;
|
||||||
virSocketAddrParseIPv6;
|
virSocketAddrParseIPv6;
|
||||||
|
@ -2605,7 +2605,6 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
|
|||||||
if (VIR_STRDUP(migrateFrom, "stdio") < 0)
|
if (VIR_STRDUP(migrateFrom, "stdio") < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
virSocketAddr listenAddressSocket;
|
|
||||||
bool encloseAddress = false;
|
bool encloseAddress = false;
|
||||||
bool hostIPv6Capable = false;
|
bool hostIPv6Capable = false;
|
||||||
bool qemuIPv6Capable = false;
|
bool qemuIPv6Capable = false;
|
||||||
@ -2627,28 +2626,21 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
|
|||||||
virObjectUnref(qemuCaps);
|
virObjectUnref(qemuCaps);
|
||||||
|
|
||||||
if (listenAddress) {
|
if (listenAddress) {
|
||||||
if (virSocketAddrIsNumeric(listenAddress)) {
|
if (virSocketAddrNumericFamily(listenAddress) == AF_INET6) {
|
||||||
/* listenAddress is numeric IPv4 or IPv6 */
|
if (!qemuIPv6Capable) {
|
||||||
if (virSocketAddrParse(&listenAddressSocket, listenAddress, AF_UNSPEC) < 0)
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
||||||
|
_("qemu isn't capable of IPv6"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* address parsed successfully */
|
|
||||||
if (VIR_SOCKET_ADDR_IS_FAMILY(&listenAddressSocket, AF_INET6)) {
|
|
||||||
if (!qemuIPv6Capable) {
|
|
||||||
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
|
||||||
_("qemu isn't capable of IPv6"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (!hostIPv6Capable) {
|
|
||||||
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
|
||||||
_("host isn't capable of IPv6"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
/* IPv6 address must be escaped in brackets on the cmd line */
|
|
||||||
encloseAddress = true;
|
|
||||||
}
|
}
|
||||||
|
if (!hostIPv6Capable) {
|
||||||
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
||||||
|
_("host isn't capable of IPv6"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
/* IPv6 address must be escaped in brackets on the cmd line */
|
||||||
|
encloseAddress = true;
|
||||||
} else {
|
} else {
|
||||||
/* listenAddress is a hostname */
|
/* listenAddress is a hostname or IPv4 */
|
||||||
}
|
}
|
||||||
} else if (qemuIPv6Capable && hostIPv6Capable) {
|
} else if (qemuIPv6Capable && hostIPv6Capable) {
|
||||||
/* Listen on :: instead of 0.0.0.0 if QEMU understands it
|
/* Listen on :: instead of 0.0.0.0 if QEMU understands it
|
||||||
@ -2950,15 +2942,17 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
|
|||||||
* to be a correct hostname which refers to the target machine).
|
* to be a correct hostname which refers to the target machine).
|
||||||
*/
|
*/
|
||||||
if (uri_in == NULL) {
|
if (uri_in == NULL) {
|
||||||
|
bool encloseAddress = false;
|
||||||
|
const char *incFormat;
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
|
if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (migrateHost != NULL) {
|
if (migrateHost != NULL) {
|
||||||
if (virSocketAddrIsNumeric(migrateHost) &&
|
if (virSocketAddrNumericFamily(migrateHost) == AF_INET6)
|
||||||
virSocketAddrParse(NULL, migrateHost, AF_UNSPEC) < 0)
|
encloseAddress = true;
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (VIR_STRDUP(hostname, migrateHost) < 0)
|
if (VIR_STRDUP(hostname, migrateHost) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
if ((hostname = virGetHostname()) == NULL)
|
if ((hostname = virGetHostname()) == NULL)
|
||||||
@ -2977,7 +2971,12 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
|
|||||||
* compatibility with old targets. We at least make the
|
* compatibility with old targets. We at least make the
|
||||||
* new targets accept both syntaxes though.
|
* new targets accept both syntaxes though.
|
||||||
*/
|
*/
|
||||||
if (virAsprintf(uri_out, "tcp:%s:%d", hostname, port) < 0)
|
if (encloseAddress)
|
||||||
|
incFormat = "%s:[%s]:%d";
|
||||||
|
else
|
||||||
|
incFormat = "%s:%s:%d";
|
||||||
|
|
||||||
|
if (virAsprintf(uri_out, incFormat, "tcp", hostname, port) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
bool well_formed_uri;
|
bool well_formed_uri;
|
||||||
|
@ -856,26 +856,25 @@ virSocketAddrGetIpPrefix(const virSocketAddr *address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virSocketAddrIsNumeric:
|
* virSocketAddrNumericFamily:
|
||||||
* @address: address to check
|
* @address: address to check
|
||||||
*
|
*
|
||||||
* Check if passed address is an IP address in numeric format. For
|
* Check if passed address is an IP address in numeric format. and
|
||||||
* instance, for 0.0.0.0 true is returned, for 'examplehost"
|
* return the address family, otherwise return 0.
|
||||||
* false is returned.
|
|
||||||
*
|
*
|
||||||
* Returns: true if @address is an IP address,
|
* Returns: AF_INET or AF_INET6 if @address is an numeric IP address,
|
||||||
* false otherwise
|
* -1 otherwise.
|
||||||
*/
|
*/
|
||||||
bool
|
int
|
||||||
virSocketAddrIsNumeric(const char *address)
|
virSocketAddrNumericFamily(const char *address)
|
||||||
{
|
{
|
||||||
struct addrinfo *res;
|
struct addrinfo *res;
|
||||||
unsigned short family;
|
unsigned short family;
|
||||||
|
|
||||||
if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, false) < 0)
|
if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, false) < 0)
|
||||||
return false;
|
return -1;
|
||||||
|
|
||||||
family = res->ai_addr->sa_family;
|
family = res->ai_addr->sa_family;
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
return family == AF_INET || family == AF_INET6;
|
return family;
|
||||||
}
|
}
|
||||||
|
@ -125,5 +125,5 @@ bool virSocketAddrIsPrivate(const virSocketAddr *addr);
|
|||||||
|
|
||||||
bool virSocketAddrIsWildcard(const virSocketAddr *addr);
|
bool virSocketAddrIsWildcard(const virSocketAddr *addr);
|
||||||
|
|
||||||
bool virSocketAddrIsNumeric(const char *address);
|
int virSocketAddrNumericFamily(const char *address);
|
||||||
#endif /* __VIR_SOCKETADDR_H__ */
|
#endif /* __VIR_SOCKETADDR_H__ */
|
||||||
|
@ -219,19 +219,19 @@ static int testWildcardHelper(const void *opaque)
|
|||||||
return testWildcard(data->addr, data->pass);
|
return testWildcard(data->addr, data->pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct testIsNumericData {
|
struct testNumericData {
|
||||||
const char *addr;
|
const char *addr;
|
||||||
bool pass;
|
int expected;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testIsNumericHelper(const void *opaque)
|
testNumericHelper(const void *opaque)
|
||||||
{
|
{
|
||||||
const struct testIsNumericData *data = opaque;
|
const struct testNumericData *data = opaque;
|
||||||
|
|
||||||
if (virSocketAddrIsNumeric(data->addr))
|
if (virSocketAddrNumericFamily(data->addr) != data->expected)
|
||||||
return data->pass ? 0 : -1;
|
return -1;
|
||||||
return data->pass ? -1 : 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -314,11 +314,11 @@ mymain(void)
|
|||||||
ret = -1; \
|
ret = -1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define DO_TEST_IS_NUMERIC(addr, pass) \
|
#define DO_TEST_NUMERIC_FAMILY(addr, pass) \
|
||||||
do { \
|
do { \
|
||||||
struct testIsNumericData data = { addr, pass}; \
|
struct testNumericData data = { addr, pass }; \
|
||||||
if (virtTestRun("Test isNumeric " addr, \
|
if (virtTestRun("Test Numeric Family" addr, \
|
||||||
testIsNumericHelper, &data) < 0) \
|
testNumericHelper, &data) < 0) \
|
||||||
ret = -1; \
|
ret = -1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -385,11 +385,11 @@ mymain(void)
|
|||||||
DO_TEST_WILDCARD("1", false);
|
DO_TEST_WILDCARD("1", false);
|
||||||
DO_TEST_WILDCARD("0.1", false);
|
DO_TEST_WILDCARD("0.1", false);
|
||||||
|
|
||||||
DO_TEST_IS_NUMERIC("0.0.0.0", true);
|
DO_TEST_NUMERIC_FAMILY("0.0.0.0", AF_INET);
|
||||||
DO_TEST_IS_NUMERIC("::", true);
|
DO_TEST_NUMERIC_FAMILY("::", AF_INET6);
|
||||||
DO_TEST_IS_NUMERIC("1", true);
|
DO_TEST_NUMERIC_FAMILY("1", AF_INET);
|
||||||
DO_TEST_IS_NUMERIC("::ffff", true);
|
DO_TEST_NUMERIC_FAMILY("::ffff", AF_INET6);
|
||||||
DO_TEST_IS_NUMERIC("examplehost", false);
|
DO_TEST_NUMERIC_FAMILY("examplehost", -1);
|
||||||
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user