[ovs-dev] [patch v9 08/11] ipf: Add command to disable fragmentation handling.

Darrell Ball dlu998 at gmail.com
Mon Nov 19 19:09:27 UTC 2018


Commands are added to disable and also enable V4/V6 fragmentation
handling for conntrack, which is enabled by default.

Signed-off-by: Darrell Ball <dlu998 at gmail.com>
---
 NEWS                |  2 ++
 lib/ct-dpif.c       |  8 ++++++++
 lib/ct-dpif.h       |  1 +
 lib/dpctl.c         | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/dpctl.man       |  9 +++++++++
 lib/dpif-netdev.c   |  9 +++++++++
 lib/dpif-netlink.c  |  1 +
 lib/dpif-provider.h |  6 ++++++
 lib/ipf.c           |  7 +++++++
 lib/ipf.h           |  1 +
 10 files changed, 91 insertions(+)

diff --git a/NEWS b/NEWS
index d2e8724..cedc726 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ Post-v2.10.0
      * ovn-ctl: allow passing user:group ids to the OVN daemons.
    - Userspace datapath:
      * Add v4/v6 fragmentation support for conntrack.
+     * New ovs-appctl "dpctl/ipf-set-enabled" and "dpctl/ipf-set-disabled"
+       commands 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 67eccd0..edb14f8 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -194,6 +194,14 @@ ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *zone_limits)
             : EOPNOTSUPP);
 }
 
+int
+ct_dpif_ipf_set_enabled(struct dpif *dpif, bool v6, bool enable)
+{
+    return (dpif->dpif_class->ipf_set_enabled
+            ? dpif->dpif_class->ipf_set_enabled(dpif, v6, enable)
+            : EOPNOTSUPP);
+}
+
 void
 ct_dpif_entry_uninit(struct ct_dpif_entry *entry)
 {
diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h
index decc14f..d61cf71 100644
--- a/lib/ct-dpif.h
+++ b/lib/ct-dpif.h
@@ -212,6 +212,7 @@ int ct_dpif_set_limits(struct dpif *dpif, const uint32_t *default_limit,
 int ct_dpif_get_limits(struct dpif *dpif, uint32_t *default_limit,
                        const struct ovs_list *, struct ovs_list *);
 int ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *);
+int ct_dpif_ipf_set_enabled(struct dpif *, bool v6, bool enable);
 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 59071cd..d6dac73 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1917,6 +1917,51 @@ out:
     return error;
 }
 
+static int
+ipf_set_enabled__(int argc, const char *argv[], struct dpctl_params *dpctl_p,
+                  bool enabled)
+{
+    struct dpif *dpif;
+    int error = opt_dpif_open(argc, argv, dpctl_p, 4, &dpif);
+    if (!error) {
+        char v4_or_v6[3] = {0};
+        if (ovs_scan(argv[argc - 1], "%2s", v4_or_v6) &&
+            (!strncmp(v4_or_v6, "v4", 2) || !strncmp(v4_or_v6, "v6", 2))) {
+            error = ct_dpif_ipf_set_enabled(
+                        dpif, !strncmp(v4_or_v6, "v6", 2), enabled);
+            if (!error) {
+                dpctl_print(dpctl_p,
+                            "%s fragmentation reassembly successful",
+                            enabled ? "enabling" : "disabling");
+            } else {
+                dpctl_error(dpctl_p, error,
+                            "%s fragmentation reassembly failed",
+                            enabled ? "enabling" : "disabling");
+            }
+        } else {
+            error = EINVAL;
+            dpctl_error(dpctl_p, error,
+                        "parameter missing: 'v4' for IPv4 or 'v6' for IPv6");
+        }
+        dpif_close(dpif);
+    }
+    return error;
+}
+
+static int
+dpctl_ipf_set_enabled(int argc, const char *argv[],
+                      struct dpctl_params *dpctl_p)
+{
+    return ipf_set_enabled__(argc, argv, dpctl_p, true);
+}
+
+static int
+dpctl_ipf_set_disabled(int argc, const char *argv[],
+                       struct dpctl_params *dpctl_p)
+{
+    return ipf_set_enabled__(argc, argv, dpctl_p, false);
+}
+
 /* Undocumented commands for unit testing. */
 
 static int
@@ -2222,6 +2267,8 @@ static const struct dpctl_command all_commands[] = {
         DP_RO },
     { "ct-get-limits", "[dp] [zone=N1[,N2]...]", 0, 2, dpctl_ct_get_limits,
         DP_RO },
+    { "ipf-set-enabled", "[dp] v4|v6", 1, 2, dpctl_ipf_set_enabled, DP_RW },
+    { "ipf-set-disabled", "[dp] v4|v6", 1, 2, dpctl_ipf_set_disabled, 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 9b13e0d..32c8259 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -220,6 +220,15 @@ nftables and the regular host stack).  Therefore, the following commands
 do not apply specifically to one datapath.
 .
 .TP
+\*(DX\fBipf\-set\-enabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
+.TQ
+\*(DX\fBipf\-set\-disabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
+Enables or disables IP fragmentation handling for the userspace
+connection tracker.  Either \fBv4\fR or \fBv6\fR must be specified.
+Both IPv4 and IPv6 fragment reassembly are enabled by default.  Only
+supported for the 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 1564db9..56fcd7e 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -47,6 +47,7 @@
 #include "flow.h"
 #include "hmapx.h"
 #include "id-pool.h"
+#include "ipf.h"
 #include "latch.h"
 #include "netdev.h"
 #include "netdev-provider.h"
@@ -6922,6 +6923,13 @@ dpif_netdev_ct_get_nconns(struct dpif *dpif, uint32_t *nconns)
     return conntrack_get_nconns(&dp->conntrack, nconns);
 }
 
+static int
+dpif_netdev_ipf_set_enabled(struct dpif *dpif OVS_UNUSED, bool v6,
+                            bool enable)
+{
+    return ipf_set_enabled(v6, enable);
+}
+
 const struct dpif_class dpif_netdev_class = {
     "netdev",
     dpif_netdev_init,
@@ -6973,6 +6981,7 @@ const struct dpif_class dpif_netdev_class = {
     NULL,                       /* ct_set_limits */
     NULL,                       /* ct_get_limits */
     NULL,                       /* ct_del_limits */
+    dpif_netdev_ipf_set_enabled,
     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 0347060..1f452ff 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -3429,6 +3429,7 @@ const struct dpif_class dpif_netlink_class = {
     dpif_netlink_ct_set_limits,
     dpif_netlink_ct_get_limits,
     dpif_netlink_ct_del_limits,
+    NULL,                       /* ipf_set_enabled */
     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 78e153c..c379bec 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -468,6 +468,12 @@ struct dpif_class {
      * list of 'struct ct_dpif_zone_limit' entries. */
     int (*ct_del_limits)(struct dpif *, const struct ovs_list *zone_limits);
 
+    /* IP Fragmentation. */
+
+    /* Disables or enables conntrack fragment reassembly.  The default
+     * setting is enabled. */
+    int (*ipf_set_enabled)(struct dpif *, bool v6, bool enabled);
+
     /* Meters */
 
     /* Queries 'dpif' for supported meter features.
diff --git a/lib/ipf.c b/lib/ipf.c
index cc8427e..c2f09be 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -1361,3 +1361,10 @@ ipf_destroy(void)
     ipf_lock_unlock(&ipf_lock);
     ipf_lock_destroy(&ipf_lock);
 }
+
+int
+ipf_set_enabled(bool v6, bool enable)
+{
+    atomic_store_relaxed(v6 ? &ifp_v6_enabled : &ifp_v4_enabled, enable);
+    return 0;
+}
diff --git a/lib/ipf.h b/lib/ipf.h
index 040031f..a1673a6 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -29,5 +29,6 @@ void ipf_postprocess_conntrack(struct dp_packet_batch *pb, long long now,
 
 void ipf_init(void);
 void ipf_destroy(void);
+int ipf_set_enabled(bool v6, bool enable);
 
 #endif /* ipf.h */
-- 
1.9.1



More information about the dev mailing list