Skip to content

Commit

Permalink
dpctl conntrack: Add get and set maxconns command.
Browse files Browse the repository at this point in the history
Get and set dpctl commands are added for conntrack maxconns.
These commands are only supported in the userspace
datapath at this time.

Signed-off-by: Darrell Ball <[email protected]>
Signed-off-by: Antonio Fischetti <[email protected]>
Co-authored-by: Antonio Fischetti <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
2 people authored and blp committed Jan 9, 2018
1 parent a98d35a commit c92339a
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 2 deletions.
6 changes: 4 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ Post-v2.8.0
* ovn-ctl: New commands run_nb_ovsdb and run_sb_ovsdb.
- Linux kernel 4.13
* Add support for compiling OVS with the latest Linux 4.13 kernel
- "flush-conntrack" in ovs-dpctl and ovs-appctl now accept a 5-tuple to
delete a specific connection tracking entry.
- ovs-dpctl and related ovs-appctl commands:
* "flush-conntrack" now accept a 5-tuple to delete a specific
connection tracking entry.
* New "ct-set-maxconns" and "ct-get-maxconns" for userspace datapath.
- DPDK:
* Add support for DPDK v17.11
* Add support for vHost IOMMU
Expand Down
14 changes: 14 additions & 0 deletions lib/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -2562,6 +2562,20 @@ conntrack_flush(struct conntrack *ct, const uint16_t *zone)
return 0;
}

int
conntrack_set_maxconns(struct conntrack *ct, uint32_t maxconns)
{
atomic_store_relaxed(&ct->n_conn_limit, maxconns);
return 0;
}

int
conntrack_get_maxconns(struct conntrack *ct, uint32_t *maxconns)
{
atomic_read_relaxed(&ct->n_conn_limit, maxconns);
return 0;
}

/* This function must be called with the ct->resources read lock taken. */
static struct alg_exp_node *
expectation_lookup(struct hmap *alg_expectations,
Expand Down
2 changes: 2 additions & 0 deletions lib/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ int conntrack_dump_next(struct conntrack_dump *, struct ct_dpif_entry *);
int conntrack_dump_done(struct conntrack_dump *);

int conntrack_flush(struct conntrack *, const uint16_t *zone);
int conntrack_set_maxconns(struct conntrack *ct, uint32_t maxconns);
int conntrack_get_maxconns(struct conntrack *ct, uint32_t *maxconns);

/* 'struct ct_lock' is a wrapper for an adaptive mutex. It's useful to try
* different types of locks (e.g. spinlocks) */
Expand Down
16 changes: 16 additions & 0 deletions lib/ct-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ ct_dpif_flush(struct dpif *dpif, const uint16_t *zone,
: EOPNOTSUPP);
}

int
ct_dpif_set_maxconns(struct dpif *dpif, uint32_t maxconns)
{
return (dpif->dpif_class->ct_set_maxconns
? dpif->dpif_class->ct_set_maxconns(dpif, maxconns)
: EOPNOTSUPP);
}

int
ct_dpif_get_maxconns(struct dpif *dpif, uint32_t *maxconns)
{
return (dpif->dpif_class->ct_get_maxconns
? dpif->dpif_class->ct_get_maxconns(dpif, maxconns)
: EOPNOTSUPP);
}

void
ct_dpif_entry_uninit(struct ct_dpif_entry *entry)
{
Expand Down
2 changes: 2 additions & 0 deletions lib/ct-dpif.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ int ct_dpif_dump_next(struct ct_dpif_dump_state *, struct ct_dpif_entry *);
int ct_dpif_dump_done(struct ct_dpif_dump_state *);
int ct_dpif_flush(struct dpif *, const uint16_t *zone,
const struct ct_dpif_tuple *);
int ct_dpif_set_maxconns(struct dpif *dpif, uint32_t maxconns);
int ct_dpif_get_maxconns(struct dpif *dpif, uint32_t *maxconns);
void ct_dpif_entry_uninit(struct ct_dpif_entry *);
void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *,
bool verbose, bool print_stats);
Expand Down
72 changes: 72 additions & 0 deletions lib/dpctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,76 @@ dpctl_ct_bkts(int argc, const char *argv[],
return error;
}

static int
dpctl_ct_open_dp(int argc, const char *argv[],
struct dpctl_params *dpctl_p, struct dpif **dpif,
uint8_t max_args)
{
int error = 0;
/* The datapath name is not a mandatory parameter for this command.
* If it is not specified - so argc < max_args - we retrieve it from the
* current setup, assuming only one exists. */
char *dpname = argc >= max_args ? xstrdup(argv[1]) : get_one_dp(dpctl_p);
if (!dpname) {
error = EINVAL;
dpctl_error(dpctl_p, error, "datapath not found");
} else {
error = parsed_dpif_open(dpname, false, dpif);
free(dpname);
if (error) {
dpctl_error(dpctl_p, error, "opening datapath");
}
}
return error;
}

static int
dpctl_ct_set_maxconns(int argc, const char *argv[],
struct dpctl_params *dpctl_p)
{
struct dpif *dpif;
int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 3);
if (!error) {
uint32_t maxconns;
if (ovs_scan(argv[argc - 1], "%"SCNu32, &maxconns)) {
error = ct_dpif_set_maxconns(dpif, maxconns);

if (!error) {
dpctl_print(dpctl_p, "setting maxconns successful");
} else {
dpctl_error(dpctl_p, error, "ct set maxconns failed");
}
} else {
error = EINVAL;
dpctl_error(dpctl_p, error, "maxconns missing or malformed");
}
dpif_close(dpif);
}

return error;
}

static int
dpctl_ct_get_maxconns(int argc, const char *argv[],
struct dpctl_params *dpctl_p)
{
struct dpif *dpif;
int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 2);
if (!error) {
uint32_t maxconns;
error = ct_dpif_get_maxconns(dpif, &maxconns);

if (!error) {
dpctl_print(dpctl_p, "%u\n", maxconns);
} else {
dpctl_error(dpctl_p, error, "maxconns could not be retrieved");
}
dpif_close(dpif);
}

return error;
}

/* Undocumented commands for unit testing. */

static int
Expand Down Expand Up @@ -1951,6 +2021,8 @@ static const struct dpctl_command all_commands[] = {
{ "ct-stats-show", "[dp] [zone=N] [verbose]",
0, 3, dpctl_ct_stats_show, DP_RO },
{ "ct-bkts", "[dp] [gt=N]", 0, 2, dpctl_ct_bkts, DP_RO },
{ "ct-set-maxconns", "[dp] maxconns", 1, 2, dpctl_ct_set_maxconns, DP_RW },
{ "ct-get-maxconns", "[dp]", 0, 1, dpctl_ct_get_maxconns, DP_RO },
{ "help", "", 0, INT_MAX, dpctl_help, DP_RO },
{ "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO },

Expand Down
16 changes: 16 additions & 0 deletions lib/dpctl.man
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,19 @@ For each ConnTracker bucket, displays the number of connections used
by \fIdp\fR.
If \fBgt=\fIThreshold\fR is specified, bucket numbers are displayed when
the number of connections in a bucket is greater than \fIThreshold\fR.
.
.TP
\*(DX\fBct\-set\-maxconns\fR [\fIdp\fR] \fBparam\fR
Set the maximum limit of connection tracker connections.
Can be used to reduce the processing load on the system due to
connection tracking or simply limiting connection tracking.
If the number of connections is already beyond the new maximum limit
request for the number of connections then the new maximum limit will
be enforced when the number of connections decreases to that limit, which
normally happens due to connection expiry. Only supported for userspace
datapath.
.
.TP
\*(DX\fBct\-get\-maxconns\fR [\fIdp\fR]
Read the maximum limit of connection tracker connections.
Only supported for userspace datapath.
18 changes: 18 additions & 0 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -5846,6 +5846,22 @@ dpif_netdev_ct_flush(struct dpif *dpif, const uint16_t *zone,
return conntrack_flush(&dp->conntrack, zone);
}

static int
dpif_netdev_ct_set_maxconns(struct dpif *dpif, uint32_t maxconns)
{
struct dp_netdev *dp = get_dp_netdev(dpif);

return conntrack_set_maxconns(&dp->conntrack, maxconns);
}

static int
dpif_netdev_ct_get_maxconns(struct dpif *dpif, uint32_t *maxconns)
{
struct dp_netdev *dp = get_dp_netdev(dpif);

return conntrack_get_maxconns(&dp->conntrack, maxconns);
}

const struct dpif_class dpif_netdev_class = {
"netdev",
dpif_netdev_init,
Expand Down Expand Up @@ -5891,6 +5907,8 @@ const struct dpif_class dpif_netdev_class = {
dpif_netdev_ct_dump_next,
dpif_netdev_ct_dump_done,
dpif_netdev_ct_flush,
dpif_netdev_ct_set_maxconns,
dpif_netdev_ct_get_maxconns,
dpif_netdev_meter_get_features,
dpif_netdev_meter_set,
dpif_netdev_meter_get,
Expand Down
2 changes: 2 additions & 0 deletions lib/dpif-netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -2989,6 +2989,8 @@ const struct dpif_class dpif_netlink_class = {
dpif_netlink_ct_dump_next,
dpif_netlink_ct_dump_done,
dpif_netlink_ct_flush,
NULL, /* ct_set_maxconns */
NULL, /* ct_get_maxconns */
dpif_netlink_meter_get_features,
dpif_netlink_meter_set,
dpif_netlink_meter_get,
Expand Down
4 changes: 4 additions & 0 deletions lib/dpif-provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@ struct dpif_class {
* (zone 0). */
int (*ct_flush)(struct dpif *, const uint16_t *zone,
const struct ct_dpif_tuple *tuple);
/* Set max connections allowed. */
int (*ct_set_maxconns)(struct dpif *, uint32_t maxconns);
/* Get max connections allowed. */
int (*ct_get_maxconns)(struct dpif *, uint32_t *maxconns);

/* Meters */

Expand Down

0 comments on commit c92339a

Please sign in to comment.