From af25eb9b8463225827fd38223f36a9c361f2d254 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Mon, 13 Mar 2017 22:28:09 +0200 Subject: Software mode for latency and flow stat statistics Also supporting QinQ for flow stat Signed-off-by: Ido Barnea --- src/flow_stat_parser.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) (limited to 'src/flow_stat_parser.cpp') diff --git a/src/flow_stat_parser.cpp b/src/flow_stat_parser.cpp index 4a6722e6..417299ee 100644 --- a/src/flow_stat_parser.cpp +++ b/src/flow_stat_parser.cpp @@ -371,6 +371,129 @@ int CFlowStatParserTest::test() { return 0; } +int CFlowStatParserSW::parse(uint8_t *p, uint16_t len) { + EthernetHeader *ether = (EthernetHeader *)p; + int min_len = ETH_HDR_LEN; + reset(); + + if (len < min_len) + return -1; + + m_start = p; + m_len = len; + switch( ether->getNextProtocol() ) { + case EthernetHeader::Protocol::IP : + min_len += IPV4_HDR_LEN; + if (len < min_len) + return -1; + m_ipv4 = (IPHeader *)(p + ETH_HDR_LEN); + m_l4 = ((uint8_t *)m_ipv4) + m_ipv4->getHeaderLength(); + m_l4_proto = m_ipv4->getProtocol(); + m_stat_supported = true; + break; + case EthernetHeader::Protocol::IPv6 : + min_len += IPV6_HDR_LEN; + if (len < min_len) + return -1; + m_ipv6 = (IPv6Header *)(p + ETH_HDR_LEN); + m_stat_supported = true; + break; + case EthernetHeader::Protocol::VLAN : + m_vlan_offset = 4; + min_len += 4; + if (len < min_len) + return -1; + + switch ( ether->getVlanProtocol() ){ + case EthernetHeader::Protocol::IP: + min_len += IPV4_HDR_LEN; + if (len < min_len) + return -1; + m_ipv4 = (IPHeader *)(p + ETH_HDR_LEN + 4); + m_l4 = ((uint8_t *)m_ipv4) + m_ipv4->getHeaderLength(); + m_l4_proto = m_ipv4->getProtocol(); + m_stat_supported = true; + break; + case EthernetHeader::Protocol::IPv6 : + min_len += IPV6_HDR_LEN; + if (len < min_len) + return -1; + m_ipv6 = (IPv6Header *)(p + ETH_HDR_LEN + 4); + m_stat_supported = true; + break; + case EthernetHeader::Protocol::VLAN : + m_vlan_offset = 8; + min_len += 8; + if (len < min_len) + return -1; + + switch ( ether->getQinQProtocol() ){ + case EthernetHeader::Protocol::IP: + min_len += IPV4_HDR_LEN; + if (len < min_len) + return -1; + m_ipv4 = (IPHeader *)(p + ETH_HDR_LEN + 8); + m_l4 = ((uint8_t *)m_ipv4) + m_ipv4->getHeaderLength(); + m_l4_proto = m_ipv4->getProtocol(); + m_stat_supported = true; + break; + case EthernetHeader::Protocol::IPv6 : + min_len += IPV6_HDR_LEN; + if (len < min_len) + return -1; + m_ipv6 = (IPv6Header *)(p + ETH_HDR_LEN + 8); + m_stat_supported = true; + break; + default: + m_stat_supported = false; + return -1; + } + break; + + default: + m_stat_supported = false; + return -1; + } + break; + + case EthernetHeader::Protocol::QINQ : + m_vlan_offset = 8; + min_len += 8; + if (len < min_len) + return -1; + + switch ( ether->getQinQProtocol() ) { + case EthernetHeader::Protocol::IP: + min_len += IPV4_HDR_LEN; + if (len < min_len) + return -1; + m_ipv4 = (IPHeader *)(p + ETH_HDR_LEN + 8); + m_l4 = ((uint8_t *)m_ipv4) + m_ipv4->getHeaderLength(); + m_l4_proto = m_ipv4->getProtocol(); + m_stat_supported = true; + break; + case EthernetHeader::Protocol::IPv6 : + min_len += IPV6_HDR_LEN; + if (len < min_len) + return -1; + m_ipv6 = (IPv6Header *)(p + ETH_HDR_LEN + 8); + m_stat_supported = true; + break; + default: + m_stat_supported = false; + return -1; + } + break; + + default: + m_stat_supported = false; + return -1; + break; + } + + return 0; +} + // In 82599 10G card we do not support VLANs int C82599Parser::parse(uint8_t *p, uint16_t len) { EthernetHeader *ether = (EthernetHeader *)p; -- cgit 1.2.3-korg