[ovs-dev] [PATCH v2] sflow: Expose ethernet stats via sFlow

Robert Wojciechowicz robertx.wojciechowicz at intel.com
Fri Feb 24 11:57:04 UTC 2017


Expose existing netdev stats via sFlow.
Export sFlow ETHERNET structure with available counters.
Map existing stats to counters in the GENERIC INTERFACE
sFlow structure.
Adjust unit test to accommodate these new counters.

Signed-off-by: Robert Wojciechowicz <robertx.wojciechowicz at intel.com>
Acked-by: Neil McKee <neil.mckee at inmon.com>
Acked-by: Ian Stokes <ian.stokes at intel.com>

---
v2:
- remove VLAN counters
---
 ofproto/ofproto-dpif-sflow.c |  27 ++++++++--
 tests/ofproto-dpif.at        | 126 +++++++++++++++++++++++++++++++++++--------
 tests/test-sflow.c           |  26 ++++++++-
 3 files changed, 154 insertions(+), 25 deletions(-)

diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c
index 520b8dd..e91d01d 100644
--- a/ofproto/ofproto-dpif-sflow.c
+++ b/ofproto/ofproto-dpif-sflow.c
@@ -298,9 +298,11 @@ sflow_agent_get_counters(void *ds_, SFLPoller *poller,
 {
     struct dpif_sflow *ds = ds_;
     SFLCounters_sample_element elem, lacp_elem, of_elem, name_elem;
+    SFLCounters_sample_element eth_elem;
     enum netdev_features current;
     struct dpif_sflow_port *dsp;
     SFLIf_counters *counters;
+    SFLEthernet_counters* eth_counters;
     struct netdev_stats stats;
     enum netdev_flags flags;
     struct lacp_slave_stats lacp_stats;
@@ -343,14 +345,14 @@ sflow_agent_get_counters(void *ds_, SFLPoller *poller,
     counters->ifInOctets = stats.rx_bytes;
     counters->ifInUcastPkts = stats.rx_packets;
     counters->ifInMulticastPkts = stats.multicast;
-    counters->ifInBroadcastPkts = -1;
+    counters->ifInBroadcastPkts = stats.rx_broadcast_packets;
     counters->ifInDiscards = stats.rx_dropped;
     counters->ifInErrors = stats.rx_errors;
     counters->ifInUnknownProtos = -1;
     counters->ifOutOctets = stats.tx_bytes;
     counters->ifOutUcastPkts = stats.tx_packets;
-    counters->ifOutMulticastPkts = -1;
-    counters->ifOutBroadcastPkts = -1;
+    counters->ifOutMulticastPkts = stats.tx_multicast_packets;
+    counters->ifOutBroadcastPkts = stats.tx_broadcast_packets;
     counters->ifOutDiscards = stats.tx_dropped;
     counters->ifOutErrors = stats.tx_errors;
     counters->ifPromiscuousMode = 0;
@@ -407,6 +409,25 @@ sflow_agent_get_counters(void *ds_, SFLPoller *poller,
       (OVS_FORCE uint32_t)dsp->ofport->ofp_port;
     SFLADD_ELEMENT(cs, &of_elem);
 
+    /* Include ethernet counters */
+    memset(&eth_elem, 0, sizeof eth_elem);
+    eth_elem.tag = SFLCOUNTERS_ETHERNET;
+    eth_counters = &eth_elem.counterBlock.ethernet;
+    eth_counters->dot3StatsAlignmentErrors = stats.rx_frame_errors;
+    eth_counters->dot3StatsFCSErrors = stats.rx_crc_errors;
+    eth_counters->dot3StatsFrameTooLongs = stats.rx_oversize_errors;
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsSingleCollisionFrames);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsMultipleCollisionFrames);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsSQETestErrors);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsDeferredTransmissions);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsLateCollisions);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsExcessiveCollisions);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsInternalMacTransmitErrors);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsCarrierSenseErrors);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsInternalMacReceiveErrors);
+    SFL_UNDEF_COUNTER(eth_counters->dot3StatsSymbolErrors);
+    SFLADD_ELEMENT(cs, &eth_elem);
+
     sfl_poller_writeCountersSample(poller, cs);
 }
 
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index e861d9f..9a30b57 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -5467,19 +5467,103 @@ HEADER
 	hdr=50-54-00-00-00-05-50-54-00-00-00-07-86-DD-67-00-00-00-00-00-0A-80-FE-80-00-00-00-00-00-00-00-00-00-00-00-00-00-01-FE-80-00-00-00-00-00-00-00-00-00-00-00-00-00-02
 ])
 
-  AT_CHECK_UNQUOTED([[sort sflow.log | $EGREP 'IFCOUNTERS|ERROR|PORTNAME|OPENFLOWPORT' | head -18 | sed 's/ /\
+  AT_CHECK_UNQUOTED([[sort sflow.log | $EGREP 'ETHCOUNTERS|IFCOUNTERS|ERROR|PORTNAME|OPENFLOWPORT' | head -24 | sed 's/ /\
 	/g']], [0], [dnl
+ETHCOUNTERS
+	dot3StatsAlignmentErrors=4294967295
+	dot3StatsFCSErrors=4294967295
+	dot3StatsSingleCollisionFrames=4294967295
+	dot3StatsMultipleCollisionFrames=4294967295
+	dot3StatsSQETestErrors=4294967295
+	dot3StatsDeferredTransmissions=4294967295
+	dot3StatsLateCollisions=4294967295
+	dot3StatsExcessiveCollisions=4294967295
+	dot3StatsInternalMacTransmitErrors=4294967295
+	dot3StatsCarrierSenseErrors=4294967295
+	dot3StatsFrameTooLongs=4294967295
+	dot3StatsInternalMacReceiveErrors=4294967295
+	dot3StatsSymbolErrors=4294967295
+ETHCOUNTERS
+	dot3StatsAlignmentErrors=4294967295
+	dot3StatsFCSErrors=4294967295
+	dot3StatsSingleCollisionFrames=4294967295
+	dot3StatsMultipleCollisionFrames=4294967295
+	dot3StatsSQETestErrors=4294967295
+	dot3StatsDeferredTransmissions=4294967295
+	dot3StatsLateCollisions=4294967295
+	dot3StatsExcessiveCollisions=4294967295
+	dot3StatsInternalMacTransmitErrors=4294967295
+	dot3StatsCarrierSenseErrors=4294967295
+	dot3StatsFrameTooLongs=4294967295
+	dot3StatsInternalMacReceiveErrors=4294967295
+	dot3StatsSymbolErrors=4294967295
+ETHCOUNTERS
+	dot3StatsAlignmentErrors=4294967295
+	dot3StatsFCSErrors=4294967295
+	dot3StatsSingleCollisionFrames=4294967295
+	dot3StatsMultipleCollisionFrames=4294967295
+	dot3StatsSQETestErrors=4294967295
+	dot3StatsDeferredTransmissions=4294967295
+	dot3StatsLateCollisions=4294967295
+	dot3StatsExcessiveCollisions=4294967295
+	dot3StatsInternalMacTransmitErrors=4294967295
+	dot3StatsCarrierSenseErrors=4294967295
+	dot3StatsFrameTooLongs=4294967295
+	dot3StatsInternalMacReceiveErrors=4294967295
+	dot3StatsSymbolErrors=4294967295
+ETHCOUNTERS
+	dot3StatsAlignmentErrors=4294967295
+	dot3StatsFCSErrors=4294967295
+	dot3StatsSingleCollisionFrames=4294967295
+	dot3StatsMultipleCollisionFrames=4294967295
+	dot3StatsSQETestErrors=4294967295
+	dot3StatsDeferredTransmissions=4294967295
+	dot3StatsLateCollisions=4294967295
+	dot3StatsExcessiveCollisions=4294967295
+	dot3StatsInternalMacTransmitErrors=4294967295
+	dot3StatsCarrierSenseErrors=4294967295
+	dot3StatsFrameTooLongs=4294967295
+	dot3StatsInternalMacReceiveErrors=4294967295
+	dot3StatsSymbolErrors=4294967295
+ETHCOUNTERS
+	dot3StatsAlignmentErrors=4294967295
+	dot3StatsFCSErrors=4294967295
+	dot3StatsSingleCollisionFrames=4294967295
+	dot3StatsMultipleCollisionFrames=4294967295
+	dot3StatsSQETestErrors=4294967295
+	dot3StatsDeferredTransmissions=4294967295
+	dot3StatsLateCollisions=4294967295
+	dot3StatsExcessiveCollisions=4294967295
+	dot3StatsInternalMacTransmitErrors=4294967295
+	dot3StatsCarrierSenseErrors=4294967295
+	dot3StatsFrameTooLongs=4294967295
+	dot3StatsInternalMacReceiveErrors=4294967295
+	dot3StatsSymbolErrors=4294967295
+ETHCOUNTERS
+	dot3StatsAlignmentErrors=4294967295
+	dot3StatsFCSErrors=4294967295
+	dot3StatsSingleCollisionFrames=4294967295
+	dot3StatsMultipleCollisionFrames=4294967295
+	dot3StatsSQETestErrors=4294967295
+	dot3StatsDeferredTransmissions=4294967295
+	dot3StatsLateCollisions=4294967295
+	dot3StatsExcessiveCollisions=4294967295
+	dot3StatsInternalMacTransmitErrors=4294967295
+	dot3StatsCarrierSenseErrors=4294967295
+	dot3StatsFrameTooLongs=4294967295
+	dot3StatsInternalMacReceiveErrors=4294967295
+	dot3StatsSymbolErrors=4294967295
 IFCOUNTERS
 	dgramSeqNo=1
-	ds=127.0.0.1>0:1002
+	ds=127.0.0.1>0:1003
 	csSeqNo=1
-	ifindex=1002
+	ifindex=1003
 	type=6
 	ifspeed=100000000
 	direction=0
 	status=0
-	in_octets=0
-	in_unicasts=0
+	in_octets=138
+	in_unicasts=3
 	in_multicasts=4294967295
 	in_broadcasts=4294967295
 	in_discards=4294967295
@@ -5494,52 +5578,52 @@ IFCOUNTERS
 	promiscuous=0
 IFCOUNTERS
 	dgramSeqNo=1
-	ds=127.0.0.1>0:1003
+	ds=127.0.0.1>0:1004
 	csSeqNo=1
-	ifindex=1003
+	ifindex=1004
 	type=6
 	ifspeed=100000000
 	direction=0
 	status=0
-	in_octets=138
-	in_unicasts=3
+	in_octets=84
+	in_unicasts=2
 	in_multicasts=4294967295
 	in_broadcasts=4294967295
 	in_discards=4294967295
 	in_errors=4294967295
 	in_unknownprotos=4294967295
-	out_octets=84
-	out_unicasts=2
+	out_octets=138
+	out_unicasts=3
 	out_multicasts=4294967295
 	out_broadcasts=4294967295
 	out_discards=4294967295
 	out_errors=4294967295
 	promiscuous=0
 IFCOUNTERS
-	dgramSeqNo=1
-	ds=127.0.0.1>0:1004
+	dgramSeqNo=2
+	ds=127.0.0.1>0:1002
 	csSeqNo=1
-	ifindex=1004
+	ifindex=1002
 	type=6
 	ifspeed=100000000
 	direction=0
 	status=0
-	in_octets=84
-	in_unicasts=2
+	in_octets=0
+	in_unicasts=0
 	in_multicasts=4294967295
 	in_broadcasts=4294967295
 	in_discards=4294967295
 	in_errors=4294967295
 	in_unknownprotos=4294967295
-	out_octets=138
-	out_unicasts=3
+	out_octets=84
+	out_unicasts=2
 	out_multicasts=4294967295
 	out_broadcasts=4294967295
 	out_discards=4294967295
 	out_errors=4294967295
 	promiscuous=0
 IFCOUNTERS
-	dgramSeqNo=2
+	dgramSeqNo=3
 	ds=127.0.0.1>0:1002
 	csSeqNo=2
 	ifindex=1002
@@ -5562,7 +5646,7 @@ IFCOUNTERS
 	out_errors=4294967295
 	promiscuous=0
 IFCOUNTERS
-	dgramSeqNo=2
+	dgramSeqNo=3
 	ds=127.0.0.1>0:1003
 	csSeqNo=2
 	ifindex=1003
@@ -5585,7 +5669,7 @@ IFCOUNTERS
 	out_errors=4294967295
 	promiscuous=0
 IFCOUNTERS
-	dgramSeqNo=2
+	dgramSeqNo=3
 	ds=127.0.0.1>0:1004
 	csSeqNo=2
 	ifindex=1004
diff --git a/tests/test-sflow.c b/tests/test-sflow.c
index 60870df..6125d38 100644
--- a/tests/test-sflow.c
+++ b/tests/test-sflow.c
@@ -54,6 +54,7 @@ static unixctl_cb_func test_sflow_exit;
 
 /* Structure element tag numbers. */
 #define SFLOW_TAG_CTR_IFCOUNTERS 1
+#define SFLOW_TAG_CTR_ETHCOUNTERS 2
 #define SFLOW_TAG_CTR_LACPCOUNTERS 7
 #define SFLOW_TAG_CTR_OPENFLOWPORT 1004
 #define SFLOW_TAG_CTR_PORTNAME 1005
@@ -115,7 +116,8 @@ struct sflow_xdr {
 	uint32_t TUNNEL_VNI_OUT;
 	uint32_t TUNNEL_VNI_IN;
 	uint32_t MPLS;
-        uint32_t IFCOUNTERS;
+	uint32_t IFCOUNTERS;
+	uint32_t ETHCOUNTERS;
 	uint32_t LACPCOUNTERS;
 	uint32_t OPENFLOWPORT;
 	uint32_t PORTNAME;
@@ -297,6 +299,25 @@ process_counter_sample(struct sflow_xdr *x)
 	printf(" portName=%s", portName);
 	printf("\n");
     }
+    if (x->offset.ETHCOUNTERS) {
+        sflowxdr_setc(x, x->offset.ETHCOUNTERS);
+        printf("ETHCOUNTERS");
+        printf(" dot3StatsAlignmentErrors=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsFCSErrors=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsSingleCollisionFrames=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsMultipleCollisionFrames=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsSQETestErrors=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsDeferredTransmissions=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsLateCollisions=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsExcessiveCollisions=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsInternalMacTransmitErrors=%"PRIu32,
+               sflowxdr_next(x));
+        printf(" dot3StatsCarrierSenseErrors=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsFrameTooLongs=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsInternalMacReceiveErrors=%"PRIu32, sflowxdr_next(x));
+        printf(" dot3StatsSymbolErrors=%"PRIu32, sflowxdr_next(x));
+        printf("\n");
+    }
 }
 
 static char
@@ -513,6 +534,9 @@ process_datagram(struct sflow_xdr *x)
                 case SFLOW_TAG_CTR_IFCOUNTERS:
                     sflowxdr_mark_unique(x, &x->offset.IFCOUNTERS);
                     break;
+                case SFLOW_TAG_CTR_ETHCOUNTERS:
+                    sflowxdr_mark_unique(x, &x->offset.ETHCOUNTERS);
+                    break;
                 case SFLOW_TAG_CTR_LACPCOUNTERS:
                     sflowxdr_mark_unique(x, &x->offset.LACPCOUNTERS);
                     break;
-- 
1.8.3.1



More information about the dev mailing list