[ovs-dev] [patch v4 05/10] ipf: Add command to enable fragmentation handling.
Darrell Ball
dlu998 at gmail.com
Tue Jan 30 08:58:46 UTC 2018
A new command "ovs-appctl dpctl/ipf-set-enabled" is added to
enable/disable 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 | 40 ++++++++++++++++++++++++++++++++++++++++
lib/dpctl.man | 11 +++++++++++
lib/dpif-netdev.c | 9 +++++++++
lib/dpif-netlink.c | 1 +
lib/dpif-provider.h | 2 ++
lib/ipf.c | 15 +++++++++++++++
lib/ipf.h | 3 +++
10 files changed, 92 insertions(+)
diff --git a/NEWS b/NEWS
index dccff06..d4859e5 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Post-v2.9.0
- Userspace datapath:
* Add v4/v6 fragmentation support for conntrack.
+ * New "ovs-appctl dpctl/ipf-set-enabled" 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 5fa3a97..32d55c1 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_change_enabled(struct dpif *dpif, bool v6, bool enable)
+{
+ return (dpif->dpif_class->ipf_change_enabled
+ ? dpif->dpif_class->ipf_change_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..3f0bce5 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_change_enabled(struct dpif *, bool, bool);
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 87f0412..a302ed5 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1746,6 +1746,44 @@ dpctl_ct_get_nconns(int argc, const char *argv[],
return error;
}
+static int
+dpctl_ct_ipf_change_enabled(int argc, const char *argv[],
+ struct dpctl_params *dpctl_p)
+{
+ struct dpif *dpif;
+ int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 4);
+ if (!error) {
+ char v4_or_v6[3] = {0};
+ if (ovs_scan(argv[argc - 2], "%2s", v4_or_v6) &&
+ (!strncmp(v4_or_v6, "v4", 2) || !strncmp(v4_or_v6, "v6", 2))) {
+ uint32_t enabled;
+ if (ovs_scan(argv[argc - 1], "%"SCNu32, &enabled)) {
+ error = ct_dpif_ipf_change_enabled(
+ dpif, !strncmp(v4_or_v6, "v6", 2), enabled);
+ if (!error) {
+ dpctl_print(dpctl_p,
+ "changing fragmentation enabled successful");
+ } else {
+ dpctl_error(dpctl_p, error,
+ "changing fragmentation enabled failed");
+ }
+ } else {
+ error = EINVAL;
+ dpctl_error(
+ dpctl_p, error,
+ "parameter missing: 0 for disabled or 1 for enabled");
+ }
+ } else {
+ error = EINVAL;
+ dpctl_error(dpctl_p, error,
+ "parameter missing: v4 for ipv4 or v6 for ipv6");
+ }
+ dpif_close(dpif);
+ }
+
+ return error;
+}
+
/* Undocumented commands for unit testing. */
static int
@@ -2045,6 +2083,8 @@ 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] enabled", 2, 3,
+ dpctl_ct_ipf_change_enabled, 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 9e9d2dc..491de0b 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -268,3 +268,14 @@ Only supported for userspace datapath.
\*(DX\fBct\-get\-nconns\fR [\fIdp\fR]
Read the current number of connection tracker connections.
Only supported for userspace datapath.
+.
+.TP
+\*(DX\fBipf\-set\-enabled\fR [\fIdp\fR] [\fIv4 or v6\fR] \fBenable\fR
+Enables or disables fragmentation handling for the userspace datapath
+connection tracker. Either v4 or v6 must be specified. Both v4 and v6
+are disabled by default. When fragmentation handling is enabled, the
+rules for handling fragments before entering conntrack should not
+differentiate between first and other fragments. Although, this would
+logically happen naturally anyways, it is mentioned for clarity. If there
+is a need to differentiate between first and other fragments, do it after
+conntrack.
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index ba62128..d4d0f07 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-vport.h"
@@ -5871,6 +5872,13 @@ dpif_netdev_ct_get_nconns(struct dpif *dpif, uint32_t *nconns)
return conntrack_get_nconns(&dp->conntrack, nconns);
}
+static int
+dpif_netdev_ipf_change_enabled(struct dpif *dpif OVS_UNUSED, bool v6,
+ bool enable)
+{
+ return ipf_change_enabled(v6, enable);
+}
+
const struct dpif_class dpif_netdev_class = {
"netdev",
dpif_netdev_init,
@@ -5919,6 +5927,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_change_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 f8d75eb..f089617 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -2992,6 +2992,7 @@ const struct dpif_class dpif_netlink_class = {
NULL, /* ct_set_maxconns */
NULL, /* ct_get_maxconns */
NULL, /* ct_get_nconns */
+ NULL, /* ipf_change_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..08e0944 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -444,6 +444,8 @@ struct dpif_class {
/* Get number of connections tracked. */
int (*ct_get_nconns)(struct dpif *, uint32_t *nconns);
+ /* IP Fragmentation. */
+ int (*ipf_change_enabled)(struct dpif *, bool, bool);
/* Meters */
/* Queries 'dpif' for supported meter features.
diff --git a/lib/ipf.c b/lib/ipf.c
index 74c4b32..28920ab 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -1177,3 +1177,18 @@ ipf_destroy(void)
ipf_lock_unlock(&ipf_lock);
ipf_lock_destroy(&ipf_lock);
}
+
+int
+ipf_change_enabled(bool v6, bool enable)
+{
+ if ((v6 != true && v6 != false) ||
+ (enable != true && enable != false)) {
+ return 1;
+ }
+ if (v6) {
+ atomic_store_relaxed(&ifp_v6_enabled, enable);
+ } else {
+ atomic_store_relaxed(&ifp_v4_enabled, enable);
+ }
+ return 0;
+}
diff --git a/lib/ipf.h b/lib/ipf.h
index 1caee1a..d0d25d5 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -58,4 +58,7 @@ ipf_init(void);
void
ipf_destroy(void);
+int
+ipf_change_enabled(bool v6, bool enable);
+
#endif /* ipf.h */
--
1.9.1
More information about the dev
mailing list