A new command "ovs-appctl dpctl/ipf-set-maxfrags" is added
for userspace datapath conntrack fragmentation support.

Signed-off-by: Darrell Ball <dlu...@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 e98c990..65ac7ac 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,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 3464afe..12cccba 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] v4_or_v6 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 e78abb4..cddd59a 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -1276,3 +1276,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 277852d..fb24078 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -66,4 +66,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

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to