- Make outport optional in 'nf-add'.
- Accept 'vtap' mode in 'nfg-add'.
Signed-off-by: Naveen Yerramneni <[email protected]>
Acked-by: Sragdhara Datta Chaudhuri <[email protected]>
Acked-by: Aditya Mehakare <[email protected]>
---
tests/ovn-nbctl.at | 46 ++++++++++++++++++++++---
utilities/ovn-nbctl.8.xml | 55 +++++++++++++++++++++++-------
utilities/ovn-nbctl.c | 72 +++++++++++++++++++++++++++++++++------
3 files changed, 145 insertions(+), 28 deletions(-)
diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at
index bf3896361..51c576f6e 100644
--- a/tests/ovn-nbctl.at
+++ b/tests/ovn-nbctl.at
@@ -3319,13 +3319,13 @@ AT_CHECK([ovn-nbctl nfg-add nfg0 2 inline nf0], [1], [],
])
AT_CHECK([ovn-nbctl --may-exist nfg-add nfg0 1 inline nf0])
AT_CHECK([ovn-nbctl nfg-list | uuidfilt], [0], [dnl
-<0> (nfg0)
+<0> (nfg0) mode:inline
])
# Test --may-exist overwrite behavior: update existing network function group
with new config
AT_CHECK([ovn-nbctl --may-exist nfg-add nfg0 5 inline nf1 nf2])
AT_CHECK([ovn-nbctl nfg-list | uuidfilt], [0], [dnl
-<0> (nfg0)
+<0> (nfg0) mode:inline
])
# nf1 and nf2 are already in the group, so adding them should fail without
--may-exist
AT_CHECK([ovn-nbctl nfg-add-nf nfg0 nf1], [1], [],
@@ -3336,8 +3336,8 @@ AT_CHECK([ovn-nbctl nfg-add-nf nfg0 nf0])
AT_CHECK([ovn-nbctl nfg-del-nf nfg0 nf0])
AT_CHECK([ovn-nbctl nfg-add nfg1 2 inline nf1])
AT_CHECK([ovn-nbctl nfg-list | uuidfilt], [0], [dnl
-<0> (nfg0)
-<1> (nfg1)
+<0> (nfg0) mode:inline
+<1> (nfg1) mode:inline
])
# Access-list with network-function-group.
@@ -3386,6 +3386,44 @@ AT_CHECK([ovn-nbctl nf-list | uuidfilt], [0], [dnl
<0> (nf3) id:10 in:svc-port6 out:svc-port7
])
AT_CHECK([ovn-nbctl nf-del nf3])
+
+# Create network-function with only inport (vtap mode).
+AT_CHECK([ovn-nbctl nf-add nf0 1 svc-port6])
+AT_CHECK([ovn-nbctl nf-list | uuidfilt], [0], [dnl
+<0> (nf0) id:1 in:svc-port6 out:<not_set>
+])
+
+# Create a network-function-group in vtap mode.
+AT_CHECK([ovn-nbctl nfg-add nfg0 1 vtap nf0])
+AT_CHECK([ovn-nbctl nfg-list | uuidfilt], [0], [dnl
+<0> (nfg0) mode:vtap
+])
+AT_CHECK([ovn-nbctl nfg-del nfg0])
+
+# Validation: nf0 has only inport, attempting to use it in an inline
+# network-function-group must be rejected.
+AT_CHECK([ovn-nbctl nfg-add nfg0 1 inline nf0], [1], [], [dnl
+ovn-nbctl: network-function nf0 has no outport set; outport is required for
inline mode network functions
+])
+AT_CHECK([ovn-nbctl nfg-add nfg0 1 inline])
+AT_CHECK([ovn-nbctl nfg-add-nf nfg0 nf0], [1], [], [dnl
+ovn-nbctl: network-function nf0 has no outport set; outport is required for
inline mode network functions
+])
+AT_CHECK([ovn-nbctl nfg-del nfg0])
+
+# Validation: an NF with outport set must not be allowed in a vtap
+# network-function-group.
+AT_CHECK([ovn-nbctl nf-add nf-inline 11 svc-port6 svc-port7])
+AT_CHECK([ovn-nbctl nfg-add nfg0 1 vtap nf-inline], [1], [], [dnl
+ovn-nbctl: network-function nf-inline has outport set; outport must not be set
for vtap mode network functions
+])
+AT_CHECK([ovn-nbctl nfg-add nfg0 1 vtap])
+AT_CHECK([ovn-nbctl nfg-add-nf nfg0 nf-inline], [1], [], [dnl
+ovn-nbctl: network-function nf-inline has outport set; outport must not be set
for vtap mode network functions
+])
+AT_CHECK([ovn-nbctl nfg-del nfg0])
+AT_CHECK([ovn-nbctl nf-del nf-inline])
+AT_CHECK([ovn-nbctl nf-del nf0])
])
AT_SETUP([ovn-nbctl - TLS server name indication (SNI) with --ssl-server-name])
diff --git a/utilities/ovn-nbctl.8.xml b/utilities/ovn-nbctl.8.xml
index 6ce6f9322..ce09bdce5 100644
--- a/utilities/ovn-nbctl.8.xml
+++ b/utilities/ovn-nbctl.8.xml
@@ -475,17 +475,31 @@
<h2>Network Function Commands</h2>
<dl>
- <dt>[<code>--may-exist</code>] <code>nf-add</code> <var>nf</var>
<var>id</var> <var>inport</var> <var>outport</var></dt>
+ <dt>[<code>--may-exist</code>] <code>nf-add</code> <var>nf</var>
<var>id</var> <var>inport</var> [<var>outport</var>]</dt>
<dd>
<p>
Creates a new network function named <var>nf</var> with the specified
<var>id</var> (an integer between 1 and 255) and logical switch ports
- <var>inport</var> and <var>outport</var>. Both the ports must be on
- the same logical switch and must be already created. When used in an
- ACL action, traffic matching the ACL are redirected to the
- <var>inport</var> if it is from-lport ACL and to <var>outport</var>
- if it is to-lport ACL. The response packets are sent through the same
- ports in reverse order.
+ <var>inport</var> and (optionally) <var>outport</var>. The ports must
+ be on the same logical switch and must be already created.
+ </p>
+
+ <p>
+ When the network function is used in an
+ <code>inline</code>-mode network function group, both
+ <var>inport</var> and <var>outport</var> must be specified.
+ Traffic matching the ACL is redirected to the <var>inport</var> for
+ from-lport ACLs and to the <var>outport</var> for to-lport ACLs.
+ The response packets are sent through the same ports in reverse
+ order.
+ </p>
+
+ <p>
+ When the network function is used in a <code>vtap</code>-mode
+ network function group, only <var>inport</var> is used; traffic
+ matching the ACL is mirrored (cloned) to <var>inport</var> in both
+ directions while the original packet continues to its destination.
+ <var>outport</var> must not be specified for vtap network functions.
</p>
<p>
@@ -517,16 +531,31 @@
<p>
Creates a new network function group named <var>nfg</var> with
optionally one of more <code>nf</code> added to the group. The nfs
- must be already created. Traffic redirection would be done towards
- one of the active network functions, based on health monitoring.
- If all are down, any one would be chosen for redirection.
+ must be already created. Traffic redirection/mirroring is performed
+ towards one of the active network functions, based on health
+ monitoring (inline) or port binding status (vtap). If all are down,
+ the configured fallback behavior applies.
</p>
<p>
Each network function group must have a unique <var>id</var> between
- <code>1</code> and <code>255</code>. The <var>mode</var> must be
- <code>inline</code> which is currently the only supported mode.
- </p>
+ <code>1</code> and <code>255</code>. The supported values for
+ <var>mode</var> are:
+ </p>
+
+ <ul>
+ <li>
+ <code>inline</code>: traffic matching the ACL is redirected
+ through the active network function. Both <code>inport</code> and
+ <code>outport</code> must be set on every member network function.
+ </li>
+ <li>
+ <code>vtap</code>: traffic matching the ACL is mirrored (cloned)
+ to the active network function while the original packet
+ continues to its destination. Only <code>inport</code> is used on
+ member network functions.
+ </li>
+ </ul>
<p>
Without any options, this command regards it as an error if
diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c
index 4e2271d07..0c111a9fd 100644
--- a/utilities/ovn-nbctl.c
+++ b/utilities/ovn-nbctl.c
@@ -414,7 +414,7 @@ Network function group commands:\n\
\n\
Network function commands:\n\
[--may-exist]\n\
- nf-add NETWORK-FUNCTION ID PORT-IN PORT-OUT\n\
+ nf-add NETWORK-FUNCTION ID PORT-IN [PORT-OUT]\n\
create a network-function\n\
[--if-exists]\n\
nf-del NETWORK-FUNCTION delete a network-function\n\
@@ -2248,6 +2248,8 @@ static void
nbctl_pre_nf_group_add(struct ctl_context *ctx)
{
ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_col_name);
+ ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_col_inport);
+ ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_col_outport);
ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_group_col_name);
ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_group_col_id);
ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_group_col_mode);
@@ -2255,10 +2257,35 @@ nbctl_pre_nf_group_add(struct ctl_context *ctx)
ctx->idl, &nbrec_network_function_group_col_network_function);
}
+/* Validates that 'nf' is compatible with the given 'mode'. In inline
+ * mode both inport and outport must be set; in vtap mode only inport is
+ * used and outport must not be set. Returns NULL on success or a
+ * dynamically allocated error string on failure. */
+static char * OVS_WARN_UNUSED_RESULT
+nf_check_mode_compatibility(const struct nbrec_network_function *nf,
+ const char *mode)
+{
+ if (!strcmp(mode, "vtap")) {
+ if (nf->outport) {
+ return xasprintf("network-function %s has outport set; outport "
+ "must not be set for vtap mode network "
+ "functions", nf->name);
+ }
+ } else { /* inline */
+ if (!nf->outport) {
+ return xasprintf("network-function %s has no outport set; "
+ "outport is required for inline mode network "
+ "functions", nf->name);
+ }
+ }
+ return NULL;
+}
+
static char *
set_network_function_in_network_function_group(
struct ctl_context *ctx,
const struct nbrec_network_function_group *nf_group,
+ const char *mode,
char **new_network_function, size_t num_new_network_function)
{
struct nbrec_network_function **nfs =
@@ -2272,6 +2299,11 @@ set_network_function_in_network_function_group(
free(nfs);
return error;
}
+ error = nf_check_mode_compatibility(nf, mode);
+ if (error) {
+ free(nfs);
+ return error;
+ }
nfs[i] = CONST_CAST(struct nbrec_network_function *, nf);
}
nbrec_network_function_group_verify_network_function(nf_group);
@@ -2319,9 +2351,9 @@ nbctl_nf_group_add(struct ctl_context *ctx)
/* Validate and set mode */
const char *nfg_mode = ctx->argv[3];
- if (strcmp(nfg_mode, "inline")) {
+ if (strcmp(nfg_mode, "inline") && strcmp(nfg_mode, "vtap")) {
ctl_error(ctx, "Unsupported mode provided for "
- "network-function-group:%s, supported values: inline",
+ "network-function-group:%s, supported values: inline, vtap",
nfg_name);
return;
}
@@ -2330,7 +2362,7 @@ nbctl_nf_group_add(struct ctl_context *ctx)
/* Set network functions if provided */
if (ctx->argc > 4) {
ctx->error = set_network_function_in_network_function_group(
- ctx, nf_group, ctx->argv + 4, ctx->argc - 4);
+ ctx, nf_group, nfg_mode, ctx->argv + 4, ctx->argc - 4);
}
}
@@ -2365,6 +2397,7 @@ nbctl_pre_nf_group_list(struct ctl_context *ctx)
ovsdb_idl_add_column(ctx->idl,
&nbrec_network_function_group_col_network_function);
ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_group_col_name);
+ ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_group_col_mode);
}
static void
@@ -2375,9 +2408,10 @@ nbctl_nf_group_list(struct ctl_context *ctx)
NBREC_NETWORK_FUNCTION_GROUP_FOR_EACH (nf_group, ctx->idl) {
smap_add_format(&nf_groups, nf_group->name,
- UUID_FMT " (%s)",
+ UUID_FMT " (%s) mode:%s",
UUID_ARGS(&nf_group->header_.uuid),
- nf_group->name);
+ nf_group->name,
+ nf_group->mode ? nf_group->mode : "inline");
}
const struct smap_node **nodes = smap_sort(&nf_groups);
for (size_t i = 0; i < smap_count(&nf_groups); i++) {
@@ -2394,7 +2428,10 @@ nbctl_pre_nf_group_add_network_function(struct
ctl_context *ctx)
ovsdb_idl_add_column(ctx->idl,
&nbrec_network_function_group_col_network_function);
ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_group_col_name);
+ ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_group_col_mode);
ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_col_name);
+ ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_col_inport);
+ ovsdb_idl_add_column(ctx->idl, &nbrec_network_function_col_outport);
}
static void
@@ -2421,6 +2458,15 @@ nbctl_nf_group_add_network_function(struct ctl_context
*ctx)
return;
}
+ /* Validate mode compatibility of the network function. */
+ const char *mode = nf_group->mode ? nf_group->mode : "inline";
+ error = nf_check_mode_compatibility(nf, mode);
+ if (error) {
+ ctl_error(ctx, "%s", error);
+ free(error);
+ return;
+ }
+
/* Do not add network_function more than once in a given
* network-function-group */
for (size_t i = 0; i < nf_group->n_network_function; i++) {
@@ -2520,10 +2566,14 @@ nbctl_nf_add(struct ctl_context *ctx)
ctx->error = error;
return;
}
- error = lsp_by_name_or_uuid(ctx, ctx->argv[4], true, &lsp_out);
- if (error) {
- ctx->error = error;
- return;
+ if (ctx->argc == 5) {
+ error = lsp_by_name_or_uuid(ctx, ctx->argv[4], true, &lsp_out);
+ if (error) {
+ ctx->error = error;
+ return;
+ }
+ } else {
+ lsp_out = NULL;
}
/* Validate and parse ID */
@@ -9367,7 +9417,7 @@ static const struct ctl_command_syntax nbctl_commands[] =
{
nbctl_nf_group_del_network_function, NULL, "--if-exists", RW },
/* network-function commands. */
- { "nf-add", 4, 4, "NETWORK-FUNCTION ID PORT-IN PORT-OUT",
+ { "nf-add", 3, 4, "NETWORK-FUNCTION ID PORT-IN [PORT-OUT]",
nbctl_pre_nf_add,
nbctl_nf_add,
NULL, "--may-exist", RW },
--
2.43.5
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev