2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

ofp, dpif: Allow CT flush based on partial match.

Currently, the CT can be flushed by dpctl only by specifying
the whole 5-tuple.  This is not very convenient when there are
only some fields known to the user of CT flush.  Add new struct
ofp_ct_match which represents the generic filtering that can
be done for CT flush. The match is done only on fields that are
non-zero with exception to the icmp fields.

This allows the filtering just within dpctl, however it is a
preparation for OpenFlow extension.

Reported-at: https://bugzilla.redhat.com/2120546
Signed-off-by: Ales Musil <amusil@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
Ales Musil
2023-01-16 12:45:07 +01:00
committed by Ilya Maximets
parent de3bbdc479
commit a9ae73b916
10 changed files with 617 additions and 143 deletions

View File

@@ -41,6 +41,7 @@
#include "netlink.h"
#include "odp-util.h"
#include "openvswitch/ofpbuf.h"
#include "openvswitch/ofp-ct.h"
#include "packets.h"
#include "openvswitch/shash.h"
#include "simap.h"
@@ -1707,37 +1708,55 @@ dpctl_flush_conntrack(int argc, const char *argv[],
struct dpctl_params *dpctl_p)
{
struct dpif *dpif = NULL;
struct ct_dpif_tuple tuple, *ptuple = NULL;
struct ofp_ct_match match = {0};
struct ds ds = DS_EMPTY_INITIALIZER;
uint16_t zone, *pzone = NULL;
int error;
int args = argc - 1;
/* Parse ct tuple */
if (args && ct_dpif_parse_tuple(&tuple, argv[args], &ds)) {
ptuple = &tuple;
args--;
}
/* Parse zone */
if (args && ovs_scan(argv[args], "zone=%"SCNu16, &zone)) {
/* Parse zone. */
if (args && !strncmp(argv[1], "zone=", 5)) {
if (!ovs_scan(argv[1], "zone=%"SCNu16, &zone)) {
ds_put_cstr(&ds, "failed to parse zone");
error = EINVAL;
goto error;
}
pzone = &zone;
args--;
}
/* Report error if there are more than one unparsed argument. */
/* 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 = argv[argc - args];
if (arg[0] && !ofp_ct_tuple_parse(tuple, arg, &ds, &match.ip_proto,
&match.l3_type)) {
error = EINVAL;
goto error;
}
args--;
}
/* Report error if there is more than one unparsed argument. */
if (args > 1) {
ds_put_cstr(&ds, "invalid arguments");
error = EINVAL;
goto error;
}
error = opt_dpif_open(argc, argv, dpctl_p, 4, &dpif);
error = opt_dpif_open(argc, argv, dpctl_p, 5, &dpif);
if (error) {
dpctl_error(dpctl_p, error, "Cannot open dpif");
return error;
}
error = ct_dpif_flush(dpif, pzone, ptuple);
error = ct_dpif_flush(dpif, pzone, &match);
if (!error) {
dpif_close(dpif);
return 0;
@@ -2862,8 +2881,8 @@ static const struct dpctl_command all_commands[] = {
0, 1, dpctl_offload_stats_show, DP_RO },
{ "dump-conntrack", "[-m] [-s] [dp] [zone=N]",
0, 4, dpctl_dump_conntrack, DP_RO },
{ "flush-conntrack", "[dp] [zone=N] [ct-tuple]", 0, 3,
dpctl_flush_conntrack, DP_RW },
{ "flush-conntrack", "[dp] [zone=N] [ct-orig-tuple] [ct-reply-tuple]",
0, 4, dpctl_flush_conntrack, DP_RW },
{ "cache-get-size", "[dp]", 0, 1, dpctl_cache_get_size, DP_RO },
{ "cache-set-size", "dp cache <size>", 3, 3, dpctl_cache_set_size, DP_RW },
{ "ct-stats-show", "[dp] [zone=N]",