summaryrefslogtreecommitdiff
path: root/ofproto
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 /ofproto
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 'ofproto')
-rw-r--r--ofproto/ofproto-dpif.c9
-rw-r--r--ofproto/ofproto-provider.h7
-rw-r--r--ofproto/ofproto.c29
3 files changed, 40 insertions, 5 deletions
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index f9562dee8..f87e27a8c 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -5358,11 +5358,12 @@ type_set_config(const char *type, const struct smap *other_config)
}
static void
-ct_flush(const struct ofproto *ofproto_, const uint16_t *zone)
+ct_flush(const struct ofproto *ofproto_, const uint16_t *zone,
+ const struct ofp_ct_match *match)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
- ct_dpif_flush(ofproto->backer->dpif, zone, NULL);
+ ct_dpif_flush(ofproto->backer->dpif, zone, match);
}
static struct ct_timeout_policy *
@@ -5674,6 +5675,10 @@ get_datapath_cap(const char *datapath_type, struct smap *cap)
smap_add(cap, "lb_output_action", s.lb_output_action ? "true" : "false");
smap_add(cap, "ct_zero_snat", s.ct_zero_snat ? "true" : "false");
smap_add(cap, "add_mpls", s.add_mpls ? "true" : "false");
+
+ /* The ct_tuple_flush is implemented on dpif level, so it is supported
+ * for all backers. */
+ smap_add(cap, "ct_flush", "true");
}
/* Gets timeout policy name in 'backer' based on 'zone', 'dl_type' and
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index 7e3fb6698..a84ddc1d0 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -42,6 +42,7 @@
#include "ofproto/ofproto.h"
#include "openvswitch/list.h"
#include "openvswitch/ofp-actions.h"
+#include "openvswitch/ofp-ct.h"
#include "openvswitch/ofp-errors.h"
#include "openvswitch/ofp-flow.h"
#include "openvswitch/ofp-group.h"
@@ -1902,8 +1903,10 @@ struct ofproto_class {
/* ## Connection tracking ## */
/* ## ------------------- ## */
/* Flushes the connection tracking tables. If 'zone' is not NULL,
- * only deletes connections in '*zone'. */
- void (*ct_flush)(const struct ofproto *, const uint16_t *zone);
+ * only deletes connections in '*zone'. If 'match' is not NULL,
+ * deletes connections specified by the match. */
+ void (*ct_flush)(const struct ofproto *, const uint16_t *zone,
+ const struct ofp_ct_match *match);
/* Sets conntrack timeout policy specified by 'timeout_policy' to 'zone'
* in datapath type 'dp_type'. */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 3a527683c..17f636ed9 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -42,6 +42,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-match.h"
#include "openvswitch/ofp-msgs.h"
@@ -934,7 +935,30 @@ handle_nxt_ct_flush_zone(struct ofconn *ofconn, const struct ofp_header *oh)
uint16_t zone = ntohs(nzi->zone_id);
if (ofproto->ofproto_class->ct_flush) {
- ofproto->ofproto_class->ct_flush(ofproto, &zone);
+ ofproto->ofproto_class->ct_flush(ofproto, &zone, NULL);
+ } else {
+ return EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static enum ofperr
+handle_nxt_ct_flush(struct ofconn *ofconn, const struct ofp_header *oh)
+{
+ struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
+ struct ofp_ct_match match = {0};
+ bool with_zone = false;
+ uint16_t zone_id = 0;
+
+ enum ofperr error = ofp_ct_match_decode(&match, &with_zone, &zone_id, oh);
+ if (error) {
+ return error;
+ }
+
+ if (ofproto->ofproto_class->ct_flush) {
+ ofproto->ofproto_class->ct_flush(ofproto, with_zone ? &zone_id : NULL,
+ &match);
} else {
return EOPNOTSUPP;
}
@@ -8787,6 +8811,9 @@ handle_single_part_openflow(struct ofconn *ofconn, const struct ofp_header *oh,
case OFPTYPE_CT_FLUSH_ZONE:
return handle_nxt_ct_flush_zone(ofconn, oh);
+ case OFPTYPE_CT_FLUSH:
+ return handle_nxt_ct_flush(ofconn, oh);
+
case OFPTYPE_HELLO:
case OFPTYPE_ERROR:
case OFPTYPE_FEATURES_REPLY: