Skip to content

Commit 609cf63

Browse files
committed
ndp ctt integration - parsing metadata from ndp pkt
1 parent cc7b4e4 commit 609cf63

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

input/ndp.cpp

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,41 @@
2727
*
2828
*/
2929

30+
#include <cstdint>
3031
#include <cstdio>
3132
#include <cstring>
32-
#include <iostream>
33+
#include <netinet/in.h>
34+
#include <sys/types.h>
35+
#include <cstdint>
36+
#include <cstddef>
37+
#include <inttypes.h>
3338

3439
#include "ndp.hpp"
40+
#include "ipfixprobe/packet.hpp"
41+
#include "ipfixprobe/plugin.hpp"
3542
#include "parser.hpp"
3643

3744
namespace ipxp {
3845

46+
uint64_t extract(const uint8_t* bitvec, size_t start_bit, size_t bit_length) {
47+
size_t start_byte = start_bit / 8;
48+
size_t end_bit = start_bit + bit_length;
49+
size_t end_byte = (end_bit + 7) / 8;
50+
uint64_t value = 0;
51+
for (size_t i = 0; i < end_byte - start_byte; ++i) {
52+
value |= static_cast<uint64_t>(bitvec[start_byte + i]) << (8 * i);
53+
}
54+
value >>= (start_bit % 8);
55+
uint64_t mask = (bit_length == 64) ? ~0ULL : ((1ULL << bit_length) - 1);
56+
return value & mask;
57+
}
58+
3959
telemetry::Content NdpPacketReader::get_queue_telemetry()
4060
{
4161
telemetry::Dict dict;
4262
dict["received_packets"] = m_stats.receivedPackets;
4363
dict["received_bytes"] = m_stats.receivedBytes;
64+
dict["bad_metadata"] = m_stats.bad_metadata;
4465
return dict;
4566
}
4667

@@ -71,6 +92,9 @@ void NdpPacketReader::init(const char *params)
7192
if (parser.m_dev.empty()) {
7293
throw PluginError("specify device path");
7394
}
95+
if (parser.m_metadata == "ctt") {
96+
m_ctt_metadata = true;
97+
}
7498
init_ifc(parser.m_dev);
7599
}
76100

@@ -86,6 +110,38 @@ void NdpPacketReader::init_ifc(const std::string &dev)
86110
}
87111
}
88112

113+
int NdpPacketReader::parse_ctt_metadata(const ndp_packet *ndp_packet, Metadata_CTT &ctt)
114+
{
115+
if (ndp_packet->header_length != 32) {
116+
return -1;
117+
}
118+
const uint8_t *metadata = ndp_packet->header;
119+
120+
ctt.ts.tv_usec = extract(metadata, 0, 32);
121+
ctt.ts.tv_sec = extract(metadata, 32, 32);
122+
ctt.vlan_tci = extract(metadata, 64, 16);
123+
ctt.vlan_vld = extract(metadata, 80, 1);
124+
ctt.vlan_stripped = extract(metadata, 81, 1);
125+
ctt.ip_csum_status = static_cast<CsumStatus>(extract(metadata, 82, 2));
126+
ctt.l4_csum_status = static_cast<CsumStatus>(extract(metadata, 84, 2));
127+
ctt.parser_status = static_cast<ParserStatus>(extract(metadata, 86, 2));
128+
ctt.ifc = extract(metadata, 88, 8);
129+
ctt.filter_bitmap = extract(metadata, 96, 16);
130+
ctt.ctt_export_trig = extract(metadata, 112, 1);
131+
ctt.ctt_rec_matched = extract(metadata, 113, 1);
132+
ctt.ctt_rec_created = extract(metadata, 114, 1);
133+
ctt.ctt_rec_deleted = extract(metadata, 115, 1);
134+
ctt.flow_hash = extract(metadata, 128, 64);
135+
ctt.l2_len = extract(metadata, 192, 7);
136+
ctt.l3_len = extract(metadata, 199, 9);
137+
ctt.l4_len = extract(metadata, 208, 8);
138+
ctt.l2_ptype = static_cast<L2PType>(extract(metadata, 216, 4));
139+
ctt.l3_ptype = static_cast<L3PType>(extract(metadata, 220, 4));
140+
ctt.l4_ptype = static_cast<L4PType>(extract(metadata, 224, 4));
141+
142+
return 0;
143+
}
144+
89145
InputPlugin::Result NdpPacketReader::get(PacketBlock &packets)
90146
{
91147
parser_opt_t opt = {&packets, false, false, 0};
@@ -107,7 +163,18 @@ InputPlugin::Result NdpPacketReader::get(PacketBlock &packets)
107163
throw PluginError(ndpReader.error_msg);
108164
}
109165
read_pkts++;
110-
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
166+
if (m_ctt_metadata) {
167+
Metadata_CTT ctt;
168+
int ret = parse_ctt_metadata(ndp_packet, ctt);
169+
if (ret == -1) {
170+
m_stats.bad_metadata++;
171+
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
172+
} else {
173+
parse_packet_ctt_metadata(&opt, m_parser_stats, ctt, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
174+
}
175+
} else {
176+
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
177+
}
111178
}
112179

113180
m_seen += read_pkts;

input/ndp.hpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,31 @@
3030
#ifndef IPXP_INPUT_NDP_HPP
3131
#define IPXP_INPUT_NDP_HPP
3232

33+
#include <bits/types/struct_timeval.h>
3334
#include <ndpreader.hpp>
3435

3536
#include <ipfixprobe/input.hpp>
3637
#include <ipfixprobe/packet.hpp>
3738
#include <ipfixprobe/options.hpp>
3839
#include <ipfixprobe/utils.hpp>
3940

41+
#include "ipfixprobe/cttmeta.hpp"
42+
4043
namespace ipxp {
4144

4245
class NdpOptParser : public OptionsParser
4346
{
4447
public:
4548
std::string m_dev;
4649
uint64_t m_id;
50+
std::string m_metadata;
4751

48-
NdpOptParser() : OptionsParser("ndp", "Input plugin for reading packets from a ndp device"), m_dev(""), m_id(0)
52+
NdpOptParser() : OptionsParser("ndp", "Input plugin for reading packets from a ndp device"), m_dev(""), m_id(0), m_metadata("")
4953
{
5054
register_option("d", "dev", "PATH", "Path to a device file", [this](const char *arg){m_dev = arg; return true;}, OptionFlags::RequiredArgument);
5155
register_option("I", "id", "NUM", "Link identifier number",
52-
[this](const char *arg){try {m_id = str2num<decltype(m_id)>(arg);} catch(std::invalid_argument &e) {return false;} return true;},
53-
OptionFlags::RequiredArgument);
56+
[this](const char *arg){try {m_id = str2num<decltype(m_id)>(arg);} catch(std::invalid_argument &e) {return false;} return true;}, OptionFlags::RequiredArgument);
57+
register_option("M", "meta", "Metadata type", "Choose metadata type if any", [this](const char *arg){m_metadata = arg; return true;}, OptionFlags::RequiredArgument);
5458
}
5559
};
5660

@@ -74,14 +78,18 @@ class NdpPacketReader : public InputPlugin
7478
struct RxStats {
7579
uint64_t receivedPackets;
7680
uint64_t receivedBytes;
81+
uint64_t bad_metadata;
7782
};
7883

7984
telemetry::Content get_queue_telemetry();
8085

8186
NdpReader ndpReader;
8287
RxStats m_stats = {};
8388

89+
bool m_ctt_metadata = false;
90+
8491
void init_ifc(const std::string &dev);
92+
int parse_ctt_metadata(const ndp_packet *ndp_packet, Metadata_CTT &ctt);
8593
};
8694

8795
}

0 commit comments

Comments
 (0)