[ovs-dev,v8,6/9] ipf: Add command to disable fragmentation handling.

Message ID 1531795191-58140-7-git-send-email-dlu998@gmail.com
State Changes Requested
Headers show
Series
  • Userspace datapath: Add fragmentation support.
Related show

Commit Message

Darrell Ball July 17, 2018, 2:39 a.m.
Commands are added to disable and also enable fragmentation handling
for conntrack.

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

Comments

Justin Pettit Aug. 1, 2018, 9:36 a.m. | #1
> On Jul 16, 2018, at 4:39 PM, Darrell Ball <dlu998@gmail.com> wrote:
> 
> diff --git a/lib/dpctl.man b/lib/dpctl.man
> index 5d987e6..a1eb026 100644
> --- a/lib/dpctl.man
> +++ b/lib/dpctl.man
> @@ -272,3 +272,18 @@ Only supported for userspace datapath.
> \*(DX\fBct\-get\-nconns\fR [\fIdp\fR]
> Prints the current number of connection tracker entries on \fIdp\fR.
> Only supported for userspace datapath.
> +.
> +.TP
> +\*(DX\fBipf\-set\-enabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
> +Enables fragmentation handling for the userspace datapath connection
> +tracker.  Either \fBv4\fR or \fBv6\fR must be specified.  When fragmentation
> +handling is enabled, the rules for handling fragments before entering
> +conntrack should not differentiate between first and other fragments.  If
> +there is a need to differentiate between first and other fragments, do it
> +after conntrack.  Both v4 and v6 are enabled by default.

I'm not sure that I understand the two sentences that begins at "When fragmentation handling is enabled..."  It's a great idea to explain what users should expect with the fragment reassembly and how the userspace implementation may differ from the kernel one.  However, I think that would better fit in "Documentation/topics/design.rst" instead of this man page fragment.

Let's remove it from here.  Can you add the appropriate documentation to that design file?

> +\*(DX\fBipf\-set\-disabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
> +Disables fragmentation handling for the userspace datapath connection
> +tracker.  Either \fBv4\fR or \fBv6\fR must be specified.  Both v4 and v6 are
> +enabled by default.

I think we can combine these two commands into one group, which will make it a bit more compact.

I'd like to commit it with the incremental at the bottom of this message.

--Justin


-=-=-=-=-=-=-=-=-

diff --git a/NEWS b/NEWS
index 2d79a2aac6cd..f5fe0ef9f392 100644
--- a/NEWS
+++ b/NEWS
@@ -20,10 +20,8 @@ v2.10.0 - xx xxx xxxx
        use --names or --no-names to override.  See ovs-ofctl(8) for details.
    - Userspace datapath:
      * Add v4/v6 fragmentation support for conntrack.
-     * New "ovs-appctl dpctl/ipf-set-enabled" command for userspace datapath
-       conntrack fragmentation support.
-     * New "ovs-appctl dpctl/ipf-set-disabled" command for userspace datapath
-       conntrack fragmentation support.
+     * New ovs-appctl "dpctl/ipf-set-enabled" and "dpctl/ipf-set-disabled"
+       commands for userspace datapath conntrack fragmentation support.
    - ovs-vsctl: New commands "add-bond-iface" and "del-bond-iface".
    - OpenFlow:
      * OFPT_ROLE_STATUS is now available in OpenFlow 1.3.
diff --git a/lib/dpctl.c b/lib/dpctl.c
index d6800fb2db99..1d3a8f80268e 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1705,7 +1705,7 @@ ipf_set_enabled__(int argc, const char *argv[], struct dpctl_params *dpctl_p,
         } else {
             error = EINVAL;
             dpctl_error(dpctl_p, error,
-                        "parameter missing: 'v4' for ipv4 or 'v6' for ipv6");
+                        "parameter missing: 'v4' for IPv4 or 'v6' for IPv6");
         }
         dpif_close(dpif);
     }
diff --git a/lib/dpctl.man b/lib/dpctl.man
index a1eb0260be18..c231cff7d161 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -275,15 +275,9 @@ Only supported for userspace datapath.
 .
 .TP
 \*(DX\fBipf\-set\-enabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
-Enables fragmentation handling for the userspace datapath connection
-tracker.  Either \fBv4\fR or \fBv6\fR must be specified.  When fragmentation
-handling is enabled, the rules for handling fragments before entering
-conntrack should not differentiate between first and other fragments.  If
-there is a need to differentiate between first and other fragments, do it
-after conntrack.  Both v4 and v6 are enabled by default.
-.
-.TP
+.TQ
 \*(DX\fBipf\-set\-disabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
-Disables fragmentation handling for the userspace datapath connection
-tracker.  Either \fBv4\fR or \fBv6\fR must be specified.  Both v4 and v6 are
-enabled by default.
+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 userspace datapath.

Patch

diff --git a/NEWS b/NEWS
index 9c82234..104b16f 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,10 @@  Post-v2.9.0
        use --names or --no-names to override.  See ovs-ofctl(8) for details.
    - Userspace datapath:
      * Add v4/v6 fragmentation support for conntrack.
+     * New "ovs-appctl dpctl/ipf-set-enabled" command for userspace datapath
+       conntrack fragmentation support.
+     * New "ovs-appctl dpctl/ipf-set-disabled" command for userspace datapath
+       conntrack fragmentation support.
    - ovs-vsctl: New commands "add-bond-iface" and "del-bond-iface".
    - OpenFlow:
      * OFPT_ROLE_STATUS is now available in OpenFlow 1.3.
diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c
index 5fa3a97..b1f29dc 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -164,6 +164,14 @@  ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns)
             : 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 09e7698..bd6234d 100644
--- a/lib/ct-dpif.h
+++ b/lib/ct-dpif.h
@@ -200,6 +200,7 @@  int ct_dpif_flush(struct dpif *, const uint16_t *zone,
 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_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 4f1e443..d6800fb 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -35,6 +35,7 @@ 
 #include "dpif.h"
 #include "openvswitch/dynamic-string.h"
 #include "flow.h"
+#include "ipf.h"
 #include "openvswitch/match.h"
 #include "netdev.h"
 #include "netdev-dpdk.h"
@@ -1680,6 +1681,51 @@  dpctl_ct_get_nconns(int argc, const char *argv[],
     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
@@ -1979,6 +2025,10 @@  static const struct dpctl_command all_commands[] = {
     { "ct-set-maxconns", "[dp] maxconns", 1, 2, dpctl_ct_set_maxconns, DP_RW },
     { "ct-get-maxconns", "[dp]", 0, 1, dpctl_ct_get_maxconns, DP_RO },
     { "ct-get-nconns", "[dp]", 0, 1, dpctl_ct_get_nconns, 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 5d987e6..a1eb026 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -272,3 +272,18 @@  Only supported for userspace datapath.
 \*(DX\fBct\-get\-nconns\fR [\fIdp\fR]
 Prints the current number of connection tracker entries on \fIdp\fR.
 Only supported for userspace datapath.
+.
+.TP
+\*(DX\fBipf\-set\-enabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
+Enables fragmentation handling for the userspace datapath connection
+tracker.  Either \fBv4\fR or \fBv6\fR must be specified.  When fragmentation
+handling is enabled, the rules for handling fragments before entering
+conntrack should not differentiate between first and other fragments.  If
+there is a need to differentiate between first and other fragments, do it
+after conntrack.  Both v4 and v6 are enabled by default.
+.
+.TP
+\*(DX\fBipf\-set\-disabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
+Disables fragmentation handling for the userspace datapath connection
+tracker.  Either \fBv4\fR or \fBv6\fR must be specified.  Both v4 and v6 are
+enabled by default.
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 8b3556d..ddab09e 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"
@@ -6531,6 +6532,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,
@@ -6579,6 +6587,7 @@  const struct dpif_class dpif_netdev_class = {
     dpif_netdev_ct_set_maxconns,
     dpif_netdev_ct_get_maxconns,
     dpif_netdev_ct_get_nconns,
+    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 aa9bbd9..e1331e4 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -3006,6 +3006,7 @@  const struct dpif_class dpif_netlink_class = {
     NULL,                       /* ct_set_maxconns */
     NULL,                       /* ct_get_maxconns */
     NULL,                       /* ct_get_nconns */
+    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 62b3598..db65227 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -444,8 +444,10 @@  struct dpif_class {
     /* Get number of connections tracked. */
     int (*ct_get_nconns)(struct dpif *, uint32_t *nconns);
 
-    /* Meters */
+    /* IP Fragmentation. */
+    int (*ipf_set_enabled)(struct dpif *, bool v6, bool enabled);
 
+    /* Meters */
     /* Queries 'dpif' for supported meter features.
      * NULL pointer means no meter features are supported. */
     void (*meter_get_features)(const struct dpif *,
diff --git a/lib/ipf.c b/lib/ipf.c
index 1169a8a..cc76c99 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -1297,3 +1297,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 212d1b3..da47dcb 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -57,4 +57,6 @@  void ipf_init(void);
 
 void ipf_destroy(void);
 
+int ipf_set_enabled(bool v6, bool enable);
+
 #endif /* ipf.h */