[ovs-dev] [patch v9 10/11] ipf: Add set maximum fragments supported command.

Darrell Ball dlu998 at gmail.com
Mon Nov 19 19:09:29 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       |  9 +++++++++
 lib/dpif-netdev.c   |  8 ++++++++
 lib/dpif-netlink.c  |  1 +
 lib/dpif-provider.h |  3 +++
 lib/ipf.c           | 10 ++++++++++
 lib/ipf.h           |  1 +
 10 files changed, 73 insertions(+)

diff --git a/NEWS b/NEWS
index ea354a1..a64e0a5 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,8 @@ Post-v2.10.0
        commands for userspace datapath 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.
    - DPDK:
      * Add option for simple round-robin based Rxq to PMD assignment.
        It can be set with pmd-rxq-assign.
diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c
index d3dad70..aa34feb 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -210,6 +210,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 dca75b7..d104e8a 100644
--- a/lib/ct-dpif.h
+++ b/lib/ct-dpif.h
@@ -214,6 +214,7 @@ int ct_dpif_get_limits(struct dpif *dpif, uint32_t *default_limit,
 int ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *);
 int ct_dpif_ipf_set_enabled(struct dpif *, bool v6, bool enable);
 int ct_dpif_ipf_set_min_frag(struct dpif *, bool v6, uint32_t min_frag);
+int ct_dpif_ipf_set_max_nfrags(struct dpif *, uint32_t max_frags);
 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 72d6c45..e020234 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -2000,6 +2000,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
@@ -2309,6 +2337,8 @@ static const struct dpctl_command all_commands[] = {
     { "ipf-set-disabled", "[dp] v4|v6", 1, 2, 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 9bfc8a4..43eb45f 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -240,6 +240,15 @@ this value too high might result in valid fragments being dropped.  Only
 supported for userspace datapath.
 .
 .TP
+\*(DX\fBipf\-set\-max\-nfrags\fR [\fIdp\fR] \fImaxfrags\fR
+Sets the maximum number of fragments tracked by the userspace datapath
+connection tracker to \fImaxfrags\fR.  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.  Only supported for userspace datapath.
+.
+.TP
 .DO "[\fB\-m\fR | \fB\-\-more\fR] [\fB\-s\fR | \fB\-\-statistics\fR]" "\*(DX\fBdump\-conntrack\fR" "[\fIdp\fR] [\fBzone=\fIzone\fR]"
 Prints to the console all the connection entries in the tracker used by
 \fIdp\fR.  If \fBzone=\fIzone\fR is specified, only shows the connections
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index ebb316c..221ce18 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -6937,6 +6937,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,
@@ -6990,6 +6997,7 @@ const struct dpif_class dpif_netdev_class = {
     NULL,                       /* ct_del_limits */
     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 30f5acf..b08eea1 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -3431,6 +3431,7 @@ const struct dpif_class dpif_netlink_class = {
     dpif_netlink_ct_del_limits,
     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 28a6a97..7cc7804 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -477,6 +477,9 @@ struct dpif_class {
     /* 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 f9d2de6..b3f5045 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -1391,3 +1391,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 cf221f1..6cf4d1e 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -31,5 +31,6 @@ void ipf_init(void);
 void ipf_destroy(void);
 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