diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 79509fc4c0..83a2e19dbe 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -787,6 +787,90 @@ nwfilterBindingGetXMLDesc(virNWFilterBindingPtr binding, } +static virNWFilterBindingPtr +nwfilterBindingCreateXML(virConnectPtr conn, + const char *xml, + unsigned int flags) +{ + virNWFilterBindingObjPtr obj; + virNWFilterBindingDefPtr def; + virNWFilterBindingPtr ret = NULL; + + virCheckFlags(0, NULL); + + def = virNWFilterBindingDefParseString(xml); + if (!def) + return NULL; + + if (virNWFilterBindingCreateXMLEnsureACL(conn, def) < 0) + goto cleanup; + + obj = virNWFilterBindingObjListFindByPortDev(driver->bindings, def->portdevname); + if (obj) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Filter already present for NIC %s"), def->portdevname); + goto cleanup; + } + + obj = virNWFilterBindingObjListAdd(driver->bindings, + def); + if (!obj) + goto cleanup; + + if (!(ret = virGetNWFilterBinding(conn, def->portdevname, def->filter))) + goto cleanup; + + if (virNWFilterInstantiateFilter(driver, def) < 0) { + virNWFilterBindingObjListRemove(driver->bindings, obj); + virObjectUnref(ret); + ret = NULL; + goto cleanup; + } + virNWFilterBindingObjSave(obj, driver->bindingDir); + + cleanup: + if (!obj) + virNWFilterBindingDefFree(def); + virNWFilterBindingObjEndAPI(&obj); + + return ret; +} + + +/* + * Note that this is primarily intended for usage by the hypervisor + * drivers. it is exposed to the admin, however, and nothing stops + * an admin from deleting filter bindings created by the hypervisor + * drivers. IOW, it is the admin's responsibility not to shoot + * themself in the foot + */ +static int +nwfilterBindingDelete(virNWFilterBindingPtr binding) +{ + virNWFilterBindingObjPtr obj; + virNWFilterBindingDefPtr def; + int ret = -1; + + obj = virNWFilterBindingObjListFindByPortDev(driver->bindings, binding->portdev); + if (!obj) + return -1; + + def = virNWFilterBindingObjGetDef(obj); + if (virNWFilterBindingDeleteEnsureACL(binding->conn, def) < 0) + goto cleanup; + + virNWFilterTeardownFilter(def); + virNWFilterBindingObjDelete(obj, driver->bindingDir); + virNWFilterBindingObjListRemove(driver->bindings, obj); + + ret = 0; + + cleanup: + virNWFilterBindingObjEndAPI(&obj); + return ret; +} + + static virNWFilterDriver nwfilterDriver = { .name = "nwfilter", .connectNumOfNWFilters = nwfilterConnectNumOfNWFilters, /* 0.8.0 */ @@ -800,6 +884,8 @@ static virNWFilterDriver nwfilterDriver = { .nwfilterBindingLookupByPortDev = nwfilterBindingLookupByPortDev, /* 4.5.0 */ .connectListAllNWFilterBindings = nwfilterConnectListAllNWFilterBindings, /* 4.5.0 */ .nwfilterBindingGetXMLDesc = nwfilterBindingGetXMLDesc, /* 4.5.0 */ + .nwfilterBindingCreateXML = nwfilterBindingCreateXML, /* 4.5.0 */ + .nwfilterBindingDelete = nwfilterBindingDelete, /* 4.5.0 */ };