[ovs-dev] [patch v4 07/10] ipf: Add set maximum fragments supported command.
Darrell Ball
dlu998 at gmail.com
Tue Jan 30 08:58:48 UTC 2018
A new command "ovs-appctl dpctl/ipf-set-maxfrags" is added
for userspace datapath conntrack fragmentation support.
Signed-off-by: Darrell Ball <dlu998 at gmail.com>
---
NEWS | 2 ++
lib/ct-dpif.c | 8 ++++++++
lib/ct-dpif.h | 1 +
lib/dpctl.c | 31 +++++++++++++++++++++++++++++++
lib/dpctl.man | 8 ++++++++
lib/dpif-netdev.c | 8 ++++++++
lib/dpif-netlink.c | 1 +
lib/dpif-provider.h | 2 ++
lib/ipf.c | 10 ++++++++++
lib/ipf.h | 3 +++
10 files changed, 74 insertions(+)
diff --git a/NEWS b/NEWS
index d2107a8..044f1ab 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ Post-v2.9.0
conntrack fragmentation support.
* New "ovs-appctl dpctl/ipf-set-minfragment" command for userspace
datapath conntrack fragmentation support.
+ * New "ovs-appctl dpctl/ipf-set-maxfrags" command for userspace datapath
+ conntrack fragmentation support.
v2.9.0 - xx xxx xxxx
--------------------
diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c
index 4a93bf6..81f9d92 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -180,6 +180,14 @@ ct_dpif_ipf_set_min_frag(struct dpif *dpif, bool v6, uint32_t min_frag)
: EOPNOTSUPP);
}
+int
+ct_dpif_ipf_set_nfrag_max(struct dpif *dpif, uint32_t max_frags)
+{
+ return (dpif->dpif_class->ipf_set_nfrag_max
+ ? dpif->dpif_class->ipf_set_nfrag_max(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 449f958..4ce4dd4 100644
--- a/lib/ct-dpif.h
+++ b/lib/ct-dpif.h
@@ -202,6 +202,7 @@ int ct_dpif_get_maxconns(struct dpif *dpif, uint32_t *maxconns);
int ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns);
int ct_dpif_ipf_change_enabled(struct dpif *, bool, bool);
int ct_dpif_ipf_set_min_frag(struct dpif *, bool, uint32_t);
+int ct_dpif_ipf_set_nfrag_max(struct dpif *, uint32_t);
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 e15626d..e58917c 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1822,6 +1822,35 @@ dpctl_ct_ipf_set_min_frag(int argc, const char *argv[],
return error;
}
+static int
+dpctl_ct_ipf_set_nfrag_max(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 nfrags_max;
+ if (ovs_scan(argv[argc - 1], "%"SCNu32, &nfrags_max)) {
+ error = ct_dpif_ipf_set_nfrag_max(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
@@ -2125,6 +2154,8 @@ static const struct dpctl_command all_commands[] = {
dpctl_ct_ipf_change_enabled, DP_RW },
{ "ipf-set-minfragment", "[dp] minfragment", 2, 3,
dpctl_ct_ipf_set_min_frag, DP_RW },
+ { "ipf-set-maxfrags", "[dp] maxfrags", 1, 2,
+ dpctl_ct_ipf_set_nfrag_max, 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 87067f9..53b3cdc 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -286,3 +286,11 @@ Sets the minimum fragment size supported by the userspace datapath
connection tracker. Either v4 or v6 must be specified. The default v4
value is 1200 and the clamped minimum is 400. The default v6 value is
1280, which is also the clamped minimum.
+.
+.TP
+\*(DX\fBipf\-set\-maxfrags\fR [\fIdp\fR] \fBmaxfrags\fR
+Sets the maximum number of fragments tracked by the userspace datapath
+connection tracker. 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.
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 44e511f..925917d 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -5886,6 +5886,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_nfrag_max(struct dpif *dpif OVS_UNUSED,
+ uint32_t max_frags)
+{
+ return ipf_set_nfrag_max(max_frags);
+}
+
const struct dpif_class dpif_netdev_class = {
"netdev",
dpif_netdev_init,
@@ -5936,6 +5943,7 @@ const struct dpif_class dpif_netdev_class = {
dpif_netdev_ct_get_nconns,
dpif_netdev_ipf_change_enabled,
dpif_netdev_ipf_set_min_frag,
+ dpif_netdev_ipf_set_nfrag_max,
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 8366de8..6fd3ea8 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -2994,6 +2994,7 @@ const struct dpif_class dpif_netlink_class = {
NULL, /* ct_get_nconns */
NULL, /* ipf_change_enabled */
NULL, /* ipf_set_min_frag */
+ NULL, /* ipf_set_nfrag_max */
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 aa9c490..7679169 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -448,6 +448,8 @@ struct dpif_class {
int (*ipf_change_enabled)(struct dpif *, bool, bool);
/* Set minimum fragment allowed. */
int (*ipf_set_min_frag)(struct dpif *, bool, uint32_t);
+ /* Set maximum number of fragments tracked. */
+ int (*ipf_set_nfrag_max)(struct dpif *, uint32_t);
/* Meters */
/* Queries 'dpif' for supported meter features.
diff --git a/lib/ipf.c b/lib/ipf.c
index 5647f50..25df533 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -1215,3 +1215,13 @@ ipf_set_min_frag(bool v6, uint32_t value)
ipf_lock_unlock(&ipf_lock);
return 0;
}
+
+int
+ipf_set_nfrag_max(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 c803209..2c296f1 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -64,4 +64,7 @@ ipf_change_enabled(bool v6, bool enable);
int
ipf_set_min_frag(bool v6, uint32_t value);
+int
+ipf_set_nfrag_max(uint32_t value);
+
#endif /* ipf.h */
--
1.9.1
More information about the dev
mailing list