Introduce --all option for acl-list command. If this option is set while attempting to show ACLs of a logical switch, port group ACLs associated with each logical switch port will also be listed.
$ovn-nbctl --all acl-list ls1 Reported-at: https://issues.redhat.com/browse/FDP-1462 Signed-off-by: Mairtin O'Loingsigh <moloi...@redhat.com> --- v2: Code review changes v3: Cleanup autotest Add pg_nodes free Fix code nits NEWS | 3 ++ tests/ovn-nbctl.at | 44 +++++++++++++++++- utilities/ovn-nbctl.8.xml | 7 ++- utilities/ovn-nbctl.c | 96 ++++++++++++++++++++++++++++----------- 4 files changed, 122 insertions(+), 28 deletions(-) diff --git a/NEWS b/NEWS index 699217ca9..486f12963 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,9 @@ Post v25.03.0 - The ovn-controller option ovn-ofctrl-wait-before-clear is no longer supported. It will be ignored if used. ovn-controller will automatically care about proper delay before clearing lflow. + - Added a new ACL option "--all" to "acl-list" command. When set, + "acl-list" command will list port groups associated with each port of the + target logical switch. OVN v25.03.0 - 07 Mar 2025 -------------------------- diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at index 6e1f3fd45..7f0bf79cb 100644 --- a/tests/ovn-nbctl.at +++ b/tests/ovn-nbctl.at @@ -304,7 +304,49 @@ dnl Test when same name exists in logical switches and portgroups AT_CHECK([ovn-nbctl create port_group name=ls0], [0], [ignore]) AT_CHECK([ovn-nbctl acl-add ls0 to-lport 100 ip drop], [1], [], [stderr]) AT_CHECK([grep 'exists in both' stderr], [0], [ignore]) -AT_CHECK([ovn-nbctl --type=port-group acl-add ls0 to-lport 100 ip drop], [0], [ignore])]) +AT_CHECK([ovn-nbctl --type=port-group acl-add ls0 to-lport 100 ip drop], [0], [ignore]) + +dnl Test using all option to show port group acls for a logical switch +check ovn-nbctl ls-del ls1 +check ovn-nbctl ls-add ls1 +check ovn-nbctl lsp-add ls1 lp0 +check ovn-nbctl lsp-add ls1 lp1 +check ovn-nbctl lsp-add ls1 lp2 +check ovn-nbctl pg-del pg0 +check ovn-nbctl pg-add pg0 +check ovn-nbctl pg-set-ports pg0 lp0 +check ovn-nbctl pg-add pg1 +check ovn-nbctl pg-set-ports pg1 lp1 +check ovn-nbctl pg-add pg2 +check ovn-nbctl pg-set-ports pg2 lp0 lp2 lp1 +check ovn-nbctl --type=switch acl-add ls1 to-lport 100 ip drop +check ovn-nbctl --type=switch acl-add ls1 from-lport 500 ip drop +check ovn-nbctl --type=port-group acl-add pg0 to-lport 144 ip drop +check ovn-nbctl --type=port-group acl-add pg0 to-lport 11 ip drop +check ovn-nbctl --type=port-group acl-add pg1 to-lport 12 ip drop +check ovn-nbctl --type=port-group acl-add pg2 to-lport 99 ip drop +check ovn-nbctl --type=port-group acl-add pg2 from-lport 100 ip drop +check ovn-nbctl --type=port-group acl-add pg2 from-lport 98 ip drop + +AT_CHECK([ovn-nbctl --all acl-list ls1], [0], [dnl +from-lport 500 (ip) drop + to-lport 100 (ip) drop + to-lport 144 (ip) drop [[pg0]] + to-lport 11 (ip) drop [[pg0]] + to-lport 12 (ip) drop [[pg1]] +from-lport 100 (ip) drop [[pg2]] +from-lport 98 (ip) drop [[pg2]] + to-lport 99 (ip) drop [[pg2]] +]) + +check ovn-nbctl acl-del ls1 +check ovn-nbctl acl-del pg0 +check ovn-nbctl acl-del pg1 +check ovn-nbctl acl-del pg2 +check ovn-nbctl pg-del pg0 +check ovn-nbctl pg-del pg1 +check ovn-nbctl pg-del pg2 +check ovn-nbctl ls-del ls1]) dnl --------------------------------------------------------------------- diff --git a/utilities/ovn-nbctl.8.xml b/utilities/ovn-nbctl.8.xml index 9f9547bdb..8569559ab 100644 --- a/utilities/ovn-nbctl.8.xml +++ b/utilities/ovn-nbctl.8.xml @@ -399,7 +399,7 @@ must be either <code>switch</code> or <code>port-group</code>. </p> <dl> - <dt>[<code>--type=</code>{<code>switch</code> | <code>port-group</code>}] [<code>--log</code>] [<code>--meter=</code><var>meter</var>] [<code>--severity=</code><var>severity</var>] [<code>--name=</code><var>name</var>] [<code>--label=</code><var>label</var>] [<code>--sample-new=</code><var>sample</var>] [<code>--sample-est=</code><var>sample</var>] [<code>--may-exist</code>] [<code>--apply-after-lb</code>] [<code>--tier</code>] <code>acl-add</code> <var>entity</var> <var>direction</var> <var>priority</var> <var>match</var> <var>verdict</var></dt> + <dt>[<code>--type=</code>{<code>switch</code> | <code>port-group</code>}] [<code>--log</code>] [<code>--meter=</code><var>meter</var>] [<code>--severity=</code><var>severity</var>] [<code>--name=</code><var>name</var>] [<code>--label=</code><var>label</var>] [<code>--sample-new=</code><var>sample</var>] [<code>--sample-est=</code><var>sample</var>] [<code>--may-exist</code>] [<code>--apply-after-lb</code>] [<code>--tier</code>] [<code>--all</code>] <code>acl-add</code> <var>entity</var> <var>direction</var> <var>priority</var> <var>match</var> <var>verdict</var></dt> <dd> <p> Adds the specified ACL to <var>entity</var>. <var>direction</var> @@ -441,6 +441,11 @@ value. For more information about ACL tiers, see the documentation for the <code>ovn-nb</code>(5) database. </p> + <p> + The <code>--all</code> option will list the port group ACLs + associated with each logical switch port, when a logical switch + is provided as an argument. + </p> </dd> <dt>[<code>--type=</code>{<code>switch</code> | <code>port-group</code>}] [<code>--tier</code>] <code>acl-del</code> <var>entity</var> [<var>direction</var> [<var>priority</var> <var>match</var>]]</dt> diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index 329c28cee..6f52e921a 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -50,6 +50,7 @@ #include "openvswitch/vlog.h" #include "bitmap.h" #include "vec.h" +#include "uuidset.h" VLOG_DEFINE_THIS_MODULE(nbctl); @@ -2222,31 +2223,11 @@ acl_cmd_get_pg_or_ls(struct ctl_context *ctx, return NULL; } -static void -nbctl_acl_list(struct ctl_context *ctx) +static inline void +nbctl_acl_print(struct ctl_context *ctx, const struct nbrec_acl **acls, + size_t n_acls, const char *pg_name) { - const struct nbrec_logical_switch *ls = NULL; - const struct nbrec_port_group *pg = NULL; - const struct nbrec_acl **acls; - size_t i; - - char *error = acl_cmd_get_pg_or_ls(ctx, &ls, &pg); - if (error) { - ctx->error = error; - return; - } - - size_t n_acls = pg ? pg->n_acls : ls->n_acls; - struct nbrec_acl **nb_acls = pg ? pg->acls : ls->acls; - - acls = xmalloc(sizeof *acls * n_acls); - for (i = 0; i < n_acls; i++) { - acls[i] = nb_acls[i]; - } - - qsort(acls, n_acls, sizeof *acls, acl_cmp); - - for (i = 0; i < n_acls; i++) { + for (size_t i = 0; i < n_acls; i++) { const struct nbrec_acl *acl = acls[i]; ds_put_format(&ctx->output, "%10s %5"PRId64" (%s) %s", acl->direction, acl->priority, acl->match, @@ -2271,10 +2252,70 @@ nbctl_acl_list(struct ctl_context *ctx) if (smap_get_bool(&acl->options, "apply-after-lb", false)) { ds_put_cstr(&ctx->output, " [after-lb]"); } + if (pg_name) { + ds_put_format(&ctx->output, " [%s]", pg_name); + } ds_put_cstr(&ctx->output, "\n"); } +} + +static void +nbctl_acl_list(struct ctl_context *ctx) +{ + const struct nbrec_logical_switch *ls = NULL; + const struct nbrec_port_group *pg = NULL; + const struct nbrec_acl **acls; + + char *error = acl_cmd_get_pg_or_ls(ctx, &ls, &pg); + if (error) { + ctx->error = error; + return; + } + + size_t n_acls = pg ? pg->n_acls : ls->n_acls; + struct nbrec_acl **nb_acls = pg ? pg->acls : ls->acls; + acls = xmalloc(sizeof *acls * n_acls); + for (size_t i = 0; i < n_acls; i++) { + acls[i] = nb_acls[i]; + } + qsort(acls, n_acls, sizeof *acls, acl_cmp); + nbctl_acl_print(ctx, acls, n_acls, NULL); free(acls); + if (shash_find(&ctx->options, "--all") && ls) { + struct uuidset ports = UUIDSET_INITIALIZER(&ports); + for (size_t i = 0; i < ls->n_ports; i++) { + uuidset_insert(&ports, &ls->ports[i]->header_.uuid); + } + + struct shash pg_map = SHASH_INITIALIZER(&pg_map); + const struct nbrec_port_group *iter; + NBREC_PORT_GROUP_FOR_EACH (iter, ctx->idl) { + for (size_t i = 0; i < iter->n_ports; i++) { + if (uuidset_find(&ports, &iter->ports[i]->header_.uuid)) { + shash_add(&pg_map, iter->name, iter); + break; + } + } + } + + const struct shash_node **pg_nodes = shash_sort(&pg_map); + for (size_t i = 0; i < shash_count(&pg_map); i++) { + iter = pg_nodes[i]->data; + acls = xmalloc(sizeof *acls * iter->n_acls); + for (size_t j = 0; j < iter->n_acls; j++) { + acls[j] = iter->acls[j]; + } + + qsort(acls, iter->n_acls, sizeof *acls, acl_cmp); + nbctl_acl_print(ctx, acls, iter->n_acls, iter->name); + free(acls); + } + + uuidset_destroy(&ports); + shash_destroy(&pg_map); + free(pg_nodes); + } } static int @@ -2347,9 +2388,12 @@ nbctl_pre_acl(struct ctl_context *ctx) { ovsdb_idl_add_column(ctx->idl, &nbrec_port_group_col_name); ovsdb_idl_add_column(ctx->idl, &nbrec_port_group_col_acls); + ovsdb_idl_add_column(ctx->idl, &nbrec_port_group_col_ports); + ovsdb_idl_add_column(ctx->idl, &nbrec_logical_switch_port_col_name); ovsdb_idl_add_column(ctx->idl, &nbrec_logical_switch_col_name); ovsdb_idl_add_column(ctx->idl, &nbrec_logical_switch_col_acls); + ovsdb_idl_add_column(ctx->idl, &nbrec_logical_switch_col_ports); ovsdb_idl_add_column(ctx->idl, &nbrec_acl_col_direction); ovsdb_idl_add_column(ctx->idl, &nbrec_acl_col_priority); @@ -8226,8 +8270,8 @@ static const struct ctl_command_syntax nbctl_commands[] = { "--apply-after-lb,--tier=,--sample-new=,--sample-est=", RW }, { "acl-del", 1, 4, "{SWITCH | PORTGROUP} [DIRECTION [PRIORITY MATCH]]", nbctl_pre_acl, nbctl_acl_del, NULL, "--type=,--tier=", RW }, - { "acl-list", 1, 1, "{SWITCH | PORTGROUP}", - nbctl_pre_acl_list, nbctl_acl_list, NULL, "--type=", RO }, + { "acl-list", 1, 2, "{SWITCH | PORTGROUP}", + nbctl_pre_acl_list, nbctl_acl_list, NULL, "--all,--type=", RO }, /* qos commands. */ { "qos-add", 5, 7, -- 2.49.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev