summaryrefslogtreecommitdiff
path: root/utilities
diff options
context:
space:
mode:
authorAles Musil <amusil@redhat.com>2023-01-16 12:45:08 +0100
committerIlya Maximets <i.maximets@ovn.org>2023-01-16 19:58:08 +0100
commit08146bf7d9b4ad635312901ae017370b0108c62f (patch)
treecf7f599ca0a549128e553d95b28fed0dd59c77af /utilities
parenta9ae73b916bad528dcac2b8bb302fee6935fc163 (diff)
downloadopenvswitch-08146bf7d9b4ad635312901ae017370b0108c62f.tar.gz
openflow: Add extension to flush CT by generic match.
Add extension that allows to flush connections from CT by specifying fields that the connections should be matched against. This allows to match only some fields of the connection e.g. source address for orig direction. Reported-at: https://bugzilla.redhat.com/2120546 Signed-off-by: Ales Musil <amusil@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'utilities')
-rw-r--r--utilities/ovs-ofctl.8.in31
-rw-r--r--utilities/ovs-ofctl.c51
2 files changed, 82 insertions, 0 deletions
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 10a6a64de..0a611b2ee 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -296,6 +296,37 @@ Flushes the connection tracking entries in \fIzone\fR on \fIswitch\fR.
This command uses an Open vSwitch extension that is only in Open
vSwitch 2.6 and later.
.
+.IP "\fBct\-flush \fIswitch [zone=N] [ct-orig-tuple [ct-reply-tuple]]\fR
+Flushes the connection entries on \fIswitch\fR based on \fIzone\fR and
+connection tracking tuples \fIct-[orig|reply]-tuple\fR.
+.IP
+If \fIct-[orig|reply]-tuple\fR is not provided, flushes all the connection
+entries. If \fIzone\fR is specified, only flushes the connections in
+\fIzone\fR.
+.IP
+If \fIct-[orig|reply]-tuple\fR is provided, flushes the connection entry
+specified by \fIct-[orig|reply]-tuple\fR in \fIzone\fR. The zone defaults
+to 0 if it is not provided. The userspace connection tracker requires flushing
+with the original pre-NATed tuple and a warning log will be otherwise
+generated. The tuple can be partial and will remove all connections that are
+matching on the specified fields. In order to specify only
+\fIct-reply-tuple\fR, provide empty string as \fIct-orig-tuple\fR.
+.IP
+Note: Currently there is limitation for matching on ICMP, in order to partially
+match on ICMP parameters the \fIct-[orig|reply]-tuple\fR has to include
+either source or destination IP.
+.IP
+An example of an IPv4 ICMP \fIct-[orig|reply]-tuple\fR:
+.IP
+"ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=1,icmp_type=8,icmp_code=0,icmp_id=10"
+.IP
+An example of an IPv6 TCP \fIct-[orig|reply]-tuple\fR:
+.IP
+"ct_ipv6_src=fc00::1,ct_ipv6_dst=fc00::2,ct_nw_proto=6,ct_tp_src=1,ct_tp_dst=2"
+.IP
+This command uses an Open vSwitch extension that is only in Open vSwitch 3.1
+and later.
+.
.SS "OpenFlow Switch Flow Table Commands"
.
These commands manage the flow table in an OpenFlow switch. In each
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index fe9114580..eabec18a3 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -48,6 +48,7 @@
#include "openvswitch/meta-flow.h"
#include "openvswitch/ofp-actions.h"
#include "openvswitch/ofp-bundle.h"
+#include "openvswitch/ofp-ct.h"
#include "openvswitch/ofp-errors.h"
#include "openvswitch/ofp-group.h"
#include "openvswitch/ofp-match.h"
@@ -485,6 +486,9 @@ usage(void)
" dump-ipfix-bridge SWITCH print ipfix stats of bridge\n"
" dump-ipfix-flow SWITCH print flow ipfix of a bridge\n"
" ct-flush-zone SWITCH ZONE flush conntrack entries in ZONE\n"
+ " ct-flush SWITCH [ZONE] [CT_ORIG_TUPLE [CT_REPLY_TUPLE]]\n"
+ " flush conntrack entries specified\n"
+ " by CT_ORIG/REPLY_TUPLE and ZONE\n"
"\nFor OpenFlow switches and controllers:\n"
" probe TARGET probe whether TARGET is up\n"
" ping TARGET [N] latency of N-byte echos\n"
@@ -3051,6 +3055,50 @@ ofctl_ct_flush_zone(struct ovs_cmdl_context *ctx)
}
static void
+ofctl_ct_flush(struct ovs_cmdl_context *ctx)
+{
+ struct vconn *vconn;
+ struct ofp_ct_match match = {0};
+ struct ds ds = DS_EMPTY_INITIALIZER;
+ uint16_t zone, *pzone = NULL;
+ int args = ctx->argc - 2;
+
+ /* Parse zone. */
+ if (args && !strncmp(ctx->argv[2], "zone=", 5)) {
+ if (!ovs_scan(ctx->argv[2], "zone=%"SCNu16, &zone)) {
+ ovs_fatal(0, "Failed to parse zone");
+ }
+ pzone = &zone;
+ args--;
+ }
+
+ /* Parse ct tuples. */
+ for (int i = 0; i < 2; i++) {
+ if (!args) {
+ break;
+ }
+
+ struct ofp_ct_tuple *tuple =
+ i ? &match.tuple_reply : &match.tuple_orig;
+ const char *arg = ctx->argv[ctx->argc - args];
+
+ if (arg[0] && !ofp_ct_tuple_parse(tuple, arg, &ds, &match.ip_proto,
+ &match.l3_type)) {
+ ovs_fatal(0, "Failed to parse ct-tuple: %s", ds_cstr(&ds));
+ }
+ args--;
+ }
+
+ open_vconn(ctx->argv[1], &vconn);
+ enum ofp_version version = vconn_get_version(vconn);
+ struct ofpbuf *msg = ofp_ct_match_encode(&match, pzone, version);
+
+ ds_destroy(&ds);
+ transact_noreply(vconn, msg);
+ vconn_close(vconn);
+}
+
+static void
ofctl_dump_ipfix_flow(struct ovs_cmdl_context *ctx)
{
dump_trivial_transaction(ctx->argv[1], OFPRAW_NXST_IPFIX_FLOW_REQUEST);
@@ -5063,6 +5111,9 @@ static const struct ovs_cmdl_command all_commands[] = {
{ "ct-flush-zone", "switch zone",
2, 2, ofctl_ct_flush_zone, OVS_RO },
+ { "ct-flush", "switch [zone=N] [ct-orig-tuple [ct-reply-tuple]]",
+ 1, 4, ofctl_ct_flush, OVS_RO },
+
{ "ofp-parse", "file",
1, 1, ofctl_ofp_parse, OVS_RW },
{ "ofp-parse-pcap", "pcap",