@@ -5,6 +5,11 @@ Post v24.03.0
cloned to all unknown ports connected to the same Logical Switch.
- Added a new logical switch port option "disable_arp_nd_rsp" to
disable adding the ARP responder flows if set to true.
+ - Add ovn-debug tool containing two commands.
+ "lflow-stage-to-ltable STAGE_NAME" that converts stage name into logical
+ flow table id.
+ "lflow-stage-to-oftable STAGE_NAME" that converts stage name into OpenFlow
+ table id.
OVN v24.03.0 - 01 Mar 2024
--------------------------
@@ -56,6 +56,7 @@ The main components of this distribution are:
- ovn-sbctl, a tool for interfacing with the southbound database.
- ovn-trace, a debugging utility that allows for tracing of packets through
the logical network.
+- ovn-debug, a tool to simplify debugging of OVN setup.
- Scripts and specs for building RPMs.
What other documentation is available?
@@ -5,6 +5,7 @@ usr/bin/ovn-ic-nbctl
usr/bin/ovn-ic-sbctl
usr/bin/ovn-trace
usr/bin/ovn_detrace.py
+usr/bin/ovn-debug
usr/share/ovn/scripts/ovn-ctl
usr/share/ovn/scripts/ovndb-servers.ocf
usr/share/ovn/scripts/ovn-lib
@@ -11,3 +11,4 @@ utilities/ovn-ic-nbctl.8
utilities/ovn-ic-sbctl.8
utilities/ovn-trace.8
utilities/ovn-detrace.1
+utilities/ovn-debug.8
@@ -495,6 +495,7 @@ fi
%{_bindir}/ovn-appctl
%{_bindir}/ovn-ic-nbctl
%{_bindir}/ovn-ic-sbctl
+%{_bindir}/ovn-debug
%{_datadir}/ovn/scripts/ovn-ctl
%{_datadir}/ovn/scripts/ovn-lib
%{_datadir}/ovn/scripts/ovndb-servers.ocf
@@ -515,6 +516,7 @@ fi
%{_mandir}/man8/ovn-ic.8*
%{_mandir}/man5/ovn-ic-nb.5*
%{_mandir}/man5/ovn-ic-sb.5*
+%{_mandir}/man8/ovn-debug.8*
%{_prefix}/lib/ocf/resource.d/ovn/ovndb-servers
%config(noreplace) %{_sysconfdir}/logrotate.d/ovn
%{_unitdir}/ovn-db@.service
@@ -13,6 +13,8 @@
/ovn-trace.8
/ovn_detrace.py
/ovn-detrace.1
+/ovn-debug
+/ovn-debug.8
/ovn-docker-overlay-driver
/ovn-docker-underlay-driver
/ovn-lib
@@ -11,7 +11,8 @@ man_MANS += \
utilities/ovn-ic-sbctl.8 \
utilities/ovn-trace.8 \
utilities/ovn-detrace.1 \
- utilities/ovn-appctl.8
+ utilities/ovn-appctl.8 \
+ utilities/ovn-debug.8
MAN_ROOTS += \
utilities/ovn-detrace.1.in
@@ -34,6 +35,7 @@ EXTRA_DIST += \
utilities/ovn-ic-sbctl.8.xml \
utilities/ovn-appctl.8.xml \
utilities/ovn-trace.8.xml \
+ utilities/ovn-debug.8.xml \
utilities/ovn_detrace.py.in \
utilities/ovndb-servers.ocf \
utilities/checkpatch.py \
@@ -63,6 +65,7 @@ CLEANFILES += \
utilities/ovn-ic-nbctl.8 \
utilities/ovn-ic-sbctl.8 \
utilities/ovn-trace.8 \
+ utilities/ovn-debug.8 \
utilities/ovn-detrace.1 \
utilities/ovn-detrace \
utilities/ovn_detrace.py \
@@ -120,4 +123,9 @@ UNINSTALL_LOCAL += ovn-detrace-uninstall
ovn-detrace-uninstall:
rm -f $(DESTDIR)$(bindir)/ovn-detrace
+# ovn-debug
+bin_PROGRAMS += utilities/ovn-debug
+utilities_ovn_debug_SOURCES = utilities/ovn-debug.c
+utilities_ovn_debug_LDADD = lib/libovn.la $(OVSDB_LIBDIR)/libovsdb.la $(OVS_LIBDIR)/libopenvswitch.la
+
include utilities/bugtool/automake.mk
new file mode 100644
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manpage program="ovn-debug" section="8" title="ovn-debug">
+ <h1>Name</h1>
+ <p>ovn-debug -- Open Virtual Network debug tool</p>
+
+ <h1>Synopsis</h1>
+ <p><code>ovn-debug</code> <var>COMMAND</var> <var>[ARG...]</var></p>
+
+ <h1>Description</h1>
+ <p>
+ <code>ovn-debug</code>, OVN debug tool, is a tool to help with
+ debugging of OVN setup.
+ </p>
+
+ <h1>Commands</h1>
+ <dl>
+ <dt><code>lflow-stage-to-ltable <var>STAGE_NAME</var></code></dt>
+ <dd>
+ Convert the logical flow stage name e.g. <code>ls_in_lb</code> into
+ the logical flow table number e.g. <code>13</code>.
+ </dd>
+ <dt><code>lflow-stage-to-oftable <var>STAGE_NAME</var></code></dt>
+ <dd>
+ Convert the logical flow stage name e.g. <code>ls_in_lb</code> into
+ the OpenFlow table number e.g. <code>21</code>.
+ </dd>
+ </dl>
+</manpage>
new file mode 100644
@@ -0,0 +1,155 @@
+/* Copyright (c) 2024, Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+#include <getopt.h>
+#include <stdint.h>
+
+#include "command-line.h"
+#include "controller/lflow.h"
+#include "northd/northd.h"
+#include "ovn-util.h"
+
+struct ovn_lflow_stage {
+ const char *name;
+ uint8_t table_id;
+ enum ovn_pipeline pipeline;
+};
+
+static const struct ovn_lflow_stage ovn_lflow_stages[] = {
+#define PIPELINE_STAGE(DP_TYPE, PIPELINE, STAGE, TABLE, NAME) \
+ (struct ovn_lflow_stage) { \
+ .name = NAME, \
+ .table_id = TABLE, \
+ .pipeline = P_##PIPELINE, \
+ },
+ PIPELINE_STAGES
+#undef PIPELINE_STAGE
+};
+
+static const struct ovn_lflow_stage *
+ovn_lflow_stage_find_by_name(const char *name)
+{
+
+ for (size_t i = 0; i < ARRAY_SIZE(ovn_lflow_stages); i++) {
+ const struct ovn_lflow_stage *stage = &ovn_lflow_stages[i];
+ if (!strcmp(stage->name, name)) {
+ return stage;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+lflow_stage_to_table(struct ovs_cmdl_context *ctx)
+{
+ const char *name = ctx->argv[1];
+ const struct ovn_lflow_stage *stage = ovn_lflow_stage_find_by_name(name);
+
+ if (!stage) {
+ ovs_fatal(0, "Couldn't find OVN logical flow stage with name \"%s\"",
+ name);
+ }
+
+ uint8_t table = stage->table_id;
+
+ if (!strcmp("lflow-stage-to-oftable", ctx->argv[0])) {
+ table += stage->pipeline == P_IN
+ ? OFTABLE_LOG_INGRESS_PIPELINE
+ : OFTABLE_LOG_EGRESS_PIPELINE;
+ }
+
+ printf("%"PRIu8"\n", table);
+ exit(EXIT_SUCCESS);
+}
+
+
+static void
+usage(void)
+{
+ printf("\
+%s: OVN debug utility\n\
+usage: %s COMMAND [ARG...]\n\
+\n\
+lflow-stage-to-ltable STAGE_NAME\n\
+ Converts STAGE_NAME into logical flow table number.\n\
+lflow-stage-to-oftable STAGE_NAME\n\
+ Converts STAGE_NAME into OpenFlow table number.\n\
+\n\
+Options:\n\
+ -h, --help display this help message\n\
+ -V, --version display version information\n",
+ program_name, program_name);
+ exit(EXIT_SUCCESS);
+}
+
+static void
+help(struct ovs_cmdl_context *ctx OVS_UNUSED)
+{
+ usage();
+}
+
+int
+main(int argc, char *argv[])
+{
+ static const struct option long_options[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'V'},
+ {NULL, 0, NULL, 0},
+ };
+ char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
+
+ ovn_set_program_name(argv[0]);
+
+ for (;;) {
+ int option_index = 0;
+ int c = getopt_long(argc, argv, short_options, long_options,
+ &option_index);
+
+ if (c == -1) {
+ break;
+ }
+ switch (c) {
+ case 'V':
+ ovn_print_version(0, 0);
+ exit(EXIT_SUCCESS);
+
+ case 'h':
+ usage();
+ /* fall through */
+
+ case '?':
+ exit(1);
+
+ default:
+ ovs_abort(0, "Invalid option.");
+ }
+ }
+ free(short_options);
+
+ static const struct ovs_cmdl_command commands[] = {
+ {"lflow-stage-to-oftable", NULL, 1, 1, lflow_stage_to_table,
+ OVS_RO},
+ {"lflow-stage-to-ltable", NULL, 1, 1, lflow_stage_to_table,
+ OVS_RO},
+ { "help", NULL, 0, INT_MAX, help, OVS_RO },
+ {NULL, NULL, 0, 0, NULL, OVS_RO},
+ };
+ struct ovs_cmdl_context ctx;
+ ctx.argc = argc - optind;
+ ctx.argv = argv + optind;
+ ovs_cmdl_run_command(&ctx, commands);
+}