[ovs-dev] [patch v1 7/9] ipf: Add command to get fragmentation handling status.

Darrell Ball dlu998 at gmail.com
Wed Jan 24 19:22:33 UTC 2018


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 at gmail.com>
---
 NEWS                |  2 ++
 lib/ct-dpif.c       | 15 +++++++++++++++
 lib/ct-dpif.h       |  4 ++++
 lib/dpctl.c         | 42 ++++++++++++++++++++++++++++++++++++++++++
 lib/dpctl.man       |  5 +++++
 lib/dpif-netdev.c   | 23 +++++++++++++++++++++++
 lib/dpif-netlink.c  |  1 +
 lib/dpif-provider.h |  5 +++++
 lib/ipf.c           | 15 +++++++++++++++
 lib/ipf.h           |  3 +++
 10 files changed, 115 insertions(+)

diff --git a/NEWS b/NEWS
index 33be40e..5fe1de0 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ Post-v2.9.0
        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.
 
 v2.9.0 - xx xxx xxxx
 --------------------
diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c
index b3f9183..91d56ab 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -188,6 +188,21 @@ 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_enabled,
+    unsigned int *min_frag_size, unsigned int *nfrag_max,
+    unsigned int *nfrag, unsigned int *nfrag_accepted,
+    unsigned int *nfrag_completed_sent,
+    unsigned int *nfrag_expired_sent, unsigned int *nfrag_too_small,
+    unsigned int *n_overlap_frag)
+{
+    return (dpif->dpif_class->ipf_get_status
+            ? dpif->dpif_class->ipf_get_status(dpif, ipf_enabled,
+            min_frag_size, nfrag_max, nfrag, nfrag_accepted,
+            nfrag_completed_sent, nfrag_expired_sent, nfrag_too_small,
+            n_overlap_frag)
+            : EOPNOTSUPP);
+}
+
 void
 ct_dpif_entry_uninit(struct ct_dpif_entry *entry)
 {
diff --git a/lib/ct-dpif.h b/lib/ct-dpif.h
index a2a82fe..70778a7 100644
--- a/lib/ct-dpif.h
+++ b/lib/ct-dpif.h
@@ -203,6 +203,10 @@ int ct_dpif_get_nconns(struct dpif *dpif, uint32_t *nconns);
 int ct_dpif_ipf_change_enabled(struct dpif *, bool);
 int ct_dpif_ipf_set_min_frag(struct dpif *, 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 *);
 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 0b2a5fc..1e1dc4e 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1833,6 +1833,46 @@ 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_enabled;
+        unsigned int min_frag_size;
+        unsigned int nfrag_max;
+        unsigned int nfrag;
+        unsigned int nfrag_accepted;
+        unsigned int nfrag_completed_sent;
+        unsigned int nfrag_expired_sent;
+        unsigned int nfrag_too_small;
+        unsigned int n_overlap_frag;
+        error = ct_dpif_ipf_get_status(dpif, &ipf_enabled, &min_frag_size,
+            &nfrag_max, &nfrag, &nfrag_accepted, &nfrag_completed_sent,
+            &nfrag_expired_sent, &nfrag_too_small, &n_overlap_frag);
+
+        if (!error) {
+            dpctl_print(dpctl_p, "\tenabled: %u\n", ipf_enabled);
+            dpctl_print(dpctl_p, "\tmin frag size: %u\n", min_frag_size);
+            dpctl_print(dpctl_p, "\tmax num frags: %u\n", nfrag_max);
+            dpctl_print(dpctl_p, "\tnum frag: %u\n", nfrag);
+            dpctl_print(dpctl_p, "\tfrags accepted: %u\n", nfrag_accepted);
+            dpctl_print(dpctl_p, "\tfrags completed: %u\n",
+                        nfrag_completed_sent);
+            dpctl_print(dpctl_p, "\tfrags expired: %u\n", nfrag_expired_sent);
+            dpctl_print(dpctl_p, "\tfrags too small: %u\n", nfrag_too_small);
+            dpctl_print(dpctl_p, "\tfrags overlapped: %u\n", n_overlap_frag);
+        } else {
+            dpctl_error(dpctl_p, error, "ipf status could not be retrieved");
+        }
+        dpif_close(dpif);
+    }
+
+    return error;
+}
+
 /* Undocumented commands for unit testing. */
 
 static int
@@ -2138,6 +2178,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 },
 
diff --git a/lib/dpctl.man b/lib/dpctl.man
index a45a4a6..245a811 100644
--- a/lib/dpctl.man
+++ b/lib/dpctl.man
@@ -286,3 +286,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.
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 8635208..ab15709 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -5892,6 +5892,28 @@ 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_enabled,
+    unsigned int *min_frag_size, unsigned int *nfrag_max,
+    unsigned int *nfrag, unsigned int *nfrag_accepted,
+    unsigned int *nfrag_completed_sent,
+    unsigned int *nfrag_expired_sent, unsigned int *nfrag_too_small,
+    unsigned int *n_overlap_frag)
+{
+    struct ipf_status ipf_status;
+    ipf_get_status(&ipf_status);
+    *ipf_enabled = ipf_status.ifp_enabled;
+    *min_frag_size = ipf_status.min_frag_size;
+    *nfrag_max = ipf_status.nfrag_max;
+    *nfrag = ipf_status.nfrag;
+    *nfrag_accepted = ipf_status.nfrag_accepted;
+    *nfrag_completed_sent = ipf_status.nfrag_completed_sent;
+    *nfrag_expired_sent = ipf_status.nfrag_expired_sent;
+    *nfrag_too_small = ipf_status.nfrag_too_small;
+    *n_overlap_frag = ipf_status.n_overlap_frag;
+    return 0;
+}
+
 const struct dpif_class dpif_netdev_class = {
     "netdev",
     dpif_netdev_init,
@@ -5943,6 +5965,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,
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index 6fd3ea8..cac931c 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -2995,6 +2995,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,
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index 7535724..50d50a1 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -451,6 +451,11 @@ struct dpif_class {
     int (*ipf_set_min_frag)(struct dpif *, uint32_t);
     /* Set maximum number of fragments tracked. */
     int (*ipf_set_nfrag_max)(struct dpif *, uint32_t);
+    /* Enable/Disable fragmentation handling. */
+    int (*ipf_get_status)(struct dpif *, bool *, unsigned int *,
+        unsigned int *, unsigned int *, unsigned int *,
+        unsigned int *, unsigned int *, unsigned int *,
+        unsigned int *);
 
     /* Meters */
 
diff --git a/lib/ipf.c b/lib/ipf.c
index 0b5169c..136a8d5 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -883,3 +883,18 @@ 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_enabled, &ipf_status->ifp_enabled);
+    atomic_read_relaxed(&min_frag_size, &ipf_status->min_frag_size);
+    atomic_read_relaxed(&nfrag_max, &ipf_status->nfrag_max);
+    ipf_status->nfrag = atomic_count_get(&nfrag);
+    ipf_status->nfrag_accepted = atomic_count_get(&nfrag_accepted);
+    ipf_status->nfrag_completed_sent = atomic_count_get(&nfrag_completed_sent);
+    ipf_status->nfrag_expired_sent = atomic_count_get(&nfrag_expired_sent);
+    ipf_status->nfrag_too_small = atomic_count_get(&nfrag_too_small);
+    ipf_status->n_overlap_frag = atomic_count_get(&n_overlap_frag);
+    return 0;
+}
diff --git a/lib/ipf.h b/lib/ipf.h
index 60be24d..0ad09a3 100644
--- a/lib/ipf.h
+++ b/lib/ipf.h
@@ -59,4 +59,7 @@ ipf_set_min_frag(uint32_t value);
 int
 ipf_set_nfrag_max(uint32_t value);
 
+int
+ipf_get_status(struct ipf_status *ipf_status);
+
 #endif /* ipf.h */
-- 
1.9.1



More information about the dev mailing list