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> <p>
<span class="since">Since 1.2.12</span> route elements can also be added <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 to define the network routes to use for the network device. The attributes
has a <code>family</code> attribute set either to <code>ipv4</code> or of this element are described in the documentation for the <code>route</code>
<code>ipv6</code>, a mandatory <code>via</code> attribute defining the element in <a href="formatnetwork.html#elementsStaticroute">network definitions</a>.
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.
This is only used by the LXC driver. This is only used by the LXC driver.
</p> </p>

View File

@@ -2330,9 +2330,7 @@
</element> </element>
</zeroOrMore> </zeroOrMore>
<zeroOrMore> <zeroOrMore>
<element name="route"> <ref name="route"/>
<ref name="route"/>
</element>
</zeroOrMore> </zeroOrMore>
<optional> <optional>
<element name="script"> <element name="script">
@@ -3602,27 +3600,6 @@
</element> </element>
</define> </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"> <define name="hostdev">
<element name="hostdev"> <element name="hostdev">
<interleave> <interleave>
@@ -3859,9 +3836,7 @@
</element> </element>
</zeroOrMore> </zeroOrMore>
<zeroOrMore> <zeroOrMore>
<element name="route"> <ref name="route"/>
<ref name="route"/>
</element>
</zeroOrMore> </zeroOrMore>
</interleave> </interleave>
</define> </define>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
* lxc_native.c: LXC native configuration import * lxc_native.c: LXC native configuration import
* *
* Copyright (c) 2014 Red Hat, Inc. * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -433,24 +433,37 @@ typedef struct {
static int static int
lxcAddNetworkRouteDefinition(const char *address, lxcAddNetworkRouteDefinition(const char *address,
int family, int family,
virDomainNetRouteDefPtr **routes, virNetworkRouteDefPtr **routes,
size_t *nroutes) 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; 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; goto error;
if (VIR_APPEND_ELEMENT(*routes, *nroutes, route) < 0) if (VIR_APPEND_ELEMENT(*routes, *nroutes, route) < 0)
goto error; goto error;
VIR_FREE(familyStr);
VIR_FREE(zero);
return 0; return 0;
error: error:
VIR_FREE(route); VIR_FREE(familyStr);
VIR_FREE(zero);
virNetworkRouteDefFree(route);
return -1; return -1;
} }

View File

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

View File

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

View File

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

View File

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