Use the network route definitions for domains

This commit is contained in:
Cédric Bosdonnat 2015-01-14 16:15:57 +01:00
parent ca481a6f8f
commit a117652917
14 changed files with 78 additions and 172 deletions

View File

@ -4371,12 +4371,9 @@ qemu-kvm -net nic,model=? /dev/null
<p>
<span class="since">Since 1.2.12</span> route elements can also be added
to define the network routes to use for the network device. This element
has a <code>family</code> attribute set either to <code>ipv4</code> or
<code>ipv6</code>, a mandatory <code>via</code> attribute defining the
IP address to route throught and optional <code>address</code> and <code>prefix</code>
attributes defining the target network range. If those aren't given, then
a default route will be set.
to define the network routes to use for the network device. The attributes
of this element are described in the documentation for the <code>route</code>
element in <a href="formatnetwork.html#elementsStaticroute">network definitions</a>.
This is only used by the LXC driver.
</p>

View File

@ -2330,9 +2330,7 @@
</element>
</zeroOrMore>
<zeroOrMore>
<element name="route">
<ref name="route"/>
</element>
<ref name="route"/>
</zeroOrMore>
<optional>
<element name="script">
@ -3602,27 +3600,6 @@
</element>
</define>
<define name="route">
<interleave>
<attribute name="family">
<ref name="addr-family"/>
</attribute>
<attribute name="via">
<ref name="ipAddr"/>
</attribute>
<optional>
<attribute name="address">
<ref name="ipAddr"/>
</attribute>
</optional>
<optional>
<attribute name="prefix">
<ref name="ipPrefix"/>
</attribute>
</optional>
</interleave>
</define>
<define name="hostdev">
<element name="hostdev">
<interleave>
@ -3859,9 +3836,7 @@
</element>
</zeroOrMore>
<zeroOrMore>
<element name="route">
<ref name="route"/>
</element>
<ref name="route"/>
</zeroOrMore>
</interleave>
</define>

View File

@ -371,7 +371,7 @@
</zeroOrMore>
<!-- <route> element -->
<zeroOrMore>
<ref name="routex"/>
<ref name="route"/>
</zeroOrMore>
</interleave>
</element>

View File

@ -228,7 +228,7 @@
<!-- The (static) route element specifies a network address and gateway
address to access that network. Both the network address and
the gateway address must be specified. -->
<define name='routex'>
<define name='route'>
<element name="route">
<optional>
<attribute name="family"><ref name="addr-family"/></attribute>

View File

@ -3,6 +3,7 @@
*
* Copyright (C) 2006-2014 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
* Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -1448,10 +1449,10 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
VIR_FREE(def->ips);
for (i = 0; i < def->nroutes; i++)
VIR_FREE(def->routes[i]);
virNetworkRouteDefFree(def->routes[i]);
VIR_FREE(def->routes);
virDomainDeviceInfoClear(&def->info);
virDomainDeviceInfoClear(&def->info);
VIR_FREE(def->filter);
virNWFilterHashTableFree(def->filterparams);
@ -4810,64 +4811,6 @@ virDomainNetIpParseXML(xmlNodePtr node)
return NULL;
}
static virDomainNetRouteDefPtr
virDomainNetRouteParse(xmlNodePtr node)
{
virDomainNetRouteDefPtr route = NULL;
char *familyStr = NULL;
int family = AF_UNSPEC;
char *via = NULL;
char *to = NULL;
char *prefixStr = NULL;
to = virXMLPropString(node, "address");
if (!(via = virXMLPropString(node, "via"))) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("Missing route address"));
goto error;
}
familyStr = virXMLPropString(node, "family");
if (familyStr && STREQ(familyStr, "ipv4"))
family = AF_INET;
else if (familyStr && STREQ(familyStr, "ipv6"))
family = AF_INET6;
else
family = virSocketAddrNumericFamily(via);
if (VIR_ALLOC(route) < 0)
goto error;
if (virSocketAddrParse(&route->via, via, family) < 0) {
virReportError(VIR_ERR_INVALID_ARG,
_("Failed to parse IP address: '%s'"),
via);
goto error;
}
if (to && virSocketAddrParse(&route->to, to, family) < 0) {
virReportError(VIR_ERR_INVALID_ARG,
_("Failed to parse IP address: '%s'"),
to);
goto error;
}
if (!(prefixStr = virXMLPropString(node, "prefix")) ||
(virStrToLong_ui(prefixStr, NULL, 10, &route->prefix) < 0)) {
}
return route;
error:
VIR_FREE(familyStr);
VIR_FREE(via);
VIR_FREE(to);
VIR_FREE(prefixStr);
VIR_FREE(route);
return NULL;
}
static int
virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
xmlXPathContextPtr ctxt,
@ -4961,14 +4904,17 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
if (nroutenodes) {
size_t i;
for (i = 0; i < nroutenodes; i++) {
virDomainNetRouteDefPtr route = virDomainNetRouteParse(routenodes[i]);
virNetworkRouteDefPtr route = NULL;
if (!route)
if (!(route = virNetworkRouteDefParseXML(_("Domain hostdev device"),
routenodes[i],
ctxt)))
goto error;
if (VIR_APPEND_ELEMENT(def->source.caps.u.net.routes,
def->source.caps.u.net.nroutes, route) < 0) {
VIR_FREE(route);
virNetworkRouteDefFree(route);
goto error;
}
}
@ -7429,7 +7375,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
size_t nips = 0;
virDomainNetIpDefPtr *ips = NULL;
size_t nroutes = 0;
virDomainNetRouteDefPtr *routes = NULL;
virNetworkRouteDefPtr *routes = NULL;
if (VIR_ALLOC(def) < 0)
return NULL;
@ -7527,12 +7473,15 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
if (VIR_APPEND_ELEMENT(ips, nips, ip) < 0)
goto error;
} else if (xmlStrEqual(cur->name, BAD_CAST "route")) {
virDomainNetRouteDefPtr route = NULL;
if (!(route = virDomainNetRouteParse(cur)))
virNetworkRouteDefPtr route = NULL;
if (!(route = virNetworkRouteDefParseXML(_("Domain interface"),
cur, ctxt)))
goto error;
if (VIR_APPEND_ELEMENT(routes, nroutes, route) < 0)
if (VIR_APPEND_ELEMENT(routes, nroutes, route) < 0) {
virNetworkRouteDefFree(route);
goto error;
}
} else if (!ifname &&
xmlStrEqual(cur->name, BAD_CAST "target")) {
ifname = virXMLPropString(cur, "dev");
@ -17271,35 +17220,17 @@ virDomainNetIpsFormat(virBufferPtr buf, virDomainNetIpDefPtr *ips, size_t nips)
}
}
static void
static int
virDomainNetRoutesFormat(virBufferPtr buf,
virDomainNetRouteDefPtr *routes,
virNetworkRouteDefPtr *routes,
size_t nroutes)
{
size_t i;
for (i = 0; i < nroutes; i++) {
virDomainNetRouteDefPtr route = routes[i];
const char *familyStr = NULL;
char *via = virSocketAddrFormat(&route->via);
char *to = NULL;
if (VIR_SOCKET_ADDR_IS_FAMILY(&route->via, AF_INET6))
familyStr = "ipv6";
else if (VIR_SOCKET_ADDR_IS_FAMILY(&route->via, AF_INET))
familyStr = "ipv4";
virBufferAsprintf(buf, "<route family='%s' via='%s'", familyStr, via);
if (VIR_SOCKET_ADDR_VALID(&route->to)) {
to = virSocketAddrFormat(&route->to);
virBufferAsprintf(buf, " address='%s'", to);
}
if (route->prefix > 0)
virBufferAsprintf(buf, " prefix='%d'", route->prefix);
virBufferAddLit(buf, "/>\n");
}
for (i = 0; i < nroutes; i++)
if (virNetworkRouteDefFormat(buf, routes[i]) < 0)
return -1;
return 0;
}
static int
@ -17457,8 +17388,9 @@ virDomainHostdevDefFormatCaps(virBufferPtr buf,
if (def->source.caps.type == VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET) {
virDomainNetIpsFormat(buf, def->source.caps.u.net.ips,
def->source.caps.u.net.nips);
virDomainNetRoutesFormat(buf, def->source.caps.u.net.routes,
def->source.caps.u.net.nroutes);
if (virDomainNetRoutesFormat(buf, def->source.caps.u.net.routes,
def->source.caps.u.net.nroutes) < 0)
return -1;
}
return 0;
@ -17848,7 +17780,8 @@ virDomainNetDefFormat(virBufferPtr buf,
}
virDomainNetIpsFormat(buf, def->ips, def->nips);
virDomainNetRoutesFormat(buf, def->routes, def->nroutes);
if (virDomainNetRoutesFormat(buf, def->routes, def->nroutes) < 0)
return -1;
virBufferEscapeString(buf, "<script path='%s'/>\n",
def->script);

View File

@ -3,6 +3,7 @@
*
* Copyright (C) 2006-2014 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
* Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -35,6 +36,7 @@
# include "virthread.h"
# include "virhash.h"
# include "virsocketaddr.h"
# include "networkcommon_conf.h"
# include "nwfilter_params.h"
# include "numatune_conf.h"
# include "virnetdevmacvlan.h"
@ -485,14 +487,6 @@ struct _virDomainNetIpDef {
unsigned int prefix; /* number of 1 bits in the net mask */
};
typedef struct _virDomainNetRouteDef virDomainNetRouteDef;
typedef virDomainNetRouteDef *virDomainNetRouteDefPtr;
struct _virDomainNetRouteDef {
virSocketAddr via;
virSocketAddr to;
unsigned int prefix;
};
typedef struct _virDomainHostdevCaps virDomainHostdevCaps;
typedef virDomainHostdevCaps *virDomainHostdevCapsPtr;
struct _virDomainHostdevCaps {
@ -509,7 +503,7 @@ struct _virDomainHostdevCaps {
size_t nips;
virDomainNetIpDefPtr *ips;
size_t nroutes;
virDomainNetRouteDefPtr *routes;
virNetworkRouteDefPtr *routes;
} net;
} u;
};
@ -1013,7 +1007,7 @@ struct _virDomainNetDef {
size_t nips;
virDomainNetIpDefPtr *ips;
size_t nroutes;
virDomainNetRouteDefPtr *routes;
virNetworkRouteDefPtr *routes;
};
/* Used for prefix of ifname of any network name generated dynamically

View File

@ -59,9 +59,9 @@ virNetworkRouteDefFree(virNetworkRouteDefPtr def)
virNetworkRouteDefPtr
virNetworkRouteDefCreate(const char *errorDetail,
char *family,
char *address,
char *netmask,
char *gateway,
const char *address,
const char *netmask,
const char *gateway,
unsigned int prefix,
bool hasPrefix,
unsigned int metric,

View File

@ -41,9 +41,9 @@ virNetworkRouteDefFree(virNetworkRouteDefPtr def);
virNetworkRouteDefPtr
virNetworkRouteDefCreate(const char *networkName,
char *family,
char *address,
char *netmask,
char *gateway,
const char *address,
const char *netmask,
const char *gateway,
unsigned int prefix,
bool hasPrefix,
unsigned int metric,

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2008-2014 Red Hat, Inc.
* Copyright (C) 2008 IBM Corp.
* Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
* lxc_container.c: file description
*
@ -544,20 +545,13 @@ static int lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef,
/* Set the routes */
for (j = 0; j < netDef->nroutes; j++) {
virDomainNetRouteDefPtr route = netDef->routes[j];
if (VIR_SOCKET_ADDR_VALID(&route->to))
toStr = virSocketAddrFormat(&route->to);
else
if (VIR_STRDUP(toStr, "default") < 0)
goto error_out;
viaStr = virSocketAddrFormat(&route->via);
VIR_DEBUG("Adding route %s/%d via %s", toStr, route->prefix, viaStr);
virNetworkRouteDefPtr route = netDef->routes[j];
if (virNetDevAddRoute(newname, &route->to, route->prefix,
&route->via, 0) < 0) {
virReportError(VIR_ERR_SYSTEM_ERROR,
_("Failed to add route %s/%d via %s"),
toStr, route->prefix, viaStr);
if (virNetDevAddRoute(newname,
virNetworkRouteDefGetAddress(route),
virNetworkRouteDefGetPrefix(route),
virNetworkRouteDefGetGateway(route),
virNetworkRouteDefGetMetric(route)) < 0) {
goto error_out;
}
VIR_FREE(toStr);

View File

@ -2,7 +2,7 @@
* lxc_native.c: LXC native configuration import
*
* Copyright (c) 2014 Red Hat, Inc.
* Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
* Copyright (c) 2013-2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -433,24 +433,37 @@ typedef struct {
static int
lxcAddNetworkRouteDefinition(const char *address,
int family,
virDomainNetRouteDefPtr **routes,
virNetworkRouteDefPtr **routes,
size_t *nroutes)
{
virDomainNetRouteDefPtr route = NULL;
virNetworkRouteDefPtr route = NULL;
char *familyStr = NULL;
char *zero = NULL;
if (VIR_ALLOC(route) < 0)
if (VIR_STRDUP(zero, family == AF_INET ? VIR_SOCKET_ADDR_IPV4_ALL
: VIR_SOCKET_ADDR_IPV6_ALL) < 0)
goto error;
if (virSocketAddrParse(&route->via, address, family) < 0)
if (VIR_STRDUP(familyStr, family == AF_INET ? "ipv4" : "ipv6") < 0)
goto error;
if (!(route = virNetworkRouteDefCreate(_("Domain interface"), familyStr,
zero, NULL, address, 0, false,
0, false)))
goto error;
if (VIR_APPEND_ELEMENT(*routes, *nroutes, route) < 0)
goto error;
VIR_FREE(familyStr);
VIR_FREE(zero);
return 0;
error:
VIR_FREE(route);
VIR_FREE(familyStr);
VIR_FREE(zero);
virNetworkRouteDefFree(route);
return -1;
}

View File

@ -27,8 +27,8 @@
</source>
<ip address='192.168.122.2' family='ipv4' prefix='24'/>
<ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='64'/>
<route family='ipv4' via='192.168.122.1'/>
<route family='ipv6' via='2003:db8:1:0:214:1234:fe0b:3595'/>
<route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
<route family='ipv6' address='::' gateway='2003:db8:1:0:214:1234:fe0b:3595'/>
</hostdev>
</devices>
</domain>

View File

@ -39,8 +39,8 @@
<source bridge='virbr0'/>
<ip address='192.168.122.2' family='ipv4' prefix='24'/>
<ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='64'/>
<route family='ipv4' via='192.168.122.1'/>
<route family='ipv6' via='2003:db8:1:0:214:1234:fe0b:3595'/>
<route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
<route family='ipv6' address='::' gateway='2003:db8:1:0:214:1234:fe0b:3595'/>
<guest dev='eth0'/>
<link state='up'/>
</interface>

View File

@ -37,8 +37,8 @@
</source>
<ip address='192.168.122.2' family='ipv4'/>
<ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='24'/>
<route family='ipv4' via='192.168.122.1'/>
<route family='ipv6' via='2003:db8:1:0:214:1234:fe0b:3595'/>
<route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
<route family='ipv6' address='::' gateway='2003:db8:1:0:214:1234:fe0b:3595'/>
</hostdev>
</devices>
</domain>

View File

@ -30,8 +30,8 @@
<source bridge='bri0'/>
<ip address='192.168.122.12' family='ipv4' prefix='24'/>
<ip address='192.168.122.13' family='ipv4' prefix='24'/>
<route family='ipv4' via='192.168.122.1'/>
<route family='ipv4' via='192.168.124.1' address='192.168.124.0' prefix='24'/>
<route family='ipv4' address='0.0.0.0' gateway='192.168.122.1'/>
<route family='ipv4' address='192.168.124.0' prefix='24' gateway='192.168.124.1'/>
<target dev='veth0'/>
<guest dev='eth2'/>
</interface>