1
0
Fork 0
mirror of https://github.com/pavel-odintsov/fastnetmon synced 2024-06-08 16:46:06 +02:00

Added option to control fanout mode in AF_PACKET.

This commit is contained in:
Pavel Odintsov 2022-02-09 14:27:32 +00:00
parent 69e4140629
commit 6e6f1ca053
2 changed files with 52 additions and 7 deletions

View File

@ -43,14 +43,16 @@
#include <sys/mman.h>
#include <sys/socket.h>
#include <linux/filter.h> // for struct sock_filter
#include "../unified_parser.hpp"
bool afpacket_read_packet_length_from_ip_header = false;
// Get log4cpp logger from main program
// Get log4cpp logger from main programm
extern log4cpp::Category& logger;
// Pass unparsed packets number to main program
// Pass unparsed packets number to main programm
extern uint64_t total_unparsed_packets;
// Global configuration map
@ -74,6 +76,44 @@ struct block_desc {
struct tpacket_hdr_v1 h1;
};
/*
* - PACKET_FANOUT_HASH: schedule to socket by skb's packet hash
* - PACKET_FANOUT_LB: schedule to socket by round-robin
* - PACKET_FANOUT_CPU: schedule to socket by CPU packet arrives on
* - PACKET_FANOUT_RND: schedule to socket by random selection
* - PACKET_FANOUT_ROLLOVER: if one socket is full, rollover to another
* - PACKET_FANOUT_QM: schedule to socket by skbs recorded queue_mapping
*/
int fanout_type = PACKET_FANOUT_CPU;
// Our kernel headers aren't so fresh and we need it
#ifndef PACKET_FANOUT_QM
#define PACKET_FANOUT_QM 5
#endif
int get_fanout_by_name(std::string fanout_name) {
if (fanout_name == "" || fanout_name == "cpu") {
// Default mode for backward compatibility
return PACKET_FANOUT_CPU;
} else if (fanout_name == "lb") {
return PACKET_FANOUT_LB;
} else if (fanout_name == "hash") {
return PACKET_FANOUT_HASH;
} else if (fanout_name == "random") {
return PACKET_FANOUT_RND;
} else if (fanout_name == "rollover") {
return PACKET_FANOUT_ROLLOVER;
} else if (fanout_name == "queue_mapping") {
return PACKET_FANOUT_QM;
} else {
// Return default one
logger << log4cpp::Priority::ERROR << "Unknown FANOUT mode: " << fanout_name << " switched to default (CPU)";
return PACKET_FANOUT_CPU;
}
}
// Get interface number by name
int get_interface_number_by_device_name(int socket_fd, std::string interface_name) {
struct ifreq ifr;
@ -221,7 +261,7 @@ bool setup_socket(std::string interface_name, bool enable_fanout, int fanout_gro
MAP_SHARED | MAP_LOCKED, packet_socket, 0);
if (mapped_buffer == MAP_FAILED) {
logger << log4cpp::Priority::ERROR << "MMAP failed";
logger << log4cpp::Priority::ERROR << "MMAP failed errno: " << errno << " error: " << strerror(errno);
return false;
}
@ -242,10 +282,6 @@ bool setup_socket(std::string interface_name, bool enable_fanout, int fanout_gro
}
if (enable_fanout) {
// PACKET_FANOUT_LB - round robin
// PACKET_FANOUT_CPU - send packets to CPU where packet arrived
int fanout_type = PACKET_FANOUT_CPU;
int fanout_arg = (fanout_group_id | (fanout_type << 16));
int setsockopt_fanout =
@ -318,6 +354,11 @@ void start_afpacket_collection(process_packet_pointer func_ptr) {
convert_string_to_integer(configuration_map["mirror_af_packet_custom_sampling_rate"]);
}
if (configuration_map.count("mirror_af_packet_fanout_mode") != 0) {
// Set FANOUT mode
fanout_type = get_fanout_by_name(configuration_map["mirror_af_packet_fanout_mode"]);
}
std::vector<std::string> interfaces_for_listen;
boost::split(interfaces_for_listen, interfaces_list, boost::is_any_of(","), boost::token_compress_on);

View File

@ -104,6 +104,10 @@ mirror_afpacket = off
# It may be useful for sampled mirror ports
mirror_af_packet_custom_sampling_rate = 1
# AF_PACKET fanout mode mode, http://man7.org/linux/man-pages/man7/packet.7.html
# Available modes: cpu, lb, hash, random, rollover, queue_mapping
mirror_af_packet_fanout_mode = cpu
# use PCI-e addresses here instead of OS device names. You can find them in "lspci" output
interfaces_snabbswitch = 0000:04:00.0,0000:04:00.1,0000:03:00.0,0000:03:00.1