48uint16_t get_bdf_from_pcie_addr(
const std::string& pcie_addr) {
49 uint32_t domain, bus, dev, func;
52 if (sscanf(pcie_addr.c_str(),
"%x:%x.%x", &bus, &dev, &func) != 3) {
54 if (sscanf(pcie_addr.c_str(),
"%x:%x:%x.%x", &domain, &bus, &dev, &func) !=
60 bdf = (bus << 8) | (dev << 3) | (func & 0x7);
64void print_buf(
void* buf,
const uint32_t nb_cache_lines) {
65 for (uint32_t i = 0; i < nb_cache_lines * 64; i++) {
66 printf(
"%02x ", ((uint8_t*)buf)[i]);
67 if ((i + 1) % 8 == 0) {
70 if ((i + 1) % 16 == 0) {
73 if ((i + 1) % 64 == 0) {
79void print_ip(uint32_t ip) {
80 std::cout << ((ip >> 0) & 0xff) <<
"." << ((ip >> 8) & 0xff) <<
"."
81 << ((ip >> 16) & 0xff) <<
"." << ((ip >> 24) & 0xff);
84void print_pkt_ips(uint8_t* pkt) {
85 struct ether_header* l2_hdr = (
struct ether_header*)pkt;
86 struct iphdr* l3_hdr = (
struct iphdr*)(l2_hdr + 1);
89 print_ip(l3_hdr->saddr);
91 std::cout <<
" dst: ";
92 print_ip(l3_hdr->daddr);
94 std::cout << std::endl;
97void print_pkt_header(uint8_t* pkt) {
98 struct ether_header* l2_hdr = (
struct ether_header*)pkt;
99 std::cout <<
"Eth - dst MAC: " << ether_ntoa((ether_addr*)l2_hdr->ether_dhost)
100 <<
" src MAC: " << ether_ntoa((ether_addr*)l2_hdr->ether_shost)
103 struct iphdr* l3_hdr = (
struct iphdr*)(l2_hdr + 1);
105 uint8_t protocol = l3_hdr->protocol;
106 std::cout <<
"IP - protocol: " << (uint32_t)protocol
107 <<
" checksum: " << ntohs(l3_hdr->check);
109 std::cout <<
" src IP: ";
110 print_ip(l3_hdr->saddr);
112 std::cout <<
" dst IP: ";
113 print_ip(l3_hdr->daddr);
114 std::cout << std::endl;
118 struct tcphdr* l4_hdr = (
struct tcphdr*)(l3_hdr + 1);
119 std::cout <<
"TCP - src port: " << ntohs(l4_hdr->source)
120 <<
" dst port: " << ntohs(l4_hdr->dest)
121 <<
" seq: " << ntohl(l4_hdr->seq) << std::endl;
125 struct udphdr* l4_hdr = (
struct udphdr*)(l3_hdr + 1);
126 std::cout <<
"UDP - src port: " << ntohs(l4_hdr->source)
127 <<
" dst port: " << ntohs(l4_hdr->dest) << std::endl;
135int set_core_id(std::thread& thread,
int core_id) {
138 CPU_SET(core_id, &cpuset);
139 return pthread_setaffinity_np(thread.native_handle(),
sizeof(cpuset),
143static void print_stats_line(uint64_t recv_bytes, uint64_t nb_batches,
144 uint64_t nb_pkts, uint64_t delta_bytes,
145 uint64_t delta_pkts, uint64_t delta_batches) {
146 std::cout << std::dec << (delta_bytes + delta_pkts * 20) * 8. / 1e6
147 <<
" Mbps " << delta_pkts / 1e6 <<
" Mpps " << recv_bytes
148 <<
" B " << nb_batches <<
" batches " << nb_pkts <<
" pkts";
150 if (delta_batches > 0) {
151 std::cout <<
" " << delta_bytes / delta_batches <<
" B/batch";
152 std::cout <<
" " << delta_pkts / delta_batches <<
" pkt/batch";
154 std::cout << std::endl;
157void show_stats(
const std::vector<stats_t>& thread_stats,
158 volatile bool* keep_running) {
159 while (*keep_running) {
160 std::vector<uint64_t> recv_bytes_before;
161 std::vector<uint64_t> nb_batches_before;
162 std::vector<uint64_t> nb_pkts_before;
164 std::vector<uint64_t> recv_bytes_after;
165 std::vector<uint64_t> nb_batches_after;
166 std::vector<uint64_t> nb_pkts_after;
168 recv_bytes_before.reserve(thread_stats.size());
169 nb_batches_before.reserve(thread_stats.size());
170 nb_pkts_before.reserve(thread_stats.size());
172 recv_bytes_after.reserve(thread_stats.size());
173 nb_batches_after.reserve(thread_stats.size());
174 nb_pkts_after.reserve(thread_stats.size());
176 for (
auto& stats : thread_stats) {
177 recv_bytes_before.push_back(stats.recv_bytes);
178 nb_batches_before.push_back(stats.nb_batches);
179 nb_pkts_before.push_back(stats.nb_pkts);
182 std::this_thread::sleep_for(std::chrono::seconds(1));
184 for (
auto& stats : thread_stats) {
185 recv_bytes_after.push_back(stats.recv_bytes);
186 nb_batches_after.push_back(stats.nb_batches);
187 nb_pkts_after.push_back(stats.nb_pkts);
190 uint64_t total_recv_bytes = 0;
191 uint64_t total_nb_batches = 0;
192 uint64_t total_nb_pkts = 0;
194 uint64_t total_delta_bytes = 0;
195 uint64_t total_delta_pkts = 0;
196 uint64_t total_delta_batches = 0;
198 for (uint16_t i = 0; i < thread_stats.size(); ++i) {
199 uint64_t recv_bytes = recv_bytes_after[i];
200 uint64_t nb_batches = nb_batches_after[i];
201 uint64_t nb_pkts = nb_pkts_after[i];
203 total_recv_bytes += recv_bytes;
204 total_nb_batches += nb_batches;
205 total_nb_pkts += nb_pkts;
207 uint64_t delta_bytes = recv_bytes - recv_bytes_before[i];
208 uint64_t delta_pkts = nb_pkts - nb_pkts_before[i];
209 uint64_t delta_batches = nb_batches - nb_batches_before[i];
211 total_delta_bytes += delta_bytes;
212 total_delta_pkts += delta_pkts;
213 total_delta_batches += delta_batches;
216 if (thread_stats.size() > 1) {
217 std::cout <<
" Thread " << i <<
":" << std::endl;
219 print_stats_line(recv_bytes, nb_batches, nb_pkts, delta_bytes,
220 delta_pkts, delta_batches);
223 print_stats_line(total_recv_bytes, total_nb_batches, total_nb_pkts,
224 total_delta_bytes, total_delta_pkts, total_delta_batches);
226 if (thread_stats.size() > 1) {
227 std::cout << std::endl;
Miscellaneous helper functions.