summaryrefslogtreecommitdiffstats
path: root/src/flow_stat_parser.cpp
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-02-08 11:25:07 +0200
committerIdo Barnea <ibarnea@cisco.com>2016-02-24 14:21:29 +0200
commitf0ab9eba97221e491cf7b3dd846eb8c23d920ec2 (patch)
treecaf0b2f4f9cc0874a53bb3af813d5bae8d644914 /src/flow_stat_parser.cpp
parent252b8ab3f41a18af8561cece71cf07bc9872f39f (diff)
Rx stat per flow. Low level working for xl710, and partly for i350.
added full clone (with CP VM) to stream
Diffstat (limited to 'src/flow_stat_parser.cpp')
-rw-r--r--src/flow_stat_parser.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/flow_stat_parser.cpp b/src/flow_stat_parser.cpp
new file mode 100644
index 00000000..52824f73
--- /dev/null
+++ b/src/flow_stat_parser.cpp
@@ -0,0 +1,137 @@
+/*
+ Ido Barnea
+ Cisco Systems, Inc.
+*/
+
+/*
+ Copyright (c) 2016-2016 Cisco Systems, Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <common/basic_utils.h>
+#include <common/Network/Packet/IPHeader.h>
+#include <common/Network/Packet/IPv6Header.h>
+#include <common/Network/Packet/EthernetHeader.h>
+#include <flow_stat_parser.h>
+
+Cxl710Parser::Cxl710Parser() {
+ reset();
+}
+
+void Cxl710Parser::reset() {
+ m_ipv4 = 0;
+ m_l4_proto = 0;
+ m_fdir_supported = false;
+}
+
+int Cxl710Parser::parse(uint8_t *p, uint16_t len) {
+ EthernetHeader *ether = (EthernetHeader *)p;
+
+ switch( ether->getNextProtocol() ) {
+ case EthernetHeader::Protocol::IP :
+ m_ipv4 = (IPHeader *)(p + 14);
+ m_fdir_supported = true;
+ break;
+ case EthernetHeader::Protocol::VLAN :
+ switch ( ether->getVlanProtocol() ){
+ case EthernetHeader::Protocol::IP:
+ m_ipv4 = (IPHeader *)(p + 18);
+ m_fdir_supported = true;
+ break;
+ default:
+ m_fdir_supported = false;
+ return -1;
+ }
+
+ break;
+ default:
+ m_fdir_supported = false;
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
+int Cxl710Parser::get_ip_id(uint16_t &ip_id) {
+ if (! m_ipv4)
+ return -1;
+
+ ip_id = m_ipv4->getId();
+
+ return 0;
+}
+
+int Cxl710Parser::set_ip_id(uint16_t new_id) {
+ if (! m_ipv4)
+ return -1;
+
+ // Updating checksum, not recalculating, so if someone put bad checksum on purpose, it will stay bad
+ m_ipv4->updateCheckSum(m_ipv4->getId(), PKT_NTOHS(new_id));
+ m_ipv4->setId(new_id);
+
+ return 0;
+}
+
+int Cxl710Parser::get_l4_proto(uint8_t &proto) {
+ if (! m_ipv4)
+ return -1;
+
+ proto = m_ipv4->getProtocol();
+
+ return 0;
+}
+
+static const uint16_t TEST_IP_ID = 0xabcd;
+static const uint8_t TEST_L4_PROTO = 0x11;
+
+int Cxl710Parser::test() {
+ uint16_t ip_id = 0;
+ uint8_t l4_proto;
+ uint8_t test_pkt[] = {
+ // ether header
+ 0x74, 0xa2, 0xe6, 0xd5, 0x39, 0x25,
+ 0xa0, 0x36, 0x9f, 0x38, 0xa4, 0x02,
+ 0x81, 0x00,
+ 0x0a, 0xbc, 0x08, 0x00, // vlan
+ // IP header
+ 0x45,0x02,0x00,0x30,
+ 0x00,0x00,0x40,0x00,
+ 0xff, TEST_L4_PROTO, 0xbd,0x04,
+ 0x10,0x0,0x0,0x1,
+ 0x30,0x0,0x0,0x1,
+ };
+
+ // good packet
+ assert (parse(test_pkt, sizeof(test_pkt)) == 0);
+ m_ipv4->updateCheckSum();
+ assert(m_ipv4->isChecksumOK() == true);
+ set_ip_id(TEST_IP_ID);
+ // utl_DumpBuffer(stdout, test_pkt, sizeof(test_pkt), 0);
+ get_ip_id(ip_id);
+ assert(ip_id == TEST_IP_ID);
+ assert(m_ipv4->isChecksumOK() == true);
+ assert(get_l4_proto(l4_proto) == 0);
+ assert(l4_proto == TEST_L4_PROTO);
+ assert(m_fdir_supported == true);
+
+ reset();
+
+ // bad packet
+ test_pkt[16] = 0xaa;
+ assert (parse(test_pkt, sizeof(test_pkt)) == -1);
+ assert(m_fdir_supported == false);
+
+ return 0;
+}