A new command "ovs-appctl dpctl/ipf-set-max-nfrags" is added for userspace datapath conntrack fragmentation support.
Signed-off-by: Darrell Ball <dlu...@gmail.com> --- NEWS | 2 ++ lib/ct-dpif.c | 8 ++++++++ lib/ct-dpif.h | 1 + lib/dpctl.c | 30 ++++++++++++++++++++++++++++++ lib/dpctl.man | 8 ++++++++ lib/dpif-netdev.c | 8 ++++++++ lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 2 ++ lib/ipf.c | 10 ++++++++++ lib/ipf.h | 2 ++ 10 files changed, 72 insertions(+) diff --git a/NEWS b/NEWS index 9ab9970..2b22a84 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,8 @@ Post-v2.9.0 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. - 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 d5596af..ee23a4d 100644 --- a/lib/ct-dpif.c +++ b/lib/ct-dpif.c @@ -180,6 +180,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 f8a3192..2286dfb 100644 --- a/lib/ct-dpif.h +++ b/lib/ct-dpif.h @@ -202,6 +202,7 @@ 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); int ct_dpif_ipf_set_min_frag(struct dpif *, bool, uint32_t); +int ct_dpif_ipf_set_max_nfrags(struct dpif *, uint32_t); 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 e74d713..ab0f60b 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1764,6 +1764,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 @@ -2069,6 +2097,8 @@ static const struct dpctl_command all_commands[] = { 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 900900d..c6c4a87 100644 --- a/lib/dpctl.man +++ b/lib/dpctl.man @@ -296,3 +296,11 @@ must be specified. The default v4 value is 1200 and the clamped minimum is 400. The default v6 value is 1280, with a clamped minimum of 400, for testing flexibility. The maximum frag size is not clamped, however setting this value too high might result in valid fragments being dropped. +. +.TP +\*(DX\fBipf\-set\-max\-nfrags\fR [\fIdp\fR] \fImaxfrags\fR +Sets the maximum number of fragments tracked by the userspace datapath +connection tracker. 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. diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 653c313..76bc1d9 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -6546,6 +6546,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, @@ -6596,6 +6603,7 @@ const struct dpif_class dpif_netdev_class = { dpif_netdev_ct_get_nconns, 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 043398d..80c54f5 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -3008,6 +3008,7 @@ const struct dpif_class dpif_netlink_class = { NULL, /* ct_get_nconns */ 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 2bd375b..10b39ca 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -448,6 +448,8 @@ struct dpif_class { int (*ipf_set_enabled)(struct dpif *, bool v6, bool enabled); /* 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 2b435c7..ef3236a 100644 --- a/lib/ipf.c +++ b/lib/ipf.c @@ -1294,3 +1294,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 fa6da5d..4289e5e 100644 --- a/lib/ipf.h +++ b/lib/ipf.h @@ -61,4 +61,6 @@ 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 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev