Userspace conntrack doesn't support conntrack stats for packets and
bytes. This patch implements it.

Signed-off-by: Yifeng Sun <pkusunyif...@gmail.com>
---
 lib/conntrack-private.h       |  9 +++++++++
 lib/conntrack.c               | 28 ++++++++++++++++++++++++++++
 tests/system-common-macros.at |  2 +-
 tests/system-traffic.at       | 30 ++++++++++++++++++++++++++++++
 4 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/lib/conntrack-private.h b/lib/conntrack-private.h
index dfdf4e676..7f21d3772 100644
--- a/lib/conntrack-private.h
+++ b/lib/conntrack-private.h
@@ -91,6 +91,11 @@ enum OVS_PACKED_ENUM ct_conn_type {
     CT_CONN_TYPE_UN_NAT,
 };
 
+struct conn_counter {
+    atomic_uint64_t packets;
+    atomic_uint64_t bytes;
+};
+
 struct conn {
     /* Immutable data. */
     struct conn_key key;
@@ -123,6 +128,10 @@ struct conn {
     enum ct_conn_type conn_type;
 
     uint32_t tp_id; /* Timeout policy ID. */
+
+    /* Counters. */
+    struct conn_counter counters_orig;
+    struct conn_counter counters_reply;
 };
 
 enum ct_update_res {
diff --git a/lib/conntrack.c b/lib/conntrack.c
index 33a1a9295..177154cd8 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -1245,6 +1245,21 @@ conn_update_state_alg(struct conntrack *ct, struct 
dp_packet *pkt,
     return false;
 }
 
+static void
+conn_update_counters(struct conn *conn,
+                     const struct dp_packet *pkt, bool reply)
+{
+    if (conn) {
+        struct conn_counter *counter = (reply
+                                       ? &conn->counters_reply
+                                       : &conn->counters_orig);
+        uint64_t old;
+
+        atomic_count_inc64(&counter->packets);
+        atomic_add(&counter->bytes, dp_packet_size(pkt), &old);
+    }
+}
+
 static void
 set_cached_conn(const struct nat_action_info_t *nat_action_info,
                 const struct conn_lookup_ctx *ctx, struct conn *conn,
@@ -1283,6 +1298,8 @@ process_one_fast(uint16_t zone, const uint32_t *setmark,
     if (setlabel) {
         set_label(pkt, conn, &setlabel[0], &setlabel[1]);
     }
+
+    conn_update_counters(conn, pkt, pkt->md.reply);
 }
 
 static void
@@ -1420,6 +1437,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt,
         set_label(pkt, conn, &setlabel[0], &setlabel[1]);
     }
 
+    conn_update_counters(conn, pkt, ctx->reply);
+
     handle_alg_ctl(ct, ctx, pkt, ct_alg_ctl, conn, now, !!nat_action_info);
 
     set_cached_conn(nat_action_info, ctx, conn, pkt);
@@ -2641,6 +2660,15 @@ conn_to_ct_dpif_entry(const struct conn *conn, struct 
ct_dpif_entry *entry,
     }
     ovs_mutex_unlock(&conn->lock);
 
+    entry->counters_orig.packets = atomic_count_get64(
+            (atomic_uint64_t *)&conn->counters_orig.packets);
+    entry->counters_orig.bytes = atomic_count_get64(
+            (atomic_uint64_t *)&conn->counters_orig.bytes);
+    entry->counters_reply.packets = atomic_count_get64(
+            (atomic_uint64_t *)&conn->counters_reply.packets);
+    entry->counters_reply.bytes = atomic_count_get64(
+            (atomic_uint64_t *)&conn->counters_reply.bytes);
+
     entry->timeout = (expiration > 0) ? expiration / 1000 : 0;
 
     if (conn->alg) {
diff --git a/tests/system-common-macros.at b/tests/system-common-macros.at
index 19a0b125b..89cd7b83c 100644
--- a/tests/system-common-macros.at
+++ b/tests/system-common-macros.at
@@ -240,7 +240,7 @@ m4_define([STRIP_MONITOR_CSUM], [grep "csum:" | sed 
's/csum:.*/csum: <skip>/'])
 # and limit the output to the rows containing 'ip-addr'.
 #
 m4_define([FORMAT_CT],
-    [[grep "dst=$1" | sed -e 's/port=[0-9]*/port=<cleared>/g' -e 
's/id=[0-9]*/id=<cleared>/g' -e 's/state=[0-9_A-Z]*/state=<cleared>/g' | sort | 
uniq]])
+    [[grep "dst=$1" | sed -e 's/port=[0-9]*/port=<cleared>/g' -e 
's/id=[0-9]*/id=<cleared>/g' -e 's/state=[0-9_A-Z]*/state=<cleared>/g' -e 
's/timeout=[0-9]*/timeout=<cleared>/g' | sort | uniq]])
 
 # NETNS_DAEMONIZE([namespace], [command], [pidfile])
 #
diff --git a/tests/system-traffic.at b/tests/system-traffic.at
index f22d86e46..15b2c288c 100644
--- a/tests/system-traffic.at
+++ b/tests/system-traffic.at
@@ -6743,6 +6743,36 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | 
OFPROTO_CLEAR_DURATION_IDLE
 OVS_TRAFFIC_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([conntrack - stats])
+CHECK_CONNTRACK()
+OVS_TRAFFIC_VSWITCHD_START()
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+AT_DATA([flows.txt], [dnl
+priority=1,action=drop
+priority=10,arp,action=normal
+priority=100,in_port=1,icmp,action=ct(commit),2
+priority=100,in_port=2,ct_state=-trk,icmp,action=ct(table=0)
+priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1
+])
+
+AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
+
+NS_CHECK_EXEC([at_ns0], [ping -s 500 -q -c 3 -i 0.3 -w 2 10.1.1.2 | 
FORMAT_PING], [0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack -s | FORMAT_CT(10.1.1.2)], [0], [dnl
+icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=<cleared>,type=8,code=0,packets=3,bytes=1626),reply=(src=10.1.1.2,dst=10.1.1.1,id=<cleared>,type=0,code=0,packets=3,bytes=1626),timeout=<cleared>
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_BANNER([802.1ad])
 
 AT_SETUP([802.1ad - vlan_limit])
-- 
2.17.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to