A new command "ovs-appctl dpctl/ipf-set-minfragment" 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         | 31 +++++++++++++++++++++++++++++++
 lib/dpctl.man       |  6 ++++++
 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, 72 insertions(+)

diff --git a/NEWS b/NEWS
index cafd3bb..35bf759 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ Post-v2.9.0
      * Add v4 fragmentation support for conntrack.
      * New "ovs-appctl dpctl/ipf-set-enabled" command for userspace datapath
        conntrack fragmentation support.
+     * New "ovs-appctl dpctl/ipf-set-minfragment" 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 f8fc632..ecc8281 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -172,6 +172,14 @@ ct_dpif_ipf_change_enabled(struct dpif *dpif, bool enable)
             : EOPNOTSUPP);
 }
 
+int
+ct_dpif_ipf_set_min_frag(struct dpif *dpif, uint32_t min_frag)
+{
+    return (dpif->dpif_class->ipf_set_min_frag
+            ? dpif->dpif_class->ipf_set_min_frag(dpif, min_frag)
+            : EOPNOTSUPP);
+}
+
 void
 ct_dpif_entry_uninit(struct ct_dpif_entry *entry)
 {
diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h
index 0737ad7..2844306 100644
--- a/lib/ct-dpif.h
+++ b/lib/ct-dpif.h
@@ -201,6 +201,7 @@ int ct_dpif_set_maxconns(struct dpif *dpif, uint32_t 
maxconns);
 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);
 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 e0a2eee..98b1185 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1775,6 +1775,35 @@ dpctl_ct_ipf_change_enabled(int argc, const char *argv[],
     return error;
 }
 
+static int
+dpctl_ct_ipf_set_min_frag(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 min_fragment;
+        if (ovs_scan(argv[argc - 1], "%"SCNu32, &min_fragment)) {
+            error = ct_dpif_ipf_set_min_frag(dpif, min_fragment);
+
+            if (!error) {
+                dpctl_print(dpctl_p,
+                            "setting minimum fragment size successful");
+            } else {
+                dpctl_error(dpctl_p, error,
+                            "setting minimum fragment size failed");
+            }
+        } else {
+            error = EINVAL;
+            dpctl_error(dpctl_p, error,
+                        "parameter missing for minimum fragment size");
+        }
+        dpif_close(dpif);
+    }
+
+    return error;
+}
+
 /* Undocumented commands for unit testing. */
 
 static int
@@ -2076,6 +2105,8 @@ static const struct dpctl_command all_commands[] = {
     { "ct-get-nconns", "[dp]", 0, 1, dpctl_ct_get_nconns, DP_RO },
     { "ipf-set-enabled", "[dp] enabled", 1, 2,
        dpctl_ct_ipf_change_enabled, DP_RW },
+    { "ipf-set-minfragment", "[dp] minfragment", 1, 2,
+       dpctl_ct_ipf_set_min_frag, 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 a427108..b5c8408 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -272,3 +272,9 @@ Only supported for userspace datapath.
 \*(DX\fBipf\-set\-enabled\fR [\fIdp\fR] \fBparam\fR
 Enables or disables fragmentation handling for the userspace datapath
 connection tracker.  Disabled by default.
+.
+.TP
+\*(DX\fBipf\-set\-minfragment\fR [\fIdp\fR] \fBparam\fR
+Sets the minimum fragment size supported by the userspace datapath
+connection tracker.  The default value is 1200 and the clamped
+minimum is 400.
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 68b5d52..52562fc 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -5878,6 +5878,13 @@ dpif_netdev_ipf_change_enabled(struct dpif *dpif 
OVS_UNUSED, bool enable)
     return ipf_change_enabled(enable);
 }
 
+static int
+dpif_netdev_ipf_set_min_frag(struct dpif *dpif OVS_UNUSED,
+                             uint32_t min_frag)
+{
+    return ipf_set_min_frag(min_frag);
+}
+
 const struct dpif_class dpif_netdev_class = {
     "netdev",
     dpif_netdev_init,
@@ -5927,6 +5934,7 @@ const struct dpif_class dpif_netdev_class = {
     dpif_netdev_ct_get_maxconns,
     dpif_netdev_ct_get_nconns,
     dpif_netdev_ipf_change_enabled,
+    dpif_netdev_ipf_set_min_frag,
     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 f089617..8366de8 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -2993,6 +2993,7 @@ const struct dpif_class dpif_netlink_class = {
     NULL,                       /* ct_get_maxconns */
     NULL,                       /* ct_get_nconns */
     NULL,                       /* ipf_change_enabled */
+    NULL,                       /* ipf_set_min_frag */
     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 fcea867..01988d8 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -447,6 +447,8 @@ struct dpif_class {
 
     /* IP Fragmentation. */
     int (*ipf_change_enabled)(struct dpif *, bool);
+    /* Set minimum fragment allowed. */
+    int (*ipf_set_min_frag)(struct dpif *, uint32_t);
 
     /* Meters */
 
diff --git a/lib/ipf.c b/lib/ipf.c
index dea34bb..f55f83a 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -863,3 +863,13 @@ ipf_change_enabled(bool enable)
     atomic_store_relaxed(&ifp_enabled, enable);
     return 0;
 }
+
+int
+ipf_set_min_frag(uint32_t value)
+{
+    if (value < FRAG_SIZE_LOWER_BOUND) {
+        return 1;
+    }
+    atomic_store_relaxed(&min_frag_size, value);
+    return 0;
+}
diff --git a/lib/ipf.h b/lib/ipf.h
index 63eb4a0..7ca233a 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -53,4 +53,7 @@ ipf_destroy(void);
 int
 ipf_change_enabled(bool enable);
 
+int
+ipf_set_min_frag(uint32_t value);
+
 #endif /* ipf.h */
-- 
1.9.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to