[ovs-dev] [patch v7 8/9] ipf: Add set maximum fragments supported command.
Darrell Ball
dlu998 at gmail.com
Mon Jul 9 22:29:22 UTC 2018
A new command "ovs-appctl dpctl/ipf-set-max-nfrags" 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 | 30 ++++++++++++++++++++++++++++++
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 | 2 ++
10 files changed, 72 insertions(+)
diff --git a/NEWS b/NEWS
index 9ab9970..2b22a84 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,8 @@ Post-v2.9.0
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.
- ovs-vsctl: New commands "add-bond-iface" and "del-bond-iface".
- OpenFlow:
* OFPT_ROLE_STATUS is now available in OpenFlow 1.3.
diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c
index d5596af..ee23a4d 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_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 6eb55b4..f886ab9 100644
--- a/lib/ct-dpif.h
+++ b/lib/ct-dpif.h
@@ -203,6 +203,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_set_enabled(struct dpif *, bool v6, bool enable);
int ct_dpif_ipf_set_min_frag(struct dpif *, bool, uint32_t);
+int ct_dpif_ipf_set_max_nfrags(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 e74d713..ab0f60b 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1764,6 +1764,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
@@ -2069,6 +2097,8 @@ static const struct dpctl_command all_commands[] = {
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 900900d..c6c4a87 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -296,3 +296,11 @@ must be specified. The default v4 value is 1200 and the clamped minimum is
400. The default v6 value is 1280, with a clamped minimum of 400, for
testing flexibility. The maximum frag size is not clamped, however setting
this value too high might result in valid fragments being dropped.
+.
+.TP
+\*(DX\fBipf\-set\-max\-nfrags\fR [\fIdp\fR] \fImaxfrags\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 653c313..76bc1d9 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -6546,6 +6546,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,
@@ -6596,6 +6603,7 @@ const struct dpif_class dpif_netdev_class = {
dpif_netdev_ct_get_nconns,
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 043398d..80c54f5 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -3008,6 +3008,7 @@ const struct dpif_class dpif_netlink_class = {
NULL, /* ct_get_nconns */
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 62a4574..214f570 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -449,6 +449,8 @@ struct dpif_class {
int (*ipf_set_enabled)(struct dpif *, bool v6, bool enabled);
/* 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 2b435c7..ef3236a 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -1294,3 +1294,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 fa6da5d..4289e5e 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -61,4 +61,6 @@ 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
More information about the dev
mailing list