[ovs-dev] [patch v3 6/9] ipf: Add set maximum fragments supported command.

Darrell Ball dlu998 at gmail.com
Fri Jan 26 02:05:06 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 9b2d38b..0d37f8a 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,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 ecc8281..b3f9183 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -180,6 +180,14 @@ ct_dpif_ipf_set_min_frag(struct dpif *dpif, 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 2844306..a2a82fe 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);
 int ct_dpif_ipf_set_min_frag(struct dpif *, 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 98b1185..0b2a5fc 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1804,6 +1804,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
@@ -2107,6 +2136,8 @@ static const struct dpctl_command all_commands[] = {
        dpctl_ct_ipf_change_enabled, DP_RW },
     { "ipf-set-minfragment", "[dp] minfragment", 1, 2,
        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 cffb53c..bce341a 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -284,3 +284,11 @@ first and other fragments, do it after conntrack.
 Sets the minimum fragment size supported by the userspace datapath
 connection tracker.  The default value is 1200 and the clamped
 minimum is 400.
+.
+.TP
+\*(DX\fBipf\-set\-maxfrags\fR [\fIdp\fR] \fBparam\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 52562fc..8635208 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -5885,6 +5885,13 @@ dpif_netdev_ipf_set_min_frag(struct dpif *dpif OVS_UNUSED,
     return ipf_set_min_frag(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,
@@ -5935,6 +5942,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 3b922b4..47141e7 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);
     /* Set minimum fragment allowed. */
     int (*ipf_set_min_frag)(struct dpif *, 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 94fccaa..ece40cc 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -894,3 +894,13 @@ ipf_set_min_frag(uint32_t value)
     ipf_lock_unlock(&ipf_lock);
     return 0;
 }
+
+int
+ipf_set_nfrag_max(uint32_t value)
+{
+    if (value > NFRAG_UPPER_BOUND) {
+        return 1;
+    }
+    atomic_store_relaxed(&nfrag_max, value);
+    return 0;
+}
diff --git a/lib/ipf.h b/lib/ipf.h
index 7ca233a..60be24d 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -56,4 +56,7 @@ ipf_change_enabled(bool enable);
 int
 ipf_set_min_frag(uint32_t value);
 
+int
+ipf_set_nfrag_max(uint32_t value);
+
 #endif /* ipf.h */
-- 
1.9.1



More information about the dev mailing list