From nobody Wed May 14 01:04:59 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1526406387817454.85885395251285; Tue, 15 May 2018 10:46:27 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA7A2C19AE39; Tue, 15 May 2018 17:46:25 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 258862B4C2; Tue, 15 May 2018 17:46:25 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 80A53180124E; Tue, 15 May 2018 17:46:24 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w4FHhmXU004258 for ; Tue, 15 May 2018 13:43:48 -0400 Received: by smtp.corp.redhat.com (Postfix) id 5D37B112D19A; Tue, 15 May 2018 17:43:48 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.6]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC57E112D198; Tue, 15 May 2018 17:43:47 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Tue, 15 May 2018 18:43:26 +0100 Message-Id: <20180515174337.11287-11-berrange@redhat.com> In-Reply-To: <20180515174337.11287-1-berrange@redhat.com> References: <20180515174337.11287-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 10/21] virsh: add nwfilter binding commands X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 15 May 2018 17:46:26 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 $ virsh nwfilter-binding-list Port Dev Filter ------------------------------------------------------------------ vnet0 clean-traffic vnet1 clean-traffic $ virsh nwfilter-binding-dumpxml vnet1 f25arm7 12ac8b8c-4f23-4248-ae42-fdcd50c400fd Signed-off-by: Daniel P. Berrang=C3=A9 --- tools/virsh-completer.c | 45 ++++++ tools/virsh-completer.h | 4 + tools/virsh-nwfilter.c | 318 ++++++++++++++++++++++++++++++++++++++++ tools/virsh-nwfilter.h | 8 + 4 files changed, 375 insertions(+) diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c index e3b8234b41..b1737130b4 100644 --- a/tools/virsh-completer.c +++ b/tools/virsh-completer.c @@ -427,6 +427,51 @@ virshNWFilterNameCompleter(vshControl *ctl, } =20 =20 +char ** +virshNWFilterBindingNameCompleter(vshControl *ctl, + const vshCmd *cmd ATTRIBUTE_UNUSED, + unsigned int flags) +{ + virshControlPtr priv =3D ctl->privData; + virNWFilterBindingPtr *bindings =3D NULL; + int nbindings =3D 0; + size_t i =3D 0; + char **ret =3D NULL; + + virCheckFlags(0, NULL); + + if (!priv->conn || virConnectIsAlive(priv->conn) <=3D 0) + return NULL; + + if ((nbindings =3D virConnectListAllNWFilterBindings(priv->conn, &bind= ings, flags)) < 0) + return NULL; + + if (VIR_ALLOC_N(ret, nbindings + 1) < 0) + goto error; + + for (i =3D 0; i < nbindings; i++) { + const char *name =3D virNWFilterBindingGetPortDev(bindings[i]); + + if (VIR_STRDUP(ret[i], name) < 0) + goto error; + + virNWFilterBindingFree(bindings[i]); + } + VIR_FREE(bindings); + + return ret; + + error: + for (; i < nbindings; i++) + virNWFilterBindingFree(bindings[i]); + VIR_FREE(bindings); + for (i =3D 0; i < nbindings; i++) + VIR_FREE(ret[i]); + VIR_FREE(ret); + return NULL; +} + + char ** virshSecretUUIDCompleter(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED, diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h index fa443d3ad7..3abced765c 100644 --- a/tools/virsh-completer.h +++ b/tools/virsh-completer.h @@ -62,6 +62,10 @@ char ** virshNWFilterNameCompleter(vshControl *ctl, const vshCmd *cmd, unsigned int flags); =20 +char ** virshNWFilterBindingNameCompleter(vshControl *ctl, + const vshCmd *cmd, + unsigned int flags); + char ** virshSecretUUIDCompleter(vshControl *ctl, const vshCmd *cmd, unsigned int flags); diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c index 06a002dffd..881afc5dda 100644 --- a/tools/virsh-nwfilter.c +++ b/tools/virsh-nwfilter.c @@ -443,6 +443,300 @@ cmdNWFilterEdit(vshControl *ctl, const vshCmd *cmd) return ret; } =20 +virNWFilterBindingPtr +virshCommandOptNWFilterBindingBy(vshControl *ctl, const vshCmd *cmd, + const char **name, unsigned int flags) +{ + virNWFilterBindingPtr binding =3D NULL; + const char *n =3D NULL; + const char *optname =3D "binding"; + virshControlPtr priv =3D ctl->privData; + + virCheckFlags(0, NULL); + + if (vshCommandOptStringReq(ctl, cmd, optname, &n) < 0) + return NULL; + + vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n", + cmd->def->name, optname, n); + + if (name) + *name =3D n; + + vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as nwfilter binding port= dev\n", + cmd->def->name, optname); + binding =3D virNWFilterBindingLookupByPortDev(priv->conn, n); + + if (!binding) + vshError(ctl, _("failed to get nwfilter binding '%s'"), n); + + return binding; +} + +/* + * "nwfilter-binding-create" command + */ +static const vshCmdInfo info_nwfilter_binding_create[] =3D { + {.name =3D "help", + .data =3D N_("create a network filter binding from an XML file") + }, + {.name =3D "desc", + .data =3D N_("Create a new network filter binding.") + }, + {.name =3D NULL} +}; + +static const vshCmdOptDef opts_nwfilter_binding_create[] =3D { + VIRSH_COMMON_OPT_FILE(N_("file containing an XML network " + "filter binding description")), + {.name =3D NULL} +}; + +static bool +cmdNWFilterBindingCreate(vshControl *ctl, const vshCmd *cmd) +{ + virNWFilterBindingPtr binding; + const char *from =3D NULL; + bool ret =3D true; + char *buffer; + virshControlPtr priv =3D ctl->privData; + + if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) + return false; + + if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) + return false; + + binding =3D virNWFilterBindingCreateXML(priv->conn, buffer, 0); + VIR_FREE(buffer); + + if (binding !=3D NULL) { + vshPrintExtra(ctl, _("Network filter binding on %s created from %s= \n"), + virNWFilterBindingGetPortDev(binding), from); + virNWFilterBindingFree(binding); + } else { + vshError(ctl, _("Failed to create network filter from %s"), from); + ret =3D false; + } + return ret; +} + +/* + * "nwfilter-binding-delete" command + */ +static const vshCmdInfo info_nwfilter_binding_delete[] =3D { + {.name =3D "help", + .data =3D N_("delete a network filter binding") + }, + {.name =3D "desc", + .data =3D N_("Delete a given network filter binding.") + }, + {.name =3D NULL} +}; + +static const vshCmdOptDef opts_nwfilter_binding_delete[] =3D { + {.name =3D "binding", + .type =3D VSH_OT_DATA, + .flags =3D VSH_OFLAG_REQ, + .help =3D N_("network filter binding port dev"), + .completer =3D virshNWFilterBindingNameCompleter, + }, + {.name =3D NULL} +}; + +static bool +cmdNWFilterBindingDelete(vshControl *ctl, const vshCmd *cmd) +{ + virNWFilterBindingPtr binding; + bool ret =3D true; + const char *portdev; + + if (!(binding =3D virshCommandOptNWFilterBinding(ctl, cmd, &portdev))) + return false; + + if (virNWFilterBindingDelete(binding) =3D=3D 0) { + vshPrintExtra(ctl, _("Network filter binding on %s deleted\n"), po= rtdev); + } else { + vshError(ctl, _("Failed to delete network filter binding on %s"), = portdev); + ret =3D false; + } + + virNWFilterBindingFree(binding); + return ret; +} + +/* + * "nwfilter-binding-dumpxml" command + */ +static const vshCmdInfo info_nwfilter_binding_dumpxml[] =3D { + {.name =3D "help", + .data =3D N_("network filter information in XML") + }, + {.name =3D "desc", + .data =3D N_("Output the network filter information as an XML dump to= stdout.") + }, + {.name =3D NULL} +}; + +static const vshCmdOptDef opts_nwfilter_binding_dumpxml[] =3D { + {.name =3D "binding", + .type =3D VSH_OT_DATA, + .flags =3D VSH_OFLAG_REQ, + .help =3D N_("network filter binding portdev"), + .completer =3D virshNWFilterBindingNameCompleter, + }, + {.name =3D NULL} +}; + +static bool +cmdNWFilterBindingDumpXML(vshControl *ctl, const vshCmd *cmd) +{ + virNWFilterBindingPtr binding; + bool ret =3D true; + char *dump; + + if (!(binding =3D virshCommandOptNWFilterBinding(ctl, cmd, NULL))) + return false; + + dump =3D virNWFilterBindingGetXMLDesc(binding, 0); + if (dump !=3D NULL) { + vshPrint(ctl, "%s", dump); + VIR_FREE(dump); + } else { + ret =3D false; + } + + virNWFilterBindingFree(binding); + return ret; +} + +static int +virshNWFilterBindingSorter(const void *a, const void *b) +{ + virNWFilterBindingPtr *fa =3D (virNWFilterBindingPtr *) a; + virNWFilterBindingPtr *fb =3D (virNWFilterBindingPtr *) b; + + if (*fa && !*fb) + return -1; + + if (!*fa) + return *fb !=3D NULL; + + return vshStrcasecmp(virNWFilterBindingGetPortDev(*fa), + virNWFilterBindingGetPortDev(*fb)); +} + +struct virshNWFilterBindingList { + virNWFilterBindingPtr *bindings; + size_t nbindings; +}; +typedef struct virshNWFilterBindingList *virshNWFilterBindingListPtr; + +static void +virshNWFilterBindingListFree(virshNWFilterBindingListPtr list) +{ + size_t i; + + if (list && list->bindings) { + for (i =3D 0; i < list->nbindings; i++) { + if (list->bindings[i]) + virNWFilterBindingFree(list->bindings[i]); + } + VIR_FREE(list->bindings); + } + VIR_FREE(list); +} + +static virshNWFilterBindingListPtr +virshNWFilterBindingListCollect(vshControl *ctl, + unsigned int flags) +{ + virshNWFilterBindingListPtr list =3D vshMalloc(ctl, sizeof(*list)); + size_t i; + int ret; + bool success =3D false; + size_t deleted =3D 0; + int nbindings =3D 0; + char **names =3D NULL; + virshControlPtr priv =3D ctl->privData; + + /* try the list with flags support (0.10.2 and later) */ + if ((ret =3D virConnectListAllNWFilterBindings(priv->conn, + &list->bindings, + flags)) < 0) { + /* there was an error during the call */ + vshError(ctl, "%s", _("Failed to list network filter bindings")); + goto cleanup; + } + + list->nbindings =3D ret; + + /* sort the list */ + if (list->bindings && list->nbindings) + qsort(list->bindings, list->nbindings, + sizeof(*list->bindings), virshNWFilterBindingSorter); + + /* truncate the list for not found filter objects */ + if (deleted) + VIR_SHRINK_N(list->bindings, list->nbindings, deleted); + + success =3D true; + + cleanup: + for (i =3D 0; nbindings !=3D -1 && i < nbindings; i++) + VIR_FREE(names[i]); + VIR_FREE(names); + + if (!success) { + virshNWFilterBindingListFree(list); + list =3D NULL; + } + + return list; +} + +/* + * "nwfilter-binding-list" command + */ +static const vshCmdInfo info_nwfilter_binding_list[] =3D { + {.name =3D "help", + .data =3D N_("list network filter bindings") + }, + {.name =3D "desc", + .data =3D N_("Returns list of network filter bindings.") + }, + {.name =3D NULL} +}; + +static const vshCmdOptDef opts_nwfilter_binding_list[] =3D { + {.name =3D NULL} +}; + +static bool +cmdNWFilterBindingList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + size_t i; + virshNWFilterBindingListPtr list =3D NULL; + + if (!(list =3D virshNWFilterBindingListCollect(ctl, 0))) + return false; + + vshPrintExtra(ctl, " %-36s %-20s \n", _("Port Dev"), _("Filter")); + vshPrintExtra(ctl, "---------------------------------" + "---------------------------------\n"); + + for (i =3D 0; i < list->nbindings; i++) { + virNWFilterBindingPtr binding =3D list->bindings[i]; + + vshPrint(ctl, " %-20s %-20s\n", + virNWFilterBindingGetPortDev(binding), + virNWFilterBindingGetFilterName(binding)); + } + + virshNWFilterBindingListFree(list); + return true; +} + const vshCmdDef nwfilterCmds[] =3D { {.name =3D "nwfilter-define", .handler =3D cmdNWFilterDefine, @@ -474,5 +768,29 @@ const vshCmdDef nwfilterCmds[] =3D { .info =3D info_nwfilter_undefine, .flags =3D 0 }, + {.name =3D "nwfilter-binding-create", + .handler =3D cmdNWFilterBindingCreate, + .opts =3D opts_nwfilter_binding_create, + .info =3D info_nwfilter_binding_create, + .flags =3D 0 + }, + {.name =3D "nwfilter-binding-delete", + .handler =3D cmdNWFilterBindingDelete, + .opts =3D opts_nwfilter_binding_delete, + .info =3D info_nwfilter_binding_delete, + .flags =3D 0 + }, + {.name =3D "nwfilter-binding-dumpxml", + .handler =3D cmdNWFilterBindingDumpXML, + .opts =3D opts_nwfilter_binding_dumpxml, + .info =3D info_nwfilter_binding_dumpxml, + .flags =3D 0 + }, + {.name =3D "nwfilter-binding-list", + .handler =3D cmdNWFilterBindingList, + .opts =3D opts_nwfilter_binding_list, + .info =3D info_nwfilter_binding_list, + .flags =3D 0 + }, {.name =3D NULL} }; diff --git a/tools/virsh-nwfilter.h b/tools/virsh-nwfilter.h index 2b76a7c849..d8ca0e3960 100644 --- a/tools/virsh-nwfilter.h +++ b/tools/virsh-nwfilter.h @@ -32,11 +32,19 @@ virNWFilterPtr virshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd, const char **name, unsigned int flags); =20 +virNWFilterBindingPtr +virshCommandOptNWFilterBindingBy(vshControl *ctl, const vshCmd *cmd, + const char **name, unsigned int flags); + /* default is lookup by Name and UUID */ # define virshCommandOptNWFilter(_ctl, _cmd, _name) \ virshCommandOptNWFilterBy(_ctl, _cmd, _name, \ VIRSH_BYUUID | VIRSH_BYNAME) =20 +/* default is lookup by port dev */ +# define virshCommandOptNWFilterBinding(_ctl, _cmd, _name) \ + virshCommandOptNWFilterBindingBy(_ctl, _cmd, _name, 0) + extern const vshCmdDef nwfilterCmds[]; =20 #endif /* VIRSH_NWFILTER_H */ --=20 2.17.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list