2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 09:58:01 +00:00

ovs-vsctl: Add limit to CT zone.

Add limit to the CT zone DB table with ovs-vsctl
helper methods. The limit has two special values
besides any number, 0 is unlimited and empty limit
is to leave the value untouched in the datapath.

This is preparation step and the value is not yet
propagated to the datapath.

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-12-04 06:49:10 +01:00 committed by Ilya Maximets
parent 8f4b86237b
commit 3248833619
6 changed files with 276 additions and 16 deletions

5
NEWS
View File

@ -17,6 +17,11 @@ Post-v3.2.0
Reported names adjusted accordingly. Reported names adjusted accordingly.
* Added support for removal of default CT zone limit, e.g. * Added support for removal of default CT zone limit, e.g.
"ovs-appctl dpctl/ct-del-limits default". "ovs-appctl dpctl/ct-del-limits default".
- ovs-vsctl:
* New commands 'set-zone-limit', 'del-zone-limit' and 'list-zone-limits'
to manage the maximum number of connections in conntrack zones via
a new 'limit' column in the 'CT_Zone' database table and
'ct_zone_default_limit' column in the 'Datapath' table.
- Userspace datapath: - Userspace datapath:
* Added support for Generic Segmentation Offloading for the cases where * Added support for Generic Segmentation Offloading for the cases where
TSO is enabled but not supported by an egress interface (except for TSO is enabled but not supported by an egress interface (except for

View File

@ -975,6 +975,67 @@ AT_CHECK(
[0], [stdout]) [0], [stdout])
AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:10, Timeout Policies: system default AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:10, Timeout Policies: system default
]) ])
AT_CHECK([RUN_OVS_VSCTL([--if-exists del-zone-tp netdev zone=10])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev 1 1])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])], [0], [dnl
Zone: 1, Limit: 1
])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev 1 5])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])], [0], [dnl
Zone: 1, Limit: 5
])
AT_CHECK([RUN_OVS_VSCTL([del-zone-limit netdev 1])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev 10 5])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])], [0], [dnl
Zone: 10, Limit: 5
])
AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=10 icmp_first=1 icmp_reply=2])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [dnl
Zone:10, Timeout Policies: icmp_first=1 icmp_reply=2
])
AT_CHECK([RUN_OVS_VSCTL([del-zone-limit netdev 10])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [dnl
Zone:10, Timeout Policies: icmp_first=1 icmp_reply=2
])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev 10 5])])
AT_CHECK([RUN_OVS_VSCTL([del-zone-tp netdev zone=10])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])], [0], [dnl
Zone: 10, Limit: 5
])
AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [dnl
Zone:10, Timeout Policies: system default
])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev default 5])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])], [0], [dnl
Default, Limit: 5
Zone: 10, Limit: 5
])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev default 10])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])], [0], [dnl
Default, Limit: 10
Zone: 10, Limit: 5
])
AT_CHECK([RUN_OVS_VSCTL([del-zone-limit netdev default])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-limits netdev])], [0], [dnl
Zone: 10, Limit: 5
])
AT_CHECK([RUN_OVS_VSCTL([--if-exists del-zone-limit netdev default])])
AT_CHECK([RUN_OVS_VSCTL([-- --id=@m create Datapath datapath_version=0 'capabilities={recirc=true}' -- set Open_vSwitch . datapaths:"system"=@m])], [0], [stdout]) AT_CHECK([RUN_OVS_VSCTL([-- --id=@m create Datapath datapath_version=0 'capabilities={recirc=true}' -- set Open_vSwitch . datapaths:"system"=@m])], [0], [stdout])
AT_CHECK([RUN_OVS_VSCTL([list-dp-cap system])], [0], [recirc=true AT_CHECK([RUN_OVS_VSCTL([list-dp-cap system])], [0], [recirc=true
@ -1113,16 +1174,39 @@ AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdevxx zone=1 icmp_first=1 icmp_reply=2])
]) ])
AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=2 icmp_first=2 icmp_reply=3])]) AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=2 icmp_first=2 icmp_reply=3])])
AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=2 icmp_first=2 icmp_reply=3])], AT_CHECK([RUN_OVS_VSCTL([add-zone-tp netdev zone=2 icmp_first=2 icmp_reply=3])],
[1], [], [ovs-vsctl: zone id 2 already exists [1], [], [ovs-vsctl: zone id 2 already has a policy
]) ])
AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3 AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3
]) ])
AT_CHECK([RUN_OVS_VSCTL([del-zone-tp netdev zone=11])], AT_CHECK([RUN_OVS_VSCTL([del-zone-tp netdev zone=11])],
[1], [], [ovs-vsctl: zone id 11 does not exist [1], [], [ovs-vsctl: zone id 11 does not have a policy
]) ])
AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3 AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3
]) ])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdevxx 5 1])],
[1], [], [ovs-vsctl: datapath netdevxx does not exist
])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev 88888 1])],
[1], [], [ovs-vsctl: zone_id (88888) out of range
])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev 5 -1])],
[1], [], [ovs-vsctl: limit (-1) out of range
])
AT_CHECK([RUN_OVS_VSCTL([del-zone-limit netdev 10])],
[1], [], [ovs-vsctl: zone_id 10 does not have a limit
])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdevxx default 1])],
[1], [], [ovs-vsctl: datapath netdevxx does not exist
])
AT_CHECK([RUN_OVS_VSCTL([set-zone-limit netdev default -1])],
[1], [], [ovs-vsctl: limit (-1) out of range
])
AT_CHECK([RUN_OVS_VSCTL([del-zone-limit netdev default])],
[1], [], [ovs-vsctl: datapath netdev does not have a limit
])
AT_CHECK([RUN_OVS_VSCTL([-- --id=@m create Datapath datapath_version=0 'capabilities={recirc=true}' -- set Open_vSwitch . datapaths:"system"=@m])], [0], [stdout]) AT_CHECK([RUN_OVS_VSCTL([-- --id=@m create Datapath datapath_version=0 'capabilities={recirc=true}' -- set Open_vSwitch . datapaths:"system"=@m])], [0], [stdout])
AT_CHECK([RUN_OVS_VSCTL([list-dp-cap nosystem])], AT_CHECK([RUN_OVS_VSCTL([list-dp-cap nosystem])],
[1], [], [ovs-vsctl: datapath "nosystem" record not found [1], [], [ovs-vsctl: datapath "nosystem" record not found

View File

@ -354,7 +354,7 @@ Prints the name of the bridge that contains \fIiface\fR on standard
output. output.
. .
.SS "Conntrack Zone Commands" .SS "Conntrack Zone Commands"
These commands query and modify datapath CT zones and Timeout Policies. These commands query and modify datapath CT zones, Timeout Policies and Limits.
. .
.IP "[\fB\-\-may\-exist\fR] \fBadd\-zone\-tp \fIdatapath \fBzone=\fIzone_id \fIpolicies\fR" .IP "[\fB\-\-may\-exist\fR] \fBadd\-zone\-tp \fIdatapath \fBzone=\fIzone_id \fIpolicies\fR"
Creates a conntrack zone timeout policy with \fIzone_id\fR in Creates a conntrack zone timeout policy with \fIzone_id\fR in
@ -365,20 +365,37 @@ packet and a 60-second policy for ICMP reply packets. See the
\fBCT_Timeout_Policy\fR table in \fBovs-vswitchd.conf.db\fR(5) for the \fBCT_Timeout_Policy\fR table in \fBovs-vswitchd.conf.db\fR(5) for the
supported keys. supported keys.
.IP .IP
Without \fB\-\-may\-exist\fR, attempting to add a \fIzone_id\fR that Without \fB\-\-may\-exist\fR, attempting to add a \fIpolicy\fR for
already exists is an error. With \fB\-\-may\-exist\fR, \fIzone_id\fR that already has a policy is an error.
this command does nothing if \fIzone_id\fR already exists. With \fB\-\-may\-exist\fR, this command does nothing if policy for
\fIzone_id\fR already exists.
. .
.IP "[\fB\-\-if\-exists\fR] \fBdel\-zone\-tp \fIdatapath \fBzone=\fIzone_id\fR" .IP "[\fB\-\-if\-exists\fR] \fBdel\-zone\-tp \fIdatapath \fBzone=\fIzone_id\fR"
Delete the timeout policy associated with \fIzone_id\fR from \fIdatapath\fR. Delete the timeout policy associated with \fIzone_id\fR from \fIdatapath\fR.
.IP .IP
Without \fB\-\-if\-exists\fR, attempting to delete a zone that Without \fB\-\-if\-exists\fR, attempting to delete a policy for zone that
does not exist is an error. With \fB\-\-if\-exists\fR, attempting to does not exist or doesn't have a policy is an error. With
delete a zone that does not exist has no effect. \fB\-\-if\-exists\fR, attempting to delete a a policy that does not
exist has no effect.
. .
.IP "\fBlist\-zone\-tp \fIdatapath\fR" .IP "\fBlist\-zone\-tp \fIdatapath\fR"
Prints the timeout policies of all zones in \fIdatapath\fR. Prints the timeout policies of all zones in \fIdatapath\fR.
. .
.IP "\fBset\-zone\-limit \fIdatapath \fIzone_id\fR|\fBdefault \fIzone_limit\fR"
Sets a conntrack zone limit with \fIzone_id\fR|\fIdefault\fR in
\fIdatapath\fR. The \fIlimit\fR with value \fB0\fR means unlimited.
.IP
.
.IP "[\fB\-\-if\-exists\fR] \fBdel\-zone\-limit \fIdatapath \fIzone_id\fR|\fBdefault\fR"
Delete the limit associated with \fIzone_id\fR from \fIdatapath\fR.
.IP
Without \fB\-\-if\-exists\fR, attempting to delete a limit for zone that
does not exist or doesn't have a limit is an error. With \fB\-\-if\-exists\fR,
attempting to delete a limit that does not exist has no effect.
.
.IP "\fBlist\-zone\-limits \fIdatapath\fR"
Prints the limits of all zones in \fIdatapath\fR.
.
.SS "Datapath Capabilities Command" .SS "Datapath Capabilities Command"
The command query datapath capabilities. The command query datapath capabilities.
. .

View File

@ -442,6 +442,13 @@ Auto Attach commands:\n\
Switch commands:\n\ Switch commands:\n\
emer-reset reset switch to known good state\n\ emer-reset reset switch to known good state\n\
\n\ \n\
Connection Tracking commands:\n\
set-zone-limit DATAPATH ZONE|default LIMIT\n\
set CT LIMIT for ZONE|default on DATAPATH\n\
del-zone-limit DATAPATH ZONE|default\n\
delete CT limit for ZONE|default on DATAPATH\n\
list-zone-limits DATAPATH list all limits configured on DATAPATH\n\
\n\
%s\ %s\
%s\ %s\
\n\ \n\
@ -1302,8 +1309,8 @@ cmd_add_zone_tp(struct ctl_context *ctx)
ctl_fatal("No timeout policy"); ctl_fatal("No timeout policy");
} }
if (zone && !may_exist) { if (zone && zone->timeout_policy && !may_exist) {
ctl_fatal("zone id %"PRIu64" already exists", zone_id); ctl_fatal("zone id %"PRIu64" already has a policy", zone_id);
} }
tp = create_timeout_policy(ctx, &ctx->argv[3], n_tps); tp = create_timeout_policy(ctx, &ctx->argv[3], n_tps);
@ -1332,11 +1339,20 @@ cmd_del_zone_tp(struct ctl_context *ctx)
} }
struct ovsrec_ct_zone *zone = find_ct_zone(dp, zone_id); struct ovsrec_ct_zone *zone = find_ct_zone(dp, zone_id);
if (must_exist && !zone) { if (must_exist && !(zone && zone->timeout_policy)) {
ctl_fatal("zone id %"PRIu64" does not exist", zone_id); ctl_fatal("zone id %"PRIu64" does not have a policy", zone_id);
} }
if (zone) { if (!zone) {
return;
}
if (zone->limit) {
if (zone->timeout_policy) {
ovsrec_ct_timeout_policy_delete(zone->timeout_policy);
}
ovsrec_ct_zone_set_timeout_policy(zone, NULL);
} else {
ovsrec_datapath_update_ct_zones_delkey(dp, zone_id); ovsrec_datapath_update_ct_zones_delkey(dp, zone_id);
} }
} }
@ -1371,12 +1387,118 @@ cmd_list_zone_tp(struct ctl_context *ctx)
} }
} }
static void
cmd_set_zone_limit(struct ctl_context *ctx)
{
struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
int64_t zone_id = -1;
int64_t limit = -1;
const char *dp_name = ctx->argv[1];
ovs_scan(ctx->argv[2], "%"SCNi64, &zone_id);
ovs_scan(ctx->argv[3], "%"SCNi64, &limit);
struct ovsrec_datapath *dp = find_datapath(vsctl_ctx, dp_name);
if (!dp) {
ctl_fatal("datapath %s does not exist", dp_name);
}
if (limit < 0 || limit > UINT32_MAX) {
ctl_fatal("limit (%"PRIi64") out of range", limit);
}
if (!strcmp(ctx->argv[2], "default")) {
ovsrec_datapath_set_ct_zone_default_limit(dp, &limit, 1);
return;
}
if (zone_id < 0 || zone_id > UINT16_MAX) {
ctl_fatal("zone_id (%"PRIi64") out of range", zone_id);
}
struct ovsrec_ct_zone *zone = find_ct_zone(dp, zone_id);
if (!zone) {
zone = ovsrec_ct_zone_insert(ctx->txn);
ovsrec_datapath_update_ct_zones_setkey(dp, zone_id, zone);
}
ovsrec_ct_zone_set_limit(zone, &limit, 1);
}
static void
cmd_del_zone_limit(struct ctl_context *ctx)
{
struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
int64_t zone_id;
bool must_exist = !shash_find(&ctx->options, "--if-exists");
const char *dp_name = ctx->argv[1];
ovs_scan(ctx->argv[2], "%"SCNi64, &zone_id);
struct ovsrec_datapath *dp = find_datapath(vsctl_ctx, dp_name);
if (!dp) {
ctl_fatal("datapath %s does not exist", dp_name);
}
if (!strcmp(ctx->argv[2], "default")) {
if (must_exist && !dp->ct_zone_default_limit) {
ctl_fatal("datapath %s does not have a limit", dp_name);
}
ovsrec_datapath_set_ct_zone_default_limit(dp, NULL, 0);
return;
}
struct ovsrec_ct_zone *zone = find_ct_zone(dp, zone_id);
if (must_exist && !(zone && zone->limit)) {
ctl_fatal("zone_id %"PRIi64" does not have a limit", zone_id);
}
if (!zone) {
return;
}
if (zone->timeout_policy) {
ovsrec_ct_zone_set_limit(zone, NULL, 0);
} else {
ovsrec_datapath_update_ct_zones_delkey(dp, zone_id);
}
}
static void
cmd_list_zone_limits(struct ctl_context *ctx)
{
struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
struct ovsrec_datapath *dp = find_datapath(vsctl_ctx, ctx->argv[1]);
if (!dp) {
ctl_fatal("datapath: %s record not found", ctx->argv[1]);
}
if (dp->ct_zone_default_limit) {
ds_put_format(&ctx->output, "Default, Limit: %"PRIu64"\n",
*dp->ct_zone_default_limit);
}
for (int i = 0; i < dp->n_ct_zones; i++) {
struct ovsrec_ct_zone *zone = dp->value_ct_zones[i];
if (zone->limit) {
ds_put_format(&ctx->output, "Zone: %"PRIu64", Limit: %"PRIu64"\n",
dp->key_ct_zones[i], *zone->limit);
}
}
}
static void static void
pre_get_zone(struct ctl_context *ctx) pre_get_zone(struct ctl_context *ctx)
{ {
ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_datapaths); ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_datapaths);
ovsdb_idl_add_column(ctx->idl, &ovsrec_datapath_col_ct_zones); ovsdb_idl_add_column(ctx->idl, &ovsrec_datapath_col_ct_zones);
ovsdb_idl_add_column(ctx->idl, &ovsrec_datapath_col_ct_zone_default_limit);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_zone_col_timeout_policy); ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_zone_col_timeout_policy);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_zone_col_limit);
ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_timeout_policy_col_timeouts); ovsdb_idl_add_column(ctx->idl, &ovsrec_ct_timeout_policy_col_timeouts);
} }
@ -3159,6 +3281,14 @@ static const struct ctl_command_syntax vsctl_commands[] = {
/* Datapath capabilities. */ /* Datapath capabilities. */
{"list-dp-cap", 1, 1, "", pre_get_dp_cap, cmd_list_dp_cap, NULL, "", RO}, {"list-dp-cap", 1, 1, "", pre_get_dp_cap, cmd_list_dp_cap, NULL, "", RO},
/* CT zone limit. */
{"set-zone-limit", 3, 3, "ARG ARG ARG", pre_get_zone, cmd_set_zone_limit,
NULL, "", RW},
{"del-zone-limit", 2, 2, "ARG ARG", pre_get_zone, cmd_del_zone_limit, NULL,
"--if-exists", RW},
{"list-zone-limits", 1, 1, "ARG", pre_get_zone, cmd_list_zone_limits, NULL,
"", RO},
{NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO}, {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
}; };

View File

@ -1,6 +1,6 @@
{"name": "Open_vSwitch", {"name": "Open_vSwitch",
"version": "8.4.0", "version": "8.5.0",
"cksum": "2738838700 27127", "cksum": "4040946650 27557",
"tables": { "tables": {
"Open_vSwitch": { "Open_vSwitch": {
"columns": { "columns": {
@ -670,6 +670,11 @@
"capabilities": { "capabilities": {
"type": {"key": "string", "value": "string", "type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}, "min": 0, "max": "unlimited"}},
"ct_zone_default_limit": {
"type": { "key": {"type": "integer",
"minInteger": 0,
"maxInteger": 4294967295},
"min": 0, "max": 1}},
"external_ids": { "external_ids": {
"type": {"key": "string", "value": "string", "type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}}}, "min": 0, "max": "unlimited"}}}},
@ -679,6 +684,11 @@
"type": {"key": {"type": "uuid", "type": {"key": {"type": "uuid",
"refTable": "CT_Timeout_Policy"}, "refTable": "CT_Timeout_Policy"},
"min": 0, "max": 1}}, "min": 0, "max": 1}},
"limit": {
"type": { "key": {"type": "integer",
"minInteger": 0,
"maxInteger": 4294967295},
"min": 0, "max": 1}},
"external_ids": { "external_ids": {
"type": {"key": "string", "value": "string", "type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}}}, "min": 0, "max": "unlimited"}}}},

View File

@ -6488,6 +6488,14 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
</column> </column>
</group> </group>
<column name="ct_zone_default_limit">
Default connection tracking zone limit that is applied to all zones
that didn't specify the <ref table="CT_Zone" column="limit"/>
explicitly. If the limit is unspecified the default limit
configuration for the datapath is left intact. The value 0 means
unlimited.
</column>
<group title="Common Columns"> <group title="Common Columns">
The overall purpose of these columns is described under <code>Common The overall purpose of these columns is described under <code>Common
Columns</code> at the beginning of this document. Columns</code> at the beginning of this document.
@ -6504,6 +6512,12 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
is not specified, it defaults to the timeout policy in the system. is not specified, it defaults to the timeout policy in the system.
</column> </column>
<column name="limit">
Connection tracking limit for this zone. If the limit is unspecified
the <ref table="Datapath" column="ct_zone_default_limit"/> will be used.
The value 0 means unlimited.
</column>
<group title="Common Columns"> <group title="Common Columns">
The overall purpose of these columns is described under <code>Common The overall purpose of these columns is described under <code>Common
Columns</code> at the beginning of this document. Columns</code> at the beginning of this document.