Skip to content

Commit 019fcad

Browse files
committed
ndp ctt table controller - init
1 parent 8fc07dc commit 019fcad

File tree

8 files changed

+250
-8
lines changed

8 files changed

+250
-8
lines changed

include/ipfixprobe/flowifc.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ struct Flow : public Record {
263263
};
264264

265265
uint64_t flow_hash;
266+
uint64_t flow_hash_ctt; /**< Flow hash for CTT. */
267+
bool ctt_valid; /**< CTT validity flag. */
266268
PluginsStatus plugins_status; /**< Statuses of the process plugins for this flow, used to check
267269
if the flow process plugins requires all available data, only
268270
metadata or nothing of this. */

include/ipfixprobe/packet.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace ipxp {
4747
*/
4848
struct Packet : public Record {
4949
Metadata_CTT cttmeta; /**< Metadata from CTT */
50+
bool cttmeta_valid; /**< True if CTT metadata is valid */
5051
struct timeval ts;
5152

5253
uint8_t dst_mac[6];
@@ -108,7 +109,7 @@ struct Packet : public Record {
108109
* \brief Constructor.
109110
*/
110111
Packet() :
111-
ts({0}),
112+
cttmeta_valid(false), ts({0}),
112113
dst_mac(), src_mac(), ethertype(0),
113114
ip_len(0), ip_payload_len(0), ip_version(0), ip_ttl(0),
114115
ip_proto(0), ip_tos(0), ip_flags(0), src_ip({0}), dst_ip({0}), vlan_id(0),

include/ipfixprobe/storage.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ class StoragePlugin : public Plugin
189189
*/
190190
int plugins_post_create(Flow& rec, const Packet& pkt)
191191
{
192+
// if metadata are valid, add flow hash ctt to the flow record
193+
if (pkt.cttmeta_valid) {
194+
rec.ctt_valid = true;
195+
rec.flow_hash_ctt = pkt.cttmeta.flow_hash;
196+
} else {
197+
rec.ctt_valid = false;
198+
}
192199
PluginStatusConverter plugin_status_converter(m_plugins_status);
193200
int ret = 0;
194201
for (unsigned int i = 0; i < m_plugin_cnt; i++) {

input/ndp.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,10 @@ InputPlugin::Result NdpPacketReader::get(PacketBlock &packets)
170170
m_stats.bad_metadata++;
171171
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
172172
} else {
173-
parse_packet_ctt_metadata(&opt, m_parser_stats, ctt, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
173+
if (parse_packet_ctt_metadata(&opt, m_parser_stats, ctt, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length) == -1) {
174+
m_stats.bad_metadata++;
175+
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);
176+
}
174177
}
175178
} else {
176179
parse_packet(&opt, m_parser_stats, timestamp, ndp_packet->data, ndp_packet->data_length, ndp_packet->data_length);

input/parser.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#include "parser.hpp"
3737
#include "headers.hpp"
38+
#include <ipfixprobe/cttmeta.hpp>
3839
#include <ipfixprobe/packet.hpp>
3940

4041
namespace ipxp {
@@ -776,12 +777,21 @@ void parse_packet(parser_opt_t *opt, ParserStats& stats, struct timeval ts, cons
776777
opt->pblock->bytes += len;
777778
}
778779

779-
void parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Metadata_CTT& metadata, const uint8_t *data, uint16_t len, uint16_t caplen)
780+
int parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Metadata_CTT& metadata, const uint8_t *data, uint16_t len, uint16_t caplen)
780781
{
781782
if (opt->pblock->cnt >= opt->pblock->size) {
782-
return;
783+
return 0;
783784
}
784785
Packet *pkt = &opt->pblock->pkts[opt->pblock->cnt];
786+
787+
// check metadata validity
788+
if (metadata.parser_status == PA_OK) {
789+
pkt->cttmeta_valid = true;
790+
} else {
791+
pkt->cttmeta_valid = false;
792+
return -1;
793+
}
794+
785795
pkt->cttmeta = metadata;
786796

787797
pkt->packet_len_wire = len;
@@ -831,7 +841,7 @@ void parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Meta
831841
stats.pppoe_packets++;
832842
} else { // if not previous, we try delegate to original parser
833843
parse_packet(opt, stats, metadata.ts, data, len, caplen);
834-
return;
844+
return 0;
835845
}
836846

837847
// L4
@@ -843,11 +853,11 @@ void parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Meta
843853
stats.udp_packets++;
844854
} else { // if not previous, we try delegate to original parser
845855
parse_packet(opt, stats, metadata.ts, data, len, caplen);
846-
return;
856+
return 0;
847857
}
848858
} catch (const char *err) {
849859
DEBUG_MSG("%s\n", err);
850-
return;
860+
return 0;
851861
}
852862

853863
if (pkt->vlan_id) {
@@ -880,6 +890,7 @@ void parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Meta
880890
opt->packet_valid = true;
881891
opt->pblock->cnt++;
882892
opt->pblock->bytes += len;
893+
return 0;
883894
}
884895

885896
}

input/parser.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ typedef struct parser_opt_s {
8686
*/
8787
void parse_packet(parser_opt_t *opt, ParserStats& stats, struct timeval ts, const uint8_t *data, uint16_t len, uint16_t caplen);
8888

89-
void parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Metadata_CTT& metadata, const uint8_t *data, uint16_t len, uint16_t caplen);
89+
int parse_packet_ctt_metadata(parser_opt_t *opt, ParserStats& stats, const Metadata_CTT& metadata, const uint8_t *data, uint16_t len, uint16_t caplen);
9090

9191
}
9292
#endif /* IPXP_INPUT_PARSER_HPP */

storage/ctt-controller.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* \file ctt-controller.cpp
3+
* \brief Connection Tracking Table (CTT) controller
4+
* \author Jaroslav Pesek <[email protected]>
5+
* \date 2024
6+
*/
7+
/*
8+
* Copyright (C) 2024 CESNET
9+
*
10+
* LICENSE TERMS
11+
*
12+
* Redistribution and use in source and binary forms, with or without
13+
* modification, are permitted provided that the following conditions
14+
* are met:
15+
* 1. Redistributions of source code must retain the above copyright
16+
* notice, this list of conditions and the following disclaimer.
17+
* 2. Redistributions in binary form must reproduce the above copyright
18+
* notice, this list of conditions and the following disclaimer in
19+
* the documentation and/or other materials provided with the
20+
* distribution.
21+
* 3. Neither the name of the Company nor the names of its contributors
22+
* may be used to endorse or promote products derived from this
23+
* software without specific prior written permission.
24+
*
25+
*
26+
*
27+
*/
28+
29+
#include "ctt-controller.hpp"
30+
#include <cstddef>
31+
#include <vector>
32+
33+
namespace ipxp {
34+
35+
CttController::CttController(const std::string& nfb_dev, unsigned ctt_comp_index)
36+
: m_commander(ctt::NfbParams{nfb_dev, ctt_comp_index})
37+
{
38+
try {
39+
// Get UserInfo to determine key, state, and state_mask sizes
40+
ctt::UserInfo user_info = m_commander.get_user_info();
41+
key_size_bytes = (user_info.key_bit_width + 7) / 8;
42+
state_size_bytes = (user_info.state_bit_width + 7) / 8;
43+
state_mask_size_bytes = (user_info.state_mask_bit_width + 7) / 8;
44+
45+
// Enable the CTT
46+
std::future<void> enable_future = m_commander.enable(true);
47+
enable_future.wait();
48+
}
49+
catch (const std::exception& e) {
50+
throw;
51+
}
52+
}
53+
54+
void CttController::create_record(uint64_t flow_hash_ctt, const struct timeval& ts)
55+
{
56+
try {
57+
std::vector<std::byte> key = assemble_key(flow_hash_ctt);
58+
std::vector<std::byte> state = assemble_state(
59+
OffloadMode::PACKET_OFFLOAD_WITH_EXPORT,
60+
MetaType::FULL,
61+
ts);
62+
63+
m_commander.write_record(std::move(key), std::move(state));
64+
}
65+
catch (const std::exception& e) {
66+
throw;
67+
}
68+
}
69+
70+
void CttController::export_record(uint64_t flow_hash_ctt)
71+
{
72+
try {
73+
std::vector<std::byte> key = assemble_key(flow_hash_ctt);
74+
75+
m_commander.export_record(std::move(key));
76+
}
77+
catch (const std::exception& e) {
78+
throw;
79+
}
80+
}
81+
82+
std::vector<std::byte> CttController::assemble_key(uint64_t flow_hash_ctt)
83+
{
84+
std::vector<std::byte> key(key_size_bytes, std::byte(0));
85+
for (size_t i = 0; i < sizeof(flow_hash_ctt) && i < key_size_bytes; ++i) {
86+
key[i] = static_cast<std::byte>((flow_hash_ctt >> (8 * i)) & 0xFF);
87+
}
88+
return key;
89+
90+
}
91+
92+
std::vector<std::byte> CttController::assemble_state(
93+
OffloadMode offload_mode, MetaType meta_type, const struct timeval& ts)
94+
{
95+
std::vector<std::byte> state(state_size_bytes, std::byte(0));
96+
std::vector<std::byte> state_mask(state_mask_size_bytes, std::byte(0));
97+
98+
state[0] = static_cast<std::byte>(offload_mode);
99+
state[1] = static_cast<std::byte>(meta_type);
100+
101+
// timestamp in sec/ns format, 32+32 bits - 64 bits in total
102+
for (size_t i = 0; i < sizeof(ts.tv_sec) && i < 4; ++i) {
103+
state[2 + i] = static_cast<std::byte>((ts.tv_sec >> (8 * i)) & 0xFF);
104+
}
105+
for (size_t i = 0; i < sizeof(ts.tv_usec) && i < 4; ++i) {
106+
state[6 + i] = static_cast<std::byte>((ts.tv_usec >> (8 * i)) & 0xFF);
107+
}
108+
return state;
109+
}
110+
111+
} // namespace ipxp

storage/ctt-controller.hpp

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/**
2+
* \file ctt-controller.hpp
3+
* \brief Connection Tracking Table (CTT) controller
4+
* \author Jaroslav Pesek <[email protected]>
5+
* \date 2024
6+
*/
7+
/*
8+
* Copyright (C) 2024 CESNET
9+
*
10+
* LICENSE TERMS
11+
*
12+
* Redistribution and use in source and binary forms, with or without
13+
* modification, are permitted provided that the following conditions
14+
* are met:
15+
* 1. Redistributions of source code must retain the above copyright
16+
* notice, this list of conditions and the following disclaimer.
17+
* 2. Redistributions in binary form must reproduce the above copyright
18+
* notice, this list of conditions and the following disclaimer in
19+
* the documentation and/or other materials provided with the
20+
* distribution.
21+
* 3. Neither the name of the Company nor the names of its contributors
22+
* may be used to endorse or promote products derived from this
23+
* software without specific prior written permission.
24+
*
25+
*
26+
*
27+
*/
28+
29+
#ifndef IPXP_CTT_CONTROLLER_HPP
30+
#define IPXP_CTT_CONTROLLER_HPP
31+
32+
#include <sys/time.h>
33+
34+
#include <ctt_async.hpp>
35+
#include <ctt_factory.hpp>
36+
#include <ctt_exceptions.hpp>
37+
#include <ctt_modes.hpp>
38+
39+
#include <ipfixprobe/flowifc.hpp>
40+
41+
namespace ipxp {
42+
43+
class CttController {
44+
public:
45+
enum class OffloadMode : uint8_t {
46+
NO_OFFLOAD = 0x0,
47+
PACKET_OFFLOAD = 0x1,
48+
META_EXPORT = 0x2,
49+
PACKET_OFFLOAD_WITH_EXPORT = 0x3
50+
};
51+
enum class MetaType : uint8_t {
52+
FULL = 0x0,
53+
HALF = 0x1,
54+
TS_ONLY = 0x2,
55+
NO_META = 0x3
56+
};
57+
/**
58+
* @brief Constructor that initializes the CTT.
59+
*
60+
* @param nfb_dev The NFB device file (e.g., "/dev/nfb0").
61+
* @param ctt_comp_index The index of the CTT component.
62+
*/
63+
CttController(const std::string& nfb_dev, unsigned ctt_comp_index);
64+
65+
/**
66+
* @brief Command: mark a flow for offload.
67+
*
68+
* @param flow_hash_ctt The flow hash to be offloaded.
69+
*/
70+
void create_record(uint64_t flow_hash_ctt, const struct timeval& timestamp_first);
71+
72+
/**
73+
* @brief Command: export a flow from the CTT.
74+
*
75+
* @param flow_hash_ctt The flow hash to be exported.
76+
*/
77+
void export_record(uint64_t flow_hash_ctt);
78+
79+
private:
80+
ctt::AsyncCommander m_commander;
81+
size_t key_size_bytes;
82+
size_t state_size_bytes;
83+
size_t state_mask_size_bytes;
84+
85+
/**
86+
* @brief Assembles the state vector from the given values.
87+
*
88+
* @param offload_mode The offload mode.
89+
* @param meta_type The metadata type.
90+
* @param timestamp_first The first timestamp of the flow.
91+
* @return A byte vector representing the assembled state vector.
92+
*/
93+
std::vector<std::byte> assemble_state(
94+
OffloadMode offload_mode, MetaType meta_type,
95+
const struct timeval& timestamp_first);
96+
97+
/**
98+
* @brief Assembles the key vector from the given flow hash.
99+
*
100+
* @param flow_hash_ctt The flow hash.
101+
* @return A byte vector representing the assembled key vector.
102+
*/
103+
std::vector<std::byte> assemble_key(uint64_t flow_hash_ctt);
104+
};
105+
} // namespace ipxp
106+
107+
#endif /* IPXP_CTT_CONTROLLER_HPP */

0 commit comments

Comments
 (0)