Commands are added to disable and also enable V4/V6 fragmentation handling for conntrack, which is enabled by default.
Signed-off-by: Darrell Ball <dlu...@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 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev