mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
virsh: add nwfilter binding commands
$ virsh nwfilter-binding-list Port Dev Filter ------------------------------------------------------------------ vnet0 clean-traffic vnet1 clean-traffic $ virsh nwfilter-binding-dumpxml vnet1 <filterbinding> <owner> <name>f25arm7</name> <uuid>12ac8b8c-4f23-4248-ae42-fdcd50c400fd</uuid> </owner> <portdev name='vnet1'/> <mac address='52:54:00:9d:81:b1'/> <filterref filter='clean-traffic'> <parameter name='MAC' value='52:54:00:9d:81:b1'/> </filterref> </filterbinding> Reviewed-by: John Ferlan <jferlan@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
ede0924eb4
commit
278659fff6
@ -473,6 +473,51 @@ virshNWFilterNameCompleter(vshControl *ctl,
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
virshNWFilterBindingNameCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd ATTRIBUTE_UNUSED,
|
||||
unsigned int flags)
|
||||
{
|
||||
virshControlPtr priv = ctl->privData;
|
||||
virNWFilterBindingPtr *bindings = NULL;
|
||||
int nbindings = 0;
|
||||
size_t i = 0;
|
||||
char **ret = NULL;
|
||||
|
||||
virCheckFlags(0, NULL);
|
||||
|
||||
if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
|
||||
return NULL;
|
||||
|
||||
if ((nbindings = virConnectListAllNWFilterBindings(priv->conn, &bindings, flags)) < 0)
|
||||
return NULL;
|
||||
|
||||
if (VIR_ALLOC_N(ret, nbindings + 1) < 0)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < nbindings; i++) {
|
||||
const char *name = 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 = 0; i < nbindings; i++)
|
||||
VIR_FREE(ret[i]);
|
||||
VIR_FREE(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
virshSecretUUIDCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd ATTRIBUTE_UNUSED,
|
||||
|
@ -66,6 +66,10 @@ char ** virshNWFilterNameCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags);
|
||||
|
||||
char ** virshNWFilterBindingNameCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags);
|
||||
|
||||
char ** virshSecretUUIDCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags);
|
||||
|
@ -443,6 +443,299 @@ cmdNWFilterEdit(vshControl *ctl, const vshCmd *cmd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
virNWFilterBindingPtr
|
||||
virshCommandOptNWFilterBindingBy(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
const char **name,
|
||||
unsigned int flags)
|
||||
{
|
||||
virNWFilterBindingPtr binding = NULL;
|
||||
const char *n = NULL;
|
||||
const char *optname = "binding";
|
||||
virshControlPtr priv = 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 = n;
|
||||
|
||||
vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as nwfilter binding port dev\n",
|
||||
cmd->def->name, optname);
|
||||
binding = 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[] = {
|
||||
{.name = "help",
|
||||
.data = N_("create a network filter binding from an XML file")
|
||||
},
|
||||
{.name = "desc",
|
||||
.data = N_("Create a new network filter binding.")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_nwfilter_binding_create[] = {
|
||||
VIRSH_COMMON_OPT_FILE(N_("file containing an XML network "
|
||||
"filter binding description")),
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
cmdNWFilterBindingCreate(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virNWFilterBindingPtr binding;
|
||||
const char *from = NULL;
|
||||
bool ret = true;
|
||||
char *buffer;
|
||||
virshControlPtr priv = ctl->privData;
|
||||
|
||||
if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
|
||||
return false;
|
||||
|
||||
if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
|
||||
return false;
|
||||
|
||||
binding = virNWFilterBindingCreateXML(priv->conn, buffer, 0);
|
||||
VIR_FREE(buffer);
|
||||
|
||||
if (binding != 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 = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "nwfilter-binding-delete" command
|
||||
*/
|
||||
static const vshCmdInfo info_nwfilter_binding_delete[] = {
|
||||
{.name = "help",
|
||||
.data = N_("delete a network filter binding")
|
||||
},
|
||||
{.name = "desc",
|
||||
.data = N_("Delete a given network filter binding.")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_nwfilter_binding_delete[] = {
|
||||
{.name = "binding",
|
||||
.type = VSH_OT_DATA,
|
||||
.flags = VSH_OFLAG_REQ,
|
||||
.help = N_("network filter binding port dev"),
|
||||
.completer = virshNWFilterBindingNameCompleter,
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
cmdNWFilterBindingDelete(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virNWFilterBindingPtr binding;
|
||||
bool ret = true;
|
||||
const char *portdev;
|
||||
|
||||
if (!(binding = virshCommandOptNWFilterBinding(ctl, cmd, &portdev)))
|
||||
return false;
|
||||
|
||||
if (virNWFilterBindingDelete(binding) == 0) {
|
||||
vshPrintExtra(ctl, _("Network filter binding on %s deleted\n"), portdev);
|
||||
} else {
|
||||
vshError(ctl, _("Failed to delete network filter binding on %s"), portdev);
|
||||
ret = false;
|
||||
}
|
||||
|
||||
virNWFilterBindingFree(binding);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "nwfilter-binding-dumpxml" command
|
||||
*/
|
||||
static const vshCmdInfo info_nwfilter_binding_dumpxml[] = {
|
||||
{.name = "help",
|
||||
.data = N_("network filter information in XML")
|
||||
},
|
||||
{.name = "desc",
|
||||
.data = N_("Output the network filter information as an XML dump to stdout.")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_nwfilter_binding_dumpxml[] = {
|
||||
{.name = "binding",
|
||||
.type = VSH_OT_DATA,
|
||||
.flags = VSH_OFLAG_REQ,
|
||||
.help = N_("network filter binding portdev"),
|
||||
.completer = virshNWFilterBindingNameCompleter,
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
cmdNWFilterBindingDumpXML(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virNWFilterBindingPtr binding;
|
||||
bool ret = true;
|
||||
char *dump;
|
||||
|
||||
if (!(binding = virshCommandOptNWFilterBinding(ctl, cmd, NULL)))
|
||||
return false;
|
||||
|
||||
dump = virNWFilterBindingGetXMLDesc(binding, 0);
|
||||
if (dump != NULL) {
|
||||
vshPrint(ctl, "%s", dump);
|
||||
VIR_FREE(dump);
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
virNWFilterBindingFree(binding);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virshNWFilterBindingSorter(const void *a, const void *b)
|
||||
{
|
||||
virNWFilterBindingPtr *fa = (virNWFilterBindingPtr *) a;
|
||||
virNWFilterBindingPtr *fb = (virNWFilterBindingPtr *) b;
|
||||
|
||||
if (*fa && !*fb)
|
||||
return -1;
|
||||
|
||||
if (!*fa)
|
||||
return *fb != 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 = 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 = vshMalloc(ctl, sizeof(*list));
|
||||
int ret;
|
||||
bool success = false;
|
||||
virshControlPtr priv = ctl->privData;
|
||||
|
||||
if ((ret = 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 = ret;
|
||||
|
||||
/* sort the list */
|
||||
if (list->bindings && list->nbindings > 1)
|
||||
qsort(list->bindings, list->nbindings,
|
||||
sizeof(*list->bindings), virshNWFilterBindingSorter);
|
||||
|
||||
success = true;
|
||||
|
||||
cleanup:
|
||||
if (!success) {
|
||||
virshNWFilterBindingListFree(list);
|
||||
list = NULL;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "nwfilter-binding-list" command
|
||||
*/
|
||||
static const vshCmdInfo info_nwfilter_binding_list[] = {
|
||||
{.name = "help",
|
||||
.data = N_("list network filter bindings")
|
||||
},
|
||||
{.name = "desc",
|
||||
.data = N_("Returns list of network filter bindings.")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_nwfilter_binding_list[] = {
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
cmdNWFilterBindingList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
||||
{
|
||||
size_t i;
|
||||
virshNWFilterBindingListPtr list = NULL;
|
||||
|
||||
if (!(list = virshNWFilterBindingListCollect(ctl, 0)))
|
||||
return false;
|
||||
|
||||
vshPrintExtra(ctl, " %-20s %-20s \n", _("Port Dev"), _("Filter"));
|
||||
vshPrintExtra(ctl, "---------------------------------"
|
||||
"---------------------------------\n");
|
||||
|
||||
for (i = 0; i < list->nbindings; i++) {
|
||||
virNWFilterBindingPtr binding = list->bindings[i];
|
||||
|
||||
vshPrint(ctl, " %-20s %-20s\n",
|
||||
virNWFilterBindingGetPortDev(binding),
|
||||
virNWFilterBindingGetFilterName(binding));
|
||||
}
|
||||
|
||||
virshNWFilterBindingListFree(list);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const vshCmdDef nwfilterCmds[] = {
|
||||
{.name = "nwfilter-define",
|
||||
.handler = cmdNWFilterDefine,
|
||||
@ -474,5 +767,29 @@ const vshCmdDef nwfilterCmds[] = {
|
||||
.info = info_nwfilter_undefine,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "nwfilter-binding-create",
|
||||
.handler = cmdNWFilterBindingCreate,
|
||||
.opts = opts_nwfilter_binding_create,
|
||||
.info = info_nwfilter_binding_create,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "nwfilter-binding-delete",
|
||||
.handler = cmdNWFilterBindingDelete,
|
||||
.opts = opts_nwfilter_binding_delete,
|
||||
.info = info_nwfilter_binding_delete,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "nwfilter-binding-dumpxml",
|
||||
.handler = cmdNWFilterBindingDumpXML,
|
||||
.opts = opts_nwfilter_binding_dumpxml,
|
||||
.info = info_nwfilter_binding_dumpxml,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "nwfilter-binding-list",
|
||||
.handler = cmdNWFilterBindingList,
|
||||
.opts = opts_nwfilter_binding_list,
|
||||
.info = info_nwfilter_binding_list,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
@ -32,11 +32,19 @@ virNWFilterPtr
|
||||
virshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd,
|
||||
const char **name, unsigned int flags);
|
||||
|
||||
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)
|
||||
|
||||
/* default is lookup by port dev */
|
||||
# define virshCommandOptNWFilterBinding(_ctl, _cmd, _name) \
|
||||
virshCommandOptNWFilterBindingBy(_ctl, _cmd, _name, 0)
|
||||
|
||||
extern const vshCmdDef nwfilterCmds[];
|
||||
|
||||
#endif /* VIRSH_NWFILTER_H */
|
||||
|
Loading…
Reference in New Issue
Block a user