diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4617f5d5d2..8579cfd4f2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1931,6 +1931,7 @@ virNetDevBridgeSetVlanFiltering; virNetDevIPAddrAdd; virNetDevIPAddrDel; virNetDevIPAddrGet; +virNetDevIPInfoAddToDev; virNetDevIPInfoClear; virNetDevIPRouteAdd; virNetDevIPRouteFree; diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 0d5f16c517..916a37b68e 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -490,7 +490,7 @@ lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef, char **veths) { int ret = -1; - size_t i, j; + size_t i; const char *newname; virDomainNetDefPtr netDef; bool privNet = vmDef->features[VIR_DOMAIN_FEATURE_PRIVNET] == @@ -509,53 +509,28 @@ lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef, VIR_DEBUG("Renaming %s to %s", veths[i], newname); if (virNetDevSetName(veths[i], newname) < 0) - goto cleanup; - - for (j = 0; j < netDef->guestIP.nips; j++) { - virNetDevIPAddrPtr ip = netDef->guestIP.ips[j]; - int prefix; - char *ipStr = virSocketAddrFormat(&ip->address); - - if ((prefix = virSocketAddrGetIPPrefix(&ip->address, - NULL, ip->prefix)) < 0) { - ipStr = virSocketAddrFormat(&ip->address); - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to determine prefix for IP address '%s'"), - ipStr); - VIR_FREE(ipStr); - goto cleanup; - } - VIR_FREE(ipStr); - - if (virNetDevIPAddrAdd(newname, &ip->address, NULL, prefix) < 0) - goto cleanup; - } + goto cleanup; + /* Only enable this device if there is a reason to do so (either + * at least one IP was specified, or link state was set to up in + * the config) + */ if (netDef->guestIP.nips || netDef->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP) { VIR_DEBUG("Enabling %s", newname); if (virNetDevSetOnline(newname, true) < 0) goto cleanup; - - /* Set the routes */ - for (j = 0; j < netDef->guestIP.nroutes; j++) { - virNetDevIPRoutePtr route = netDef->guestIP.routes[j]; - - if (virNetDevIPRouteAdd(newname, - virNetDevIPRouteGetAddress(route), - virNetDevIPRouteGetPrefix(route), - virNetDevIPRouteGetGateway(route), - virNetDevIPRouteGetMetric(route)) < 0) { - goto cleanup; - } - } } + + /* set IP addresses and routes */ + if (virNetDevIPInfoAddToDev(newname, &netDef->guestIP) < 0) + goto cleanup; } /* enable lo device only if there were other net devices */ if ((veths || privNet) && virNetDevSetOnline("lo", true) < 0) - goto cleanup; + goto cleanup; ret = 0; cleanup: diff --git a/src/util/virnetdevip.c b/src/util/virnetdevip.c index 01d4867106..da92d5bbff 100644 --- a/src/util/virnetdevip.c +++ b/src/util/virnetdevip.c @@ -886,3 +886,63 @@ virNetDevIPInfoClear(virNetDevIPInfoPtr ip) virNetDevIPRouteFree(ip->routes[i]); VIR_FREE(ip->routes); } + + +/** + * virNetDevIPInfoAddToDev: + * @ifname: name of device to operate on + * @ipInfo: list of routes and IP addresses to add to this device + * + * All IP routes and IP addresses in ipInfo are added to the named device. + * + * Returns: 0 on success, -1 (and error reported) on failure. + */ +int +virNetDevIPInfoAddToDev(const char *ifname, + virNetDevIPInfo const *ipInfo) +{ + int ret = -1; + size_t i; + char *ipStr = NULL; + int prefix; + + /* add all IP addresses */ + for (i = 0; i < ipInfo->nips; i++) { + virNetDevIPAddrPtr ip = ipInfo->ips[i]; + + ipStr = virSocketAddrFormat(&ip->address); + if ((prefix = virSocketAddrGetIPPrefix(&ip->address, + NULL, ip->prefix)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to determine prefix for IP address '%s'"), + ipStr); + goto cleanup; + } + if (virNetDevIPAddrAdd(ifname, &ip->address, NULL, prefix) < 0) + goto cleanup; + VIR_FREE(ipStr); + } + + /* add all routes */ + for (i = 0; i < ipInfo->nroutes; i++) { + virNetDevIPRoutePtr route = ipInfo->routes[i]; + + ipStr = virSocketAddrFormat(&route->address); + if ((prefix = virNetDevIPRouteGetPrefix(route)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to determine prefix for route with destination '%s'"), + ipStr); + goto cleanup; + } + if (virNetDevIPRouteAdd(ifname, &route->address, prefix, + &route->gateway, + virNetDevIPRouteGetMetric(route)) < 0) + goto cleanup; + VIR_FREE(ipStr); + } + + ret = 0; + cleanup: + VIR_FREE(ipStr); + return ret; +} diff --git a/src/util/virnetdevip.h b/src/util/virnetdevip.h index be41636db5..86fb77e285 100644 --- a/src/util/virnetdevip.h +++ b/src/util/virnetdevip.h @@ -86,5 +86,7 @@ virSocketAddrPtr virNetDevIPRouteGetGateway(virNetDevIPRoutePtr def); /* virNetDevIPInfo object */ void virNetDevIPInfoClear(virNetDevIPInfoPtr ip); +int virNetDevIPInfoAddToDev(const char *ifname, + virNetDevIPInfo const *ipInfo); #endif /* __VIR_NETDEVIP_H__ */