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

Signed-off-by: Robert Wojciechowicz <robertx.wojciechow...@intel.com>
---
 lib/sflow.h                  |   2 +
 lib/sflow_receiver.c         |   2 +-
 ofproto/ofproto-dpif-sflow.c |  52 +++++++++-
 ofproto/ofproto-dpif.c       |   8 ++
 ofproto/ofproto-provider.h   |   8 ++
 ofproto/ofproto.c            |  16 +++
 ofproto/ofproto.h            |   1 +
 tests/ofproto-dpif.at        | 225 +++++++++++++++++++++++++++++++++++++++----
 tests/test-sflow.c           |  43 ++++++++-
 9 files changed, 332 insertions(+), 25 deletions(-)

diff --git a/lib/sflow.h b/lib/sflow.h
index 95bedd9..5beadc4 100644
--- a/lib/sflow.h
+++ b/lib/sflow.h
@@ -502,6 +502,8 @@ typedef struct _SFLVlan_counters {
     u_int32_t discards;
 } SFLVlan_counters;
 
+#define SFL_CTR_VLAN_XDR_SIZE 28
+
 /* OpenFlow port */
 typedef struct {
     u_int64_t datapath_id;
diff --git a/lib/sflow_receiver.c b/lib/sflow_receiver.c
index cde1359..8474628 100644
--- a/lib/sflow_receiver.c
+++ b/lib/sflow_receiver.c
@@ -649,7 +649,7 @@ static int computeCountersSampleSize(SFLReceiver *receiver, 
SFL_COUNTERS_SAMPLE_
        case SFLCOUNTERS_ETHERNET: elemSiz = SFL_CTR_ETHERNET_XDR_SIZE; break;
        case SFLCOUNTERS_TOKENRING: elemSiz = 
sizeof(elem->counterBlock.tokenring); break;
        case SFLCOUNTERS_VG: elemSiz = sizeof(elem->counterBlock.vg); break;
-       case SFLCOUNTERS_VLAN: elemSiz = sizeof(elem->counterBlock.vlan); break;
+       case SFLCOUNTERS_VLAN: elemSiz = SFL_CTR_VLAN_XDR_SIZE; break;
        case SFLCOUNTERS_LACP: elemSiz = SFL_CTR_LACP_XDR_SIZE; break;
        case SFLCOUNTERS_OPENFLOWPORT: elemSiz = SFL_CTR_OPENFLOWPORT_XDR_SIZE; 
break;
        case SFLCOUNTERS_PORTNAME: elemSiz = 
stringEncodingLength(&elem->counterBlock.portName.portName); break;
diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c
index 9ea8851..21adba7 100644
--- a/ofproto/ofproto-dpif-sflow.c
+++ b/ofproto/ofproto-dpif-sflow.c
@@ -298,13 +298,17 @@ 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;
+    SFLCounters_sample_element vlan_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;
     const char *ifName;
+    int vlan_id = 0;
 
     dsp = dpif_sflow_find_port(ds, u32_to_odp(poller->bridgePort));
     if (!dsp) {
@@ -343,14 +347,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 +411,48 @@ 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);
+
+    /* Include VLAN counters if this port is part of VLAN. */
+    vlan_id = ofproto_port_get_vlan_id(dsp->ofport);
+    if (vlan_id > 0 && vlan_id != UINT32_MAX) {
+        memset(&vlan_elem, 0, sizeof vlan_elem);
+        vlan_elem.tag = SFLCOUNTERS_VLAN;
+        vlan_elem.counterBlock.vlan.vlan_id = vlan_id;
+        vlan_elem.counterBlock.vlan.octets = counters->ifInOctets;
+        if (counters->ifOutOctets != UINT64_MAX) {
+            vlan_elem.counterBlock.vlan.octets += counters->ifOutOctets;
+        }
+        vlan_elem.counterBlock.vlan.ucastPkts = counters->ifInUcastPkts;
+        if (counters->ifOutUcastPkts != UINT32_MAX) {
+            vlan_elem.counterBlock.vlan.ucastPkts += counters->ifOutUcastPkts;
+        }
+        SFL_UNDEF_COUNTER(vlan_elem.counterBlock.vlan.multicastPkts);
+        SFL_UNDEF_COUNTER(vlan_elem.counterBlock.vlan.broadcastPkts);
+        vlan_elem.counterBlock.vlan.discards = counters->ifInDiscards;
+        if (counters->ifOutDiscards != UINT32_MAX) {
+            vlan_elem.counterBlock.vlan.discards += counters->ifOutDiscards;
+        }
+        SFLADD_ELEMENT(cs, &vlan_elem);
+    }
+
     sfl_poller_writeCountersSample(poller, cs);
 }
 
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 330bd48..ff95b70 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -3602,6 +3602,13 @@ port_get_lacp_stats(const struct ofport *ofport_, struct 
lacp_slave_stats *stats
     return -1;
 }
 
+static int
+port_get_vlan_id(const struct ofport *ofport_)
+{
+    struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
+    return ofport->bundle->vlan;
+}
+
 struct port_dump_state {
     struct sset_position pos;
     bool ghost;
@@ -5885,6 +5892,7 @@ const struct ofproto_class ofproto_dpif_class = {
     port_poll_wait,
     port_is_lacp_current,
     port_get_lacp_stats,
+    port_get_vlan_id,
     NULL,                       /* rule_choose_table */
     rule_alloc,
     rule_construct,
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index bc5098a..f9c3092 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -1166,6 +1166,14 @@ struct ofproto_class {
     int (*port_get_lacp_stats)(const struct ofport *port,
                                struct lacp_slave_stats *stats);
 
+    /* Get VLAN identifier.
+     *
+     * This function may be a null pointer if the ofproto implementation does
+     * not support VLAN.
+     */
+    int (*port_get_vlan_id)(const struct ofport *port);
+
+
 /* ## ----------------------- ## */
 /* ## OpenFlow Rule Functions ## */
 /* ## ----------------------- ## */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index de1c469..2c35cc0 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1316,6 +1316,22 @@ ofproto_port_get_lacp_stats(const struct ofport *port, 
struct lacp_slave_stats *
 
     return error;
 }
+
+int
+ofproto_port_get_vlan_id(const struct ofport *port)
+{
+    struct ofproto *ofproto = port->ofproto;
+    int vlan_id;
+
+    if (ofproto->ofproto_class->port_get_vlan_id) {
+        vlan_id = ofproto->ofproto_class->port_get_vlan_id(port);
+    } else {
+        vlan_id = -EOPNOTSUPP;
+    }
+
+    return vlan_id;
+}
+
 
 /* Bundles. */
 
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index d813fda..bc689ed 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -353,6 +353,7 @@ int ofproto_port_get_bfd_status(struct ofproto *, 
ofp_port_t ofp_port,
                                 struct smap *);
 int ofproto_port_is_lacp_current(struct ofproto *, ofp_port_t ofp_port);
 int ofproto_port_get_lacp_stats(const struct ofport *, struct lacp_slave_stats 
*);
+int ofproto_port_get_vlan_id(const struct ofport *);
 int ofproto_port_set_stp(struct ofproto *, ofp_port_t ofp_port,
                          const struct ofproto_port_stp_settings *);
 int ofproto_port_get_stp_status(struct ofproto *, ofp_port_t ofp_port,
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index ec7bd60..5919a78 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -5301,6 +5301,9 @@ m4_define([CHECK_SFLOW_SAMPLING_PACKET],
      --id=@sf create sflow targets=\"$1:$SFLOW_PORT\" \
        header=128 sampling=1 polling=1 agent=$LOOPBACK_INTERFACE
 
+  dnl add vlan port for checking vlan counters
+  ovs-vsctl add-port br0 p3 tag=10 -- set Interface p3 type=dummy 
options:ifindex=1005
+
   dnl open with ARP packets to seed the bridge-learning.  The output
   dnl ifIndex numbers should be reported predictably after that.
   dnl Since we set sampling=1 we should see all of these packets
@@ -5430,13 +5433,148 @@ 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|VLANCOUNTERS' | head -39 | 
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
+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:1004
        csSeqNo=1
-       ifindex=1002
+       ifindex=1004
+       type=6
+       ifspeed=100000000
+       direction=0
+       status=0
+       in_octets=84
+       in_unicasts=2
+       in_multicasts=4294967295
+       in_broadcasts=4294967295
+       in_discards=4294967295
+       in_errors=4294967295
+       in_unknownprotos=4294967295
+       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:1005
+       csSeqNo=1
+       ifindex=1005
        type=6
        ifspeed=100000000
        direction=0
@@ -5448,24 +5586,24 @@ IFCOUNTERS
        in_discards=4294967295
        in_errors=4294967295
        in_unknownprotos=4294967295
-       out_octets=84
-       out_unicasts=2
+       out_octets=0
+       out_unicasts=0
        out_multicasts=4294967295
        out_broadcasts=4294967295
        out_discards=4294967295
        out_errors=4294967295
        promiscuous=0
 IFCOUNTERS
-       dgramSeqNo=1
-       ds=127.0.0.1>0:1003
+       dgramSeqNo=2
+       ds=127.0.0.1>0:1002
        csSeqNo=1
-       ifindex=1003
+       ifindex=1002
        type=6
        ifspeed=100000000
        direction=0
        status=0
-       in_octets=138
-       in_unicasts=3
+       in_octets=0
+       in_unicasts=0
        in_multicasts=4294967295
        in_broadcasts=4294967295
        in_discards=4294967295
@@ -5479,30 +5617,30 @@ IFCOUNTERS
        out_errors=4294967295
        promiscuous=0
 IFCOUNTERS
-       dgramSeqNo=1
-       ds=127.0.0.1>0:1004
+       dgramSeqNo=2
+       ds=127.0.0.1>0:1003
        csSeqNo=1
-       ifindex=1004
+       ifindex=1003
        type=6
        ifspeed=100000000
        direction=0
        status=0
-       in_octets=84
-       in_unicasts=2
+       in_octets=138
+       in_unicasts=3
        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
@@ -5525,7 +5663,7 @@ IFCOUNTERS
        out_errors=4294967295
        promiscuous=0
 IFCOUNTERS
-       dgramSeqNo=2
+       dgramSeqNo=3
        ds=127.0.0.1>0:1003
        csSeqNo=2
        ifindex=1003
@@ -5548,7 +5686,7 @@ IFCOUNTERS
        out_errors=4294967295
        promiscuous=0
 IFCOUNTERS
-       dgramSeqNo=2
+       dgramSeqNo=3
        ds=127.0.0.1>0:1004
        csSeqNo=2
        ifindex=1004
@@ -5570,6 +5708,29 @@ IFCOUNTERS
        out_discards=4294967295
        out_errors=4294967295
        promiscuous=0
+IFCOUNTERS
+       dgramSeqNo=3
+       ds=127.0.0.1>0:1005
+       csSeqNo=2
+       ifindex=1005
+       type=6
+       ifspeed=100000000
+       direction=0
+       status=0
+       in_octets=0
+       in_unicasts=0
+       in_multicasts=4294967295
+       in_broadcasts=4294967295
+       in_discards=4294967295
+       in_errors=4294967295
+       in_unknownprotos=4294967295
+       out_octets=0
+       out_unicasts=0
+       out_multicasts=4294967295
+       out_broadcasts=4294967295
+       out_discards=4294967295
+       out_errors=4294967295
+       promiscuous=0
 OPENFLOWPORT
        datapath_id=18364758544493064720
        port_no=1
@@ -5584,6 +5745,12 @@ OPENFLOWPORT
        port_no=2
 OPENFLOWPORT
        datapath_id=18364758544493064720
+       port_no=3
+OPENFLOWPORT
+       datapath_id=18364758544493064720
+       port_no=3
+OPENFLOWPORT
+       datapath_id=18364758544493064720
        port_no=65534
 OPENFLOWPORT
        datapath_id=18364758544493064720
@@ -5600,6 +5767,24 @@ PORTNAME
        portName=p2
 PORTNAME
        portName=p2
+PORTNAME
+       portName=p3
+PORTNAME
+       portName=p3
+VLANCOUNTERS
+       vlan_id=10
+       octets=0
+       ucastPkts=0
+       multicastPkts=4294967295
+       broadcastPkts=4294967295
+       discards=4294967295
+VLANCOUNTERS
+       vlan_id=10
+       octets=0
+       ucastPkts=0
+       multicastPkts=4294967295
+       broadcastPkts=4294967295
+       discards=4294967295
 ])])
 
 AT_SETUP([ofproto-dpif - basic truncate action])
diff --git a/tests/test-sflow.c b/tests/test-sflow.c
index 60870df..8875f32 100644
--- a/tests/test-sflow.c
+++ b/tests/test-sflow.c
@@ -54,6 +54,8 @@ 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_VLANCOUNTERS 5
 #define SFLOW_TAG_CTR_LACPCOUNTERS 7
 #define SFLOW_TAG_CTR_OPENFLOWPORT 1004
 #define SFLOW_TAG_CTR_PORTNAME 1005
@@ -115,7 +117,9 @@ 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 VLANCOUNTERS;
        uint32_t LACPCOUNTERS;
        uint32_t OPENFLOWPORT;
        uint32_t PORTNAME;
@@ -297,6 +301,37 @@ 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");
+    }
+    if (x->offset.VLANCOUNTERS) {
+        sflowxdr_setc(x, x->offset.VLANCOUNTERS);
+        printf("VLANCOUNTERS");
+        printf(" vlan_id=%"PRIu32, sflowxdr_next(x));
+        printf(" octets=%"PRIu64, sflowxdr_next_int64(x));
+        printf(" ucastPkts=%"PRIu32, sflowxdr_next(x));
+        printf(" multicastPkts=%"PRIu32, sflowxdr_next(x));
+        printf(" broadcastPkts=%"PRIu32, sflowxdr_next(x));
+        printf(" discards=%"PRIu32, sflowxdr_next(x));
+        printf("\n");
+    }
+
 }
 
 static char
@@ -513,6 +548,12 @@ 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_VLANCOUNTERS:
+                    sflowxdr_mark_unique(x, &x->offset.VLANCOUNTERS);
+                    break;
                 case SFLOW_TAG_CTR_LACPCOUNTERS:
                     sflowxdr_mark_unique(x, &x->offset.LACPCOUNTERS);
                     break;
-- 
1.8.3.1

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

Reply via email to