[libvirt] [PATCH 3/3] (REVISED) Support for IPv6 / multiple addresses per interface in virInterface
Daniel Veillard
veillard at redhat.com
Wed Oct 28 11:06:24 UTC 2009
On Fri, Oct 23, 2009 at 01:31:19PM -0400, Laine Stump wrote:
> (How's this?)
>
> This patch updates the xml parsing and formatting, and the associated
> virInterfaceDef data structure to support IPv6, along the way adding
> support for multiple protocols per interface, and multiple IP
> addresses per protocol.
> ---
> src/conf/interface_conf.c | 295 ++++++++++++++++++++++++++++++++++-----------
> src/conf/interface_conf.h | 19 ++-
> 2 files changed, 241 insertions(+), 73 deletions(-)
>
> diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c
> index d46f7ac..7cb71ed 100644
> --- a/src/conf/interface_conf.c
> +++ b/src/conf/interface_conf.c
> @@ -53,9 +53,31 @@ void virInterfaceBareDefFree(virInterfaceBareDefPtr def) {
> VIR_FREE(def);
> }
>
> +static
> +void virInterfaceIpDefFree(virInterfaceIpDefPtr def) {
> + if (def == NULL)
> + return;
> + VIR_FREE(def->address);
> +}
Hum ... shouldn't def be freed too there ???
[...]
> + def->nips = 0;
> + for (ii = 0; ii < nIpNodes; ii++) {
> +
> + virInterfaceIpDefPtr ip;
>
> + if (VIR_ALLOC(ip) < 0) {
> + virReportOOMError(conn);
> + goto error;
> + }
hum, yes I really think the matching FREE is missing, but let's do
that as a separate patch
> + ctxt->node = ipNodes[ii];
> + ret = virInterfaceDefParseIp(conn, ip, ctxt);
> + if (ret != 0) {
> + virInterfaceIpDefFree(ip);
> + goto error;
Hum ....
> + }
> + def->ips[def->nips++] = ip;
> + }
> +
> + ret = 0;
> +
> +error:
> + VIR_FREE(ipNodes);
> + return(ret);
> +}
It's hard to be sure we aren't leaking there too. On second reading
this looks okay because def is passed by the caller and we are storing
the data there.
[...]
> + nProtoNodes = virXPathNodeSet(conn, "./protocol", ctxt, &protoNodes);
> + if (nProtoNodes <= 0) {
> + /* no protocols is an acceptable outcome */
> + return 0;
> }
> +
> + if (VIR_ALLOC_N(def->protos, nProtoNodes) < 0) {
> + virReportOOMError(conn);
> + goto error;
> }
>
> + def->nprotos = 0;
> + for (pp = 0; pp < nProtoNodes; pp++) {
> +
> + virInterfaceProtocolDefPtr proto;
> +
> + if (VIR_ALLOC(proto) < 0) {
> + virReportOOMError(conn);
> + goto error;
> + }
> +
> + ctxt->node = protoNodes[pp];
> + tmp = virXPathString(conn, "string(./@family)", ctxt);
> + if (tmp == NULL) {
> + virInterfaceReportError(conn, VIR_ERR_XML_ERROR,
> + "%s", _("protocol misses the family attribute"));
> + virInterfaceProtocolDefFree(proto);
> + goto error;
> + }
> + proto->family = tmp;
> + if (STREQ(tmp, "ipv4")) {
> + ret = virInterfaceDefParseProtoIPv4(conn, proto, ctxt);
> + if (ret != 0) {
> + virInterfaceProtocolDefFree(proto);
> + goto error;
> + }
> + } else if (STREQ(tmp, "ipv6")) {
> + ret = virInterfaceDefParseProtoIPv6(conn, proto, ctxt);
> + if (ret != 0) {
> + virInterfaceProtocolDefFree(proto);
> + goto error;
> + }
> + } else {
> + virInterfaceReportError(conn, VIR_ERR_XML_ERROR,
> + _("unsupported protocol family '%s'"), tmp);
> + virInterfaceProtocolDefFree(proto);
> + goto error;
> + }
> + def->protos[def->nprotos++] = proto;
> + }
> +
> + ret = 0;
> +
> +error:
> + VIR_FREE(protoNodes);
> ctxt->node = save;
> return(ret);
Hum, we don't check there that an ipv6/4 protocol is not defined
multiple time. Maybe this could be slightly refactored to search
for 1 protocol node with type IPv4 and the one protocol node for type
Ipv6 something like
v4 = virXPathNode(conn, "./protocol[@family = 'ipv4']", ctxt)
v6 = virXPathNode(conn, "./protocol[@family = 'ipv6']", ctxt)
and drop the loop.
But current code works too, just does less checking IMHO.
I think we need to patch the previous leak.
But the main problem I faced when running the regression tests.
I had installed netcf-0.1.3 and a number of thing just break with
this patch. For example when libvirtd exits in the
"testing with corrupted config" libvirtd it just segfaults:
Starting program: /u/veillard/libvirt/daemon/libvirtd --config=in1.conf
[...]
Program received signal SIGSEGV, Segmentation fault.
drv_close (ncf=0x7f0740) at drv_initscripts.c:511
511 xsltFreeStylesheet(ncf->driver->get);
(gdb) p ncf->driver
$2 = (struct driver *) 0x0
(gdb) p *ncf
$3 = {ref = 1, root = 0x7f0780 "/",
data_dir = 0x7ffff77626b8 "/usr/share/netcf", errcode = NETCF_NOERROR,
errdetails = 0x0, driver = 0x0, debug = 0}
(gdb)
IMHO it's a bug in netcf since it should protect against acessing
uninitialized fields. The libvirtd side is:
/* open netcf */
if (ncf_init(&driverState->netcf, NULL) != 0)
{
/* what error to report? */
goto netcf_error;
}
conn->interfacePrivateData = driverState;
return 0;
netcf_error:
if (driverState->netcf)
{
ncf_close(driverState->netcf);
}
maybe if ncf_init() failed we should not call ncf_close()
but we can see that there is at least a string in that driver which need
to be deallocated.
I ran the test on Fedora 11 updated with netcf-0.1.3:
What I don't understand is why that patch affecting only
src/conf/interface_conf.[ch] is the one breaking this...
Hum, I reverted that patch and still get the error, maybe it's just
the netcf update ! I will try to clarify where things went wrong.
I also noted that the interface XML parsing regression tests also failed
which might be normal though since no reg test was updated.
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list