@@ -18,6 +18,8 @@ Post-v2.9.0
datapath conntrack fragmentation support.
* New "ovs-appctl dpctl/ipf-set-maxfrags" command for userspace datapath
conntrack fragmentation support.
+ * New "ovs-appctl dpctl/ipf-get-status" 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.
@@ -188,6 +188,27 @@ ct_dpif_ipf_set_nfrag_max(struct dpif *dpif, uint32_t max_frags)
: EOPNOTSUPP);
}
+int ct_dpif_ipf_get_status(struct dpif *dpif, bool *ipf_v4_enabled,
+ unsigned int *min_v4_frag_size, unsigned int *nfrag_max,
+ unsigned int *nfrag, unsigned int *n4frag_accepted,
+ unsigned int *n4frag_completed_sent,
+ unsigned int *n4frag_expired_sent, unsigned int *n4frag_too_small,
+ unsigned int *n4frag_overlap, bool *ipf_v6_enabled,
+ unsigned int *min_v6_frag_size, unsigned int *n6frag_accepted,
+ unsigned int *n6frag_completed_sent,
+ unsigned int *n6frag_expired_sent, unsigned int *n6frag_too_small,
+ unsigned int *n6frag_overlap)
+{
+ return (dpif->dpif_class->ipf_get_status
+ ? dpif->dpif_class->ipf_get_status(dpif, ipf_v4_enabled,
+ min_v4_frag_size, nfrag_max, nfrag, n4frag_accepted,
+ n4frag_completed_sent, n4frag_expired_sent, n4frag_too_small,
+ n4frag_overlap, ipf_v6_enabled, min_v6_frag_size, n6frag_accepted,
+ n6frag_completed_sent, n6frag_expired_sent, n6frag_too_small,
+ n6frag_overlap)
+ : EOPNOTSUPP);
+}
+
void
ct_dpif_entry_uninit(struct ct_dpif_entry *entry)
{
@@ -203,6 +203,12 @@ int ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns);
int ct_dpif_ipf_change_enabled(struct dpif *, bool, bool);
int ct_dpif_ipf_set_min_frag(struct dpif *, bool, uint32_t);
int ct_dpif_ipf_set_nfrag_max(struct dpif *, uint32_t);
+int ct_dpif_ipf_get_status(struct dpif *dpif, bool *, unsigned int *,
+ unsigned int *, unsigned int *, unsigned int *,
+ unsigned int *, unsigned int *, unsigned int *,
+ unsigned int *, bool *, unsigned int *,
+ unsigned int *, unsigned int *, unsigned int *,
+ unsigned int *, unsigned int *);
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);
@@ -35,7 +35,6 @@
#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"
@@ -1853,6 +1852,78 @@ dpctl_ct_ipf_set_nfrag_max(int argc, const char *argv[],
return error;
}
+static int
+dpctl_ct_ipf_get_status(int argc, const char *argv[],
+ struct dpctl_params *dpctl_p)
+{
+ struct dpif *dpif;
+ int error = dpctl_ct_open_dp(argc, argv, dpctl_p, &dpif, 2);
+ if (!error) {
+ bool ipf_v4_enabled;
+ unsigned int min_v4_frag_size;
+ unsigned int nfrag_max;
+ unsigned int nfrag;
+ unsigned int n4frag_accepted;
+ unsigned int n4frag_completed_sent;
+ unsigned int n4frag_expired_sent;
+ unsigned int n4frag_too_small;
+ unsigned int n4frag_overlap;
+ unsigned int min_v6_frag_size;
+ bool ipf_v6_enabled;
+ unsigned int n6frag_accepted;
+ unsigned int n6frag_completed_sent;
+ unsigned int n6frag_expired_sent;
+ unsigned int n6frag_too_small;
+ unsigned int n6frag_overlap;
+ error = ct_dpif_ipf_get_status(dpif, &ipf_v4_enabled,
+ &min_v4_frag_size, &nfrag_max, &nfrag, &n4frag_accepted,
+ &n4frag_completed_sent, &n4frag_expired_sent, &n4frag_too_small,
+ &n4frag_overlap, &ipf_v6_enabled, &min_v6_frag_size,
+ &n6frag_accepted, &n6frag_completed_sent, &n6frag_expired_sent,
+ &n6frag_too_small, &n6frag_overlap);
+
+ if (!error) {
+ dpctl_print(dpctl_p, "\tFragmentation Module Status\n");
+ dpctl_print(dpctl_p, "\t---------------------------\n");
+ dpctl_print(dpctl_p, "\tv4 enabled: %u\n", ipf_v4_enabled);
+ dpctl_print(dpctl_p, "\tv6 enabled: %u\n", ipf_v6_enabled);
+ dpctl_print(dpctl_p, "\tmax num frags (v4/v6): %u\n", nfrag_max);
+ dpctl_print(dpctl_p, "\tnum frag: %u\n", nfrag);
+ dpctl_print(dpctl_p, "\tmin v4 frag size: %u\n",
+ min_v4_frag_size);
+ dpctl_print(dpctl_p, "\tv4 frags accepted: %u\n",
+ n4frag_accepted);
+ dpctl_print(dpctl_p, "\tv4 frags completed: %u\n",
+ n4frag_completed_sent);
+ dpctl_print(dpctl_p, "\tv4 frags expired: %u\n",
+ n4frag_expired_sent);
+ dpctl_print(dpctl_p, "\tv4 frags too small: %u\n",
+ n4frag_too_small);
+ dpctl_print(dpctl_p, "\tv4 frags overlapped: %u\n",
+ n4frag_overlap);
+ dpctl_print(dpctl_p, "\tmin v6 frag size: %u\n",
+ min_v6_frag_size);
+ dpctl_print(dpctl_p, "\tv6 frags accepted: %u\n",
+ n6frag_accepted);
+ dpctl_print(dpctl_p, "\tv6 frags completed: %u\n",
+ n6frag_completed_sent);
+ dpctl_print(dpctl_p, "\tv6 frags expired: %u\n",
+ n6frag_expired_sent);
+ dpctl_print(dpctl_p, "\tv6 frags too small: %u\n",
+ n6frag_too_small);
+ dpctl_print(dpctl_p, "\tv6 frags overlapped: %u\n",
+ n6frag_overlap);
+ } else {
+ dpctl_error(dpctl_p, error,
+ "ipf status could not be retrieved");
+ }
+
+ dpif_close(dpif);
+ }
+
+ return error;
+}
+
/* Undocumented commands for unit testing. */
static int
@@ -2158,6 +2229,8 @@ static const struct dpctl_command all_commands[] = {
dpctl_ct_ipf_set_min_frag, DP_RW },
{ "ipf-set-maxfrags", "[dp] maxfrags", 1, 2,
dpctl_ct_ipf_set_nfrag_max, DP_RW },
+ { "ipf-get-status", "[dp]", 0, 1, dpctl_ct_ipf_get_status,
+ DP_RO },
{ "help", "", 0, INT_MAX, dpctl_help, DP_RO },
{ "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO },
@@ -294,3 +294,8 @@ 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.
+.
+.TP
+\*(DX\fBipf\-get\-status\fR [\fIdp\fR]
+Gets the configuration settings and fragment counters associated with the
+fragmentation handling of the userspace datapath connection tracker.
@@ -5892,6 +5892,38 @@ dpif_netdev_ipf_set_nfrag_max(struct dpif *dpif OVS_UNUSED,
return ipf_set_nfrag_max(max_frags);
}
+static int
+dpif_netdev_ipf_get_status(struct dpif *dpif OVS_UNUSED,
+ bool *ipf_v4_enabled, unsigned int *min_v4_frag_size,
+ unsigned int *nfrag_max, unsigned int *nfrag,
+ unsigned int *n4frag_accepted, unsigned int *n4frag_completed_sent,
+ unsigned int *n4frag_expired_sent, unsigned int *n4frag_too_small,
+ unsigned int *n4frag_overlap, bool *ipf_v6_enabled,
+ unsigned int *min_v6_frag_size, unsigned int *n6frag_accepted,
+ unsigned int *n6frag_completed_sent, unsigned int *n6frag_expired_sent,
+ unsigned int *n6frag_too_small, unsigned int *n6frag_overlap)
+{
+ struct ipf_status ipf_status;
+ ipf_get_status(&ipf_status);
+ *ipf_v4_enabled = ipf_status.ifp_v4_enabled;
+ *min_v4_frag_size = ipf_status.min_v4_frag_size;
+ *nfrag_max = ipf_status.nfrag_max;
+ *nfrag = ipf_status.nfrag;
+ *n4frag_accepted = ipf_status.n4frag_accepted;
+ *n4frag_completed_sent = ipf_status.n4frag_completed_sent;
+ *n4frag_expired_sent = ipf_status.n4frag_expired_sent;
+ *n4frag_too_small = ipf_status.n4frag_too_small;
+ *n4frag_overlap = ipf_status.n4frag_overlap;
+ *ipf_v6_enabled = ipf_status.ifp_v6_enabled;
+ *min_v6_frag_size = ipf_status.min_v6_frag_size;
+ *n6frag_accepted = ipf_status.n6frag_accepted;
+ *n6frag_completed_sent = ipf_status.n6frag_completed_sent;
+ *n6frag_expired_sent = ipf_status.n6frag_expired_sent;
+ *n6frag_too_small = ipf_status.n6frag_too_small;
+ *n6frag_overlap = ipf_status.n6frag_overlap;
+ return 0;
+}
+
const struct dpif_class dpif_netdev_class = {
"netdev",
dpif_netdev_init,
@@ -5943,6 +5975,7 @@ const struct dpif_class dpif_netdev_class = {
dpif_netdev_ipf_change_enabled,
dpif_netdev_ipf_set_min_frag,
dpif_netdev_ipf_set_nfrag_max,
+ dpif_netdev_ipf_get_status,
dpif_netdev_meter_get_features,
dpif_netdev_meter_set,
dpif_netdev_meter_get,
@@ -2997,6 +2997,7 @@ const struct dpif_class dpif_netlink_class = {
NULL, /* ipf_change_enabled */
NULL, /* ipf_set_min_frag */
NULL, /* ipf_set_nfrag_max */
+ NULL, /* ipf_get_status */
dpif_netlink_meter_get_features,
dpif_netlink_meter_set,
dpif_netlink_meter_get,
@@ -450,6 +450,13 @@ struct dpif_class {
int (*ipf_set_min_frag)(struct dpif *, bool, uint32_t);
/* Set maximum number of fragments tracked. */
int (*ipf_set_nfrag_max)(struct dpif *, uint32_t);
+ /* Get fragmentation configuration status and counters. */
+ int (*ipf_get_status)(struct dpif *, bool *, unsigned int *,
+ unsigned int *, unsigned int *, unsigned int *,
+ unsigned int *, unsigned int *, unsigned int *,
+ unsigned int *, bool *, unsigned int *, unsigned int *,
+ unsigned int *, unsigned int *, unsigned int *,
+ unsigned int *);
/* Meters */
/* Queries 'dpif' for supported meter features.
@@ -1284,3 +1284,29 @@ ipf_set_nfrag_max(uint32_t value)
atomic_store_relaxed(&nfrag_max, value);
return 0;
}
+
+int
+ipf_get_status(struct ipf_status *ipf_status)
+{
+ atomic_read_relaxed(&ifp_v4_enabled, &ipf_status->ifp_v4_enabled);
+ atomic_read_relaxed(&min_v4_frag_size, &ipf_status->min_v4_frag_size);
+ atomic_read_relaxed(&nfrag_max, &ipf_status->nfrag_max);
+ ipf_status->nfrag = atomic_count_get(&nfrag);
+ ipf_status->n4frag_accepted = atomic_count_get(&n4frag_accepted);
+ ipf_status->n4frag_completed_sent =
+ atomic_count_get(&n4frag_completed_sent);
+ ipf_status->n4frag_expired_sent =
+ atomic_count_get(&n4frag_expired_sent);
+ ipf_status->n4frag_too_small = atomic_count_get(&n4frag_too_small);
+ ipf_status->n4frag_overlap = atomic_count_get(&n4frag_overlap);
+ atomic_read_relaxed(&ifp_v6_enabled, &ipf_status->ifp_v6_enabled);
+ atomic_read_relaxed(&min_v6_frag_size, &ipf_status->min_v6_frag_size);
+ ipf_status->n6frag_accepted = atomic_count_get(&n6frag_accepted);
+ ipf_status->n6frag_completed_sent =
+ atomic_count_get(&n6frag_completed_sent);
+ ipf_status->n6frag_expired_sent =
+ atomic_count_get(&n6frag_expired_sent);
+ ipf_status->n6frag_too_small = atomic_count_get(&n6frag_too_small);
+ ipf_status->n6frag_overlap = atomic_count_get(&n6frag_overlap);
+ return 0;
+}
@@ -69,4 +69,7 @@ ipf_set_min_frag(bool v6, uint32_t value);
int
ipf_set_nfrag_max(uint32_t value);
+int
+ipf_get_status(struct ipf_status *ipf_status);
+
#endif /* ipf.h */
A new command "ovs-appctl dpctl/ipf-get-status" is added for userspace datapath conntrack fragmentation support. The command shows the configuration status as well as fragment counters. Signed-off-by: Darrell Ball <dlu998@gmail.com> --- NEWS | 2 ++ lib/ct-dpif.c | 21 +++++++++++++++ lib/ct-dpif.h | 6 +++++ lib/dpctl.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++- lib/dpctl.man | 5 ++++ lib/dpif-netdev.c | 33 +++++++++++++++++++++++ lib/dpif-netlink.c | 1 + lib/dpif-provider.h | 7 +++++ lib/ipf.c | 26 +++++++++++++++++++ lib/ipf.h | 3 +++ 10 files changed, 178 insertions(+), 1 deletion(-)