fix zero sin6_scope_id issue

When running devstack on Ubuntu Bionic, if only ipv6 link-local address
is configured on interfaces, the calling of getaddrinfo with hint AF_INET6
in the function initAddr of msgClass.cpp succeed, but the sin6_scope_id
in the returned address structure is wrong. This will cause the failure of
the following bind operation. So we add this check, once the sin6_scope_id
is incorrect, make it switch to ipv4.
For normal StarlingX deployment, getaddrinfo will fail for the case of
ipv6, then will not run the check we added and switch to ipv4 directly.

To avoid impacting normal StarlingX, add a control gate to enable the update
only in Devstack Ubuntu Bionic environment.

Passed tests:
* Fresh building
* Deployment test (simplex, multiple node)
* Unit tests including sample code test and devstack test
* System-level test, guestAgent&guestServer can start normally. Configure
  the system to enable ipv6 link-local mode, guestAgent&guestServer still
  can start normally.

Story: 2003161
Task: 29851

Change-Id: I25711acd70358042e0505051221091e32b0929e3
Signed-off-by: Yi Wang <yi.c.wang@intel.com>
This commit is contained in:
Yi Wang 2019-03-07 16:49:09 +08:00
parent 4b29c4c481
commit cddb075f04

View File

@ -68,6 +68,25 @@ int msgClassAddr::initAddr(const char* address, int port, int proto)
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET6;
rc = getaddrinfo(this->address_str, NULL, &hints, &res);
if (!rc) {
// It is to resolve the issue of devstack found on Ubuntu Bionic. To
// avoid impacting normal StarlingX, add below control gate to only
// enable the code on Ubuntu Bionic.
if (getenv("UBUNTU_BIONIC")) {
/* check if returned ipv6 address is correct*/
if (res->ai_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)res->ai_addr;
if ((in6->sin6_scope_id == 0) &&
(in6->sin6_addr.s6_addr[0] == 0xFE) &&
((in6->sin6_addr.s6_addr[1] & 0xC0) == 0x80))
{
/* ipv6 link-local address should has non-zero sin6_scope_id */
ilog("link-local ipv6 address has zero sin6_scope_id, switch to ipv4\n");
rc = 1;
}
}
}
}
if(rc)
{
dlog("IPv6 address resolution failed, rc=%d", rc);