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