This patch extends the RPC dispatcher to support the newly added RPC calls for network filtering (ACL) support. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
--- src/remote/remote_driver.c | 311 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) Index: libvirt-acl/src/remote/remote_driver.c =================================================================== --- libvirt-acl.orig/src/remote/remote_driver.c +++ libvirt-acl/src/remote/remote_driver.c @@ -248,6 +248,7 @@ static int remoteAuthPolkit (virConnectP static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain); static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network network); +static virNWFilterPtr get_nonnull_nwfilter (virConnectPtr conn, remote_nonnull_nwfilter nwfilter); static virInterfacePtr get_nonnull_interface (virConnectPtr conn, remote_nonnull_interface iface); static virStoragePoolPtr get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool); static virStorageVolPtr get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol); @@ -259,6 +260,7 @@ static void make_nonnull_interface (remo static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src); static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src); static void make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src); +static void make_nonnull_nwfilter (remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src); void remoteDomainEventFired(int watch, int fd, int event, void *data); static void remoteDomainQueueEvent(virConnectPtr conn, XDR *xdr); void remoteDomainEventQueueFlush(int timer, void *opaque); @@ -6060,6 +6062,287 @@ done: return rv; } +/* ------------------------------------------------------------- */ + +static virDrvOpenStatus ATTRIBUTE_NONNULL (1) +remoteNWFilterOpen (virConnectPtr conn, + virConnectAuthPtr auth, + int flags) +{ + if (inside_daemon) + return VIR_DRV_OPEN_DECLINED; + + if (conn->driver && + STREQ (conn->driver->name, "remote")) { + struct private_data *priv; + + /* If we're here, the remote driver is already + * in use due to a) a QEMU uri, or b) a remote + * URI. So we can re-use existing connection + */ + priv = conn->privateData; + remoteDriverLock(priv); + priv->localUses++; + conn->nwfilterPrivateData = priv; + remoteDriverUnlock(priv); + return VIR_DRV_OPEN_SUCCESS; + } else { + /* Using a non-remote driver, so we need to open a + * new connection for network filtering APIs, forcing it to + * use the UNIX transport. This handles Xen driver + * which doesn't have its own impl of the network filtering APIs. + */ + struct private_data *priv; + int ret; + ret = remoteOpenSecondaryDriver(conn, + auth, + flags, + &priv); + if (ret == VIR_DRV_OPEN_SUCCESS) + conn->nwfilterPrivateData = priv; + return ret; + } +} + +static int +remoteNWFilterClose (virConnectPtr conn) +{ + int rv = 0; + struct private_data *priv = conn->nwfilterPrivateData; + + remoteDriverLock(priv); + priv->localUses--; + if (!priv->localUses) { + rv = doRemoteClose(conn, priv); + conn->nwfilterPrivateData = NULL; + remoteDriverUnlock(priv); + virMutexDestroy(&priv->lock); + VIR_FREE(priv); + } + if (priv) + remoteDriverUnlock(priv); + return rv; +} + + +static int +remoteNumOfNWFilters (virConnectPtr conn) +{ + int rv = -1; + remote_num_of_nwfilters_ret ret; + struct private_data *priv = conn->nwfilterPrivateData; + + remoteDriverLock(priv); + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_NWFILTERS, + (xdrproc_t) xdr_void, (char *) NULL, + (xdrproc_t) xdr_remote_num_of_nwfilters_ret, (char *) &ret) == -1) + goto done; + + rv = ret.num; + +done: + remoteDriverUnlock(priv); + return rv; +} + + +static virNWFilterPtr +remoteNWFilterDefineXML (virConnectPtr conn, const char *xmlDesc, + unsigned int flags ATTRIBUTE_UNUSED) +{ + virNWFilterPtr net = NULL; + remote_nwfilter_define_xml_args args; + remote_nwfilter_define_xml_ret ret; + struct private_data *priv = conn->nwfilterPrivateData; + + remoteDriverLock(priv); + + args.xml = (char *) xmlDesc; + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_NWFILTER_DEFINE_XML, + (xdrproc_t) xdr_remote_nwfilter_define_xml_args, (char *) &args, + (xdrproc_t) xdr_remote_nwfilter_define_xml_ret, (char *) &ret) == -1) + goto done; + + net = get_nonnull_nwfilter (conn, ret.nwfilter); + xdr_free ((xdrproc_t) &xdr_remote_nwfilter_define_xml_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return net; +} + + +static int +remoteNWFilterUndefine (virNWFilterPtr nwfilter) +{ + int rv = -1; + remote_nwfilter_undefine_args args; + struct private_data *priv = nwfilter->conn->nwfilterPrivateData; + + remoteDriverLock(priv); + + make_nonnull_nwfilter (&args.nwfilter, nwfilter); + + if (call (nwfilter->conn, priv, 0, REMOTE_PROC_NWFILTER_UNDEFINE, + (xdrproc_t) xdr_remote_nwfilter_undefine_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + + +static int +remoteListNWFilters (virConnectPtr conn, char **const names, int maxnames) +{ + int rv = -1; + int i; + remote_list_nwfilters_args args; + remote_list_nwfilters_ret ret; + struct private_data *priv = conn->nwfilterPrivateData; + + remoteDriverLock(priv); + + if (maxnames > REMOTE_NWFILTER_NAME_LIST_MAX) { + errorf (conn, VIR_ERR_RPC, + _("too many remote nwfilters: %d > %d"), + maxnames, REMOTE_NWFILTER_NAME_LIST_MAX); + goto done; + } + args.maxnames = maxnames; + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_LIST_NWFILTERS, + (xdrproc_t) xdr_remote_list_nwfilters_args, (char *) &args, + (xdrproc_t) xdr_remote_list_nwfilters_ret, (char *) &ret) == -1) + goto done; + + if (ret.names.names_len > maxnames) { + errorf (conn, VIR_ERR_RPC, + _("too many remote nwfilters: %d > %d"), + ret.names.names_len, maxnames); + goto cleanup; + } + + /* This call is caller-frees (although that isn't clear from + * the documentation). However xdr_free will free up both the + * names and the list of pointers, so we have to strdup the + * names here. + */ + for (i = 0; i < ret.names.names_len; ++i) { + names[i] = strdup (ret.names.names_val[i]); + + if (names[i] == NULL) { + for (--i; i >= 0; --i) + VIR_FREE(names[i]); + + virReportOOMError(); + goto cleanup; + } + } + + rv = ret.names.names_len; + +cleanup: + xdr_free ((xdrproc_t) xdr_remote_list_nwfilters_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return rv; +} + + + +static virNWFilterPtr +remoteNWFilterLookupByUUID (virConnectPtr conn, + const unsigned char *uuid) +{ + virNWFilterPtr net = NULL; + remote_nwfilter_lookup_by_uuid_args args; + remote_nwfilter_lookup_by_uuid_ret ret; + struct private_data *priv = conn->nwfilterPrivateData; + + remoteDriverLock(priv); + + memcpy (args.uuid, uuid, VIR_UUID_BUFLEN); + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_NWFILTER_LOOKUP_BY_UUID, + (xdrproc_t) xdr_remote_nwfilter_lookup_by_uuid_args, (char *) &args, + (xdrproc_t) xdr_remote_nwfilter_lookup_by_uuid_ret, (char *) &ret) == -1) + goto done; + + net = get_nonnull_nwfilter (conn, ret.nwfilter); + xdr_free ((xdrproc_t) &xdr_remote_nwfilter_lookup_by_uuid_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return net; +} + +static virNWFilterPtr +remoteNWFilterLookupByName (virConnectPtr conn, + const char *name) +{ + virNWFilterPtr net = NULL; + remote_nwfilter_lookup_by_name_args args; + remote_nwfilter_lookup_by_name_ret ret; + struct private_data *priv = conn->nwfilterPrivateData; + + remoteDriverLock(priv); + + args.name = (char *) name; + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_NWFILTER_LOOKUP_BY_NAME, + (xdrproc_t) xdr_remote_nwfilter_lookup_by_name_args, (char *) &args, + (xdrproc_t) xdr_remote_nwfilter_lookup_by_name_ret, (char *) &ret) == -1) + goto done; + + net = get_nonnull_nwfilter (conn, ret.nwfilter); + xdr_free ((xdrproc_t) &xdr_remote_nwfilter_lookup_by_name_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return net; +} + + +static char * +remoteNWFilterGetXMLDesc (virNWFilterPtr nwfilter, unsigned int flags) +{ + char *rv = NULL; + remote_nwfilter_get_xml_desc_args args; + remote_nwfilter_get_xml_desc_ret ret; + struct private_data *priv = nwfilter->conn->nwfilterPrivateData; + + remoteDriverLock(priv); + + make_nonnull_nwfilter (&args.nwfilter, nwfilter); + args.flags = flags; + + memset (&ret, 0, sizeof ret); + if (call (nwfilter->conn, priv, 0, REMOTE_PROC_NWFILTER_GET_XML_DESC, + (xdrproc_t) xdr_remote_nwfilter_get_xml_desc_args, (char *) &args, + (xdrproc_t) xdr_remote_nwfilter_get_xml_desc_ret, (char *) &ret) == -1) + goto done; + + /* Caller frees. */ + rv = ret.xml; + +done: + remoteDriverUnlock(priv); + return rv; +} + /*----------------------------------------------------------------------*/ @@ -8991,6 +9274,13 @@ get_nonnull_secret (virConnectPtr conn, return virGetSecret(conn, BAD_CAST secret.uuid, secret.usageType, secret.usageID); } +static virNWFilterPtr +get_nonnull_nwfilter (virConnectPtr conn, remote_nonnull_nwfilter nwfilter) +{ + return virGetNWFilter (conn, nwfilter.name, BAD_CAST nwfilter.uuid); +} + + /* Make remote_nonnull_domain and remote_nonnull_network. */ static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src) @@ -9038,6 +9328,13 @@ make_nonnull_secret (remote_nonnull_secr secret_dst->usageID = secret_src->usageID; } +static void +make_nonnull_nwfilter (remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src) +{ + nwfilter_dst->name = nwfilter_src->name; + memcpy (nwfilter_dst->uuid, nwfilter_src->uuid, VIR_UUID_BUFLEN); +} + /*----------------------------------------------------------------------*/ unsigned long remoteVersion(void) @@ -9239,6 +9536,19 @@ static virDeviceMonitor dev_monitor = { .deviceDestroy = remoteNodeDeviceDestroy }; +static virNWFilterDriver nwfilter_driver = { + .name = "remote", + .open = remoteNWFilterOpen, + .close = remoteNWFilterClose, + .nwfilterLookupByUUID = remoteNWFilterLookupByUUID, + .nwfilterLookupByName = remoteNWFilterLookupByName, + .getXMLDesc = remoteNWFilterGetXMLDesc, + .defineXML = remoteNWFilterDefineXML, + .undefine = remoteNWFilterUndefine, + .numOfNWFilters = remoteNumOfNWFilters, + .listNWFilters = remoteListNWFilters, +}; + #ifdef WITH_LIBVIRTD static virStateDriver state_driver = { @@ -9263,6 +9573,7 @@ remoteRegister (void) if (virRegisterStorageDriver (&storage_driver) == -1) return -1; if (virRegisterDeviceMonitor (&dev_monitor) == -1) return -1; if (virRegisterSecretDriver (&secret_driver) == -1) return -1; + if (virRegisterNWFilterDriver(&nwfilter_driver) == -1) return -1; #ifdef WITH_LIBVIRTD if (virRegisterStateDriver (&state_driver) == -1) return -1; #endif
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list