[libvirt] [PATCH 8/9] add DHCP snooping support to nwfilter

Stefan Berger stefanb at us.ibm.com
Wed May 11 20:11:01 UTC 2011


David Stevens/Beaverton/IBM at IBMUS wrote on 05/09/2011 04:11:19 PM:


> + */
> +
> +#include <config.h>
> +
> +#ifdef HAVE_LIBPCAP
> +#include <pcap.h>
> +#endif

This is the only place you check for HAVE_LIBPCAP. Basically when it's not 
available the snooping doesn't work and VMs referencing filters that have
the variable 'IP' no user-given value cannot start. The part checking 
again for HAVE_LIBPCAP further down seems to be missing.


> +virNWFilterDHCPSnoopReq(virConnectPtr conn,
> +                        virNWFilterTechDriverPtr techdriver 
ATTRIBUTE_UNUSED,
> +                        enum virDomainNetType nettype ATTRIBUTE_UNUSED,
> +                        virNWFilterDefPtr filter ATTRIBUTE_UNUSED,
> +                        const char *ifname ATTRIBUTE_UNUSED,
> +                        virNWFilterHashTablePtr vars ATTRIBUTE_UNUSED,
> +                        virNWFilterDriverStatePtr driver 
ATTRIBUTE_UNUSED)
> +{
> +    struct virNWFilterSnoopReq *req;
> +
> +    req = virHashLookup(SnoopReqs, ifname);

Presumably multiple threads can be here, so you'll have to protect the 
hash table 'SnoopReqs' from concurrent accesses -- everywhere.

> +    if (req)
> +        return 0;
> +    if (VIR_ALLOC(req) < 0) {
> +        virReportOOMError();
> +        return 1;
> +    }
> +
> +    req->conn = conn;
> +    req->techdriver = techdriver;
> +    req->nettype = nettype;
> +    req->filter = filter;
> +    req->ifname = strdup(ifname);
> +    req->vars = virNWFilterHashTableCreate(0);
> +    if (!req->vars) {
> +        virReportOOMError();
> +        return 1;
> +    }
> +    if (virNWFilterHashTablePutAll(vars, req->vars)) {
> +        virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
> +                               _("virNWFilterDHCPSnoopReq: can't 
> copy variables"
> +                                " on if %s"), ifname);
> +        return 1;
> +    }
> +    req->driver = driver;
> +    req->start = req->end = 0;
> +
> +    if (virHashAddEntry(SnoopReqs, ifname, req)) {

Also protect it here.

> +        VIR_FREE(req);
> +        virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
> +                               _("virNWFilterDHCPSnoopReq req add 
failed on"
> +                                "interface \"%s\""), ifname);
> +        return 1;
> +    }
> +    if (pthread_create(&req->thread, NULL, virNWFilterDHCPSnoop, req) 
!= 0) {
> +        (void) virHashRemoveEntry(SnoopReqs, ifname);

... and here ...

> +        VIR_FREE(req);
> +        virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
> +                               _("virNWFilterDHCPSnoopReq 
> pthread_create failed"
> +                                " oninterface \"%s\""), ifname);
> +        return 1;
> +    }
> +    return 0;
> +}
> +
> +/*
> + * freeReq - hash table free function to kill a request
> + */
> +static void
> +freeReq(void *req0, const void *name ATTRIBUTE_UNUSED)
> +{
> +    struct virNWFilterSnoopReq *req = (struct virNWFilterSnoopReq *) 
req0;
> +
> +    if (!req)
> +        return;
> +
> +    req->die = 1;
> +}
> +
> +int
> +virNWFilterDHCPSnoopInit(void)
> +{
> +    if (SnoopReqs)
> +        return 0;
> +    SnoopReqs = virHashCreate(0, freeReq);
> +    if (!SnoopReqs) {
> +        virReportOOMError();
> +        return -1;
> +    }
> +    return 0;
> +}
> +
> +void
> +virNWFilterDHCPSnoopEnd(const char *ifname)
> +{
> +    if (!SnoopReqs)
> +        return;
> +    if (ifname)
> +        virHashRemoveEntry(SnoopReqs, ifname);

.. and again protect here. Since SnoopReqs is a global variable, maybe 
wrap the hash table operations into functions of their own.

Great work! It's overall pretty complex. I'll try it at some point.

Regards,
   Stefan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20110511/e66385a7/attachment-0001.htm>


More information about the libvir-list mailing list