A new command "ovs-appctl dpctl/ipf-set-max-nfrags" is added for userspace datapath conntrack fragmentation support.
Signed-off-by: Darrell Ball <[email protected]> --- NEWS | 2 ++ lib/ct-dpif.c | 8 ++++++++ lib/ct-dpif.h | 1 + lib/dpctl.c | 30 ++++++++++++++++++++++++++++++ lib/dpctl.man | 9 +++++++++ lib/dpif-netdev.c | 8 ++++++++ lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 3 +++ lib/ipf.c | 10 ++++++++++ lib/ipf.h | 1 + 10 files changed, 73 insertions(+) diff --git a/NEWS b/NEWS index ea354a1..a64e0a5 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ Post-v2.10.0 commands for userspace datapath conntrack fragmentation support. * New "ovs-appctl dpctl/ipf-set-min-frag" command for userspace datapath conntrack fragmentation support. + * New "ovs-appctl dpctl/ipf-set-max-nfrags" command for userspace datapath + conntrack fragmentation support. - DPDK: * Add option for simple round-robin based Rxq to PMD assignment. It can be set with pmd-rxq-assign. diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c index d3dad70..aa34feb 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -210,6 +210,14 @@ ct_dpif_ipf_set_min_frag(struct dpif *dpif, bool v6, uint32_t min_frag) : EOPNOTSUPP); } +int +ct_dpif_ipf_set_max_nfrags(struct dpif *dpif, uint32_t max_frags) +{ + return (dpif->dpif_class->ipf_set_max_nfrags + ? dpif->dpif_class->ipf_set_max_nfrags(dpif, max_frags) + : EOPNOTSUPP); +} + void ct_dpif_entry_uninit(struct ct_dpif_entry *entry) { diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h index dca75b7..d104e8a 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -214,6 +214,7 @@ int ct_dpif_get_limits(struct dpif *dpif, uint32_t *default_limit, int ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *); 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); 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); diff --git a/lib/dpctl.c b/lib/dpctl.c index 72d6c45..e020234 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -2000,6 +2000,34 @@ dpctl_ipf_set_min_frag(int argc, const char *argv[], return error; } +static int +dpctl_ipf_set_max_nfrags(int argc, const char *argv[], + struct dpctl_params *dpctl_p) +{ + struct dpif *dpif; + int error = opt_dpif_open(argc, argv, dpctl_p, 3, &dpif); + if (!error) { + uint32_t nfrags_max; + if (ovs_scan(argv[argc - 1], "%"SCNu32, &nfrags_max)) { + error = ct_dpif_ipf_set_max_nfrags(dpif, nfrags_max); + if (!error) { + dpctl_print(dpctl_p, + "setting maximum fragments successful"); + } else { + dpctl_error(dpctl_p, error, + "setting maximum fragments failed"); + } + } else { + error = EINVAL; + dpctl_error(dpctl_p, error, + "parameter missing for maximum fragments"); + } + dpif_close(dpif); + } + + return error; +} + /* Undocumented commands for unit testing. */ static int @@ -2309,6 +2337,8 @@ static const struct dpctl_command all_commands[] = { { "ipf-set-disabled", "[dp] v4|v6", 1, 2, dpctl_ipf_set_disabled, DP_RW }, { "ipf-set-min-frag", "[dp] v4|v6 minfragment", 2, 3, dpctl_ipf_set_min_frag, DP_RW }, + { "ipf-set-max-nfrags", "[dp] maxfrags", 1, 2, + dpctl_ipf_set_max_nfrags, DP_RW }, { "help", "", 0, INT_MAX, dpctl_help, DP_RO }, { "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO }, diff --git a/lib/dpctl.man b/lib/dpctl.man index 9bfc8a4..43eb45f 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -240,6 +240,15 @@ this value too high might result in valid fragments being dropped. Only supported for userspace datapath. . .TP +\*(DX\fBipf\-set\-max\-nfrags\fR [\fIdp\fR] \fImaxfrags\fR +Sets the maximum number of fragments tracked by the userspace datapath +connection tracker to \fImaxfrags\fR. The default value is 1000 and the +clamped maximum is 5000. Note that packet buffers can be held by the +fragmentation module while fragments are incomplete, but will timeout +after 15 seconds. Memory pool sizing should be set accordingly when +fragmentation is enabled. Only supported for userspace datapath. +. +.TP .DO "[\fB\-m\fR | \fB\-\-more\fR] [\fB\-s\fR | \fB\-\-statistics\fR]" "\*(DX\fBdump\-conntrack\fR" "[\fIdp\fR] [\fBzone=\fIzone\fR]" Prints to the console all the connection entries in the tracker used by \fIdp\fR. If \fBzone=\fIzone\fR is specified, only shows the connections diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index ebb316c..221ce18 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -6937,6 +6937,13 @@ dpif_netdev_ipf_set_min_frag(struct dpif *dpif OVS_UNUSED, bool v6, return ipf_set_min_frag(v6, min_frag); } +static int +dpif_netdev_ipf_set_max_nfrags(struct dpif *dpif OVS_UNUSED, + uint32_t max_frags) +{ + return ipf_set_max_nfrags(max_frags); +} + const struct dpif_class dpif_netdev_class = { "netdev", dpif_netdev_init, @@ -6990,6 +6997,7 @@ const struct dpif_class dpif_netdev_class = { NULL, /* ct_del_limits */ dpif_netdev_ipf_set_enabled, dpif_netdev_ipf_set_min_frag, + dpif_netdev_ipf_set_max_nfrags, dpif_netdev_meter_get_features, dpif_netdev_meter_set, dpif_netdev_meter_get, diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 30f5acf..b08eea1 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -3431,6 +3431,7 @@ const struct dpif_class dpif_netlink_class = { dpif_netlink_ct_del_limits, NULL, /* ipf_set_enabled */ NULL, /* ipf_set_min_frag */ + NULL, /* ipf_set_max_nfrags */ dpif_netlink_meter_get_features, dpif_netlink_meter_set, dpif_netlink_meter_get, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 28a6a97..7cc7804 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -477,6 +477,9 @@ struct dpif_class { /* Set minimum fragment allowed. */ int (*ipf_set_min_frag)(struct dpif *, bool v6, uint32_t min_frag); + /* Set maximum number of fragments tracked. */ + int (*ipf_set_max_nfrags)(struct dpif *, uint32_t max_nfrags); + /* Meters */ /* Queries 'dpif' for supported meter features. diff --git a/lib/ipf.c b/lib/ipf.c index f9d2de6..b3f5045 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -1391,3 +1391,13 @@ ipf_set_min_frag(bool v6, uint32_t value) ipf_lock_unlock(&ipf_lock); return 0; } + +int +ipf_set_max_nfrags(uint32_t value) +{ + if (value > IPF_NFRAG_UBOUND) { + return 1; + } + atomic_store_relaxed(&nfrag_max, value); + return 0; +} diff --git a/lib/ipf.h b/lib/ipf.h index cf221f1..6cf4d1e 100644 --- a/lib/ipf.h +++ b/lib/ipf.h @@ -31,5 +31,6 @@ void ipf_init(void); void ipf_destroy(void); int ipf_set_enabled(bool v6, bool enable); int ipf_set_min_frag(bool v6, uint32_t value); +int ipf_set_max_nfrags(uint32_t value); #endif /* ipf.h */ -- 1.9.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
