diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | lib/conntrack-private.h | 1 | ||||
-rw-r--r-- | lib/conntrack.c | 18 | ||||
-rw-r--r-- | lib/conntrack.h | 2 | ||||
-rw-r--r-- | lib/ct-dpif.c | 14 | ||||
-rw-r--r-- | lib/ct-dpif.h | 1 | ||||
-rw-r--r-- | lib/dpctl.c | 61 | ||||
-rw-r--r-- | lib/dpctl.man | 9 | ||||
-rw-r--r-- | lib/dpif-netdev.c | 17 | ||||
-rw-r--r-- | lib/dpif-netlink.c | 2 | ||||
-rw-r--r-- | lib/dpif-provider.h | 4 | ||||
-rw-r--r-- | tests/ofproto-dpif.at | 22 |
12 files changed, 153 insertions, 1 deletions
@@ -11,6 +11,9 @@ Post-v3.1.0 - ovs-appctl: * Add support for selecting the source address with the 'ovs-appctl ovs/route/add' command. + * New commands "dpctl/{ct-get-sweep-interval,ct-set-sweep-interval}" that + allow to get and set, for the userspace datapath, the sweep interval + for the conntrack garbage collector. - ovs-ctl: * Added new options --[ovsdb-server|ovs-vswitchd]-umask=MODE to set umask value when starting OVS daemons. E.g., use --ovsdb-server-umask=0002 diff --git a/lib/conntrack-private.h b/lib/conntrack-private.h index fae8b3a9b..bb326868e 100644 --- a/lib/conntrack-private.h +++ b/lib/conntrack-private.h @@ -224,6 +224,7 @@ struct conntrack { struct ipf *ipf; /* Fragmentation handling context. */ uint32_t zone_limit_seq; /* Used to disambiguate zone limit counts. */ atomic_bool tcp_seq_chk; /* Check TCP sequence numbers. */ + atomic_uint32_t sweep_ms; /* Next sweep interval. */ }; /* Lock acquisition order: diff --git a/lib/conntrack.c b/lib/conntrack.c index f86fa26f4..ce8a63de5 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -320,6 +320,7 @@ conntrack_init(void) atomic_count_init(&ct->n_conn, 0); atomic_init(&ct->n_conn_limit, DEFAULT_N_CONN_LIMIT); atomic_init(&ct->tcp_seq_chk, true); + atomic_init(&ct->sweep_ms, 20000); latch_init(&ct->clean_thread_exit); ct->clean_thread = ovs_thread_create("ct_clean", clean_thread_main, ct); ct->ipf = ipf_init(); @@ -1480,6 +1481,21 @@ set_label(struct dp_packet *pkt, struct conn *conn, } +int +conntrack_set_sweep_interval(struct conntrack *ct, uint32_t ms) +{ + atomic_store_relaxed(&ct->sweep_ms, ms); + return 0; +} + +uint32_t +conntrack_get_sweep_interval(struct conntrack *ct) +{ + uint32_t ms; + atomic_read_relaxed(&ct->sweep_ms, &ms); + return ms; +} + static size_t ct_sweep(struct conntrack *ct, struct rculist *list, long long now) OVS_NO_THREAD_SAFETY_ANALYSIS @@ -1504,7 +1520,7 @@ ct_sweep(struct conntrack *ct, struct rculist *list, long long now) static long long conntrack_clean(struct conntrack *ct, long long now) { - long long next_wakeup = now + 20 * 1000; + long long next_wakeup = now + conntrack_get_sweep_interval(ct); unsigned int n_conn_limit, i; size_t clean_end, count = 0; diff --git a/lib/conntrack.h b/lib/conntrack.h index b064abc9f..524ec0acb 100644 --- a/lib/conntrack.h +++ b/lib/conntrack.h @@ -139,6 +139,8 @@ int conntrack_set_maxconns(struct conntrack *ct, uint32_t maxconns); int conntrack_get_maxconns(struct conntrack *ct, uint32_t *maxconns); int conntrack_get_nconns(struct conntrack *ct, uint32_t *nconns); int conntrack_set_tcp_seq_chk(struct conntrack *ct, bool enabled); +int conntrack_set_sweep_interval(struct conntrack *ct, uint32_t ms); +uint32_t conntrack_get_sweep_interval(struct conntrack *ct); bool conntrack_get_tcp_seq_chk(struct conntrack *ct); struct ipf *conntrack_ipf_ctx(struct conntrack *ct); struct conntrack_zone_limit zone_limit_get(struct conntrack *ct, diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index d3b2783ce..0c4b2964f 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -369,6 +369,20 @@ ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *zone_limits) } int +ct_dpif_sweep(struct dpif *dpif, uint32_t *ms) +{ + if (*ms) { + return (dpif->dpif_class->ct_set_sweep_interval + ? dpif->dpif_class->ct_set_sweep_interval(dpif, *ms) + : EOPNOTSUPP); + } else { + return (dpif->dpif_class->ct_get_sweep_interval + ? dpif->dpif_class->ct_get_sweep_interval(dpif, ms) + : EOPNOTSUPP); + } +} + +int ct_dpif_ipf_set_enabled(struct dpif *dpif, bool v6, bool enable) { return (dpif->dpif_class->ipf_set_enabled diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index 5edbbfd3b..5579ac925 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -298,6 +298,7 @@ int ct_dpif_set_limits(struct dpif *dpif, const uint32_t *default_limit, int ct_dpif_get_limits(struct dpif *dpif, uint32_t *default_limit, const struct ovs_list *, struct ovs_list *); int ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *); +int ct_dpif_sweep(struct dpif *, uint32_t *ms); int ct_dpif_ipf_set_enabled(struct dpif *, bool v6, bool enable); int ct_dpif_ipf_set_min_frag(struct dpif *, bool v6, uint32_t min_frag); int ct_dpif_ipf_set_max_nfrags(struct dpif *, uint32_t max_frags); diff --git a/lib/dpctl.c b/lib/dpctl.c index 59cc4f58c..3ba40fa8f 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -2301,6 +2301,65 @@ out: } static int +dpctl_ct_get_sweep(int argc, const char *argv[], + struct dpctl_params *dpctl_p) +{ + uint32_t sweep_ms = 0; + struct dpif *dpif; + + int error = opt_dpif_open(argc, argv, dpctl_p, 2, &dpif); + if (error) { + return error; + } + + error = ct_dpif_sweep(dpif, &sweep_ms); + if (error) { + dpctl_error(dpctl_p, error, "failed to get the sweep interval"); + } else { + dpctl_print(dpctl_p, "%"PRIu32, sweep_ms); + } + + dpif_close(dpif); + return error; +} + +static int +dpctl_ct_set_sweep(int argc, const char *argv[], + struct dpctl_params *dpctl_p) +{ + struct ds ds = DS_EMPTY_INITIALIZER; + uint32_t sweep_ms = 0; + struct dpif *dpif; + + int error = opt_dpif_open(argc, argv, dpctl_p, 3, &dpif); + if (error) { + return error; + } + + if (!ovs_scan(argv[argc - 1], "%"SCNu32, &sweep_ms) || + sweep_ms == 0) { + ds_put_format(&ds, "invalid sweep value"); + error = EINVAL; + goto error; + } + + error = ct_dpif_sweep(dpif, &sweep_ms); + if (!error) { + dpctl_print(dpctl_p, "setting sweep interval successful\n"); + goto out; + } + + ds_put_format(&ds, "failed to set the sweep interval"); + +error: + dpctl_error(dpctl_p, error, "%s", ds_cstr(&ds)); + ds_destroy(&ds); +out: + dpif_close(dpif); + return error; +} + +static int ipf_set_enabled__(int argc, const char *argv[], struct dpctl_params *dpctl_p, bool enabled) { @@ -2913,6 +2972,8 @@ static const struct dpctl_command all_commands[] = { DP_RO }, { "ct-get-limits", "[dp] [zone=N1[,N2]...]", 0, 2, dpctl_ct_get_limits, DP_RO }, + { "ct-get-sweep-interval", "[dp]", 0, 1, dpctl_ct_get_sweep, DP_RO }, + { "ct-set-sweep-interval", "[dp] ms", 1, 2, dpctl_ct_set_sweep, DP_RW }, { "ipf-set-enabled", "[dp] v4|v6", 1, 2, dpctl_ipf_set_enabled, DP_RW }, { "ipf-set-disabled", "[dp] v4|v6", 1, 2, dpctl_ipf_set_disabled, DP_RW }, { "ipf-set-min-frag", "[dp] v4|v6 minfragment", 2, 3, diff --git a/lib/dpctl.man b/lib/dpctl.man index 920446e8c..d448596d3 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -382,6 +382,15 @@ Prints whether TCP sequence checking is enabled or disabled on \fIdp\fR. Only supported for the userspace datapath. . .TP +\*(DX\fBct\-set\-sweep\-interval\fR [\fIdp\fR] \fIms\fR +Sets the sweep interval. Only supported for the userspace datapath. +. +.TP +\*(DX\fBct\-get\-sweep\-interval\fR [\fIdp\fR] +Prints the current sweep interval in ms. Only supported for the userspace +datapath. +. +.TP \*(DX\fBct\-set\-limits\fR [\fIdp\fR] [\fBdefault=\fIdefault_limit\fR] [\fBzone=\fIzone\fR,\fBlimit=\fIlimit\fR]... Sets the maximum allowed number of connections in a connection tracking zone. A specific \fIzone\fR may be set to \fIlimit\fR, and multiple zones diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index aed2c8fbb..70b953ae6 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -9318,6 +9318,21 @@ dpif_netdev_ct_get_tcp_seq_chk(struct dpif *dpif, bool *enabled) } static int +dpif_netdev_ct_set_sweep_interval(struct dpif *dpif, uint32_t ms) +{ + struct dp_netdev *dp = get_dp_netdev(dpif); + return conntrack_set_sweep_interval(dp->conntrack, ms); +} + +static int +dpif_netdev_ct_get_sweep_interval(struct dpif *dpif, uint32_t *ms) +{ + struct dp_netdev *dp = get_dp_netdev(dpif); + *ms = conntrack_get_sweep_interval(dp->conntrack); + return 0; +} + +static int dpif_netdev_ct_set_limits(struct dpif *dpif, const uint32_t *default_limits, const struct ovs_list *zone_limits) @@ -9668,6 +9683,8 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_ct_get_nconns, dpif_netdev_ct_set_tcp_seq_chk, dpif_netdev_ct_get_tcp_seq_chk, + dpif_netdev_ct_set_sweep_interval, + dpif_netdev_ct_get_sweep_interval, dpif_netdev_ct_set_limits, dpif_netdev_ct_get_limits, dpif_netdev_ct_del_limits, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 55b5b0a85..de0711277 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -4572,6 +4572,8 @@ const struct dpif_class dpif_netlink_class = { NULL, /* ct_get_nconns */ NULL, /* ct_set_tcp_seq_chk */ NULL, /* ct_get_tcp_seq_chk */ + NULL, /* ct_set_sweep_interval */ + NULL, /* ct_get_sweep_interval */ dpif_netlink_ct_set_limits, dpif_netlink_ct_get_limits, dpif_netlink_ct_del_limits, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index b8ead8a02..a33c6ec30 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -493,6 +493,10 @@ struct dpif_class { int (*ct_set_tcp_seq_chk)(struct dpif *, bool enabled); /* Get the TCP sequence checking configuration. */ int (*ct_get_tcp_seq_chk)(struct dpif *, bool *enabled); + /* Updates the sweep interval for the CT sweeper. */ + int (*ct_set_sweep_interval)(struct dpif *, uint32_t ms); + /* Get the current value of the sweep interval for the CT sweeper. */ + int (*ct_get_sweep_interval)(struct dpif *, uint32_t *ms); /* Connection tracking per zone limit */ diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 62291de4a..6824ce0bb 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -11721,6 +11721,28 @@ AT_CHECK([tail -1 stdout], [0], OVS_VSWITCHD_STOP AT_CLEANUP +dnl Checks the get/set sweep interval +AT_SETUP([ofproto-dpif - conntrack - change sweep interval]) +OVS_VSWITCHD_START + +# Check the default value. +AT_CHECK([ovs-appctl dpctl/ct-get-sweep-interval], [0], [dnl +20000 +]) + +# Set the interval to 5s. +AT_CHECK([ovs-appctl dpctl/ct-set-sweep-interval 5000], [0], [dnl +setting sweep interval successful +]) + +# Verify that the previous value has been applied. +AT_CHECK([ovs-appctl dpctl/ct-get-sweep-interval], [0], [dnl +5000 +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP + AT_SETUP([ofproto - set mtu]) OVS_VSWITCHD_START |