mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-11 12:25:52 +00:00
nwfilter: skip some interfaces on filter update
When a filter is updated, only those interfaces must have their old rules cleared that either reference the filter directly or indirectly through another filter. Remember between the different steps of the instantiation of the filters which interfaces must be skipped. I am using a hash map to remember the names of the interfaces and store a bogus pointer to ~0 into it that need not be freed.
This commit is contained in:
parent
5c77fddf4e
commit
018fd697b6
@ -2088,8 +2088,14 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
|
|||||||
.conn = conn,
|
.conn = conn,
|
||||||
.err = 0,
|
.err = 0,
|
||||||
.step = STEP_APPLY_NEW,
|
.step = STEP_APPLY_NEW,
|
||||||
|
.skipInterfaces = virHashCreate(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!cb.skipInterfaces) {
|
||||||
|
virReportOOMError();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < nCallbackDriver; i++) {
|
for (i = 0; i < nCallbackDriver; i++) {
|
||||||
callbackDrvArray[i]->vmFilterRebuild(conn,
|
callbackDrvArray[i]->vmFilterRebuild(conn,
|
||||||
virNWFilterDomainFWUpdateCB,
|
virNWFilterDomainFWUpdateCB,
|
||||||
@ -2115,6 +2121,8 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
|
|||||||
&cb);
|
&cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virHashFree(cb.skipInterfaces, NULL);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,6 +471,7 @@ struct domUpdateCBStruct {
|
|||||||
virConnectPtr conn;
|
virConnectPtr conn;
|
||||||
enum UpdateStep step;
|
enum UpdateStep step;
|
||||||
int err;
|
int err;
|
||||||
|
virHashTablePtr skipInterfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ _virNWFilterInstantiateRec(virConnectPtr conn,
|
|||||||
virNWFilterHashTablePtr vars,
|
virNWFilterHashTablePtr vars,
|
||||||
int *nEntries,
|
int *nEntries,
|
||||||
virNWFilterRuleInstPtr **insts,
|
virNWFilterRuleInstPtr **insts,
|
||||||
enum instCase useNewFilter, int *foundNewFilter,
|
enum instCase useNewFilter, bool *foundNewFilter,
|
||||||
virNWFilterDriverStatePtr driver)
|
virNWFilterDriverStatePtr driver)
|
||||||
{
|
{
|
||||||
virNWFilterPoolObjPtr obj;
|
virNWFilterPoolObjPtr obj;
|
||||||
@ -381,7 +381,7 @@ _virNWFilterInstantiateRec(virConnectPtr conn,
|
|||||||
case INSTANTIATE_FOLLOW_NEWFILTER:
|
case INSTANTIATE_FOLLOW_NEWFILTER:
|
||||||
if (obj->newDef) {
|
if (obj->newDef) {
|
||||||
next_filter = obj->newDef;
|
next_filter = obj->newDef;
|
||||||
*foundNewFilter = 1;
|
*foundNewFilter = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INSTANTIATE_ALWAYS:
|
case INSTANTIATE_ALWAYS:
|
||||||
@ -562,7 +562,7 @@ virNWFilterInstantiate(virConnectPtr conn,
|
|||||||
int ifindex,
|
int ifindex,
|
||||||
const char *linkdev,
|
const char *linkdev,
|
||||||
virNWFilterHashTablePtr vars,
|
virNWFilterHashTablePtr vars,
|
||||||
enum instCase useNewFilter, int *foundNewFilter,
|
enum instCase useNewFilter, bool *foundNewFilter,
|
||||||
bool teardownOld,
|
bool teardownOld,
|
||||||
const unsigned char *macaddr,
|
const unsigned char *macaddr,
|
||||||
virNWFilterDriverStatePtr driver,
|
virNWFilterDriverStatePtr driver,
|
||||||
@ -693,7 +693,8 @@ __virNWFilterInstantiateFilter(virConnectPtr conn,
|
|||||||
virNWFilterHashTablePtr filterparams,
|
virNWFilterHashTablePtr filterparams,
|
||||||
enum instCase useNewFilter,
|
enum instCase useNewFilter,
|
||||||
virNWFilterDriverStatePtr driver,
|
virNWFilterDriverStatePtr driver,
|
||||||
bool forceWithPendingReq)
|
bool forceWithPendingReq,
|
||||||
|
bool *foundNewFilter)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
const char *drvname = EBIPTABLES_DRIVER_ID;
|
const char *drvname = EBIPTABLES_DRIVER_ID;
|
||||||
@ -702,7 +703,6 @@ __virNWFilterInstantiateFilter(virConnectPtr conn,
|
|||||||
virNWFilterHashTablePtr vars, vars1;
|
virNWFilterHashTablePtr vars, vars1;
|
||||||
virNWFilterDefPtr filter;
|
virNWFilterDefPtr filter;
|
||||||
char vmmacaddr[VIR_MAC_STRING_BUFLEN] = {0};
|
char vmmacaddr[VIR_MAC_STRING_BUFLEN] = {0};
|
||||||
int foundNewFilter = 0;
|
|
||||||
char *str_macaddr = NULL;
|
char *str_macaddr = NULL;
|
||||||
const char *ipaddr;
|
const char *ipaddr;
|
||||||
char *str_ipaddr = NULL;
|
char *str_ipaddr = NULL;
|
||||||
@ -775,7 +775,7 @@ __virNWFilterInstantiateFilter(virConnectPtr conn,
|
|||||||
case INSTANTIATE_FOLLOW_NEWFILTER:
|
case INSTANTIATE_FOLLOW_NEWFILTER:
|
||||||
if (obj->newDef) {
|
if (obj->newDef) {
|
||||||
filter = obj->newDef;
|
filter = obj->newDef;
|
||||||
foundNewFilter = 1;
|
*foundNewFilter = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -791,7 +791,7 @@ __virNWFilterInstantiateFilter(virConnectPtr conn,
|
|||||||
ifindex,
|
ifindex,
|
||||||
linkdev,
|
linkdev,
|
||||||
vars,
|
vars,
|
||||||
useNewFilter, &foundNewFilter,
|
useNewFilter, foundNewFilter,
|
||||||
teardownOld,
|
teardownOld,
|
||||||
macaddr,
|
macaddr,
|
||||||
driver,
|
driver,
|
||||||
@ -816,7 +816,8 @@ static int
|
|||||||
_virNWFilterInstantiateFilter(virConnectPtr conn,
|
_virNWFilterInstantiateFilter(virConnectPtr conn,
|
||||||
const virDomainNetDefPtr net,
|
const virDomainNetDefPtr net,
|
||||||
bool teardownOld,
|
bool teardownOld,
|
||||||
enum instCase useNewFilter)
|
enum instCase useNewFilter,
|
||||||
|
bool *foundNewFilter)
|
||||||
{
|
{
|
||||||
const char *linkdev = (net->type == VIR_DOMAIN_NET_TYPE_DIRECT)
|
const char *linkdev = (net->type == VIR_DOMAIN_NET_TYPE_DIRECT)
|
||||||
? net->data.direct.linkdev
|
? net->data.direct.linkdev
|
||||||
@ -837,7 +838,8 @@ _virNWFilterInstantiateFilter(virConnectPtr conn,
|
|||||||
net->filterparams,
|
net->filterparams,
|
||||||
useNewFilter,
|
useNewFilter,
|
||||||
conn->nwfilterPrivateData,
|
conn->nwfilterPrivateData,
|
||||||
false);
|
false,
|
||||||
|
foundNewFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -853,6 +855,8 @@ virNWFilterInstantiateFilterLate(virConnectPtr conn,
|
|||||||
virNWFilterDriverStatePtr driver)
|
virNWFilterDriverStatePtr driver)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
bool foundNewFilter = false;
|
||||||
|
|
||||||
rc = __virNWFilterInstantiateFilter(conn,
|
rc = __virNWFilterInstantiateFilter(conn,
|
||||||
1,
|
1,
|
||||||
ifname,
|
ifname,
|
||||||
@ -864,7 +868,8 @@ virNWFilterInstantiateFilterLate(virConnectPtr conn,
|
|||||||
filterparams,
|
filterparams,
|
||||||
INSTANTIATE_ALWAYS,
|
INSTANTIATE_ALWAYS,
|
||||||
driver,
|
driver,
|
||||||
true);
|
true,
|
||||||
|
&foundNewFilter);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
//something went wrong... 'DOWN' the interface
|
//something went wrong... 'DOWN' the interface
|
||||||
if (ifaceCheck(false, ifname, NULL, ifindex) != 0 ||
|
if (ifaceCheck(false, ifname, NULL, ifindex) != 0 ||
|
||||||
@ -881,19 +886,29 @@ int
|
|||||||
virNWFilterInstantiateFilter(virConnectPtr conn,
|
virNWFilterInstantiateFilter(virConnectPtr conn,
|
||||||
const virDomainNetDefPtr net)
|
const virDomainNetDefPtr net)
|
||||||
{
|
{
|
||||||
|
bool foundNewFilter = false;
|
||||||
|
|
||||||
return _virNWFilterInstantiateFilter(conn, net,
|
return _virNWFilterInstantiateFilter(conn, net,
|
||||||
1,
|
1,
|
||||||
INSTANTIATE_ALWAYS);
|
INSTANTIATE_ALWAYS,
|
||||||
|
&foundNewFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
|
virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
|
||||||
const virDomainNetDefPtr net)
|
const virDomainNetDefPtr net,
|
||||||
|
bool *skipIface)
|
||||||
{
|
{
|
||||||
return _virNWFilterInstantiateFilter(conn, net,
|
bool foundNewFilter = false;
|
||||||
0,
|
|
||||||
INSTANTIATE_FOLLOW_NEWFILTER);
|
int rc = _virNWFilterInstantiateFilter(conn, net,
|
||||||
|
0,
|
||||||
|
INSTANTIATE_FOLLOW_NEWFILTER,
|
||||||
|
&foundNewFilter);
|
||||||
|
|
||||||
|
*skipIface = !foundNewFilter;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virNWFilterRollbackUpdateFilter(virConnectPtr conn,
|
int virNWFilterRollbackUpdateFilter(virConnectPtr conn,
|
||||||
@ -993,6 +1008,7 @@ virNWFilterDomainFWUpdateCB(void *payload,
|
|||||||
virDomainDefPtr vm = obj->def;
|
virDomainDefPtr vm = obj->def;
|
||||||
struct domUpdateCBStruct *cb = data;
|
struct domUpdateCBStruct *cb = data;
|
||||||
int i;
|
int i;
|
||||||
|
bool skipIface;
|
||||||
|
|
||||||
virDomainObjLock(obj);
|
virDomainObjLock(obj);
|
||||||
|
|
||||||
@ -1003,15 +1019,29 @@ virNWFilterDomainFWUpdateCB(void *payload,
|
|||||||
switch (cb->step) {
|
switch (cb->step) {
|
||||||
case STEP_APPLY_NEW:
|
case STEP_APPLY_NEW:
|
||||||
cb->err = virNWFilterUpdateInstantiateFilter(cb->conn,
|
cb->err = virNWFilterUpdateInstantiateFilter(cb->conn,
|
||||||
net);
|
net,
|
||||||
|
&skipIface);
|
||||||
|
if (cb->err == 0 && skipIface == true) {
|
||||||
|
// filter tree unchanged -- no update needed
|
||||||
|
cb->err = virHashAddEntry(cb->skipInterfaces,
|
||||||
|
net->ifname,
|
||||||
|
(void *)~0);
|
||||||
|
if (cb->err)
|
||||||
|
virReportOOMError();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STEP_TEAR_NEW:
|
case STEP_TEAR_NEW:
|
||||||
cb->err = virNWFilterRollbackUpdateFilter(cb->conn, net);
|
if ( !virHashLookup(cb->skipInterfaces, net->ifname)) {
|
||||||
|
cb->err = virNWFilterRollbackUpdateFilter(cb->conn,
|
||||||
|
net);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STEP_TEAR_OLD:
|
case STEP_TEAR_OLD:
|
||||||
cb->err = virNWFilterTearOldFilter(cb->conn, net);
|
if ( !virHashLookup(cb->skipInterfaces, net->ifname)) {
|
||||||
|
cb->err = virNWFilterTearOldFilter(cb->conn, net);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cb->err)
|
if (cb->err)
|
||||||
|
@ -40,7 +40,8 @@ enum instCase {
|
|||||||
int virNWFilterInstantiateFilter(virConnectPtr conn,
|
int virNWFilterInstantiateFilter(virConnectPtr conn,
|
||||||
const virDomainNetDefPtr net);
|
const virDomainNetDefPtr net);
|
||||||
int virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
|
int virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
|
||||||
const virDomainNetDefPtr net);
|
const virDomainNetDefPtr net,
|
||||||
|
bool *skipIface);
|
||||||
int virNWFilterRollbackUpdateFilter(virConnectPtr conn,
|
int virNWFilterRollbackUpdateFilter(virConnectPtr conn,
|
||||||
const virDomainNetDefPtr net);
|
const virDomainNetDefPtr net);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user