From 772d281c82026a29259e9e9169de79bd8a8f8472 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 26 Mar 2026 21:34:34 +0300 Subject: [PATCH 01/20] integrate dpdk loop --- worker/BUILD | 34 ++++- worker/Makefile.main_riscv | 28 +++++ worker/Makefile.main_x86 | 16 +++ worker/include/dpdk_filter/af_xdp_port.h | 34 +++++ worker/include/dpdk_filter/filtr_packets.h | 9 ++ worker/include/dpdk_filter/pars_packets.h | 16 +++ worker/include/dpdk_filter/proc_packets.h | 25 ++++ worker/include/worker.hpp | 11 ++ worker/scripts/set_virt_dev_for_test_xdp.sh | 10 ++ worker/scripts/setup-riscv-env.sh | 42 +++++++ worker/src/dpdk_filter/af_xdp_port.c | 130 ++++++++++++++++++++ worker/src/dpdk_filter/filtr_packets.c | 16 +++ worker/src/dpdk_filter/main.c | 77 ++++++++++++ worker/src/dpdk_filter/pars_packets.c | 90 ++++++++++++++ worker/src/dpdk_filter/proc_packets.c | 34 +++++ worker/src/main.cpp | 7 +- worker/src/worker.cpp | 47 ++++++- 17 files changed, 621 insertions(+), 5 deletions(-) create mode 100644 worker/Makefile.main_riscv create mode 100644 worker/Makefile.main_x86 create mode 100644 worker/include/dpdk_filter/af_xdp_port.h create mode 100644 worker/include/dpdk_filter/filtr_packets.h create mode 100644 worker/include/dpdk_filter/pars_packets.h create mode 100644 worker/include/dpdk_filter/proc_packets.h create mode 100755 worker/scripts/set_virt_dev_for_test_xdp.sh create mode 100755 worker/scripts/setup-riscv-env.sh create mode 100644 worker/src/dpdk_filter/af_xdp_port.c create mode 100644 worker/src/dpdk_filter/filtr_packets.c create mode 100644 worker/src/dpdk_filter/main.c create mode 100644 worker/src/dpdk_filter/pars_packets.c create mode 100644 worker/src/dpdk_filter/proc_packets.c diff --git a/worker/BUILD b/worker/BUILD index a1da9fa..0e5cb78 100644 --- a/worker/BUILD +++ b/worker/BUILD @@ -4,8 +4,9 @@ proto_library( name = "communication_proto", srcs = ["communication.proto"], deps = [ - "@com_google_protobuf//:empty_proto", + "@com_google_protobuf//:any_proto", "@com_google_protobuf//:struct_proto", + "@com_google_protobuf//:empty_proto", ], ) @@ -37,6 +38,10 @@ cc_library( hdrs = [ "include/worker.hpp", "include/metrics_collector.hpp", + "include/dpdk_filter/af_xdp_port.h", + "include/dpdk_filter/filtr_packets.h", + "include/dpdk_filter/pars_packets.h", + "include/dpdk_filter/proc_packets.h", ], srcs = [], visibility = ["//visibility:public"], @@ -48,6 +53,10 @@ cc_binary( "src/main.cpp", "src/worker.cpp", "src/metrics_collector.cpp", + "src/dpdk_filter/af_xdp_port.c", + "src/dpdk_filter/filtr_packets.c", + "src/dpdk_filter/pars_packets.c", + "src/dpdk_filter/proc_packets.c", ], deps = [ ":worker_headers", @@ -58,14 +67,37 @@ cc_binary( "@curl//:curl", ], copts = [ + "-std=c++17", + "-mssse3", + "-msse4.2", + "-mpclmul", + "-maes", "-I$(GENDIR)/..", + "-I/usr/include", ], linkopts = [ "-L/usr/local/openssl/lib", "-lssl", "-lcrypto", + "-L/usr/local/lib", "-lprometheus-cpp-push", "-lprometheus-cpp-core", + + "-L/usr/lib", + "-lrte_eal", + "-lrte_ethdev", + "-lrte_mempool", + "-lrte_mbuf", + "-lrte_bus_vdev", + "-lrte_ring", + "-lrte_telemetry", + "-lrte_kvargs", + "-lrte_log", + "-lrte_net", + + "-lnuma", + "-ldl", + "-lpthread", ], ) diff --git a/worker/Makefile.main_riscv b/worker/Makefile.main_riscv new file mode 100644 index 0000000..399a665 --- /dev/null +++ b/worker/Makefile.main_riscv @@ -0,0 +1,28 @@ +CC = riscv64-linux-gnu-gcc + +DPDK_PREFIX = ./dpdk-riscv-install +PKG_CONFIG = env PKG_CONFIG_LIBDIR=$(DPDK_PREFIX)/lib/pkgconfig pkg-config + +CFLAGS = -Iinclude -O2 $(shell $(PKG_CONFIG) --cflags libdpdk) + +LDFLAGS = -L$(DPDK_PREFIX)/lib \ + -Wl,--start-group \ + -lrte_eal -lrte_ethdev -lrte_mempool -lrte_mbuf \ + -lrte_bus_vdev \ + -lrte_ring -lrte_telemetry -lrte_kvargs \ + -lrte_log -ldl \ + -Wl,--end-group + + +SRCS = src/dpdk_filter/main.c src/dpdk_filter/af_xdp_port.c +TARGET = main-riscv + +all: $(TARGET) + +$(TARGET): $(SRCS) + $(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LDFLAGS) + +clean: + rm -f $(TARGET) + +.PHONY: all clean \ No newline at end of file diff --git a/worker/Makefile.main_x86 b/worker/Makefile.main_x86 new file mode 100644 index 0000000..76ca468 --- /dev/null +++ b/worker/Makefile.main_x86 @@ -0,0 +1,16 @@ +CC = gcc +CFLAGS = -Iinclude -O2 -msse4.2 -mpclmul -maes +LDFLAGS = -lrte_eal -lrte_ethdev -lrte_mempool -lrte_mbuf -lrte_bus_vdev -lpthread -lnuma -ldl + +SRCS = src/dpdk_filter/main.c src/dpdk_filter/af_xdp_port.c +TARGET = main + +all: $(TARGET) + +$(TARGET): $(SRCS) + $(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LDFLAGS) + +clean: + rm -f $(TARGET) + +.PHONY: all clean \ No newline at end of file diff --git a/worker/include/dpdk_filter/af_xdp_port.h b/worker/include/dpdk_filter/af_xdp_port.h new file mode 100644 index 0000000..b30920b --- /dev/null +++ b/worker/include/dpdk_filter/af_xdp_port.h @@ -0,0 +1,34 @@ +#ifndef AF_XDP_PORT_H +#define AF_XDP_PORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +struct af_xdp_port { + uint16_t port_id; + char iface_name[32]; + char dev_name[64]; + char dev_args[256]; + struct rte_mempool *mbuf_pool; +}; + +struct af_xdp_port *init_struct_af_xdp_port(const char *iface_name, + struct rte_mempool *mbuf_pool); + +int af_xdp_port_init(struct af_xdp_port *port); + +int af_xdp_port_start(uint16_t port_id); + +void af_xdp_port_close(struct af_xdp_port *port); + +int find_port_by_dev_name(const char *dev_name, uint16_t *port_id_dev); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/worker/include/dpdk_filter/filtr_packets.h b/worker/include/dpdk_filter/filtr_packets.h new file mode 100644 index 0000000..c80fe22 --- /dev/null +++ b/worker/include/dpdk_filter/filtr_packets.h @@ -0,0 +1,9 @@ +#ifndef FILTR_PAK_H +#define FILTR_PAK_H + +#include +#include + +bool main_filtring(struct info_of_pakage *info_pac); + +#endif diff --git a/worker/include/dpdk_filter/pars_packets.h b/worker/include/dpdk_filter/pars_packets.h new file mode 100644 index 0000000..82e9b41 --- /dev/null +++ b/worker/include/dpdk_filter/pars_packets.h @@ -0,0 +1,16 @@ +#ifndef PARS_PAK_H +#define PARS_PAK_H + +#include +#include + +struct info_of_pakage { + uint16_t ethernet_type_host; + uint16_t ethernet_type_protocol; + uint16_t number_port; + char *domain; +}; + +void parsing_pakage(struct rte_mbuf *paket, struct info_of_pakage *info_pac); + +#endif diff --git a/worker/include/dpdk_filter/proc_packets.h b/worker/include/dpdk_filter/proc_packets.h new file mode 100644 index 0000000..a347427 --- /dev/null +++ b/worker/include/dpdk_filter/proc_packets.h @@ -0,0 +1,25 @@ +#ifndef PROC_PAK_H +#define PROC_PAK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../include/dpdk_filter/af_xdp_port.h" +#include "../../include/dpdk_filter/filtr_packets.h" +#include "../../include/dpdk_filter/pars_packets.h" +#include +#include +#include +#include +#include + +void pakage_processing(struct af_xdp_port *port_in, + struct af_xdp_port *port_out, uint16_t queue_number, + uint16_t nb_pkts, struct rte_mbuf **pkts); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/worker/include/worker.hpp b/worker/include/worker.hpp index 58c437a..f3be34d 100644 --- a/worker/include/worker.hpp +++ b/worker/include/worker.hpp @@ -3,9 +3,14 @@ #include "communication.grpc.pb.h" #include "communication.pb.h" +#include "dpdk_filter/af_xdp_port.h" #include #include #include +#include +#include +#include +#include #define EXPECTED_POLICY_TIME 60 #define MIN_POLICY_TIME 30 @@ -29,6 +34,11 @@ class Worker { int64_t policy_interval = MIN_POLICY_TIME; int64_t stats_interval = MIN_STATS_TIME; + struct af_xdp_port *port_in = nullptr; + struct af_xdp_port *port_out = nullptr; + struct rte_mempool *mbuf_pool = nullptr; + bool dpdk_initialized = false; + std::unique_ptr stub_; WorkerState state; @@ -39,6 +49,7 @@ class Worker { Worker(uint64_t id); ~Worker(); + void initDPDK(int argc, char **argv); inline uint64_t GetID() const { return worker_id; } void requestPolicyFromController(); void classifyDomain(const std::string &domain); diff --git a/worker/scripts/set_virt_dev_for_test_xdp.sh b/worker/scripts/set_virt_dev_for_test_xdp.sh new file mode 100755 index 0000000..442d911 --- /dev/null +++ b/worker/scripts/set_virt_dev_for_test_xdp.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +sudo ip link delete veth0 2>/dev/null +sudo ip link delete veth1 2>/dev/null +sudo ip link add veth0 type veth peer name veth1 +sudo ip link set veth0 up +sudo ip link set veth1 up + +sudo ip addr add 10.0.0.1/24 dev veth0 +sudo ip addr add 10.0.0.2/24 dev veth1 diff --git a/worker/scripts/setup-riscv-env.sh b/worker/scripts/setup-riscv-env.sh new file mode 100755 index 0000000..3d1efe1 --- /dev/null +++ b/worker/scripts/setup-riscv-env.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Script for preparing the RISC-V crss compilation environment + +set -e + + +if ! command -v riscv64-linux-gnu-gcc &> /dev/null; then + echo "No cross compiler found. Install:" + echo "sudo apt install crossbuild-essential-riscv64" + exit 1 +fi + +DPDK_DIR="./dpdk-23.11" +if [ ! -d "$DPDK_DIR" ]; then + echo "$DPDK_DIR folder not found" + echo "Install DPDK 23.11:" + echo " wget https://fast.dpdk.org/rel/dpdk-23.11.tar.xz" + echo " tar -xf dpdk-23.11.tar.xz" + exit 1 +fi + + +cd "$DPDK_DIR" +rm -rf build-riscv +meson setup build-riscv \ + --cross-file config/riscv/riscv64_linux_gcc \ + --prefix=$(pwd)/../dpdk-riscv-install + +ninja -C build-riscv +ninja -C build-riscv install + +cd .. + +echo "DPDK для RISC-V установлен в ./dpdk-riscv-install" + +if [ -f "./dpdk-riscv-install/lib/pkgconfig/libdpdk.pc" ]; then + echo " .pc files created:" + ls -la ./dpdk-riscv-install/lib/pkgconfig/ +else + echo " Ошибка: .pc files not created!" + exit 1 +fi diff --git a/worker/src/dpdk_filter/af_xdp_port.c b/worker/src/dpdk_filter/af_xdp_port.c new file mode 100644 index 0000000..1d6d03e --- /dev/null +++ b/worker/src/dpdk_filter/af_xdp_port.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../include/dpdk_filter/af_xdp_port.h" + +#define RX_RING_SIZE 1024 +#define TX_RING_SIZE 1024 + +int find_port_by_dev_name(const char *dev_name, uint16_t *port_id_dev) { + uint16_t count_ports = rte_eth_dev_count_avail(); + struct rte_eth_dev_info dev_info; + char name[64]; + + for (uint16_t port_id = 0; port_id < count_ports; port_id++) { + int ret = rte_eth_dev_info_get(port_id, &dev_info); + if (rte_eth_dev_get_name_by_port(port_id, name) == 0 && + strcmp(name, dev_name) == 0) { + *port_id_dev = port_id; + return 0; + } + } + return -1; +} + +struct af_xdp_port *init_struct_af_xdp_port(const char *iface_name, + struct rte_mempool *mbuf_pool) { + struct af_xdp_port *port = calloc(1, sizeof(struct af_xdp_port)); + + snprintf(port->dev_args, sizeof(port->dev_args), + "iface=%s,start_queue=0,queue_count=1", iface_name); + snprintf(port->dev_name, sizeof(port->dev_name), "net_af_xdp_%s", iface_name); + strncpy(port->iface_name, iface_name, sizeof(port->iface_name) - 1); + port->iface_name[sizeof(port->iface_name) - 1] = '\0'; + port->mbuf_pool = mbuf_pool; + port->port_id = -1; + + return port; +} + +int af_xdp_port_init(struct af_xdp_port *port) { + int ret; + struct rte_eth_conf port_conf = {0}; + const char *dev_name = port->dev_name; + uint16_t port_id; + + ret = rte_vdev_init(dev_name, port->dev_args); + + if (ret < 0) { + printf("[ERROR] Failed to create vdev: %s\n", strerror(-ret)); + return ret; + } + + ret = find_port_by_dev_name(port->dev_name, &port_id); + if (ret) { + printf("no port was found that has the same vdev name. vdev = %s", + port->dev_name); + rte_vdev_uninit(dev_name); + return -1; + } + + port->port_id = port_id; + + if (!rte_eth_dev_is_valid_port(port_id)) { + printf("[ERROR] Port %u is not valid\n", port_id); + rte_vdev_uninit(dev_name); + return -EINVAL; + } + + ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf); + if (ret < 0) { + printf("[ERROR] Failed to configure port: %s\n", strerror(-ret)); + rte_vdev_uninit(dev_name); + return ret; + } + + ret = rte_eth_rx_queue_setup(port_id, 0, RX_RING_SIZE, + rte_eth_dev_socket_id(port_id), NULL, + port->mbuf_pool); + if (ret < 0) { + printf("[ERROR] Failed to setup RX queue: %s\n", strerror(-ret)); + rte_vdev_uninit(dev_name); + return ret; + } + + ret = rte_eth_tx_queue_setup(port_id, 0, TX_RING_SIZE, + rte_eth_dev_socket_id(port_id), NULL); + + if (ret < 0) { + printf("[ERROR] Failed to setup TX queue: %s\n", strerror(-ret)); + rte_vdev_uninit(dev_name); + return ret; + } + + printf("Port %u initialized\n", port_id); + return 0; +} + +int af_xdp_port_start(uint16_t port_id) { + int ret; + + ret = rte_eth_dev_start(port_id); + if (ret < 0) { + printf("[ERROR] Failed to start: %s\n", strerror(-ret)); + return ret; + } + + rte_eth_promiscuous_enable(port_id); + + printf("Port %u started\n", port_id); + return 0; +} + +void af_xdp_port_close(struct af_xdp_port *port) { + uint16_t port_id = port->port_id; + rte_eth_dev_stop(port_id); + rte_eth_dev_close(port_id); + rte_vdev_uninit(port->dev_name); + + printf("Port %u closed\n", port_id); +} diff --git a/worker/src/dpdk_filter/filtr_packets.c b/worker/src/dpdk_filter/filtr_packets.c new file mode 100644 index 0000000..e275823 --- /dev/null +++ b/worker/src/dpdk_filter/filtr_packets.c @@ -0,0 +1,16 @@ +#include "../../include/dpdk_filter/filtr_packets.h" +#include "../../include/dpdk_filter/pars_packets.h" + +bool check_domain(char *domain) { + // PLUG (to be added later) + return true; +} + +bool main_filtring(struct info_of_pakage *info_pac) { + if (!check_domain(info_pac->domain)) { + printf("domain is block"); + return false; + } + // OTHER REQUIRED CHECKS + return true; +} diff --git a/worker/src/dpdk_filter/main.c b/worker/src/dpdk_filter/main.c new file mode 100644 index 0000000..1546d14 --- /dev/null +++ b/worker/src/dpdk_filter/main.c @@ -0,0 +1,77 @@ +#include "../../include/dpdk_filter/af_xdp_port.h" +#include "../../include/dpdk_filter/proc_packets.h" +#include +#include +#include +#include +#include +#include +#include + +static volatile int running = 1; + +static void signal_handler(int signum) { + if (signum == SIGINT || signum == SIGTERM) { + printf("\n Signal %d received, shutting down.\n", signum); + running = 0; + } +} + +int main(int argc, char **argv) { + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + struct af_xdp_port *port_in = NULL; + struct af_xdp_port *port_out = NULL; + struct rte_mempool *mbuf_pool; + unsigned mbuf_quantity_in_pool = 8192; + unsigned cache_size_per_kernel = 250; + uint16_t queue_number = 0; + uint16_t nb_pkts = 32; + uint16_t priv_size = 0; + struct rte_mbuf *pkts[32]; + + int ret = rte_eal_init(argc, argv); + if (ret < 0) { + printf("[ERROR] EAL init failed: %s\n", rte_strerror(rte_errno)); + return 1; + } + + mbuf_pool = rte_pktmbuf_pool_create( + "POOL", mbuf_quantity_in_pool, cache_size_per_kernel, priv_size, + RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + if (!mbuf_pool) { + printf("[ERROR] Failed to create mbuf pool: %s\n", rte_strerror(rte_errno)); + return -1; + } + +#ifdef VIRT_PORTS + printf("Using virtual ports: veth0/veth1\n"); + port_in = init_struct_af_xdp_port("veth0", mbuf_pool); + port_out = init_struct_af_xdp_port("veth1", mbuf_pool); +#else + printf("Using real ports: eth0/eth1\n"); + port_in = init_struct_af_xdp_port("eth0", mbuf_pool); + port_out = init_struct_af_xdp_port("eth1", mbuf_pool); +#endif + if (af_xdp_port_init(port_in) || af_xdp_port_init(port_out)) { + return 1; + } + + if (af_xdp_port_start(port_in->port_id) || + af_xdp_port_start(port_out->port_id)) { + return 1; + } + + printf("An endless cycle has been started. Packets pass from port with id=%u " + "to port with id=%u\n", + port_in->port_id, port_out->port_id); + + while (running) { + + pakage_processing(port_in, port_out, queue_number, nb_pkts, pkts); + } + + af_xdp_port_close(port_in); + af_xdp_port_close(port_out); + return 0; +} diff --git a/worker/src/dpdk_filter/pars_packets.c b/worker/src/dpdk_filter/pars_packets.c new file mode 100644 index 0000000..635b9b0 --- /dev/null +++ b/worker/src/dpdk_filter/pars_packets.c @@ -0,0 +1,90 @@ +#include "../../include/dpdk_filter/pars_packets.h" +#include +#include +#include +#include +#include +#include +#include + +void parsing_pakage(struct rte_mbuf *packet, struct info_of_pakage *info_pac) { + + struct rte_net_hdr_lens hdr_lens; + uint32_t pkt_type = rte_net_get_ptype(packet, &hdr_lens, RTE_PTYPE_ALL_MASK); + + if (pkt_type == RTE_PTYPE_UNKNOWN) { + printf("[ERROR PARS] Problem with get lens of headers"); + return; + } + + struct rte_ether_hdr *eth_hdr = + rte_pktmbuf_mtod(packet, struct rte_ether_hdr *); + info_pac->ethernet_type_host = eth_hdr->ether_type; + + uint32_t l3_offset = hdr_lens.l2_len; + + if (pkt_type & RTE_PTYPE_L3_IPV4) { + info_pac->ethernet_type_protocol = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); + + struct rte_ipv4_hdr *ipv4_hdr = + rte_pktmbuf_mtod_offset(packet, struct rte_ipv4_hdr *, l3_offset); + + if (pkt_type & RTE_PTYPE_L4_TCP) { + struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset( + packet, struct rte_tcp_hdr *, l3_offset + hdr_lens.l3_len); + info_pac->number_port = tcp_hdr->dst_port; + } else if (pkt_type & RTE_PTYPE_L4_UDP) { + struct rte_udp_hdr *udp_hdr = rte_pktmbuf_mtod_offset( + packet, struct rte_udp_hdr *, l3_offset + hdr_lens.l3_len); + info_pac->number_port = udp_hdr->dst_port; + } + } else if (pkt_type & RTE_PTYPE_L3_IPV6) { + info_pac->ethernet_type_protocol = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); + + if (pkt_type & RTE_PTYPE_L4_TCP) { + struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset( + packet, struct rte_tcp_hdr *, l3_offset + hdr_lens.l3_len); + info_pac->number_port = tcp_hdr->dst_port; + } else if (pkt_type & RTE_PTYPE_L4_UDP) { + struct rte_udp_hdr *udp_hdr = rte_pktmbuf_mtod_offset( + packet, struct rte_udp_hdr *, l3_offset + hdr_lens.l3_len); + info_pac->number_port = udp_hdr->dst_port; + } + } + + if ((pkt_type & RTE_PTYPE_L4_UDP) && + info_pac->number_port == rte_cpu_to_be_16(53)) { + uint32_t l4_offset = l3_offset + hdr_lens.l3_len + hdr_lens.l4_len; + uint8_t *udp_payload = + rte_pktmbuf_mtod_offset(packet, uint8_t *, l4_offset); + + uint32_t len_dns_header = 12; + if (rte_pktmbuf_data_len(packet) > l4_offset + len_dns_header) { + uint8_t *dns_name_start = udp_payload + len_dns_header; + uint8_t *pos = dns_name_start; + size_t domain_len = 0; + + while (*pos != 0 && domain_len < 255) { + domain_len += *pos + 1; + pos += *pos + 1; + } + + if (*pos == 0 && domain_len > 0) { + info_pac->domain = malloc(domain_len + 1); + if (info_pac->domain) { + pos = dns_name_start; + char *dst = info_pac->domain; + while (*pos != 0) { + uint8_t label_len = *pos++; + if (dst != info_pac->domain) + *dst++ = '.'; + memcpy(dst, pos, label_len); + dst += label_len; + pos += label_len; + } + *dst = '\0'; + } + } + } + } +} diff --git a/worker/src/dpdk_filter/proc_packets.c b/worker/src/dpdk_filter/proc_packets.c new file mode 100644 index 0000000..8e376fa --- /dev/null +++ b/worker/src/dpdk_filter/proc_packets.c @@ -0,0 +1,34 @@ +#include "../../include/dpdk_filter/proc_packets.h" + +void pakage_processing(struct af_xdp_port *port_in, + struct af_xdp_port *port_out, uint16_t queue_number, + uint16_t nb_pkts, struct rte_mbuf **pkts) { + + uint16_t nb_rx = + rte_eth_rx_burst(port_in->port_id, queue_number, pkts, nb_pkts); + + for (int i = 0; i < nb_rx; i++) { + + struct info_of_pakage *info_pac = calloc(1, sizeof(struct info_of_pakage)); + parsing_pakage(pkts[i], info_pac); + + bool skip_packet = main_filtring(info_pac); + + if (!skip_packet) { + + uint16_t ret = + rte_eth_tx_burst(port_out->port_id, queue_number, &pkts[i], 1); + + if (ret < 1) { + + printf("[ERROR] Failed to send packet\n"); + // PLUG (to be added later) - need to add processing for this case + rte_pktmbuf_free(pkts[i]); + } + } else { + rte_pktmbuf_free(pkts[i]); + } + + free(info_pac); + } +} diff --git a/worker/src/main.cpp b/worker/src/main.cpp index c75d4a2..d30b3ec 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -20,7 +20,7 @@ class FiltrWorker : public Worker { ("worker-" + std::to_string(id)).c_str()) {} }; -int main() { +int main(int argc, char **argv) { const char *worker_id_str = getenv("WORKER_ID"); if (worker_id_str == nullptr) { spdlog::error("WORKER_ID environment variable not set"); @@ -33,7 +33,8 @@ int main() { if (gateway_address == nullptr || gateway_port == nullptr) { spdlog::error("Environment variables are not fully specified. " - "Specify METRICS_GATEWAY_ADDRESS and METRICS_GATEWAY_PORT"); + "Specify METRICS_GATEWAY_ADDRESS and + METRICS_GATEWAY_PORT"); return 1; } @@ -42,7 +43,7 @@ int main() { try { Worker worker(worker_id); - + worker.initDPDK(argc, argv); bool test_mode = false; if (getenv("TEST_REQUEST_POLICY") != nullptr) { test_mode = true; diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index b63c850..8394a3e 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -1,5 +1,5 @@ #include "../include/worker.hpp" - +#include "../include/dpdk_filter/proc_packets.h" #include "communication.grpc.pb.h" #include #include @@ -22,6 +22,46 @@ void Worker::SetState(WorkerState new_state) { } } +void Worker::initDPDK(int argc, char **argv) { + unsigned mbuf_quantity_in_pool = 8192; + unsigned cache_size_per_kernel = 250; + uint16_t priv_size = 0; + + int ret = rte_eal_init(argc, argv); + if (ret < 0) { + throw std::runtime_error("EAL init failed"); + } + + mbuf_pool = rte_pktmbuf_pool_create( + "POOL", mbuf_quantity_in_pool, cache_size_per_kernel, priv_size, + RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + if (!mbuf_pool) { + throw std::runtime_error("Failed to create mbuf pool"); + } + const char *iface_in = getenv("DPDK_PORT_IN"); + const char *iface_out = getenv("DPDK_PORT_OUT"); + + if (!iface_in || !iface_out) { + throw std::runtime_error("DPDK_PORT_IN and DPDK_PORT_OUT must be set"); + } + + port_in = init_struct_af_xdp_port(iface_in, mbuf_pool); + port_out = init_struct_af_xdp_port(iface_out, mbuf_pool); + + if (af_xdp_port_init(port_in) || af_xdp_port_init(port_out)) { + throw std::runtime_error("Init ports"); + } + + if (af_xdp_port_start(port_in->port_id) || + af_xdp_port_start(port_out->port_id)) { + throw std::runtime_error("Start ports"); + } + + dpdk_initialized = true; + spdlog::info("DPDK initialized: in_port={}, out_port={}", port_in->port_id, + port_out->port_id); +} + void Worker::requestPolicyFromController() { try { spdlog::info("Worker {} requests policy", worker_id); @@ -134,7 +174,12 @@ void Worker::MainLoop() { last_policy_time = steady_clock::now(); last_stats_time = steady_clock::now(); + struct rte_mbuf *pkts[32]; + uint16_t nb_pkts = 32; + uint16_t queue_number = 0; while (GetState() != WorkerState::SHUTTING_DOWN) { + pakage_processing(port_in, port_out, queue_number, nb_pkts, pkts); + auto now = steady_clock::now(); int64_t seconds_since_stats = (now - last_stats_time) / 1s; From 203ae98d6dd4c9c9382d3f162732eb5d230bf1eb Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Wed, 1 Apr 2026 15:46:55 +0300 Subject: [PATCH 02/20] interrupt handler --- worker/BUILD | 2 +- worker/include/worker.hpp | 1 - worker/src/main.cpp | 3 +-- worker/src/worker.cpp | 29 ++++++++++++++++++++++++++--- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/worker/BUILD b/worker/BUILD index 0e5cb78..024c521 100644 --- a/worker/BUILD +++ b/worker/BUILD @@ -19,7 +19,7 @@ generate_cc( name = "communication_cc_grpc_gen", srcs = [":communication_proto"], plugin = "@grpc//src/compiler:grpc_cpp_plugin", - well_known_protos = True, + well_known_protos = False, generate_mocks = True, ) diff --git a/worker/include/worker.hpp b/worker/include/worker.hpp index f3be34d..bd09faa 100644 --- a/worker/include/worker.hpp +++ b/worker/include/worker.hpp @@ -37,7 +37,6 @@ class Worker { struct af_xdp_port *port_in = nullptr; struct af_xdp_port *port_out = nullptr; struct rte_mempool *mbuf_pool = nullptr; - bool dpdk_initialized = false; std::unique_ptr stub_; diff --git a/worker/src/main.cpp b/worker/src/main.cpp index d30b3ec..5167010 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -33,8 +33,7 @@ int main(int argc, char **argv) { if (gateway_address == nullptr || gateway_port == nullptr) { spdlog::error("Environment variables are not fully specified. " - "Specify METRICS_GATEWAY_ADDRESS and - METRICS_GATEWAY_PORT"); + "Specify METRICS_GATEWAY_ADDRESS and METRICS_GATEWAY_PORT"); return 1; } diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index 8394a3e..f824857 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -5,8 +5,18 @@ #include #include #include +#include #include +static volatile bool stop_flag = false; + +static void signal_handler(int signum) { + if (signum == SIGINT || signum == SIGTERM) { + spdlog::info("Signal {} received, shutting down.", signum); + stop_flag = true; + } +} + void Worker::LogStateChange(WorkerState new_state) { const char *state_names[] = {"BOOTING", "FREE", "BUSY", "SHUTTING_DOWN", "ERROR"}; @@ -57,7 +67,6 @@ void Worker::initDPDK(int argc, char **argv) { throw std::runtime_error("Start ports"); } - dpdk_initialized = true; spdlog::info("DPDK initialized: in_port={}, out_port={}", port_in->port_id, port_out->port_id); } @@ -157,6 +166,9 @@ Worker::Worker(uint64_t id) : worker_id(id), state(WorkerState::FREE) { grpc::CreateChannel(controller_addr, grpc::InsecureChannelCredentials()); stub_ = DataService::NewStub(channel); spdlog::info("gRPC channel created to {}", controller_addr); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + spdlog::info("Signal handlers registered"); srand(time(nullptr)); SetState(WorkerState::FREE); @@ -164,8 +176,15 @@ Worker::Worker(uint64_t id) : worker_id(id), state(WorkerState::FREE) { } Worker::~Worker() { - SetState(WorkerState::SHUTTING_DOWN); spdlog::info("Worker {} shutting down", worker_id); + + if (port_in && port_out) { + af_xdp_port_close(port_in); + af_xdp_port_close(port_out); + af_xdp_port_destroy(port_in); + af_xdp_port_destroy(port_out); + spdlog::info("DPDK ports closed"); + } } void Worker::MainLoop() { @@ -177,7 +196,7 @@ void Worker::MainLoop() { struct rte_mbuf *pkts[32]; uint16_t nb_pkts = 32; uint16_t queue_number = 0; - while (GetState() != WorkerState::SHUTTING_DOWN) { + while (!stop_flag && GetState() != WorkerState::SHUTTING_DOWN) { pakage_processing(port_in, port_out, queue_number, nb_pkts, pkts); auto now = steady_clock::now(); @@ -200,4 +219,8 @@ void Worker::MainLoop() { std::this_thread::sleep_for(milliseconds(100)); } + + if (stop_flag) { + SetState(WorkerState::SHUTTING_DOWN); + } } From b61090554b4ea8ce9e4643ee3e2a7e88c8e72b69 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Wed, 1 Apr 2026 15:47:59 +0300 Subject: [PATCH 03/20] fix linter --- worker/src/worker.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index f824857..004abe0 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -4,13 +4,13 @@ #include #include #include -#include #include +#include #include static volatile bool stop_flag = false; -static void signal_handler(int signum) { +static void signal_handler(int signum) { if (signum == SIGINT || signum == SIGTERM) { spdlog::info("Signal {} received, shutting down.", signum); stop_flag = true; @@ -221,6 +221,6 @@ void Worker::MainLoop() { } if (stop_flag) { - SetState(WorkerState::SHUTTING_DOWN); - } + SetState(WorkerState::SHUTTING_DOWN); + } } From 2967fb0172e9707f9f5563e69410760fb447a239 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Sat, 4 Apr 2026 22:23:14 +0300 Subject: [PATCH 04/20] fix bazel build --- worker/BUILD | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worker/BUILD b/worker/BUILD index 024c521..098da56 100644 --- a/worker/BUILD +++ b/worker/BUILD @@ -67,7 +67,6 @@ cc_binary( "@curl//:curl", ], copts = [ - "-std=c++17", "-mssse3", "-msse4.2", "-mpclmul", @@ -75,6 +74,9 @@ cc_binary( "-I$(GENDIR)/..", "-I/usr/include", ], + cxxopts = [ + "-std=c++17", + ], linkopts = [ "-L/usr/local/openssl/lib", "-lssl", From 8283bfb15efb557b092d49be31466ba5819344e3 Mon Sep 17 00:00:00 2001 From: LapshinAE0 Date: Sun, 12 Apr 2026 16:02:14 +0300 Subject: [PATCH 05/20] add send to port in --- worker/dns_sender | Bin 17688 -> 0 bytes worker/helper for association with Worker.md | 19 +++++++++++++------ worker/src/dpdk_filter/main.c | 9 +++++---- 3 files changed, 18 insertions(+), 10 deletions(-) delete mode 100755 worker/dns_sender diff --git a/worker/dns_sender b/worker/dns_sender deleted file mode 100755 index 770ffc917214dc7d1534e69cad099c965dd6d837..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17688 zcmeHP4Rlo1oxhV1G9YAvf(@wfz{Cv^h8YYLE!Y{DffqYKgkaMx_AyK*WHgzH^8umt zBR0_THcX|bAImx09ts20JNd=)j$8Dfrw%ZTt7M-XlMp5ckXMg|u?tSy- zk=gd_$2oh>a&hv%|KI=Pe&2WBefN4_FtobN;b1b9vzr-l12YW7Cj_l4L+_|d^T-s4}k==l>8xVGq z`b2$7D(jQ#gnr9}Upw_cMnO`$U5Bu<(|}>dB&9ScY&?^0`>&+eEbR7QYxuF#%?8XQ zmFe9IJF1tzHpph)Akr(<4qHUIC8hSJu&6V(b!p?G&bEb}v3RCuVb8Lq3zs&!QwjHC zE~k7c_)+t(S+|LyS%wG`?pRr`!ApN6n=a&}f9>VR?-=e%-}C#4&oBHScEjA?y!C)e zI+Sm+Asq_jPc*s7&q0iIs6G_78*v(o6lZKMekY^<()G~M{omMe*Z0LJ251XkgM-U$ z7_ryjr%=QeT*$fg`6<7rk1r@TQnKn7E7h0 z$(FUNIur3|OL%K%lxfe0W7{&xXc1~l2fC4PXQ!6# z;dE;_a%aH{z`HWh3^Er@XS$2sP@#&DSW4R-?u@l*-3gl{l};3lyOW8oSSpf9WKvo* z&g+R67#T^HPA<}!NEMeOlE}oqXgnEA& zX5VtG9x7NRViovj{4EDs!JPOv2@;Z$tP+}&*=2~4v>Z<%dImc1?~53-G>jDdreEGP ziNW%_z$lPBc#*uaNPfpf@`*+A+b)t{vy zFEdfbd=`9)1y?P&cqQP{W(zJ}F*x38!Ce+VTP(PIw2-*Nf={#PcUy4lbG65UUt!Vj zwcxa_lwpqrw=VwnS#az6Yrh5mkaPliz=GFU@JB89Obb3>!R0Fri4R)vt1bFN7M#|c zGMupBvn6zgX<(0yzWISHFAZpv-{ff^qx>dM0~qBuc^bGVzsb{pMfpvh1}e&L@-#qEev_wx ziSnB~4M>z<@@Snp-Z}xs+Xwu@h16OFzRt#9W8-Jo_^CF&!p6Uk_bjXb^EUphjXz`K ze{17^ZsVV~@yBfZ(>DGI8~>P%f7r%<-Nt{##%FE(ZX17(jnCNlF3E?o604mGgpj< z^+2uDJCvIV_1xQNeD9C^2YWFV4!;MfUmrd~PiQ#Zj0AIUy`RrxG`n^^jL{j&F1d&2 zB3(OC)qkk!&xZ7Ob6CnTXzbYp4cFk^wG(r*F_H*r0Rl%KMkb%8!5b1zzXPYPCo5jO z9tKZN{Ur#B;)j;&$r&fW1%N&a`V8!0v~V#JZHB=Buu!&c5m=~HJP5WKB}o|WvS4BO zSrE9JXShp&BX@C7?vDIyHNc8iP;%g=LiQb1cenqH^_C9dn#8*e}yCi zrsTGQe>*sn<{E z4U}1jywrU1cK>Go?fy^swP)euUCc$f9q`e2BLC`$Yp?|kkX`Z)P@YGW;SM4EKD56> z+D!uZMlO$7yIXb*bG&)aHt8onrRp!LeSbXH+!FK-d4B}sVdO7Aqa%aE}NNTIEt z?asS)%|y@byKtZD^VNu``Z0C*Or`1|GEps$Z*lE<4@0p(=tPI#eLGb8gQ%vAFWc;B ziUeExF1TEuzZngn4xg^X@Vx?#L;4%}7Do?_kRxQfiDg$h)c(M+W%?#3A8h9VqcM*A ze3W_hF#SbPP_17>k7?J{M%SRaRGr&gbGR3R_8U(^StT9SwdTjiebXHbNgnqp1VO#} zxUZg~H26JgxwF6GZ^5g_{ZpJQ$eQ$@9QWgC;+xi#)f#mFMAu-&&5*b2{>l9nOA*r@ zfV>7YA-4`ykF3mcV!)m7>uYA^mILv=<3GM;p65okgoCrygO@jAK;XZ2zrN$Tkp5DW zzNP^>izz35*OL=!cVS}jqpTtQ%wdcY_Nq(tAJ>yXwreQ8Ow~u#zGIH%?#x+r{+oep z(xFC9?U`~#Q{)3Ra~y!PzrJfIb3&beUXA>)?}v_1NB{eEHhQSz@aVb^^s~jQFqG{lmk~zE>6zrnCp} zcY*(qk$3eZ^3ssK<7&X^T6g>KF{gje-IWa?{nRblvw-q+fw~M%{fjJ>_^1{RlmY)*0$?h>1h@I*REs*Y|EdKiY+X zY^0ZMrfTH_W%LwAm7LTLVwPe4BlI`uJ>|_G&c6f`bawaC^zFz0G_A$j^%k_?Q+P12 zgVft7F@+Xg6se)r7)7dSnMM&ODUR0R3E93cq>mk<+VsAYyA?Td4UUX{8-m<7iJ9XQ z^UI-YpwpzI8Y*r;rTTAMtN)2VfmQwIyhb*v`dde6M5y<_rcTBbQ+O!vs$B-aJJh6~ z31uIz^-Q8i-8XB`p>9x*Z>irpM0WJdIDj;d_>h^9{<3!nNgN`^sPSw?FA~n(0~OxZ zFXzVI$>(XN`89NM$H4UE9PN5Jx=rqHpasz`8l|qmkA(D5?&JtqmTQ2jUq4EwFN23X z_hCSwP5LOF75eaD>~m0scnX>i3(cv9Ce*l+J`A<_NKH8W4p+MZeQy$S>m3Su|7bjF zA3jfg&!`GZ_d5c8_5Pz&V*&kiaVIp^JNj|Be)spepOJ&?lHa21V1Xi^jq5nNB83-% z+$qFg{RjOxlpisaX(I&6ub#y7gX0ev_>ke`)k6~BVc-`8{*Y^sick-8o{;|sub`ji z{_r+sVZ}sBEDDR!>k0h~V(o?JDLtS3n*y%EH~cLD3=_OM6=Pm-9}|(aAaWQnUlREM^4_aj66Q_)X4{wx|9O;vm726`QFG= zBTtMxt<;lr7f$QsIS+wz(DJWASa=H9o;4W6=~L3lTznd+;dZ@KZbX#4urn` zFF5U5Pg}QEmtqCZ%yzTUU6oi$i6_vf>HFAZW}@ilG5(ne;5a#>Pi#hpq=o1o1sA-^ zVePo8{3DxDUsN4?Uc<%{X#MN?{6WxVpd+9s-pJ>d;hBE{v=y{wET8WI?tBZ+Ezk}; zxDNu~j|H9+i}f0;ZI^>mkbB0CPj6t3o@&QcQ!1VNpi4OI)9!yWpTCY21C_MCVzu}+ z;&<-VeEtCRSXK4vs+wC|m+f%&vX9QXso{p&c|f^6<-6l-KFP)I+k|$(U}EW6V#dhZ>91CsXPV$ zO;n!sRlPIH7dzk)Wwe#&7V_x9@7wUV2W@#T;*{TP8LED7`I;&vKDnwU$P2Gt)-I!r zwg*qc=4Y_ES=j6?OI7jJI`Nmnr5du@# z<>x=hCx{=whBF1coAXeO{S*q=D&XO?kjwS{n<9V4Dg)~!p=bTZPmnNU=lFxaaE7E+ z*wZ?Uf=G_ZZ~o1q;1X9wLNeb@QL)(F;z6cATkuj3+sV9qQ0EZ#+Bi>JKoqd0!g*QF zbAm4uax7K3T$aPI`k(tN&r#bwdcmh znpLZAQtCHt#kstU;`O>4-JXTs3}?OfE?(^RG`eq?F9d%n9qK+4*qhjaDh|}29FXi4 z4Xy|=eKH?UpX3fUlU4f=L6H5Z0dc~w^buOX8xb#K)ohD6JX6o5*f#`q-~_8@o&m^l zu@UTe>3#}0`8jPHa9adkZ9P;2jNXb#U(Q=#dC>9KLFZ0e4PMSyU*Y(bOwJpIl(8Qm zLVn~tDDe|qe+HBDki=g`WW4;BD%W}LXF5AqCp{GCcz()xhOc1q+`iPl61W4ilAL!W zzJTK&V)k+OIOZb-?Ztdj)1XVBZ$1Acr3ayZIqE^)OX2UP5Yo46!aZVszE>D*6Ziqq zF8tjRvhBbXp<^YxxxN)K;`C*By!`w#;bqgz=Yq6+qJ;iWIgUv{JTUmXA&mYAe7y6? zWhk$$OYtOT^Lmr173fX8ehR#dwE&++B~T26Ua=`eIDYZ@=TDdLvmdy^EsOtr4|w%B z?f6UyKff!1(}QbXv1`s<1$?~vUkH3!*-WPRij8h8p}$V(%Xv;(eX@l9XG-8-0$z>r zd$ldy2TSNbQ34++fxlD&pM-`RuO4P|9OFXt|C>d@JSFrul)yWIQ@Qqtc}dpKT_yB) zm%tBjKQk|?pGQjQA1#6Zq6Gd1$1xv@`JC_JAhW-t@l}RJjC{_D0=!+q&txpT#;Z@Z zF_KJs-3c7;4sVU&;Q2Pz7Ej^4JZJdL!&EwhZ%7eVxL2U1yEN?e#iJ>xwk5P}or$fuBG8sjBvV>A)58jTwVv@c=tz4^ z3n!D|oj7-&PVQvw*tm^q#%?~+FL31Jl-o*01!3wDqf3Zw$6*E&i3EAQS_iSm$5cw2B|sALn4cPo7P;q-LD8XT?>9 zB#SOq(5ZW$JkU;u)UAj1O#z)`=ao=&Yr(uEF>dPS{Q$X#ZQd?0)yKJ%Vaooq%OUd8 z16@SmySNss^(Z#B|FujiDz1Z=H#|%&tG#)r!<3f3Yl7|*PKQOkN+-oPFHA2|9I@XJ zF*P*JdRxM*Yib034WbCqG+d7ny++=Puqm{q5?V(%-iF&VGI3r(h07jh(j>QB<1lee z+nT}%H1DUFS34{kkXo){n0aXAiC$crGAkF~T`_%f6>(|D1g#yJw{cOSiZ0BUHZmlc}R4dDe*fm=EW7$ zgqmC06yF&#EtxyDvkUifK+{QscE}j+*F=-u%#BYZQTMiZ#*KQ$uuAW=KwC30T&~20 zCqv7>vS}erwp_g)&9Y+=UxlZo?cMl+hQ; zE=$LgruYmq_Xn_VWGDp8qi9w1pw<<$j8! z9;~w{P#&qCrM=wOhyf!NX)pI@B$fLyP~m}mSi@alXs<)s%l!>W143Em-_#R0y~ohr ziNxjpiKMc@DgWd{=3khzEF#n0+l=}AiJ0|R9`!hvo z3c6qPe}P_<{__w}`qEy$?@PK_8VYJp|6gtP7idC4ko3>w+!AE}kRq@8TXZvmqs zN_)94a!wqks4h`{>1QJ3R(s}yGYTGq*yn#~XGpP+4P(M&`aYkq6ZWbc=)ypV1&4QQ zk-ktj@v8-}&_s*~<&}b!%D!VrjK9soen?CV^x8^$&@%rrTeL4I^KMugf2%)i(D`_O Yvj&;2#AvvVXMf{zLt~cBz{axw04zJhEC2ui diff --git a/worker/helper for association with Worker.md b/worker/helper for association with Worker.md index de73307..ca4428e 100644 --- a/worker/helper for association with Worker.md +++ b/worker/helper for association with Worker.md @@ -1,18 +1,24 @@ -REQUESTED_CLASSIFICATION структура для передачи от контроллера к воркеру: +REQUESTED_CLASSIFICATION - структура для передачи от контроллера к воркеру: + +```code struct requested_classification { - char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN] - политика - int get_trust_level - уровень доверия к сайту + char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN] + int get_trust_level } +``` +Структура для хранения категории с минимальным уровнем доверия для этой категории: -Структура для хранения категории с минимальным уровнем доверия для этой категории +```code struct trust_categories_with_lvl { char locked_by_trust_category[CATEGORY_MAX_LEN]; int trust_lvl; } +``` +у нас есть переменные, которые получаем при инициализации воркера и заносим в структуру (периодически обновляем): -у нас есть переменные, которые получаем при инициализации воркера и заносим в структуру (периодически обновляем) +```code struct BASE_POLICY { char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; struct trust_categories_with_lvl categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]; @@ -20,7 +26,8 @@ struct BASE_POLICY { char allow_domains[MAX_DOMAINS][MAX_LEN_DOMEIN]; int min_trust_level; } +``` +Добавлен tap порт, по которому проходят пакеты исключений в ядро, обрабатываются и ответ отсылается на входящий порт (port_in) -Добавлен tap порт, по которому проходят пакеты исключений в ядро, обрабатываются и ответ отсылается на входящий порт (port_in) \ No newline at end of file diff --git a/worker/src/dpdk_filter/main.c b/worker/src/dpdk_filter/main.c index 6da81a8..74954c1 100644 --- a/worker/src/dpdk_filter/main.c +++ b/worker/src/dpdk_filter/main.c @@ -18,11 +18,11 @@ static void signal_handler(int signum) { } } -void forward_tap_to_out(struct net_port *port_exception, struct net_port *port_in, uint16_t queue_number) { +void forward_to_out(struct net_port *incoming_port, struct net_port *outgoing_port, uint16_t queue_number) { struct rte_mbuf *tap_pkts[32]; - uint16_t nb_tap = rte_eth_rx_burst(port_exception->port_id, queue_number, tap_pkts, 32); + uint16_t nb_tap = rte_eth_rx_burst(incoming_port->port_id, queue_number, tap_pkts, 32); for (int i = 0; i < nb_tap; i++) { - int ret = rte_eth_tx_burst(port_in->port_id, queue_number, &tap_pkts[i], 1); + int ret = rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); if (ret < 1) { printf("[ERROR] Failed to send packet\n"); // PLUG (to be added later) - need to add processing for this case @@ -109,8 +109,9 @@ int main(int argc, char **argv) { port_in->port_id, port_out->port_id); while (running) { - forward_tap_to_out(port_exception, port_in, queue_number); + forward_to_out(port_exception, port_in, queue_number); pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, pkts, &policy); + forward_to_out(port_out, port_in, queue_number); } // function for save cache info if need From c770dce449cb28ec215128ee424356fa1c6a95cb Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Sun, 12 Apr 2026 20:26:43 +0300 Subject: [PATCH 06/20] integrate changes dpdk --- worker/BUILD | 9 +- worker/include/dpdk_filter/constants.h | 3 +- worker/include/dpdk_filter/dns_cache.h | 5 +- worker/include/dpdk_filter/filtr_packets.h | 21 ++- worker/include/dpdk_filter/net_port.h | 9 +- worker/include/dpdk_filter/pars_packets.h | 6 +- worker/include/dpdk_filter/proc_packets.h | 12 +- worker/include/dpdk_filter/types.h | 15 +- worker/include/worker.hpp | 21 ++- worker/src/dpdk_filter/af_xdp_port.c | 176 --------------------- worker/src/dpdk_filter/filtr_packets.c | 45 ++++-- worker/src/dpdk_filter/main.c | 43 ++--- worker/src/dpdk_filter/net_port.c | 12 +- worker/src/dpdk_filter/proc_packets.c | 27 ++-- worker/src/main.cpp | 10 +- worker/src/worker.cpp | 132 ++++++++++++++-- 16 files changed, 260 insertions(+), 286 deletions(-) delete mode 100644 worker/src/dpdk_filter/af_xdp_port.c diff --git a/worker/BUILD b/worker/BUILD index 098da56..a091ccb 100644 --- a/worker/BUILD +++ b/worker/BUILD @@ -38,10 +38,13 @@ cc_library( hdrs = [ "include/worker.hpp", "include/metrics_collector.hpp", - "include/dpdk_filter/af_xdp_port.h", + "include/dpdk_filter/net_port.h", + "include/dpdk_filter/dns_cache.h", "include/dpdk_filter/filtr_packets.h", "include/dpdk_filter/pars_packets.h", "include/dpdk_filter/proc_packets.h", + "include/dpdk_filter/types.h", + "include/dpdk_filter/constants.h", ], srcs = [], visibility = ["//visibility:public"], @@ -52,8 +55,9 @@ cc_binary( srcs = [ "src/main.cpp", "src/worker.cpp", + "src/dpdk_filter/dns_cache.c", "src/metrics_collector.cpp", - "src/dpdk_filter/af_xdp_port.c", + "src/dpdk_filter/net_port.c", "src/dpdk_filter/filtr_packets.c", "src/dpdk_filter/pars_packets.c", "src/dpdk_filter/proc_packets.c", @@ -97,6 +101,7 @@ cc_binary( "-lrte_kvargs", "-lrte_log", "-lrte_net", + "-lrte_hash", "-lnuma", "-ldl", diff --git a/worker/include/dpdk_filter/constants.h b/worker/include/dpdk_filter/constants.h index 6ae6d1d..3e92808 100644 --- a/worker/include/dpdk_filter/constants.h +++ b/worker/include/dpdk_filter/constants.h @@ -1,7 +1,6 @@ #ifndef CONSTANTS_H #define CONSTANTS_H - #define MAX_CATEGORIES_BY_TRUST_LVL 64 #define MAX_DOMAINS 64 #define CACHE_SIZE 1024 @@ -10,6 +9,6 @@ #define CATEGORY_MAX_LEN 64 #define DNS_CACHE_DEFAULT_TTL (7 * 24 * 60 * 60) #define LEN_LIST_EXCEPTION_PORTS 1 -extern const uint16_t LIST_EXCEPTION_PORTS[LEN_LIST_EXCEPTION_PORTS]; +extern const uint16_t LIST_EXCEPTION_PORTS[LEN_LIST_EXCEPTION_PORTS]; #endif \ No newline at end of file diff --git a/worker/include/dpdk_filter/dns_cache.h b/worker/include/dpdk_filter/dns_cache.h index 7f953f9..f1c137a 100644 --- a/worker/include/dpdk_filter/dns_cache.h +++ b/worker/include/dpdk_filter/dns_cache.h @@ -6,16 +6,13 @@ #include #include #include +#include #include #include -#include #include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/types.h" - - - void init_dns_cache(void); int lookup_dns_cache(const char *domain, struct node_cache **return_node); void add_to_dns_cache(const char *domain, struct node_cache *node); diff --git a/worker/include/dpdk_filter/filtr_packets.h b/worker/include/dpdk_filter/filtr_packets.h index f573c36..bb052cf 100644 --- a/worker/include/dpdk_filter/filtr_packets.h +++ b/worker/include/dpdk_filter/filtr_packets.h @@ -1,22 +1,29 @@ #ifndef FILTR_PAK_H #define FILTR_PAK_H +#include "../../include/dpdk_filter/constants.h" +#include "../../include/dpdk_filter/types.h" #include "pars_packets.h" #include #include -#include "../../include/dpdk_filter/constants.h" -#include "../../include/dpdk_filter/types.h" -bool check_is_block(char domain[DOMAIN_MAX_LEN], char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); +bool check_is_block(char domain[DOMAIN_MAX_LEN], + char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); -bool check_is_allow(char domain[DOMAIN_MAX_LEN], char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); +bool check_is_allow(char domain[DOMAIN_MAX_LEN], + char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); bool check_trust_level(int get_trust_level, int min_trust_level); -bool check_categories(char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN], char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]); +bool check_categories(char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN], + char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]); -bool check_categories_with_lvl(struct requested_classification* req_clas, struct trust_categories_with_lvl categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]); +bool check_categories_with_lvl( + struct requested_classification *req_clas, + struct trust_categories_with_lvl + categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]); -bool main_filtring(struct requested_classification* req_clas, struct BASE_POLICY* policy, char domain[DOMAIN_MAX_LEN]); +bool main_filtring(struct requested_classification *req_clas, + struct BASE_POLICY *policy, char domain[DOMAIN_MAX_LEN]); #endif diff --git a/worker/include/dpdk_filter/net_port.h b/worker/include/dpdk_filter/net_port.h index e34f8b1..3c6fe82 100644 --- a/worker/include/dpdk_filter/net_port.h +++ b/worker/include/dpdk_filter/net_port.h @@ -1,18 +1,15 @@ #ifndef AF_XDP_PORT_H #define AF_XDP_PORT_H +#include "../../include/dpdk_filter/types.h" #include #include -#include "../../include/dpdk_filter/types.h" - - struct net_port *init_struct_tap_port(const char *tap_iface_name, - struct rte_mempool *mbuf_pool); - + struct rte_mempool *mbuf_pool); struct net_port *init_struct_af_xdp_port(const char *iface_name, - struct rte_mempool *mbuf_pool); + struct rte_mempool *mbuf_pool); int net_port_init(struct net_port *port); diff --git a/worker/include/dpdk_filter/pars_packets.h b/worker/include/dpdk_filter/pars_packets.h index 240dbc1..96e96f0 100644 --- a/worker/include/dpdk_filter/pars_packets.h +++ b/worker/include/dpdk_filter/pars_packets.h @@ -1,12 +1,10 @@ #ifndef PARS_PAK_H #define PARS_PAK_H -#include -#include #include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/types.h" - - +#include +#include void parsing_pakage(struct rte_mbuf *paket, struct info_of_pakage *info_pac); diff --git a/worker/include/dpdk_filter/proc_packets.h b/worker/include/dpdk_filter/proc_packets.h index 0936b92..65f3af6 100644 --- a/worker/include/dpdk_filter/proc_packets.h +++ b/worker/include/dpdk_filter/proc_packets.h @@ -5,10 +5,10 @@ extern "C" { #endif -#include "../../include/dpdk_filter/net_port.h" +#include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/filtr_packets.h" +#include "../../include/dpdk_filter/net_port.h" #include "../../include/dpdk_filter/pars_packets.h" -#include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/types.h" #include #include @@ -16,10 +16,10 @@ extern "C" { #include #include -void pakage_processing(struct net_port *port_in, - struct net_port *port_out, struct net_port *port_exception, - uint16_t queue_number, uint16_t nb_pkts, - struct rte_mbuf **pkts, struct BASE_POLICY* policy); +void pakage_processing(struct net_port *port_in, struct net_port *port_out, + struct net_port *port_exception, uint16_t queue_number, + uint16_t nb_pkts, struct rte_mbuf **pkts, + struct BASE_POLICY *policy); #ifdef __cplusplus } diff --git a/worker/include/dpdk_filter/types.h b/worker/include/dpdk_filter/types.h index d056e50..d93881b 100644 --- a/worker/include/dpdk_filter/types.h +++ b/worker/include/dpdk_filter/types.h @@ -2,8 +2,8 @@ #define TYPES_H #include "constants.h" -#include #include +#include struct net_port { uint16_t port_id; @@ -20,24 +20,24 @@ struct info_of_pakage { }; struct trust_categories_with_lvl { - char locked_by_trust_category[CATEGORY_MAX_LEN]; - int trust_lvl; + char locked_by_trust_category[CATEGORY_MAX_LEN]; + int trust_lvl; }; struct BASE_POLICY { char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; - struct trust_categories_with_lvl categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]; + struct trust_categories_with_lvl + categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]; char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]; char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]; int min_trust_level; }; struct requested_classification { - char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; - int get_trust_level; + char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; + int get_trust_level; }; - struct node_cache { char categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; bool solution_is_send; @@ -47,5 +47,4 @@ struct node_cache { char *key_domain; }; - #endif diff --git a/worker/include/worker.hpp b/worker/include/worker.hpp index bd09faa..cb5bebb 100644 --- a/worker/include/worker.hpp +++ b/worker/include/worker.hpp @@ -3,7 +3,13 @@ #include "communication.grpc.pb.h" #include "communication.pb.h" -#include "dpdk_filter/af_xdp_port.h" +extern "C" { +#include "dpdk_filter/dns_cache.h" +#include "dpdk_filter/filtr_packets.h" +#include "dpdk_filter/net_port.h" +#include "dpdk_filter/proc_packets.h" +#include "dpdk_filter/types.h" +} #include #include #include @@ -34,9 +40,13 @@ class Worker { int64_t policy_interval = MIN_POLICY_TIME; int64_t stats_interval = MIN_STATS_TIME; - struct af_xdp_port *port_in = nullptr; - struct af_xdp_port *port_out = nullptr; + struct net_port *port_in = nullptr; + struct net_port *port_out = nullptr; + struct net_port *port_exception = nullptr; struct rte_mempool *mbuf_pool = nullptr; + std::mutex policy_mutex; + struct BASE_POLICY current_policy; + uint16_t queue_number = 0; std::unique_ptr stub_; @@ -51,7 +61,10 @@ class Worker { void initDPDK(int argc, char **argv); inline uint64_t GetID() const { return worker_id; } void requestPolicyFromController(); - void classifyDomain(const std::string &domain); + bool classifyDomain(const std::string &domain, + struct requested_classification *out_req); + void forward_to_out(struct net_port *incoming_port, + struct net_port *outgoing_port, uint16_t queue_number); void statsReport(); WorkerState GetState() const { return state; } void MainLoop(); diff --git a/worker/src/dpdk_filter/af_xdp_port.c b/worker/src/dpdk_filter/af_xdp_port.c deleted file mode 100644 index 03932a2..0000000 --- a/worker/src/dpdk_filter/af_xdp_port.c +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../include/dpdk_filter/af_xdp_port.h" - -#define RX_RING_SIZE 1024 -#define TX_RING_SIZE 1024 - -int find_port_by_dev_name(const char *dev_name, uint16_t *port_id_dev) { - uint16_t count_ports = rte_eth_dev_count_avail(); - struct rte_eth_dev_info dev_info; - char name[64]; - - for (uint16_t port_id = 0; port_id < count_ports; port_id++) { - int ret = rte_eth_dev_info_get(port_id, &dev_info); - - if (ret) { - printf("[ERROR] Failed to retrieve the contextual information of an " - "Ethernet device: %s\n", - strerror(-ret)); - return ret; - } - - if (rte_eth_dev_get_name_by_port(port_id, name) == 0 && - strcmp(name, dev_name) == 0) { - *port_id_dev = port_id; - return 0; - } - } - return -1; -} - -struct af_xdp_port *init_struct_af_xdp_port(const char *iface_name, - struct rte_mempool *mbuf_pool) { - struct af_xdp_port *port = calloc(1, sizeof(struct af_xdp_port)); - if (!port) { - printf("[ERROR] Failed to allocate memory for struct af_xdp_port\n"); - return NULL; - } - - snprintf(port->dev_args, sizeof(port->dev_args), - "iface=%s,start_queue=0,queue_count=1", iface_name); - snprintf(port->dev_name, sizeof(port->dev_name), "net_af_xdp_%s", iface_name); - strncpy(port->iface_name, iface_name, sizeof(port->iface_name) - 1); - port->iface_name[sizeof(port->iface_name) - 1] = '\0'; - port->mbuf_pool = mbuf_pool; - port->port_id = -1; - - return port; -} - -int af_xdp_port_init(struct af_xdp_port *port) { - int ret; - struct rte_eth_conf port_conf = {0}; - const char *dev_name = port->dev_name; - uint16_t port_id; - - ret = rte_vdev_init(dev_name, port->dev_args); - - if (ret < 0) { - printf("[ERROR] Failed to create vdev: %s\n", strerror(-ret)); - return ret; - } - - ret = find_port_by_dev_name(port->dev_name, &port_id); - if (ret) { - printf("no port was found that has the same vdev name. vdev = %s", - port->dev_name); - rte_vdev_uninit(dev_name); - return -1; - } - - port->port_id = port_id; - - if (!rte_eth_dev_is_valid_port(port_id)) { - printf("[ERROR] Port %u is not valid\n", port_id); - rte_vdev_uninit(dev_name); - return -EINVAL; - } - - ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf); - if (ret < 0) { - printf("[ERROR] Failed to configure port: %s\n", strerror(-ret)); - rte_vdev_uninit(dev_name); - return ret; - } - - ret = rte_eth_rx_queue_setup(port_id, 0, RX_RING_SIZE, - rte_eth_dev_socket_id(port_id), NULL, - port->mbuf_pool); - if (ret < 0) { - printf("[ERROR] Failed to setup RX queue: %s\n", strerror(-ret)); - rte_vdev_uninit(dev_name); - return ret; - } - - ret = rte_eth_tx_queue_setup(port_id, 0, TX_RING_SIZE, - rte_eth_dev_socket_id(port_id), NULL); - - if (ret < 0) { - printf("[ERROR] Failed to setup TX queue: %s\n", strerror(-ret)); - rte_vdev_uninit(dev_name); - return ret; - } - - printf("Port %u initialized\n", port_id); - return 0; -} - -int af_xdp_port_start(uint16_t port_id) { - int ret; - - ret = rte_eth_dev_start(port_id); - if (ret < 0) { - printf("[ERROR] Failed to start: %s\n", strerror(-ret)); - return ret; - } - - ret = rte_eth_promiscuous_enable(port_id); - if (ret) { - printf("[ERROR] Failed to enable receipt in promiscuous mode for an " - "Ethernet device: %s\n", - strerror(-ret)); - return ret; - } - - printf("Port %u started\n", port_id); - return 0; -} - -void af_xdp_port_destroy(struct af_xdp_port *port) { - if (!port) - return; - free(port); -} - -void af_xdp_port_close(struct af_xdp_port *port) { - - if (!port) - return; - - int ret; - uint16_t port_id = port->port_id; - - ret = rte_eth_dev_stop(port_id); - if (ret) { - printf("[ERROR] Failed to stop an Ethernet device: %s\n", strerror(-ret)); - return; - } - - ret = rte_eth_dev_close(port_id); - if (ret) { - printf("[ERROR] Failed to close a stopped Ethernet device: %s\n", - strerror(-ret)); - return; - } - - ret = rte_vdev_uninit(port->dev_name); - if (ret) { - printf("[ERROR] Failed to uninitialize a driver: %s\n", strerror(-ret)); - return; - } - - port->port_id = -1; - printf("Port %u closed\n", port_id); -} diff --git a/worker/src/dpdk_filter/filtr_packets.c b/worker/src/dpdk_filter/filtr_packets.c index 6b1fc29..ccc8868 100644 --- a/worker/src/dpdk_filter/filtr_packets.c +++ b/worker/src/dpdk_filter/filtr_packets.c @@ -1,7 +1,8 @@ #include "../../include/dpdk_filter/filtr_packets.h" #include "../../include/dpdk_filter/pars_packets.h" -bool check_is_block(char domain[DOMAIN_MAX_LEN], char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { +bool check_is_block(char domain[DOMAIN_MAX_LEN], + char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { for (int i = 0; i < MAX_DOMAINS; i++) { if (strcmp(block_domains[i], domain) == 0) { @@ -12,7 +13,8 @@ bool check_is_block(char domain[DOMAIN_MAX_LEN], char block_domains[MAX_DOMAINS] return false; } -bool check_is_allow(char domain[DOMAIN_MAX_LEN], char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { +bool check_is_allow(char domain[DOMAIN_MAX_LEN], + char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { for (int i = 0; i < MAX_DOMAINS; i++) { if (strcmp(allow_domains[i], domain) == 0) { @@ -32,34 +34,41 @@ bool check_trust_level(int get_trust_level, int min_trust_level) { return true; } -bool check_categories(char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN], char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]) { - +bool check_categories( + char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN], + char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]) { + for (int i = 0; i < MAX_CATEGORIES; i++) { for (int j = 0; j < MAX_CATEGORIES; j++) { if (strcmp(get_categories[i], locked_categories[j]) == 0) { return false; } } - } + } return true; } - -bool check_categories_with_lvl(struct requested_classification* req_clas, struct trust_categories_with_lvl categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]) { +bool check_categories_with_lvl( + struct requested_classification *req_clas, + struct trust_categories_with_lvl + categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]) { for (int i = 0; i < MAX_CATEGORIES; i++) { for (int j = 0; j < MAX_CATEGORIES; j++) { - if (strcmp(req_clas->get_categories[j], categories_with_lvl[i].locked_by_trust_category) == 0 && req_clas->get_trust_level < categories_with_lvl[i].trust_lvl) { - return false; + if (strcmp(req_clas->get_categories[j], + categories_with_lvl[i].locked_by_trust_category) == 0 && + req_clas->get_trust_level < categories_with_lvl[i].trust_lvl) { + return false; } - } - } + } + } return true; } -bool main_filtring(struct requested_classification* req_clas, struct BASE_POLICY* policy, char domain[DOMAIN_MAX_LEN]) { +bool main_filtring(struct requested_classification *req_clas, + struct BASE_POLICY *policy, char domain[DOMAIN_MAX_LEN]) { if (check_is_block(domain, policy->block_domains) == true) { printf("This domain is blocked"); @@ -71,18 +80,22 @@ bool main_filtring(struct requested_classification* req_clas, struct BASE_POLICY return true; } - if (check_categories(req_clas->get_categories, policy->locked_categories) == false) { + if (check_categories(req_clas->get_categories, policy->locked_categories) == + false) { printf("This site has a locked category"); return false; } - if (check_trust_level(req_clas->get_trust_level, policy->min_trust_level) == false) { + if (check_trust_level(req_clas->get_trust_level, policy->min_trust_level) == + false) { printf("This site has a too small trust level"); return false; } - if (check_categories_with_lvl(req_clas, policy->categories_with_lvl) == false) { - printf("This site blocked in accordance with 'trust categories with level'"); + if (check_categories_with_lvl(req_clas, policy->categories_with_lvl) == + false) { + printf( + "This site blocked in accordance with 'trust categories with level'"); return false; } diff --git a/worker/src/dpdk_filter/main.c b/worker/src/dpdk_filter/main.c index e174a2f..62a49ca 100644 --- a/worker/src/dpdk_filter/main.c +++ b/worker/src/dpdk_filter/main.c @@ -1,5 +1,5 @@ -#include "../../include/dpdk_filter/net_port.h" #include "../../include/dpdk_filter/dns_cache.h" +#include "../../include/dpdk_filter/net_port.h" #include "../../include/dpdk_filter/proc_packets.h" #include #include @@ -18,21 +18,24 @@ static void signal_handler(int signum) { } } -void forward_to_out(struct net_port *incoming_port, struct net_port *outgoing_port, uint16_t queue_number) { - struct rte_mbuf *tap_pkts[32]; - uint16_t nb_tap = rte_eth_rx_burst(incoming_port->port_id, queue_number, tap_pkts, 32); - for (int i = 0; i < nb_tap; i++) { - int ret = rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); - if (ret < 1) { - printf("[ERROR] Failed to send packet\n"); - // PLUG (to be added later) - need to add processing for this case - rte_pktmbuf_free(tap_pkts[i]); - } +void forward_to_out(struct net_port *incoming_port, + struct net_port *outgoing_port, uint16_t queue_number) { + struct rte_mbuf *tap_pkts[32]; + uint16_t nb_tap = + rte_eth_rx_burst(incoming_port->port_id, queue_number, tap_pkts, 32); + for (int i = 0; i < nb_tap; i++) { + int ret = + rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); + if (ret < 1) { + printf("[ERROR] Failed to send packet\n"); + // PLUG (to be added later) - need to add processing for this case + rte_pktmbuf_free(tap_pkts[i]); } + } } int main(int argc, char **argv) { - //since BASE_POLICY is filled when initializing worker, let’s initialize here + // since BASE_POLICY is filled when initializing worker, let’s initialize here struct BASE_POLICY policy; if (signal(SIGINT, signal_handler) == SIG_ERR) { printf("[ERROR] Failed to set SIGINT handler\n"); @@ -43,8 +46,6 @@ int main(int argc, char **argv) { return 1; } - - struct net_port *port_in = NULL; struct net_port *port_out = NULL; struct net_port *port_exception = NULL; @@ -83,24 +84,23 @@ int main(int argc, char **argv) { port_exception = init_struct_tap_port("tap0", mbuf_pool); - if (!port_in || !port_out || !port_exception) { return 1; } - if (net_port_init(port_in) || net_port_init(port_out) || net_port_init(port_exception)) { + if (net_port_init(port_in) || net_port_init(port_out) || + net_port_init(port_exception)) { return 1; } - if (net_port_start(port_in->port_id) || - net_port_start(port_out->port_id) || + if (net_port_start(port_in->port_id) || net_port_start(port_out->port_id) || net_port_start(port_exception->port_id)) { return 1; } ret = system("sudo ip link set tap0 up && " - "sudo ip addr add 10.0.3.1/24 dev tap0"); - if(ret) { + "sudo ip addr add 10.0.3.1/24 dev tap0"); + if (ret) { printf("[ERROR] Failed to set tap0 up\n"); } @@ -110,7 +110,8 @@ int main(int argc, char **argv) { while (running) { forward_to_out(port_exception, port_in, queue_number); - pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, pkts, &policy); + pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, + pkts, &policy); forward_to_out(port_out, port_in, queue_number); } diff --git a/worker/src/dpdk_filter/net_port.c b/worker/src/dpdk_filter/net_port.c index 92eeca4..7237446 100644 --- a/worker/src/dpdk_filter/net_port.c +++ b/worker/src/dpdk_filter/net_port.c @@ -41,16 +41,17 @@ int find_port_by_dev_name(const char *dev_name, uint16_t *port_id_dev) { } struct net_port *init_struct_tap_port(const char *tap_iface_name, - struct rte_mempool *mbuf_pool) { + struct rte_mempool *mbuf_pool) { struct net_port *port = calloc(1, sizeof(struct net_port)); - if (!port) { + if (!port) { printf("[ERROR] Failed to allocate memory for struct net_port\n"); return NULL; } - snprintf(port->dev_args, sizeof(port->dev_args),"iface=%s", tap_iface_name); - snprintf(port->dev_name, sizeof(port->dev_name), "net_tap_%s", tap_iface_name); + snprintf(port->dev_args, sizeof(port->dev_args), "iface=%s", tap_iface_name); + snprintf(port->dev_name, sizeof(port->dev_name), "net_tap_%s", + tap_iface_name); strncpy(port->iface_name, tap_iface_name, sizeof(port->iface_name) - 1); port->iface_name[sizeof(port->iface_name) - 1] = '\0'; port->mbuf_pool = mbuf_pool; @@ -59,9 +60,8 @@ struct net_port *init_struct_tap_port(const char *tap_iface_name, return port; } - struct net_port *init_struct_af_xdp_port(const char *iface_name, - struct rte_mempool *mbuf_pool) { + struct rte_mempool *mbuf_pool) { struct net_port *port = calloc(1, sizeof(struct net_port)); if (!port) { printf("[ERROR] Failed to allocate memory for struct net_port\n"); diff --git a/worker/src/dpdk_filter/proc_packets.c b/worker/src/dpdk_filter/proc_packets.c index 6527fa2..b131e11 100644 --- a/worker/src/dpdk_filter/proc_packets.c +++ b/worker/src/dpdk_filter/proc_packets.c @@ -1,6 +1,9 @@ #include "../../include/dpdk_filter/proc_packets.h" #include "../../include/dpdk_filter/dns_cache.h" +extern bool worker_classify_domain(const char *domain, + struct requested_classification *out_req); + const uint16_t LIST_EXCEPTION_PORTS[LEN_LIST_EXCEPTION_PORTS] = {22}; void package_sending_decision(bool solution_is_send, struct rte_mbuf *pkt, @@ -20,7 +23,6 @@ void package_sending_decision(bool solution_is_send, struct rte_mbuf *pkt, rte_pktmbuf_free(pkt); } - bool check_is_exception(uint16_t number_port) { for (int i = 0; i < LEN_LIST_EXCEPTION_PORTS; i++) { if (number_port == LIST_EXCEPTION_PORTS[i]) { @@ -30,10 +32,10 @@ bool check_is_exception(uint16_t number_port) { return false; } - -void pakage_processing(struct net_port *port_in, - struct net_port *port_out, struct net_port *port_exception, uint16_t queue_number, - uint16_t nb_pkts, struct rte_mbuf **pkts, struct BASE_POLICY* policy) { +void pakage_processing(struct net_port *port_in, struct net_port *port_out, + struct net_port *port_exception, uint16_t queue_number, + uint16_t nb_pkts, struct rte_mbuf **pkts, + struct BASE_POLICY *policy) { uint16_t nb_rx = rte_eth_rx_burst(port_in->port_id, queue_number, pkts, nb_pkts); @@ -50,7 +52,7 @@ void pakage_processing(struct net_port *port_in, continue; } - if(check_is_exception(info_pac.number_port) == true) { + if (check_is_exception(info_pac.number_port) == true) { package_sending_decision(true, pkts[i], port_exception, queue_number); continue; } @@ -65,9 +67,16 @@ void pakage_processing(struct net_port *port_in, } else if (ret == -ENOENT) { struct requested_classification req_clas; - - bool solution_is_send = main_filtring(&req_clas, policy, info_pac.domain); - + memset(&req_clas, 0, sizeof(req_clas)); + bool solution_is_send; + bool classification_success = + worker_classify_domain(info_pac.domain, &req_clas); + if (classification_success) { + solution_is_send = main_filtring(&req_clas, policy, info_pac.domain); + } else { + solution_is_send = true; + printf("[WARN] Classification failed for %s\n", info_pac.domain); + } package_sending_decision(solution_is_send, pkts[i], port_out, queue_number); diff --git a/worker/src/main.cpp b/worker/src/main.cpp index 5167010..e9bad0f 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -62,7 +62,15 @@ int main(int argc, char **argv) { test_mode = true; spdlog::info("Test mode: classifying domain '{}'", domain); std::this_thread::sleep_for(std::chrono::seconds(1)); - worker.classifyDomain(domain); + struct requested_classification req_clas; + memset(&req_clas, 0, sizeof(req_clas)); + bool success = worker.classifyDomain(domain, &req_clas); + if (success) { + spdlog::info("Classification successful: trust_level={}", + req_clas.get_trust_level); + } else { + spdlog::error("Classification failed"); + } } if (test_mode) { diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index 004abe0..99c14f1 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -2,12 +2,25 @@ #include "../include/dpdk_filter/proc_packets.h" #include "communication.grpc.pb.h" #include +#include #include #include #include #include #include +Worker *g_worker = nullptr; + +extern "C" bool +worker_classify_domain(const char *domain, + struct requested_classification *out_req) { + if (!g_worker) { + fprintf(stderr, "worker_classify_domain: g_worker is null\n"); + return false; + } + return g_worker->classifyDomain(std::string(domain), out_req); +} + static volatile bool stop_flag = false; static void signal_handler(int signum) { @@ -57,20 +70,46 @@ void Worker::initDPDK(int argc, char **argv) { port_in = init_struct_af_xdp_port(iface_in, mbuf_pool); port_out = init_struct_af_xdp_port(iface_out, mbuf_pool); + port_exception = init_struct_tap_port("tap0", mbuf_pool); - if (af_xdp_port_init(port_in) || af_xdp_port_init(port_out)) { + if (net_port_init(port_in) || net_port_init(port_out) || + net_port_init(port_exception)) { throw std::runtime_error("Init ports"); } - if (af_xdp_port_start(port_in->port_id) || - af_xdp_port_start(port_out->port_id)) { + if (net_port_start(port_in->port_id) || net_port_start(port_out->port_id) || + net_port_start(port_exception->port_id)) { throw std::runtime_error("Start ports"); } + int tap_ret = system( + "sudo ip link set tap0 up && sudo ip addr add 10.0.3.1/24 dev tap0"); + if (tap_ret) + spdlog::warn("Failed to configure tap0"); + + init_dns_cache(); + spdlog::info("DPDK initialized: in_port={}, out_port={}", port_in->port_id, port_out->port_id); } +void Worker::forward_to_out(struct net_port *incoming_port, + struct net_port *outgoing_port, + uint16_t queue_number) { + struct rte_mbuf *tap_pkts[32]; + uint16_t nb_tap = + rte_eth_rx_burst(incoming_port->port_id, queue_number, tap_pkts, 32); + for (int i = 0; i < nb_tap; i++) { + int ret = + rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); + if (ret < 1) { + spdlog::warn("Failed to send packet"); + // PLUG (to be added later) - need to add processing for this case + rte_pktmbuf_free(tap_pkts[i]); + } + } +} + void Worker::requestPolicyFromController() { try { spdlog::info("Worker {} requests policy", worker_id); @@ -89,23 +128,72 @@ void Worker::requestPolicyFromController() { } switch (resp.result()) { - case GetPolicyResponse::POLICY_PROVIDED: + case GetPolicyResponse::POLICY_PROVIDED: { spdlog::info("Policy received"); + const auto &pol = resp.policy(); current_config_version = resp.policy().config_version(); + std::lock_guard lock(policy_mutex); + memset(¤t_policy, 0, sizeof(current_policy)); + + int block_cat_count = pol.block_categories_size(); + for (int i = 0; i < block_cat_count; ++i) { + strncpy(current_policy.locked_categories[i], + pol.block_categories(i).c_str(), CATEGORY_MAX_LEN - 1); + current_policy.locked_categories[i][CATEGORY_MAX_LEN - 1] = '\0'; + } + + int trust_map_count = pol.block_by_trust_size(); + int idx = 0; + for (const auto &[category, min_trust] : pol.block_by_trust()) { + if (idx >= MAX_CATEGORIES_BY_TRUST_LVL) + break; + + strncpy( + current_policy.categories_with_lvl[idx].locked_by_trust_category, + category.c_str(), CATEGORY_MAX_LEN - 1); + current_policy.categories_with_lvl[idx] + .locked_by_trust_category[CATEGORY_MAX_LEN - 1] = '\0'; + + current_policy.categories_with_lvl[idx].trust_lvl = min_trust; + + idx++; + } + + int block_dom_count = pol.block_domains_size(); + for (int i = 0; i < block_dom_count; ++i) { + strncpy(current_policy.block_domains[i], pol.block_domains(i).c_str(), + DOMAIN_MAX_LEN - 1); + current_policy.block_domains[i][DOMAIN_MAX_LEN - 1] = '\0'; + } + + int allow_dom_count = pol.allow_domains_size(); + for (int i = 0; i < allow_dom_count; ++i) { + strncpy(current_policy.allow_domains[i], pol.allow_domains(i).c_str(), + DOMAIN_MAX_LEN - 1); + current_policy.allow_domains[i][DOMAIN_MAX_LEN - 1] = '\0'; + } + + current_policy.min_trust_level = pol.min_trust_level(); + + current_config_version = pol.config_version(); break; - case GetPolicyResponse::POLICY_UNCHANGED: + } + case GetPolicyResponse::POLICY_UNCHANGED: { spdlog::info("Policy unchanged"); break; - default: + } + default: { spdlog::error("Unknown response result"); } + } } catch (const std::exception &e) { spdlog::error("requestPolicyFromController exception: {}", e.what()); } } -void Worker::classifyDomain(const std::string &domain) { +bool Worker::classifyDomain(const std::string &domain, + struct requested_classification *out_req) { try { spdlog::info("Worker {} classifying domain '{}'", worker_id, domain); @@ -119,7 +207,7 @@ void Worker::classifyDomain(const std::string &domain) { auto status = stub_->Classify(&context, req, &resp); if (!status.ok()) { spdlog::error("Classify failed: " + status.error_message()); - return; + return false; } std::string cat = @@ -127,8 +215,16 @@ void Worker::classifyDomain(const std::string &domain) { spdlog::info("Domain '{}' classified as category '{}' with trust level {}", domain, cat, resp.trust_level()); + out_req->get_trust_level = resp.trust_level(); + int cat_count = std::min(resp.categories_size(), MAX_CATEGORIES); + for (int i = 0; i < cat_count; ++i) { + strncpy(out_req->get_categories[i], resp.categories(i).c_str(), + CATEGORY_MAX_LEN - 1); + } + return true; } catch (const std::exception &e) { spdlog::error(std::string("classifyDomain: ") + e.what()); + return false; } } @@ -157,7 +253,7 @@ void Worker::statsReport() { } Worker::Worker(uint64_t id) : worker_id(id), state(WorkerState::FREE) { - + g_worker = this; std::string controller_addr = "localhost:50051"; if (const char *env_addr = getenv("CONTROLLER_GRPC_ADDR")) { controller_addr = env_addr; @@ -179,10 +275,15 @@ Worker::~Worker() { spdlog::info("Worker {} shutting down", worker_id); if (port_in && port_out) { - af_xdp_port_close(port_in); - af_xdp_port_close(port_out); - af_xdp_port_destroy(port_in); - af_xdp_port_destroy(port_out); + free_dns_cache(); + + net_port_close(port_in); + net_port_close(port_out); + net_port_close(port_exception); + + net_port_destroy(port_in); + net_port_destroy(port_out); + net_port_destroy(port_exception); spdlog::info("DPDK ports closed"); } } @@ -197,7 +298,10 @@ void Worker::MainLoop() { uint16_t nb_pkts = 32; uint16_t queue_number = 0; while (!stop_flag && GetState() != WorkerState::SHUTTING_DOWN) { - pakage_processing(port_in, port_out, queue_number, nb_pkts, pkts); + forward_to_out(port_exception, port_in, queue_number); + pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, + pkts, ¤t_policy); + forward_to_out(port_out, port_in, queue_number); auto now = steady_clock::now(); From ea99a794039f45a1a1c546932711cd03e36ed010 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Sun, 12 Apr 2026 20:41:28 +0300 Subject: [PATCH 07/20] fix linter --- worker/include/dpdk_filter/filtr_packets.h | 2 -- worker/include/dpdk_filter/pars_packets.h | 3 --- 2 files changed, 5 deletions(-) diff --git a/worker/include/dpdk_filter/filtr_packets.h b/worker/include/dpdk_filter/filtr_packets.h index 2963b91..bb052cf 100644 --- a/worker/include/dpdk_filter/filtr_packets.h +++ b/worker/include/dpdk_filter/filtr_packets.h @@ -6,8 +6,6 @@ #include "pars_packets.h" #include #include -#include "../../include/dpdk_filter/constants.h" -#include "../../include/dpdk_filter/types.h" bool check_is_block(char domain[DOMAIN_MAX_LEN], char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); diff --git a/worker/include/dpdk_filter/pars_packets.h b/worker/include/dpdk_filter/pars_packets.h index bb4f5c6..96e96f0 100644 --- a/worker/include/dpdk_filter/pars_packets.h +++ b/worker/include/dpdk_filter/pars_packets.h @@ -5,9 +5,6 @@ #include "../../include/dpdk_filter/types.h" #include #include -#include "../../include/dpdk_filter/constants.h" -#include "../../include/dpdk_filter/types.h" - void parsing_pakage(struct rte_mbuf *paket, struct info_of_pakage *info_pac); From 5017313a5964426cf0f8f508d28a841a56384cf1 Mon Sep 17 00:00:00 2001 From: LapshinAE0 Date: Mon, 13 Apr 2026 09:35:00 +0300 Subject: [PATCH 08/20] full done --- worker/Makefile.main_riscv | 8 +- worker/Makefile.main_x86 | 2 +- worker/README(DPDK FILTRING).md | 80 +++++ worker/include/dpdk_filter/constants.h | 3 +- worker/include/dpdk_filter/dns_cache.h | 10 +- worker/include/dpdk_filter/filtr_packets.h | 21 +- worker/include/dpdk_filter/net_port.h | 9 +- worker/include/dpdk_filter/pars_packets.h | 6 +- worker/include/dpdk_filter/proc_packets.h | 16 +- worker/include/dpdk_filter/types.h | 15 +- worker/scripts/set_tap_dev.sh | 7 + worker/src/dpdk_filter/af_xdp_port.c | 176 ---------- worker/src/dpdk_filter/dns_cache.c | 359 ++++++++++++++++++++- worker/src/dpdk_filter/filtr_packets.c | 45 ++- worker/src/dpdk_filter/main.c | 53 +-- worker/src/dpdk_filter/net_port.c | 13 +- worker/src/dpdk_filter/proc_packets.c | 11 +- 17 files changed, 563 insertions(+), 271 deletions(-) create mode 100644 worker/README(DPDK FILTRING).md create mode 100755 worker/scripts/set_tap_dev.sh delete mode 100644 worker/src/dpdk_filter/af_xdp_port.c diff --git a/worker/Makefile.main_riscv b/worker/Makefile.main_riscv index 3a06a3a..2d9b7dc 100644 --- a/worker/Makefile.main_riscv +++ b/worker/Makefile.main_riscv @@ -1,6 +1,7 @@ CC = riscv64-linux-gnu-gcc DPDK_PREFIX = ./dpdk-riscv-install +SQLITE_PREFIX = ./sqlite3-riscv-install PKG_CONFIG = env PKG_CONFIG_LIBDIR=$(DPDK_PREFIX)/lib/pkgconfig pkg-config CFLAGS_BASE = -Iinclude -O2 $(shell $(PKG_CONFIG) --cflags libdpdk) @@ -13,10 +14,11 @@ LDFLAGS = -L$(DPDK_PREFIX)/lib \ -lrte_net \ -lrte_log -ldl \ -lrte_hash \ - -sqlite3 \ + -lrte_timer \ -Wl,--end-group \ - -latomic - + -latomic \ + -L$(SQLITE_PREFIX)/lib \ + -lsqlite3 SRCS = src/dpdk_filter/main.c src/dpdk_filter/net_port.c src/dpdk_filter/filtr_packets.c src/dpdk_filter/pars_packets.c src/dpdk_filter/proc_packets.c src/dpdk_filter/dns_cache.c diff --git a/worker/Makefile.main_x86 b/worker/Makefile.main_x86 index 71fd148..7097920 100644 --- a/worker/Makefile.main_x86 +++ b/worker/Makefile.main_x86 @@ -1,6 +1,6 @@ CC = gcc CFLAGS_BASE = -Iinclude -O2 -msse4.2 -mpclmul -maes -LDFLAGS = -lrte_eal -lrte_ethdev -lrte_mempool -lrte_mbuf -lrte_bus_vdev -lpthread -lnuma -ldl -lrte_net -lrte_hash -lsqlite3 +LDFLAGS = -lrte_eal -lrte_ethdev -lrte_mempool -lrte_mbuf -lrte_bus_vdev -lpthread -lnuma -ldl -lrte_net -lrte_hash -lsqlite3 -lrte_timer SRCS = src/dpdk_filter/main.c src/dpdk_filter/net_port.c src/dpdk_filter/filtr_packets.c src/dpdk_filter/pars_packets.c src/dpdk_filter/proc_packets.c src/dpdk_filter/dns_cache.c diff --git a/worker/README(DPDK FILTRING).md b/worker/README(DPDK FILTRING).md new file mode 100644 index 0000000..cba6538 --- /dev/null +++ b/worker/README(DPDK FILTRING).md @@ -0,0 +1,80 @@ +# Драйвера dpdk +DPDK должен быть собран с драйверами net/af_xdp net/tap + + +# Кросс-компиляция + +## Окружение +Скрипт `scripts/setup-riscv-env.sh` автоматически скачивает (при необходимости) и собирает DPDK 23.11 для архитектуры RISC-V. + +```bash +./scripts/setup-riscv-env.sh +``` + +## SQLite +Если целевая архитектура — RISC-V, SQLite необходимо собрать кросс-компилятором. + +```bash +wget https://www.sqlite.org/2024/sqlite-autoconf-3460100.tar.gz +tar -xzf sqlite-autoconf-3460100.tar.gz +cd sqlite-autoconf-3460100 + +./configure --host=riscv64-linux-gnu --prefix=/path/to/sqlite3-riscv-install +make -j$(nproc) +make install +``` + +После установки в указанном prefix появятся подкаталоги include/ и lib/ с необходимыми файлами. + + + +# Создание пары veth и TAP-устройства + +```bash +sudo ./scripts/set_virt_dev_for_test_xdp.sh +``` +Скрипт создаёт пару veth0 - veth1 + + +```bash +sudo ./scripts/set_tap_dev.sh +``` +Скрипт создаёт TAP-устройство tap0 + + + +# Сборка проекта +Для реальных портов (eth0/eth1): +```bash +make -f Makefile.main_riscv all +``` + +Для виртуальных портов (veth0/veth1 + tap0): +```bash +make -f Makefile.main_riscv virt +``` +Определение макроса -DVIRT_PORTS переключает программу на использование виртуальных интерфейсов. + + +Перед запуском рекомендуется выполнить скрипт настройки виртуальных устройств: +```bash +sudo ./scripts/set_virt_dev_for_test_xdp.sh +``` + + +# Очистка +```bash +make -f Makefile.main_riscv clean +``` + +# Запуск +Программа требует прав суперпользователя (для работы с DPDK и XDP): +```bash +sudo ./main-riscv-virt +``` + + +# Примечания +Кэш DNS автоматически сохраняется в cache.db (SQLite) и восстанавливается при перезапуске. + +Периодическое сохранение кэша происходит каждый час с помощью таймеров DPDK. diff --git a/worker/include/dpdk_filter/constants.h b/worker/include/dpdk_filter/constants.h index 6ae6d1d..f046259 100644 --- a/worker/include/dpdk_filter/constants.h +++ b/worker/include/dpdk_filter/constants.h @@ -1,6 +1,7 @@ #ifndef CONSTANTS_H #define CONSTANTS_H +#include #define MAX_CATEGORIES_BY_TRUST_LVL 64 #define MAX_DOMAINS 64 @@ -10,6 +11,6 @@ #define CATEGORY_MAX_LEN 64 #define DNS_CACHE_DEFAULT_TTL (7 * 24 * 60 * 60) #define LEN_LIST_EXCEPTION_PORTS 1 -extern const uint16_t LIST_EXCEPTION_PORTS[LEN_LIST_EXCEPTION_PORTS]; +extern const uint16_t LIST_EXCEPTION_PORTS[LEN_LIST_EXCEPTION_PORTS]; #endif \ No newline at end of file diff --git a/worker/include/dpdk_filter/dns_cache.h b/worker/include/dpdk_filter/dns_cache.h index 7f953f9..d61ef3b 100644 --- a/worker/include/dpdk_filter/dns_cache.h +++ b/worker/include/dpdk_filter/dns_cache.h @@ -6,15 +6,19 @@ #include #include #include +#include +#include #include #include -#include #include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/types.h" - - +void load_cache_from_sqlite(void); +void close_sqlite_cache(void); +int save_single_node_to_sqlite(const char *domain, struct node_cache *node); +int save_all_cache_to_sqlite(void); +void init_tables_sqlite_dns_cache(void); void init_dns_cache(void); int lookup_dns_cache(const char *domain, struct node_cache **return_node); diff --git a/worker/include/dpdk_filter/filtr_packets.h b/worker/include/dpdk_filter/filtr_packets.h index dda5332..7a83ff7 100644 --- a/worker/include/dpdk_filter/filtr_packets.h +++ b/worker/include/dpdk_filter/filtr_packets.h @@ -1,22 +1,29 @@ #ifndef FILTR_PAK_H #define FILTR_PAK_H +#include "../../include/dpdk_filter/constants.h" +#include "../../include/dpdk_filter/types.h" #include "pars_packets.h" #include #include -#include "../../include/dpdk_filter/constants.h" -#include "../../include/dpdk_filter/types.h" -bool check_is_block(char domain[DOMAIN_MAX_LEN], char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); +bool check_is_block(char domain[DOMAIN_MAX_LEN], + char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); -bool check_is_allow(char domain[DOMAIN_MAX_LEN], char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); +bool check_is_allow(char domain[DOMAIN_MAX_LEN], + char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]); bool check_trust_level(int get_trust_level, int min_trust_level); -bool check_categories(char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN], char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]); +bool check_categories(char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN], + char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]); -bool check_categories_with_lvl(struct requested_classification* req_clas, struct trust_categories_with_lvl categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]); +bool check_categories_with_lvl( + struct requested_classification *req_clas, + struct trust_categories_with_lvl + categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]); -bool main_filtring(struct requested_classification* req_clas, struct BASE_POLICY* policy, char domain[DOMAIN_MAX_LEN]); +bool main_filtring(struct requested_classification *req_clas, + struct BASE_POLICY *policy, char domain[DOMAIN_MAX_LEN]); #endif \ No newline at end of file diff --git a/worker/include/dpdk_filter/net_port.h b/worker/include/dpdk_filter/net_port.h index e34f8b1..3c6fe82 100644 --- a/worker/include/dpdk_filter/net_port.h +++ b/worker/include/dpdk_filter/net_port.h @@ -1,18 +1,15 @@ #ifndef AF_XDP_PORT_H #define AF_XDP_PORT_H +#include "../../include/dpdk_filter/types.h" #include #include -#include "../../include/dpdk_filter/types.h" - - struct net_port *init_struct_tap_port(const char *tap_iface_name, - struct rte_mempool *mbuf_pool); - + struct rte_mempool *mbuf_pool); struct net_port *init_struct_af_xdp_port(const char *iface_name, - struct rte_mempool *mbuf_pool); + struct rte_mempool *mbuf_pool); int net_port_init(struct net_port *port); diff --git a/worker/include/dpdk_filter/pars_packets.h b/worker/include/dpdk_filter/pars_packets.h index d319225..0396ee1 100644 --- a/worker/include/dpdk_filter/pars_packets.h +++ b/worker/include/dpdk_filter/pars_packets.h @@ -1,12 +1,10 @@ #ifndef PARS_PAK_H #define PARS_PAK_H -#include -#include #include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/types.h" - - +#include +#include void parsing_pakage(struct rte_mbuf *paket, struct info_of_pakage *info_pac); diff --git a/worker/include/dpdk_filter/proc_packets.h b/worker/include/dpdk_filter/proc_packets.h index c7f7737..176bc92 100644 --- a/worker/include/dpdk_filter/proc_packets.h +++ b/worker/include/dpdk_filter/proc_packets.h @@ -1,10 +1,10 @@ #ifndef PROC_PAK_H #define PROC_PAK_H -#include "../../include/dpdk_filter/net_port.h" +#include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/filtr_packets.h" +#include "../../include/dpdk_filter/net_port.h" #include "../../include/dpdk_filter/pars_packets.h" -#include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/types.h" #include #include @@ -12,13 +12,9 @@ #include #include - - - - - -void pakage_processing(struct net_port *port_in, - struct net_port *port_out, struct net_port *port_exception, uint16_t queue_number, - uint16_t nb_pkts, struct rte_mbuf **pkts, struct BASE_POLICY* policy); +void pakage_processing(struct net_port *port_in, struct net_port *port_out, + struct net_port *port_exception, uint16_t queue_number, + uint16_t nb_pkts, struct rte_mbuf **pkts, + struct BASE_POLICY *policy); #endif \ No newline at end of file diff --git a/worker/include/dpdk_filter/types.h b/worker/include/dpdk_filter/types.h index d056e50..d93881b 100644 --- a/worker/include/dpdk_filter/types.h +++ b/worker/include/dpdk_filter/types.h @@ -2,8 +2,8 @@ #define TYPES_H #include "constants.h" -#include #include +#include struct net_port { uint16_t port_id; @@ -20,24 +20,24 @@ struct info_of_pakage { }; struct trust_categories_with_lvl { - char locked_by_trust_category[CATEGORY_MAX_LEN]; - int trust_lvl; + char locked_by_trust_category[CATEGORY_MAX_LEN]; + int trust_lvl; }; struct BASE_POLICY { char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; - struct trust_categories_with_lvl categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]; + struct trust_categories_with_lvl + categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]; char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]; char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]; int min_trust_level; }; struct requested_classification { - char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; - int get_trust_level; + char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; + int get_trust_level; }; - struct node_cache { char categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]; bool solution_is_send; @@ -47,5 +47,4 @@ struct node_cache { char *key_domain; }; - #endif diff --git a/worker/scripts/set_tap_dev.sh b/worker/scripts/set_tap_dev.sh new file mode 100755 index 0000000..cb0cb03 --- /dev/null +++ b/worker/scripts/set_tap_dev.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +TAP="tap0" + +sudo ip tuntap add $TAP mode tap +sudo ip link set $TAP up +sudo ip addr add 10.0.3.1/24 dev $TAP \ No newline at end of file diff --git a/worker/src/dpdk_filter/af_xdp_port.c b/worker/src/dpdk_filter/af_xdp_port.c deleted file mode 100644 index 25ecb7d..0000000 --- a/worker/src/dpdk_filter/af_xdp_port.c +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../include/dpdk_filter/af_xdp_port.h" - -#define RX_RING_SIZE 1024 -#define TX_RING_SIZE 1024 - -int find_port_by_dev_name(const char *dev_name, uint16_t *port_id_dev) { - uint16_t count_ports = rte_eth_dev_count_avail(); - struct rte_eth_dev_info dev_info; - char name[64]; - - for (uint16_t port_id = 0; port_id < count_ports; port_id++) { - int ret = rte_eth_dev_info_get(port_id, &dev_info); - - if (ret) { - printf("[ERROR] Failed to retrieve the contextual information of an " - "Ethernet device: %s\n", - strerror(-ret)); - return ret; - } - - if (rte_eth_dev_get_name_by_port(port_id, name) == 0 && - strcmp(name, dev_name) == 0) { - *port_id_dev = port_id; - return 0; - } - } - return -1; -} - -struct af_xdp_port *init_struct_af_xdp_port(const char *iface_name, - struct rte_mempool *mbuf_pool) { - struct af_xdp_port *port = calloc(1, sizeof(struct af_xdp_port)); - if (!port) { - printf("[ERROR] Failed to allocate memory for struct af_xdp_port\n"); - return NULL; - } - - snprintf(port->dev_args, sizeof(port->dev_args), - "iface=%s,start_queue=0,queue_count=1", iface_name); - snprintf(port->dev_name, sizeof(port->dev_name), "net_af_xdp_%s", iface_name); - strncpy(port->iface_name, iface_name, sizeof(port->iface_name) - 1); - port->iface_name[sizeof(port->iface_name) - 1] = '\0'; - port->mbuf_pool = mbuf_pool; - port->port_id = -1; - - return port; -} - -int af_xdp_port_init(struct af_xdp_port *port) { - int ret; - struct rte_eth_conf port_conf = {0}; - const char *dev_name = port->dev_name; - uint16_t port_id; - - ret = rte_vdev_init(dev_name, port->dev_args); - - if (ret < 0) { - printf("[ERROR] Failed to create vdev: %s\n", strerror(-ret)); - return ret; - } - - ret = find_port_by_dev_name(port->dev_name, &port_id); - if (ret) { - printf("no port was found that has the same vdev name. vdev = %s", - port->dev_name); - rte_vdev_uninit(dev_name); - return -1; - } - - port->port_id = port_id; - - if (!rte_eth_dev_is_valid_port(port_id)) { - printf("[ERROR] Port %u is not valid\n", port_id); - rte_vdev_uninit(dev_name); - return -EINVAL; - } - - ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf); - if (ret < 0) { - printf("[ERROR] Failed to configure port: %s\n", strerror(-ret)); - rte_vdev_uninit(dev_name); - return ret; - } - - ret = rte_eth_rx_queue_setup(port_id, 0, RX_RING_SIZE, - rte_eth_dev_socket_id(port_id), NULL, - port->mbuf_pool); - if (ret < 0) { - printf("[ERROR] Failed to setup RX queue: %s\n", strerror(-ret)); - rte_vdev_uninit(dev_name); - return ret; - } - - ret = rte_eth_tx_queue_setup(port_id, 0, TX_RING_SIZE, - rte_eth_dev_socket_id(port_id), NULL); - - if (ret < 0) { - printf("[ERROR] Failed to setup TX queue: %s\n", strerror(-ret)); - rte_vdev_uninit(dev_name); - return ret; - } - - printf("Port %u initialized\n", port_id); - return 0; -} - -int af_xdp_port_start(uint16_t port_id) { - int ret; - - ret = rte_eth_dev_start(port_id); - if (ret < 0) { - printf("[ERROR] Failed to start: %s\n", strerror(-ret)); - return ret; - } - - ret = rte_eth_promiscuous_enable(port_id); - if (ret) { - printf("[ERROR] Failed to enable receipt in promiscuous mode for an " - "Ethernet device: %s\n", - strerror(-ret)); - return ret; - } - - printf("Port %u started\n", port_id); - return 0; -} - -void af_xdp_port_destroy(struct af_xdp_port *port) { - if (!port) - return; - free(port); -} - -void af_xdp_port_close(struct af_xdp_port *port) { - - if (!port) - return; - - int ret; - uint16_t port_id = port->port_id; - - ret = rte_eth_dev_stop(port_id); - if (ret) { - printf("[ERROR] Failed to stop an Ethernet device: %s\n", strerror(-ret)); - return; - } - - ret = rte_eth_dev_close(port_id); - if (ret) { - printf("[ERROR] Failed to close a stopped Ethernet device: %s\n", - strerror(-ret)); - return; - } - - ret = rte_vdev_uninit(port->dev_name); - if (ret) { - printf("[ERROR] Failed to uninitialize a driver: %s\n", strerror(-ret)); - return; - } - - port->port_id = -1; - printf("Port %u closed\n", port_id); -} \ No newline at end of file diff --git a/worker/src/dpdk_filter/dns_cache.c b/worker/src/dpdk_filter/dns_cache.c index 4427e1f..60099ae 100644 --- a/worker/src/dpdk_filter/dns_cache.c +++ b/worker/src/dpdk_filter/dns_cache.c @@ -1,5 +1,7 @@ #include "../../include/dpdk_filter/dns_cache.h" +static sqlite3 *cache_table; + static struct rte_hash *dns_hash; static struct rte_hash_parameters hash_params = { .name = "dns_cache_hash", @@ -8,6 +10,343 @@ static struct rte_hash_parameters hash_params = { .hash_func = rte_jhash, .extra_flag = RTE_HASH_EXTRA_FLAGS_EXT_TABLE, }; +static struct rte_timer cache_save_timer; +static uint64_t save_interval_cycles; + +static int insert_loaded_node(const char *domain, struct node_cache *node) { + char *key_copy = rte_malloc("dns_key(domain)", DOMAIN_MAX_LEN, 0); + if (!key_copy) { + printf("[ERROR] Failed to allocate key for loaded node\n"); + return -ENOMEM; + } + + strncpy(key_copy, domain, DOMAIN_MAX_LEN); + key_copy[DOMAIN_MAX_LEN - 1] = '\0'; + node->key_domain = key_copy; + + int ret = rte_hash_add_key_data(dns_hash, key_copy, node); + if (ret < 0) { + printf("[ERROR] Failed to insert loaded node into hash: %s\n", + strerror(-ret)); + rte_free(key_copy); + return ret; + } + return 0; +} + +void load_cache_from_sqlite(void) { + if (!dns_hash) { + printf("[ERROR] Hash table not initialized for loading\n"); + return; + } + if (!cache_table) { + printf("[ERROR] SQLite connection not open for loading\n"); + return; + } + + uint64_t now_cycles = rte_get_timer_cycles(); + uint64_t hz = rte_get_timer_hz(); + + const char *sql = "SELECT domain, solution_is_send, trust_lvl, timestamp, " + "ttl_seconds FROM main_table;"; + + sqlite3_stmt *stmt = NULL; + int ret = sqlite3_prepare_v2(cache_table, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to prepare SELECT from main_table: %s\n", + sqlite3_errmsg(cache_table)); + return; + } + + int loaded = 0; + int expired = 0; + + while (sqlite3_step(stmt) == SQLITE_ROW) { + const char *domain = (const char *)sqlite3_column_text(stmt, 0); + int solution_is_send = sqlite3_column_int(stmt, 1); + int trust_lvl = sqlite3_column_int(stmt, 2); + uint64_t timestamp = (uint64_t)sqlite3_column_int64(stmt, 3); + uint32_t ttl_seconds = (uint32_t)sqlite3_column_int(stmt, 4); + + uint64_t age_seconds = (now_cycles - timestamp) / hz; + if (age_seconds >= ttl_seconds) { + expired++; + continue; + } + + struct node_cache *node = + rte_malloc("loaded_node_cache", sizeof(struct node_cache), 0); + if (!node) { + printf("[ERROR] Failed to allocate node for domain %s\n", domain); + continue; + } + + node->solution_is_send = solution_is_send ? true : false; + node->trust_lvl = trust_lvl; + node->timestamp = timestamp; + node->ttl_seconds = ttl_seconds; + + const char *sql_cat = + "SELECT certain_category FROM categories_table WHERE domain = ?;"; + sqlite3_stmt *stmt_cat = NULL; + int rc_cat = sqlite3_prepare_v2(cache_table, sql_cat, -1, &stmt_cat, NULL); + if (rc_cat != SQLITE_OK) { + printf("[ERROR] Failed to prepare categories SELECT: %s\n", + sqlite3_errmsg(cache_table)); + rte_free(node); + continue; + } + + sqlite3_bind_text(stmt_cat, 1, domain, -1, SQLITE_STATIC); + + int cat_idx = 0; + while (sqlite3_step(stmt_cat) == SQLITE_ROW && cat_idx < MAX_CATEGORIES) { + const unsigned char *cat_text = sqlite3_column_text(stmt_cat, 0); + if (cat_text) { + strncpy(node->categories[cat_idx], (const char *)cat_text, + CATEGORY_MAX_LEN - 1); + node->categories[cat_idx][CATEGORY_MAX_LEN - 1] = '\0'; + } else { + node->categories[cat_idx][0] = '\0'; + } + cat_idx++; + } + + sqlite3_finalize(stmt_cat); + + if (insert_loaded_node(domain, node) == 0) { + loaded++; + } else { + rte_free(node); + } + } + + ret = sqlite3_finalize(stmt); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to delete prepared statement: %s\n", + sqlite3_errmsg(cache_table)); + return; + } + printf("[INFO] Loaded %d records from SQLite, %d expired skipped\n", loaded, + expired); +} + +static void cache_save_timer_cb(struct rte_timer *tim, void *arg) { + (void)tim; + (void)arg; + + printf("[INFO] Periodic cache saving to SQLite.\n"); + save_all_cache_to_sqlite(); +} + +void close_sqlite_cache(void) { + if (cache_table) { + int ret = sqlite3_close(cache_table); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed close SQLite connection: %s\n", + sqlite3_errmsg(cache_table)); + } + } + cache_table = NULL; +} + +int save_single_node_to_sqlite(const char *domain, struct node_cache *node) { + sqlite3_stmt *stmt = NULL; + int ret; + + const char *sql_main = + "INSERT OR REPLACE INTO main_table " + "(domain, solution_is_send, trust_lvl, timestamp, ttl_seconds) " + "VALUES (?, ?, ?, ?, ?)"; + + ret = sqlite3_prepare_v2(cache_table, sql_main, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to prepare main_table insert: %s\n", + sqlite3_errmsg(cache_table)); + sqlite3_finalize(stmt); + return ret; + } + + sqlite3_bind_text(stmt, 1, domain, -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 2, node->solution_is_send ? 1 : 0); + sqlite3_bind_int(stmt, 3, node->trust_lvl); + sqlite3_bind_int64(stmt, 4, (sqlite3_int64)node->timestamp); + sqlite3_bind_int(stmt, 5, (int)node->ttl_seconds); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + printf("[ERROR] Failed to insert into main_table: %s\n", + sqlite3_errmsg(cache_table)); + sqlite3_finalize(stmt); + return ret; + } + + ret = sqlite3_finalize(stmt); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to delete prepared statement: %s\n", + sqlite3_errmsg(cache_table)); + return ret; + } + + const char *sql_del = "DELETE FROM categories_table WHERE domain = ?"; + ret = sqlite3_prepare_v2(cache_table, sql_del, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to prepare delete: %s\n", + sqlite3_errmsg(cache_table)); + sqlite3_finalize(stmt); + return ret; + } + + sqlite3_bind_text(stmt, 1, domain, -1, SQLITE_STATIC); + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + printf("[ERROR] Failed to delete old categories: %s\n", + sqlite3_errmsg(cache_table)); + sqlite3_finalize(stmt); + return ret; + } + + ret = sqlite3_finalize(stmt); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to delete prepared statement: %s\n", + sqlite3_errmsg(cache_table)); + return ret; + } + + const char *sql_cat = + "INSERT INTO categories_table (domain, certain_category) VALUES (?, ?)"; + ret = sqlite3_prepare_v2(cache_table, sql_cat, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to prepare categories insert: %s\n", + sqlite3_errmsg(cache_table)); + return ret; + } + + for (int i = 0; i < MAX_CATEGORIES; i++) { + if (strlen(node->categories[i]) == 0) { + break; + } + + sqlite3_bind_text(stmt, 1, domain, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, node->categories[i], -1, SQLITE_STATIC); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + printf("[ERROR] Failed to prepare categories_table insert: %s\n", + sqlite3_errmsg(cache_table)); + sqlite3_finalize(stmt); + return ret; + } + + ret = sqlite3_reset(stmt); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to reset prepared statement: %s\n", + sqlite3_errmsg(cache_table)); + sqlite3_finalize(stmt); + return ret; + } + } + + ret = sqlite3_finalize(stmt); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to delete prepared statement: %s\n", + sqlite3_errmsg(cache_table)); + return ret; + } + + return SQLITE_OK; +} + +int save_all_cache_to_sqlite(void) { + if (!dns_hash) { + printf("[ERROR] Hash table is not initialized\n"); + return -1; + } + + if (!cache_table) { + printf("[ERROR] SQLite connection is not open\n"); + return -1; + } + + uint32_t next = 0; + const void *key; + void *data; + int count = 0; + int errors = 0; + int ret; + + ret = sqlite3_exec(cache_table, "BEGIN TRANSACTION;", NULL, NULL, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to exec BEGIN TRANSACTION: %s\n", + sqlite3_errmsg(cache_table)); + return -1; + } + + while (rte_hash_iterate(dns_hash, &key, &data, &next) >= 0) { + const char *domain = (const char *)key; + struct node_cache *node = (struct node_cache *)data; + + if (!domain || !node) { + continue; + } + + ret = save_single_node_to_sqlite(domain, node); + if (ret == SQLITE_OK) { + count++; + } else { + errors++; + } + } + + ret = sqlite3_exec(cache_table, "COMMIT;", NULL, NULL, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to exec COMMIT: %s\n", sqlite3_errmsg(cache_table)); + return -1; + } + + printf("[INFO] Saved %d records to SQLite, %d errors\n", count, errors); + return count; +} + +void init_tables_sqlite_dns_cache(void) { + int ret = sqlite3_open("cache.db", &cache_table); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to open cache.db\n"); + return; + } + + const char *create_main_table = "CREATE TABLE IF NOT EXISTS main_table(" + "domain TEXT PRIMARY KEY, " + "solution_is_send INT NOT NULL, " + "trust_lvl INT NOT NULL, " + "timestamp INT NOT NULL, " + "ttl_seconds INT NOT NULL)"; + + ret = sqlite3_exec(cache_table, create_main_table, NULL, NULL, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to create table 'main_table'\n"); + return; + } + + const char *create_categories_table = + "CREATE TABLE IF NOT EXISTS categories_table(" + "domain TEXT NOT NULL, " + "certain_category TEXT NOT NULL, " + "PRIMARY KEY (domain, certain_category), " + "FOREIGN KEY (domain) REFERENCES main_table(domain))"; + + ret = sqlite3_exec(cache_table, create_categories_table, NULL, NULL, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to create table 'categories_table'\n"); + return; + } + + ret = + sqlite3_exec(cache_table, "PRAGMA foreign_keys = ON;", NULL, NULL, NULL); + if (ret != SQLITE_OK) { + printf("[ERROR] Failed to include foreign_keys\n"); + } +} void init_dns_cache(void) { if (dns_hash) @@ -16,7 +355,18 @@ void init_dns_cache(void) { dns_hash = rte_hash_create(&hash_params); if (!dns_hash) { printf("[ERROR] Failed to create DNS cache hash table\n"); + return; } + + init_tables_sqlite_dns_cache(); + + load_cache_from_sqlite(); + + rte_timer_init(&cache_save_timer); + save_interval_cycles = rte_get_timer_hz() * 3600; + + rte_timer_reset(&cache_save_timer, save_interval_cycles, PERIODICAL, + rte_lcore_id(), cache_save_timer_cb, NULL); } int lookup_dns_cache(const char *domain, struct node_cache **return_node) { @@ -85,5 +435,12 @@ void free_dns_cache(void) { } rte_hash_free(dns_hash); + + close_sqlite_cache(); dns_hash = NULL; -} \ No newline at end of file + + int ret = rte_timer_stop(&cache_save_timer); + if (!ret) { + printf("[ERROR] Failed to stopping timer\n"); + } +} diff --git a/worker/src/dpdk_filter/filtr_packets.c b/worker/src/dpdk_filter/filtr_packets.c index a6aeadd..258ff37 100644 --- a/worker/src/dpdk_filter/filtr_packets.c +++ b/worker/src/dpdk_filter/filtr_packets.c @@ -1,7 +1,8 @@ #include "../../include/dpdk_filter/filtr_packets.h" #include "../../include/dpdk_filter/pars_packets.h" -bool check_is_block(char domain[DOMAIN_MAX_LEN], char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { +bool check_is_block(char domain[DOMAIN_MAX_LEN], + char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { for (int i = 0; i < MAX_DOMAINS; i++) { if (strcmp(block_domains[i], domain) == 0) { @@ -12,7 +13,8 @@ bool check_is_block(char domain[DOMAIN_MAX_LEN], char block_domains[MAX_DOMAINS] return false; } -bool check_is_allow(char domain[DOMAIN_MAX_LEN], char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { +bool check_is_allow(char domain[DOMAIN_MAX_LEN], + char allow_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { for (int i = 0; i < MAX_DOMAINS; i++) { if (strcmp(allow_domains[i], domain) == 0) { @@ -32,34 +34,41 @@ bool check_trust_level(int get_trust_level, int min_trust_level) { return true; } -bool check_categories(char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN], char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]) { - +bool check_categories( + char get_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN], + char locked_categories[MAX_CATEGORIES][CATEGORY_MAX_LEN]) { + for (int i = 0; i < MAX_CATEGORIES; i++) { for (int j = 0; j < MAX_CATEGORIES; j++) { if (strcmp(get_categories[i], locked_categories[j]) == 0) { return false; } } - } + } return true; } - -bool check_categories_with_lvl(struct requested_classification* req_clas, struct trust_categories_with_lvl categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]) { +bool check_categories_with_lvl( + struct requested_classification *req_clas, + struct trust_categories_with_lvl + categories_with_lvl[MAX_CATEGORIES_BY_TRUST_LVL]) { for (int i = 0; i < MAX_CATEGORIES; i++) { for (int j = 0; j < MAX_CATEGORIES; j++) { - if (strcmp(req_clas->get_categories[j], categories_with_lvl[i].locked_by_trust_category) == 0 && req_clas->get_trust_level < categories_with_lvl[i].trust_lvl) { - return false; + if (strcmp(req_clas->get_categories[j], + categories_with_lvl[i].locked_by_trust_category) == 0 && + req_clas->get_trust_level < categories_with_lvl[i].trust_lvl) { + return false; } - } - } + } + } return true; } -bool main_filtring(struct requested_classification* req_clas, struct BASE_POLICY* policy, char domain[DOMAIN_MAX_LEN]) { +bool main_filtring(struct requested_classification *req_clas, + struct BASE_POLICY *policy, char domain[DOMAIN_MAX_LEN]) { if (check_is_block(domain, policy->block_domains) == true) { printf("This domain is blocked"); @@ -71,18 +80,22 @@ bool main_filtring(struct requested_classification* req_clas, struct BASE_POLICY return true; } - if (check_categories(req_clas->get_categories, policy->locked_categories) == false) { + if (check_categories(req_clas->get_categories, policy->locked_categories) == + false) { printf("This site has a locked category"); return false; } - if (check_trust_level(req_clas->get_trust_level, policy->min_trust_level) == false) { + if (check_trust_level(req_clas->get_trust_level, policy->min_trust_level) == + false) { printf("This site has a too small trust level"); return false; } - if (check_categories_with_lvl(req_clas, policy->categories_with_lvl) == false) { - printf("This site blocked in accordance with 'trust categories with level'"); + if (check_categories_with_lvl(req_clas, policy->categories_with_lvl) == + false) { + printf( + "This site blocked in accordance with 'trust categories with level'"); return false; } diff --git a/worker/src/dpdk_filter/main.c b/worker/src/dpdk_filter/main.c index 74954c1..96e06d2 100644 --- a/worker/src/dpdk_filter/main.c +++ b/worker/src/dpdk_filter/main.c @@ -1,5 +1,5 @@ -#include "../../include/dpdk_filter/net_port.h" #include "../../include/dpdk_filter/dns_cache.h" +#include "../../include/dpdk_filter/net_port.h" #include "../../include/dpdk_filter/proc_packets.h" #include #include @@ -18,21 +18,24 @@ static void signal_handler(int signum) { } } -void forward_to_out(struct net_port *incoming_port, struct net_port *outgoing_port, uint16_t queue_number) { - struct rte_mbuf *tap_pkts[32]; - uint16_t nb_tap = rte_eth_rx_burst(incoming_port->port_id, queue_number, tap_pkts, 32); - for (int i = 0; i < nb_tap; i++) { - int ret = rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); - if (ret < 1) { - printf("[ERROR] Failed to send packet\n"); - // PLUG (to be added later) - need to add processing for this case - rte_pktmbuf_free(tap_pkts[i]); - } +void forward_to_out(struct net_port *incoming_port, + struct net_port *outgoing_port, uint16_t queue_number) { + struct rte_mbuf *tap_pkts[32]; + uint16_t nb_tap = + rte_eth_rx_burst(incoming_port->port_id, queue_number, tap_pkts, 32); + for (int i = 0; i < nb_tap; i++) { + int ret = + rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); + if (ret < 1) { + printf("[ERROR] Failed to send packet\n"); + // PLUG (to be added later) - need to add processing for this case + rte_pktmbuf_free(tap_pkts[i]); } + } } int main(int argc, char **argv) { - //since BASE_POLICY is filled when initializing worker, let’s initialize here + // since BASE_POLICY is filled when initializing worker, let’s initialize here struct BASE_POLICY policy; if (signal(SIGINT, signal_handler) == SIG_ERR) { printf("[ERROR] Failed to set SIGINT handler\n"); @@ -43,8 +46,6 @@ int main(int argc, char **argv) { return 1; } - - struct net_port *port_in = NULL; struct net_port *port_out = NULL; struct net_port *port_exception = NULL; @@ -83,24 +84,21 @@ int main(int argc, char **argv) { port_exception = init_struct_tap_port("tap0", mbuf_pool); - if (!port_in || !port_out || !port_exception) { return 1; } - if (net_port_init(port_in) || net_port_init(port_out) || net_port_init(port_exception)) { + if (net_port_init(port_in) || net_port_init(port_out) || + net_port_init(port_exception)) { return 1; } - if (net_port_start(port_in->port_id) || - net_port_start(port_out->port_id) || + if (net_port_start(port_in->port_id) || net_port_start(port_out->port_id) || net_port_start(port_exception->port_id)) { return 1; } - ret = system("sudo ip link set tap0 up && " - "sudo ip addr add 10.0.3.1/24 dev tap0"); - if(ret) { + if (ret) { printf("[ERROR] Failed to set tap0 up\n"); } @@ -108,13 +106,22 @@ int main(int argc, char **argv) { "to port with id=%u\n", port_in->port_id, port_out->port_id); + uint64_t timer_check_counter = 0; + const uint64_t timer_check_interval = 10000; + while (running) { forward_to_out(port_exception, port_in, queue_number); - pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, pkts, &policy); + pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, + pkts, &policy); forward_to_out(port_out, port_in, queue_number); + + if (++timer_check_counter >= timer_check_interval) { + rte_timer_manage(); + timer_check_counter = 0; + } } - // function for save cache info if need + save_all_cache_to_sqlite(); free_dns_cache(); net_port_close(port_in); diff --git a/worker/src/dpdk_filter/net_port.c b/worker/src/dpdk_filter/net_port.c index 92eeca4..5c57b26 100644 --- a/worker/src/dpdk_filter/net_port.c +++ b/worker/src/dpdk_filter/net_port.c @@ -41,16 +41,18 @@ int find_port_by_dev_name(const char *dev_name, uint16_t *port_id_dev) { } struct net_port *init_struct_tap_port(const char *tap_iface_name, - struct rte_mempool *mbuf_pool) { + struct rte_mempool *mbuf_pool) { struct net_port *port = calloc(1, sizeof(struct net_port)); - if (!port) { + if (!port) { printf("[ERROR] Failed to allocate memory for struct net_port\n"); return NULL; } - snprintf(port->dev_args, sizeof(port->dev_args),"iface=%s", tap_iface_name); - snprintf(port->dev_name, sizeof(port->dev_name), "net_tap_%s", tap_iface_name); + snprintf(port->dev_args, sizeof(port->dev_args), "iface=%s, remote=%s", + tap_iface_name, tap_iface_name); + snprintf(port->dev_name, sizeof(port->dev_name), "net_tap_%s", + tap_iface_name); strncpy(port->iface_name, tap_iface_name, sizeof(port->iface_name) - 1); port->iface_name[sizeof(port->iface_name) - 1] = '\0'; port->mbuf_pool = mbuf_pool; @@ -59,9 +61,8 @@ struct net_port *init_struct_tap_port(const char *tap_iface_name, return port; } - struct net_port *init_struct_af_xdp_port(const char *iface_name, - struct rte_mempool *mbuf_pool) { + struct rte_mempool *mbuf_pool) { struct net_port *port = calloc(1, sizeof(struct net_port)); if (!port) { printf("[ERROR] Failed to allocate memory for struct net_port\n"); diff --git a/worker/src/dpdk_filter/proc_packets.c b/worker/src/dpdk_filter/proc_packets.c index 6527fa2..16e61e7 100644 --- a/worker/src/dpdk_filter/proc_packets.c +++ b/worker/src/dpdk_filter/proc_packets.c @@ -20,7 +20,6 @@ void package_sending_decision(bool solution_is_send, struct rte_mbuf *pkt, rte_pktmbuf_free(pkt); } - bool check_is_exception(uint16_t number_port) { for (int i = 0; i < LEN_LIST_EXCEPTION_PORTS; i++) { if (number_port == LIST_EXCEPTION_PORTS[i]) { @@ -30,10 +29,10 @@ bool check_is_exception(uint16_t number_port) { return false; } - -void pakage_processing(struct net_port *port_in, - struct net_port *port_out, struct net_port *port_exception, uint16_t queue_number, - uint16_t nb_pkts, struct rte_mbuf **pkts, struct BASE_POLICY* policy) { +void pakage_processing(struct net_port *port_in, struct net_port *port_out, + struct net_port *port_exception, uint16_t queue_number, + uint16_t nb_pkts, struct rte_mbuf **pkts, + struct BASE_POLICY *policy) { uint16_t nb_rx = rte_eth_rx_burst(port_in->port_id, queue_number, pkts, nb_pkts); @@ -50,7 +49,7 @@ void pakage_processing(struct net_port *port_in, continue; } - if(check_is_exception(info_pac.number_port) == true) { + if (check_is_exception(info_pac.number_port) == true) { package_sending_decision(true, pkts[i], port_exception, queue_number); continue; } From 4c7646001391530c3d1b5dea25de986ff958a32c Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Tue, 14 Apr 2026 21:40:18 +0300 Subject: [PATCH 09/20] add stdint --- worker/include/dpdk_filter/constants.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/worker/include/dpdk_filter/constants.h b/worker/include/dpdk_filter/constants.h index 3e92808..b7d69c6 100644 --- a/worker/include/dpdk_filter/constants.h +++ b/worker/include/dpdk_filter/constants.h @@ -1,6 +1,8 @@ #ifndef CONSTANTS_H #define CONSTANTS_H +#include + #define MAX_CATEGORIES_BY_TRUST_LVL 64 #define MAX_DOMAINS 64 #define CACHE_SIZE 1024 From 2a8a6fb9e47b01553a52ca3ab4f9ec071e6d0682 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Tue, 14 Apr 2026 22:08:00 +0300 Subject: [PATCH 10/20] fix build --- worker/BUILD | 2 ++ worker/include/dpdk_filter/constants.h | 4 ---- worker/src/worker.cpp | 5 ----- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/worker/BUILD b/worker/BUILD index a091ccb..c949c49 100644 --- a/worker/BUILD +++ b/worker/BUILD @@ -102,6 +102,8 @@ cc_binary( "-lrte_log", "-lrte_net", "-lrte_hash", + "-lrte_timer", + "-lsqlite3", "-lnuma", "-ldl", diff --git a/worker/include/dpdk_filter/constants.h b/worker/include/dpdk_filter/constants.h index 2fc0d9c..b7d69c6 100644 --- a/worker/include/dpdk_filter/constants.h +++ b/worker/include/dpdk_filter/constants.h @@ -1,11 +1,7 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -<<<<<<< HEAD #include -======= -#include ->>>>>>> origin/104_Adding_filtering_logic_to_loop #define MAX_CATEGORIES_BY_TRUST_LVL 64 #define MAX_DOMAINS 64 diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index 99c14f1..3f530bf 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -82,11 +82,6 @@ void Worker::initDPDK(int argc, char **argv) { throw std::runtime_error("Start ports"); } - int tap_ret = system( - "sudo ip link set tap0 up && sudo ip addr add 10.0.3.1/24 dev tap0"); - if (tap_ret) - spdlog::warn("Failed to configure tap0"); - init_dns_cache(); spdlog::info("DPDK initialized: in_port={}, out_port={}", port_in->port_id, From cd0ecf6be492c8693a0d6fbf528e4658758ab2ba Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Tue, 14 Apr 2026 22:08:36 +0300 Subject: [PATCH 11/20] fix linter --- worker/include/dpdk_filter/constants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worker/include/dpdk_filter/constants.h b/worker/include/dpdk_filter/constants.h index b7d69c6..f046259 100644 --- a/worker/include/dpdk_filter/constants.h +++ b/worker/include/dpdk_filter/constants.h @@ -1,7 +1,7 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -#include +#include #define MAX_CATEGORIES_BY_TRUST_LVL 64 #define MAX_DOMAINS 64 From cac500e3c4c957f1d5e79215b711cde240f496e0 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 16 Apr 2026 00:24:55 +0300 Subject: [PATCH 12/20] fix build worker --- worker/Dockerfile.cc_x86_to_x86 | 69 +++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/worker/Dockerfile.cc_x86_to_x86 b/worker/Dockerfile.cc_x86_to_x86 index 5d6cf09..556c7c8 100644 --- a/worker/Dockerfile.cc_x86_to_x86 +++ b/worker/Dockerfile.cc_x86_to_x86 @@ -1,17 +1,49 @@ -FROM alpine:3.21.3 AS builder +FROM ubuntu:22.04 AS builder -RUN apk update && apk add --no-cache g++ openssl-dev cmake make curl-dev protobuf-dev -RUN apk add bazel --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/ +RUN apt-get update && apt-get install -y \ + build-essential \ + cmake \ + curl \ + git \ + wget \ + meson \ + ninja-build \ + libssl-dev \ + protobuf-compiler \ + libprotobuf-dev \ + python3 \ + python3-pip \ + libnuma-dev \ + pkg-config \ + libcurl4-openssl-dev \ + libbpf-dev \ + gcc \ + g++ \ + m4 \ + libpcap-dev \ + libsqlite3-dev \ + && rm -rf /var/lib/apt/lists/* + +RUN pip3 install pyelftools + + +RUN wget https://github.com/bazelbuild/bazel/releases/download/8.2.1/bazel-8.2.1-linux-x86_64 \ + && chmod +x bazel-8.2.1-linux-x86_64 \ + && mv bazel-8.2.1-linux-x86_64 /usr/local/bin/bazel + +RUN wget https://fast.dpdk.org/rel/dpdk-23.11.tar.xz && \ + tar -xf dpdk-23.11.tar.xz && \ + cd dpdk-23.11 && \ + meson setup build --libdir=lib && \ + ninja -C build && \ + ninja -C build install + +ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig WORKDIR /app COPY scripts/get_prometheus_cpp.sh scripts/ RUN sh scripts/get_prometheus_cpp.sh -RUN apk add --no-cache llvm18 clang18 -RUN ln -s /usr/lib/llvm18/bin/llvm-ar /bin/llvm-ar-18 -RUN ln -s /usr/bin/clang++-18 /usr/bin/clang++ -RUN ln -s /usr/bin/clang-18 /usr/bin/clang - COPY ./src/ ./src/ COPY ./include/ ./include/ @@ -22,16 +54,19 @@ COPY ./toolchains ./toolchains COPY ./platforms ./platforms -RUN bazel build //:worker --extra_toolchains=//toolchains/x86_64:cc_toolchain_for_linux_x86_64 --platforms=//platforms:x86_64_linux - -FROM alpine:3.21.3 - -RUN apk update && apk add --no-cache libstdc++ libgcc libssl3 libcurl protobuf-dev - -COPY --from=builder /app/bazel-bin/worker /usr/local/bin/worker -COPY --from=builder /app/prometheus-cpp-with-submodules/build/lib/ /usr/lib +RUN bazel build //:worker +FROM ubuntu:22.04 +RUN apt-get update && apt-get install -y \ + libstdc++6 \ + libgcc-s1 \ + libssl3 \ + libcurl4 \ + libprotobuf-dev \ + numactl \ + sqlite3 \ + && rm -rf /var/lib/apt/lists/* WORKDIR /data -ENTRYPOINT ["/usr/local/bin/worker", "/data/test.txt", "sha256"] +ENTRYPOINT ["/usr/local/bin/worker"] \ No newline at end of file From b970eda53067ecfa9dd21221ab96e415073d4151 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 16 Apr 2026 01:41:45 +0300 Subject: [PATCH 13/20] fix build worker --- worker/Dockerfile.cc_x86_to_x86 | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/worker/Dockerfile.cc_x86_to_x86 b/worker/Dockerfile.cc_x86_to_x86 index 556c7c8..3557b40 100644 --- a/worker/Dockerfile.cc_x86_to_x86 +++ b/worker/Dockerfile.cc_x86_to_x86 @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 AS builder +FROM ubuntu:22.04 RUN apt-get update && apt-get install -y \ build-essential \ @@ -16,17 +16,22 @@ RUN apt-get update && apt-get install -y \ libnuma-dev \ pkg-config \ libcurl4-openssl-dev \ - libbpf-dev \ + libbpf-dev \ gcc \ g++ \ m4 \ libpcap-dev \ libsqlite3-dev \ + libstdc++6 \ + libgcc-s1 \ + libssl3 \ + libcurl4 \ + numactl \ + sqlite3 \ && rm -rf /var/lib/apt/lists/* RUN pip3 install pyelftools - RUN wget https://github.com/bazelbuild/bazel/releases/download/8.2.1/bazel-8.2.1-linux-x86_64 \ && chmod +x bazel-8.2.1-linux-x86_64 \ && mv bazel-8.2.1-linux-x86_64 /usr/local/bin/bazel @@ -53,20 +58,10 @@ COPY ./communication.proto ./ COPY ./toolchains ./toolchains COPY ./platforms ./platforms - -RUN bazel build //:worker -FROM ubuntu:22.04 - -RUN apt-get update && apt-get install -y \ - libstdc++6 \ - libgcc-s1 \ - libssl3 \ - libcurl4 \ - libprotobuf-dev \ - numactl \ - sqlite3 \ - && rm -rf /var/lib/apt/lists/* +RUN bazel build //:worker WORKDIR /data -ENTRYPOINT ["/usr/local/bin/worker"] \ No newline at end of file +RUN ldconfig + +ENTRYPOINT ["/app/bazel-bin/worker"] \ No newline at end of file From 74a285316bb02f26d1f7f971a882287deb4c006e Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 23 Apr 2026 01:34:04 +0300 Subject: [PATCH 14/20] fix: remove cache --- worker/include/dpdk_filter/constants.h | 2 - worker/include/dpdk_filter/dns_cache.h | 7 - worker/include/dpdk_filter/filtr_packets.h | 2 +- worker/include/dpdk_filter/pars_packets.h | 2 +- worker/include/dpdk_filter/proc_packets.h | 8 - worker/include/worker.hpp | 1 - worker/src/dpdk_filter/dns_cache.c | 359 +-------------------- worker/src/dpdk_filter/filtr_packets.c | 2 +- worker/src/dpdk_filter/main.c | 26 +- worker/src/dpdk_filter/proc_packets.c | 18 +- worker/src/worker.cpp | 5 - 11 files changed, 18 insertions(+), 414 deletions(-) diff --git a/worker/include/dpdk_filter/constants.h b/worker/include/dpdk_filter/constants.h index f046259..3e92808 100644 --- a/worker/include/dpdk_filter/constants.h +++ b/worker/include/dpdk_filter/constants.h @@ -1,8 +1,6 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -#include - #define MAX_CATEGORIES_BY_TRUST_LVL 64 #define MAX_DOMAINS 64 #define CACHE_SIZE 1024 diff --git a/worker/include/dpdk_filter/dns_cache.h b/worker/include/dpdk_filter/dns_cache.h index d61ef3b..f1c137a 100644 --- a/worker/include/dpdk_filter/dns_cache.h +++ b/worker/include/dpdk_filter/dns_cache.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -14,12 +13,6 @@ #include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/types.h" -void load_cache_from_sqlite(void); -void close_sqlite_cache(void); -int save_single_node_to_sqlite(const char *domain, struct node_cache *node); -int save_all_cache_to_sqlite(void); -void init_tables_sqlite_dns_cache(void); - void init_dns_cache(void); int lookup_dns_cache(const char *domain, struct node_cache **return_node); void add_to_dns_cache(const char *domain, struct node_cache *node); diff --git a/worker/include/dpdk_filter/filtr_packets.h b/worker/include/dpdk_filter/filtr_packets.h index bb052cf..7a83ff7 100644 --- a/worker/include/dpdk_filter/filtr_packets.h +++ b/worker/include/dpdk_filter/filtr_packets.h @@ -26,4 +26,4 @@ bool check_categories_with_lvl( bool main_filtring(struct requested_classification *req_clas, struct BASE_POLICY *policy, char domain[DOMAIN_MAX_LEN]); -#endif +#endif \ No newline at end of file diff --git a/worker/include/dpdk_filter/pars_packets.h b/worker/include/dpdk_filter/pars_packets.h index 96e96f0..0396ee1 100644 --- a/worker/include/dpdk_filter/pars_packets.h +++ b/worker/include/dpdk_filter/pars_packets.h @@ -8,4 +8,4 @@ void parsing_pakage(struct rte_mbuf *paket, struct info_of_pakage *info_pac); -#endif +#endif \ No newline at end of file diff --git a/worker/include/dpdk_filter/proc_packets.h b/worker/include/dpdk_filter/proc_packets.h index 65f3af6..176bc92 100644 --- a/worker/include/dpdk_filter/proc_packets.h +++ b/worker/include/dpdk_filter/proc_packets.h @@ -1,10 +1,6 @@ #ifndef PROC_PAK_H #define PROC_PAK_H -#ifdef __cplusplus -extern "C" { -#endif - #include "../../include/dpdk_filter/constants.h" #include "../../include/dpdk_filter/filtr_packets.h" #include "../../include/dpdk_filter/net_port.h" @@ -21,8 +17,4 @@ void pakage_processing(struct net_port *port_in, struct net_port *port_out, uint16_t nb_pkts, struct rte_mbuf **pkts, struct BASE_POLICY *policy); -#ifdef __cplusplus -} -#endif - #endif \ No newline at end of file diff --git a/worker/include/worker.hpp b/worker/include/worker.hpp index cb5bebb..d1859a2 100644 --- a/worker/include/worker.hpp +++ b/worker/include/worker.hpp @@ -4,7 +4,6 @@ #include "communication.grpc.pb.h" #include "communication.pb.h" extern "C" { -#include "dpdk_filter/dns_cache.h" #include "dpdk_filter/filtr_packets.h" #include "dpdk_filter/net_port.h" #include "dpdk_filter/proc_packets.h" diff --git a/worker/src/dpdk_filter/dns_cache.c b/worker/src/dpdk_filter/dns_cache.c index 60099ae..4427e1f 100644 --- a/worker/src/dpdk_filter/dns_cache.c +++ b/worker/src/dpdk_filter/dns_cache.c @@ -1,7 +1,5 @@ #include "../../include/dpdk_filter/dns_cache.h" -static sqlite3 *cache_table; - static struct rte_hash *dns_hash; static struct rte_hash_parameters hash_params = { .name = "dns_cache_hash", @@ -10,343 +8,6 @@ static struct rte_hash_parameters hash_params = { .hash_func = rte_jhash, .extra_flag = RTE_HASH_EXTRA_FLAGS_EXT_TABLE, }; -static struct rte_timer cache_save_timer; -static uint64_t save_interval_cycles; - -static int insert_loaded_node(const char *domain, struct node_cache *node) { - char *key_copy = rte_malloc("dns_key(domain)", DOMAIN_MAX_LEN, 0); - if (!key_copy) { - printf("[ERROR] Failed to allocate key for loaded node\n"); - return -ENOMEM; - } - - strncpy(key_copy, domain, DOMAIN_MAX_LEN); - key_copy[DOMAIN_MAX_LEN - 1] = '\0'; - node->key_domain = key_copy; - - int ret = rte_hash_add_key_data(dns_hash, key_copy, node); - if (ret < 0) { - printf("[ERROR] Failed to insert loaded node into hash: %s\n", - strerror(-ret)); - rte_free(key_copy); - return ret; - } - return 0; -} - -void load_cache_from_sqlite(void) { - if (!dns_hash) { - printf("[ERROR] Hash table not initialized for loading\n"); - return; - } - if (!cache_table) { - printf("[ERROR] SQLite connection not open for loading\n"); - return; - } - - uint64_t now_cycles = rte_get_timer_cycles(); - uint64_t hz = rte_get_timer_hz(); - - const char *sql = "SELECT domain, solution_is_send, trust_lvl, timestamp, " - "ttl_seconds FROM main_table;"; - - sqlite3_stmt *stmt = NULL; - int ret = sqlite3_prepare_v2(cache_table, sql, -1, &stmt, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to prepare SELECT from main_table: %s\n", - sqlite3_errmsg(cache_table)); - return; - } - - int loaded = 0; - int expired = 0; - - while (sqlite3_step(stmt) == SQLITE_ROW) { - const char *domain = (const char *)sqlite3_column_text(stmt, 0); - int solution_is_send = sqlite3_column_int(stmt, 1); - int trust_lvl = sqlite3_column_int(stmt, 2); - uint64_t timestamp = (uint64_t)sqlite3_column_int64(stmt, 3); - uint32_t ttl_seconds = (uint32_t)sqlite3_column_int(stmt, 4); - - uint64_t age_seconds = (now_cycles - timestamp) / hz; - if (age_seconds >= ttl_seconds) { - expired++; - continue; - } - - struct node_cache *node = - rte_malloc("loaded_node_cache", sizeof(struct node_cache), 0); - if (!node) { - printf("[ERROR] Failed to allocate node for domain %s\n", domain); - continue; - } - - node->solution_is_send = solution_is_send ? true : false; - node->trust_lvl = trust_lvl; - node->timestamp = timestamp; - node->ttl_seconds = ttl_seconds; - - const char *sql_cat = - "SELECT certain_category FROM categories_table WHERE domain = ?;"; - sqlite3_stmt *stmt_cat = NULL; - int rc_cat = sqlite3_prepare_v2(cache_table, sql_cat, -1, &stmt_cat, NULL); - if (rc_cat != SQLITE_OK) { - printf("[ERROR] Failed to prepare categories SELECT: %s\n", - sqlite3_errmsg(cache_table)); - rte_free(node); - continue; - } - - sqlite3_bind_text(stmt_cat, 1, domain, -1, SQLITE_STATIC); - - int cat_idx = 0; - while (sqlite3_step(stmt_cat) == SQLITE_ROW && cat_idx < MAX_CATEGORIES) { - const unsigned char *cat_text = sqlite3_column_text(stmt_cat, 0); - if (cat_text) { - strncpy(node->categories[cat_idx], (const char *)cat_text, - CATEGORY_MAX_LEN - 1); - node->categories[cat_idx][CATEGORY_MAX_LEN - 1] = '\0'; - } else { - node->categories[cat_idx][0] = '\0'; - } - cat_idx++; - } - - sqlite3_finalize(stmt_cat); - - if (insert_loaded_node(domain, node) == 0) { - loaded++; - } else { - rte_free(node); - } - } - - ret = sqlite3_finalize(stmt); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to delete prepared statement: %s\n", - sqlite3_errmsg(cache_table)); - return; - } - printf("[INFO] Loaded %d records from SQLite, %d expired skipped\n", loaded, - expired); -} - -static void cache_save_timer_cb(struct rte_timer *tim, void *arg) { - (void)tim; - (void)arg; - - printf("[INFO] Periodic cache saving to SQLite.\n"); - save_all_cache_to_sqlite(); -} - -void close_sqlite_cache(void) { - if (cache_table) { - int ret = sqlite3_close(cache_table); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed close SQLite connection: %s\n", - sqlite3_errmsg(cache_table)); - } - } - cache_table = NULL; -} - -int save_single_node_to_sqlite(const char *domain, struct node_cache *node) { - sqlite3_stmt *stmt = NULL; - int ret; - - const char *sql_main = - "INSERT OR REPLACE INTO main_table " - "(domain, solution_is_send, trust_lvl, timestamp, ttl_seconds) " - "VALUES (?, ?, ?, ?, ?)"; - - ret = sqlite3_prepare_v2(cache_table, sql_main, -1, &stmt, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to prepare main_table insert: %s\n", - sqlite3_errmsg(cache_table)); - sqlite3_finalize(stmt); - return ret; - } - - sqlite3_bind_text(stmt, 1, domain, -1, SQLITE_STATIC); - sqlite3_bind_int(stmt, 2, node->solution_is_send ? 1 : 0); - sqlite3_bind_int(stmt, 3, node->trust_lvl); - sqlite3_bind_int64(stmt, 4, (sqlite3_int64)node->timestamp); - sqlite3_bind_int(stmt, 5, (int)node->ttl_seconds); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - printf("[ERROR] Failed to insert into main_table: %s\n", - sqlite3_errmsg(cache_table)); - sqlite3_finalize(stmt); - return ret; - } - - ret = sqlite3_finalize(stmt); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to delete prepared statement: %s\n", - sqlite3_errmsg(cache_table)); - return ret; - } - - const char *sql_del = "DELETE FROM categories_table WHERE domain = ?"; - ret = sqlite3_prepare_v2(cache_table, sql_del, -1, &stmt, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to prepare delete: %s\n", - sqlite3_errmsg(cache_table)); - sqlite3_finalize(stmt); - return ret; - } - - sqlite3_bind_text(stmt, 1, domain, -1, SQLITE_STATIC); - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - printf("[ERROR] Failed to delete old categories: %s\n", - sqlite3_errmsg(cache_table)); - sqlite3_finalize(stmt); - return ret; - } - - ret = sqlite3_finalize(stmt); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to delete prepared statement: %s\n", - sqlite3_errmsg(cache_table)); - return ret; - } - - const char *sql_cat = - "INSERT INTO categories_table (domain, certain_category) VALUES (?, ?)"; - ret = sqlite3_prepare_v2(cache_table, sql_cat, -1, &stmt, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to prepare categories insert: %s\n", - sqlite3_errmsg(cache_table)); - return ret; - } - - for (int i = 0; i < MAX_CATEGORIES; i++) { - if (strlen(node->categories[i]) == 0) { - break; - } - - sqlite3_bind_text(stmt, 1, domain, -1, SQLITE_STATIC); - sqlite3_bind_text(stmt, 2, node->categories[i], -1, SQLITE_STATIC); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - printf("[ERROR] Failed to prepare categories_table insert: %s\n", - sqlite3_errmsg(cache_table)); - sqlite3_finalize(stmt); - return ret; - } - - ret = sqlite3_reset(stmt); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to reset prepared statement: %s\n", - sqlite3_errmsg(cache_table)); - sqlite3_finalize(stmt); - return ret; - } - } - - ret = sqlite3_finalize(stmt); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to delete prepared statement: %s\n", - sqlite3_errmsg(cache_table)); - return ret; - } - - return SQLITE_OK; -} - -int save_all_cache_to_sqlite(void) { - if (!dns_hash) { - printf("[ERROR] Hash table is not initialized\n"); - return -1; - } - - if (!cache_table) { - printf("[ERROR] SQLite connection is not open\n"); - return -1; - } - - uint32_t next = 0; - const void *key; - void *data; - int count = 0; - int errors = 0; - int ret; - - ret = sqlite3_exec(cache_table, "BEGIN TRANSACTION;", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to exec BEGIN TRANSACTION: %s\n", - sqlite3_errmsg(cache_table)); - return -1; - } - - while (rte_hash_iterate(dns_hash, &key, &data, &next) >= 0) { - const char *domain = (const char *)key; - struct node_cache *node = (struct node_cache *)data; - - if (!domain || !node) { - continue; - } - - ret = save_single_node_to_sqlite(domain, node); - if (ret == SQLITE_OK) { - count++; - } else { - errors++; - } - } - - ret = sqlite3_exec(cache_table, "COMMIT;", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to exec COMMIT: %s\n", sqlite3_errmsg(cache_table)); - return -1; - } - - printf("[INFO] Saved %d records to SQLite, %d errors\n", count, errors); - return count; -} - -void init_tables_sqlite_dns_cache(void) { - int ret = sqlite3_open("cache.db", &cache_table); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to open cache.db\n"); - return; - } - - const char *create_main_table = "CREATE TABLE IF NOT EXISTS main_table(" - "domain TEXT PRIMARY KEY, " - "solution_is_send INT NOT NULL, " - "trust_lvl INT NOT NULL, " - "timestamp INT NOT NULL, " - "ttl_seconds INT NOT NULL)"; - - ret = sqlite3_exec(cache_table, create_main_table, NULL, NULL, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to create table 'main_table'\n"); - return; - } - - const char *create_categories_table = - "CREATE TABLE IF NOT EXISTS categories_table(" - "domain TEXT NOT NULL, " - "certain_category TEXT NOT NULL, " - "PRIMARY KEY (domain, certain_category), " - "FOREIGN KEY (domain) REFERENCES main_table(domain))"; - - ret = sqlite3_exec(cache_table, create_categories_table, NULL, NULL, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to create table 'categories_table'\n"); - return; - } - - ret = - sqlite3_exec(cache_table, "PRAGMA foreign_keys = ON;", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - printf("[ERROR] Failed to include foreign_keys\n"); - } -} void init_dns_cache(void) { if (dns_hash) @@ -355,18 +16,7 @@ void init_dns_cache(void) { dns_hash = rte_hash_create(&hash_params); if (!dns_hash) { printf("[ERROR] Failed to create DNS cache hash table\n"); - return; } - - init_tables_sqlite_dns_cache(); - - load_cache_from_sqlite(); - - rte_timer_init(&cache_save_timer); - save_interval_cycles = rte_get_timer_hz() * 3600; - - rte_timer_reset(&cache_save_timer, save_interval_cycles, PERIODICAL, - rte_lcore_id(), cache_save_timer_cb, NULL); } int lookup_dns_cache(const char *domain, struct node_cache **return_node) { @@ -435,12 +85,5 @@ void free_dns_cache(void) { } rte_hash_free(dns_hash); - - close_sqlite_cache(); dns_hash = NULL; - - int ret = rte_timer_stop(&cache_save_timer); - if (!ret) { - printf("[ERROR] Failed to stopping timer\n"); - } -} +} \ No newline at end of file diff --git a/worker/src/dpdk_filter/filtr_packets.c b/worker/src/dpdk_filter/filtr_packets.c index ccc8868..258ff37 100644 --- a/worker/src/dpdk_filter/filtr_packets.c +++ b/worker/src/dpdk_filter/filtr_packets.c @@ -100,4 +100,4 @@ bool main_filtring(struct requested_classification *req_clas, } return true; -} +} \ No newline at end of file diff --git a/worker/src/dpdk_filter/main.c b/worker/src/dpdk_filter/main.c index a0e7c25..781d0fb 100644 --- a/worker/src/dpdk_filter/main.c +++ b/worker/src/dpdk_filter/main.c @@ -18,14 +18,13 @@ static void signal_handler(int signum) { } } -void forward_to_out(struct net_port *incoming_port, - struct net_port *outgoing_port, uint16_t queue_number) { +void forward_tap_to_out(struct net_port *port_exception, + struct net_port *port_in, uint16_t queue_number) { struct rte_mbuf *tap_pkts[32]; uint16_t nb_tap = - rte_eth_rx_burst(incoming_port->port_id, queue_number, tap_pkts, 32); + rte_eth_rx_burst(port_exception->port_id, queue_number, tap_pkts, 32); for (int i = 0; i < nb_tap; i++) { - int ret = - rte_eth_tx_burst(outgoing_port->port_id, queue_number, &tap_pkts[i], 1); + int ret = rte_eth_tx_burst(port_in->port_id, queue_number, &tap_pkts[i], 1); if (ret < 1) { printf("[ERROR] Failed to send packet\n"); // PLUG (to be added later) - need to add processing for this case @@ -98,6 +97,8 @@ int main(int argc, char **argv) { return 1; } + ret = system("sudo ip link set tap0 up && " + "sudo ip addr add 10.0.3.1/24 dev tap0"); if (ret) { printf("[ERROR] Failed to set tap0 up\n"); } @@ -106,22 +107,13 @@ int main(int argc, char **argv) { "to port with id=%u\n", port_in->port_id, port_out->port_id); - uint64_t timer_check_counter = 0; - const uint64_t timer_check_interval = 10000; - while (running) { - forward_to_out(port_exception, port_in, queue_number); + forward_tap_to_out(port_exception, port_in, queue_number); pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, pkts, &policy); - forward_to_out(port_out, port_in, queue_number); - - if (++timer_check_counter >= timer_check_interval) { - rte_timer_manage(); - timer_check_counter = 0; - } } - save_all_cache_to_sqlite(); + // function for save cache info if need free_dns_cache(); net_port_close(port_in); @@ -132,4 +124,4 @@ int main(int argc, char **argv) { net_port_destroy(port_out); net_port_destroy(port_exception); return 0; -} +} \ No newline at end of file diff --git a/worker/src/dpdk_filter/proc_packets.c b/worker/src/dpdk_filter/proc_packets.c index b131e11..2ed7e46 100644 --- a/worker/src/dpdk_filter/proc_packets.c +++ b/worker/src/dpdk_filter/proc_packets.c @@ -1,9 +1,6 @@ #include "../../include/dpdk_filter/proc_packets.h" #include "../../include/dpdk_filter/dns_cache.h" -extern bool worker_classify_domain(const char *domain, - struct requested_classification *out_req); - const uint16_t LIST_EXCEPTION_PORTS[LEN_LIST_EXCEPTION_PORTS] = {22}; void package_sending_decision(bool solution_is_send, struct rte_mbuf *pkt, @@ -46,6 +43,8 @@ void pakage_processing(struct net_port *port_in, struct net_port *port_out, memset(&info_pac, 0, sizeof(info_pac)); parsing_pakage(pkts[i], &info_pac); + printf("[PKT] port = %hu; domain = %s\n", ntohs(info_pac.number_port), + info_pac.domain); if (info_pac.domain[0] == '\0') { printf("[INFO] Packet without dns request\n"); package_sending_decision(true, pkts[i], port_out, queue_number); @@ -67,16 +66,9 @@ void pakage_processing(struct net_port *port_in, struct net_port *port_out, } else if (ret == -ENOENT) { struct requested_classification req_clas; - memset(&req_clas, 0, sizeof(req_clas)); - bool solution_is_send; - bool classification_success = - worker_classify_domain(info_pac.domain, &req_clas); - if (classification_success) { - solution_is_send = main_filtring(&req_clas, policy, info_pac.domain); - } else { - solution_is_send = true; - printf("[WARN] Classification failed for %s\n", info_pac.domain); - } + + bool solution_is_send = main_filtring(&req_clas, policy, info_pac.domain); + package_sending_decision(solution_is_send, pkts[i], port_out, queue_number); diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index 3f530bf..85ddcb9 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -82,8 +82,6 @@ void Worker::initDPDK(int argc, char **argv) { throw std::runtime_error("Start ports"); } - init_dns_cache(); - spdlog::info("DPDK initialized: in_port={}, out_port={}", port_in->port_id, port_out->port_id); } @@ -137,7 +135,6 @@ void Worker::requestPolicyFromController() { current_policy.locked_categories[i][CATEGORY_MAX_LEN - 1] = '\0'; } - int trust_map_count = pol.block_by_trust_size(); int idx = 0; for (const auto &[category, min_trust] : pol.block_by_trust()) { if (idx >= MAX_CATEGORIES_BY_TRUST_LVL) @@ -270,8 +267,6 @@ Worker::~Worker() { spdlog::info("Worker {} shutting down", worker_id); if (port_in && port_out) { - free_dns_cache(); - net_port_close(port_in); net_port_close(port_out); net_port_close(port_exception); From aa52eb6ea6c052b7511f5cb0c14c18f10f372361 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 23 Apr 2026 01:46:06 +0300 Subject: [PATCH 15/20] feact: added classification request --- worker/include/dpdk_filter/constants.h | 2 ++ worker/src/dpdk_filter/proc_packets.c | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/worker/include/dpdk_filter/constants.h b/worker/include/dpdk_filter/constants.h index 3e92808..f046259 100644 --- a/worker/include/dpdk_filter/constants.h +++ b/worker/include/dpdk_filter/constants.h @@ -1,6 +1,8 @@ #ifndef CONSTANTS_H #define CONSTANTS_H +#include + #define MAX_CATEGORIES_BY_TRUST_LVL 64 #define MAX_DOMAINS 64 #define CACHE_SIZE 1024 diff --git a/worker/src/dpdk_filter/proc_packets.c b/worker/src/dpdk_filter/proc_packets.c index 2ed7e46..54c61f8 100644 --- a/worker/src/dpdk_filter/proc_packets.c +++ b/worker/src/dpdk_filter/proc_packets.c @@ -1,6 +1,9 @@ #include "../../include/dpdk_filter/proc_packets.h" #include "../../include/dpdk_filter/dns_cache.h" +extern bool worker_classify_domain(const char *domain, + struct requested_classification *out_req); + const uint16_t LIST_EXCEPTION_PORTS[LEN_LIST_EXCEPTION_PORTS] = {22}; void package_sending_decision(bool solution_is_send, struct rte_mbuf *pkt, @@ -67,7 +70,15 @@ void pakage_processing(struct net_port *port_in, struct net_port *port_out, struct requested_classification req_clas; - bool solution_is_send = main_filtring(&req_clas, policy, info_pac.domain); + bool solution_is_send; + bool classification_success = + worker_classify_domain(info_pac.domain, &req_clas); + if (classification_success) { + solution_is_send = main_filtring(&req_clas, policy, info_pac.domain); + } else { + solution_is_send = true; + printf("[WARN] Classification failed for %s\n", info_pac.domain); + } package_sending_decision(solution_is_send, pkts[i], port_out, queue_number); From 997f0aa9795462041663edf657dcde625bd22927 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 23 Apr 2026 02:06:07 +0300 Subject: [PATCH 16/20] fix: fix absolute paths --- worker/BUILD | 1 + worker/include/dpdk_filter/dns_cache.h | 4 ++-- worker/include/dpdk_filter/filtr_packets.h | 4 ++-- worker/include/dpdk_filter/net_port.h | 2 +- worker/include/dpdk_filter/pars_packets.h | 4 ++-- worker/include/dpdk_filter/proc_packets.h | 10 +++++----- worker/src/dpdk_filter/dns_cache.c | 2 +- worker/src/dpdk_filter/filtr_packets.c | 4 ++-- worker/src/dpdk_filter/net_port.c | 2 +- worker/src/dpdk_filter/pars_packets.c | 2 +- worker/src/dpdk_filter/proc_packets.c | 4 ++-- worker/src/main.cpp | 4 ++-- worker/src/worker.cpp | 4 ++-- 13 files changed, 24 insertions(+), 23 deletions(-) diff --git a/worker/BUILD b/worker/BUILD index c949c49..3399bb0 100644 --- a/worker/BUILD +++ b/worker/BUILD @@ -46,6 +46,7 @@ cc_library( "include/dpdk_filter/types.h", "include/dpdk_filter/constants.h", ], + includes = ["include", "include/dpdk_filter"], srcs = [], visibility = ["//visibility:public"], ) diff --git a/worker/include/dpdk_filter/dns_cache.h b/worker/include/dpdk_filter/dns_cache.h index f1c137a..8463124 100644 --- a/worker/include/dpdk_filter/dns_cache.h +++ b/worker/include/dpdk_filter/dns_cache.h @@ -10,8 +10,8 @@ #include #include -#include "../../include/dpdk_filter/constants.h" -#include "../../include/dpdk_filter/types.h" +#include "constants.h" +#include "types.h" void init_dns_cache(void); int lookup_dns_cache(const char *domain, struct node_cache **return_node); diff --git a/worker/include/dpdk_filter/filtr_packets.h b/worker/include/dpdk_filter/filtr_packets.h index 7a83ff7..ef64ad4 100644 --- a/worker/include/dpdk_filter/filtr_packets.h +++ b/worker/include/dpdk_filter/filtr_packets.h @@ -1,8 +1,8 @@ #ifndef FILTR_PAK_H #define FILTR_PAK_H -#include "../../include/dpdk_filter/constants.h" -#include "../../include/dpdk_filter/types.h" +#include "constants.h" +#include "types.h" #include "pars_packets.h" #include #include diff --git a/worker/include/dpdk_filter/net_port.h b/worker/include/dpdk_filter/net_port.h index 3c6fe82..ebe9224 100644 --- a/worker/include/dpdk_filter/net_port.h +++ b/worker/include/dpdk_filter/net_port.h @@ -1,7 +1,7 @@ #ifndef AF_XDP_PORT_H #define AF_XDP_PORT_H -#include "../../include/dpdk_filter/types.h" +#include "types.h" #include #include diff --git a/worker/include/dpdk_filter/pars_packets.h b/worker/include/dpdk_filter/pars_packets.h index 0396ee1..7d72726 100644 --- a/worker/include/dpdk_filter/pars_packets.h +++ b/worker/include/dpdk_filter/pars_packets.h @@ -1,8 +1,8 @@ #ifndef PARS_PAK_H #define PARS_PAK_H -#include "../../include/dpdk_filter/constants.h" -#include "../../include/dpdk_filter/types.h" +#include "constants.h" +#include "types.h" #include #include diff --git a/worker/include/dpdk_filter/proc_packets.h b/worker/include/dpdk_filter/proc_packets.h index 176bc92..aafc1de 100644 --- a/worker/include/dpdk_filter/proc_packets.h +++ b/worker/include/dpdk_filter/proc_packets.h @@ -1,11 +1,11 @@ #ifndef PROC_PAK_H #define PROC_PAK_H -#include "../../include/dpdk_filter/constants.h" -#include "../../include/dpdk_filter/filtr_packets.h" -#include "../../include/dpdk_filter/net_port.h" -#include "../../include/dpdk_filter/pars_packets.h" -#include "../../include/dpdk_filter/types.h" +#include "constants.h" +#include "filtr_packets.h" +#include "net_port.h" +#include "pars_packets.h" +#include "types.h" #include #include #include diff --git a/worker/src/dpdk_filter/dns_cache.c b/worker/src/dpdk_filter/dns_cache.c index 4427e1f..7be7373 100644 --- a/worker/src/dpdk_filter/dns_cache.c +++ b/worker/src/dpdk_filter/dns_cache.c @@ -1,4 +1,4 @@ -#include "../../include/dpdk_filter/dns_cache.h" +#include "dns_cache.h" static struct rte_hash *dns_hash; static struct rte_hash_parameters hash_params = { diff --git a/worker/src/dpdk_filter/filtr_packets.c b/worker/src/dpdk_filter/filtr_packets.c index 258ff37..530204d 100644 --- a/worker/src/dpdk_filter/filtr_packets.c +++ b/worker/src/dpdk_filter/filtr_packets.c @@ -1,5 +1,5 @@ -#include "../../include/dpdk_filter/filtr_packets.h" -#include "../../include/dpdk_filter/pars_packets.h" +#include "filtr_packets.h" +#include "pars_packets.h" bool check_is_block(char domain[DOMAIN_MAX_LEN], char block_domains[MAX_DOMAINS][DOMAIN_MAX_LEN]) { diff --git a/worker/src/dpdk_filter/net_port.c b/worker/src/dpdk_filter/net_port.c index 5c57b26..761a1cb 100644 --- a/worker/src/dpdk_filter/net_port.c +++ b/worker/src/dpdk_filter/net_port.c @@ -11,7 +11,7 @@ #include #include -#include "../../include/dpdk_filter/net_port.h" +#include "net_port.h" #define RX_RING_SIZE 1024 #define TX_RING_SIZE 1024 diff --git a/worker/src/dpdk_filter/pars_packets.c b/worker/src/dpdk_filter/pars_packets.c index ea59e2d..4092b4b 100644 --- a/worker/src/dpdk_filter/pars_packets.c +++ b/worker/src/dpdk_filter/pars_packets.c @@ -1,4 +1,4 @@ -#include "../../include/dpdk_filter/pars_packets.h" +#include "pars_packets.h" #include #include #include diff --git a/worker/src/dpdk_filter/proc_packets.c b/worker/src/dpdk_filter/proc_packets.c index 54c61f8..6eebebb 100644 --- a/worker/src/dpdk_filter/proc_packets.c +++ b/worker/src/dpdk_filter/proc_packets.c @@ -1,5 +1,5 @@ -#include "../../include/dpdk_filter/proc_packets.h" -#include "../../include/dpdk_filter/dns_cache.h" +#include "proc_packets.h" +#include "dns_cache.h" extern bool worker_classify_domain(const char *domain, struct requested_classification *out_req); diff --git a/worker/src/main.cpp b/worker/src/main.cpp index e9bad0f..91a4c95 100644 --- a/worker/src/main.cpp +++ b/worker/src/main.cpp @@ -1,5 +1,5 @@ -#include "../include/metrics_collector.hpp" -#include "../include/worker.hpp" +#include "metrics_collector.hpp" +#include "worker.hpp" #include diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index 85ddcb9..b7ee334 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -1,5 +1,5 @@ -#include "../include/worker.hpp" -#include "../include/dpdk_filter/proc_packets.h" +#include "worker.hpp" +#include "proc_packets.h" #include "communication.grpc.pb.h" #include #include From 10248e90ce47d61a5c4e918596610014c086e7b3 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 23 Apr 2026 02:08:06 +0300 Subject: [PATCH 17/20] fix: fix absolute paths in main.c --- worker/src/dpdk_filter/main.c | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/worker/src/dpdk_filter/main.c b/worker/src/dpdk_filter/main.c index 781d0fb..f947926 100644 --- a/worker/src/dpdk_filter/main.c +++ b/worker/src/dpdk_filter/main.c @@ -1,6 +1,6 @@ -#include "../../include/dpdk_filter/dns_cache.h" -#include "../../include/dpdk_filter/net_port.h" -#include "../../include/dpdk_filter/proc_packets.h" +#include "net_port.h" +#include "dns_cache.h" +#include "proc_packets.h" #include #include #include @@ -18,23 +18,21 @@ static void signal_handler(int signum) { } } -void forward_tap_to_out(struct net_port *port_exception, - struct net_port *port_in, uint16_t queue_number) { - struct rte_mbuf *tap_pkts[32]; - uint16_t nb_tap = - rte_eth_rx_burst(port_exception->port_id, queue_number, tap_pkts, 32); - for (int i = 0; i < nb_tap; i++) { - int ret = rte_eth_tx_burst(port_in->port_id, queue_number, &tap_pkts[i], 1); - if (ret < 1) { - printf("[ERROR] Failed to send packet\n"); - // PLUG (to be added later) - need to add processing for this case - rte_pktmbuf_free(tap_pkts[i]); +void forward_tap_to_out(struct net_port *port_exception, struct net_port *port_in, uint16_t queue_number) { + struct rte_mbuf *tap_pkts[32]; + uint16_t nb_tap = rte_eth_rx_burst(port_exception->port_id, queue_number, tap_pkts, 32); + for (int i = 0; i < nb_tap; i++) { + int ret = rte_eth_tx_burst(port_in->port_id, queue_number, &tap_pkts[i], 1); + if (ret < 1) { + printf("[ERROR] Failed to send packet\n"); + // PLUG (to be added later) - need to add processing for this case + rte_pktmbuf_free(tap_pkts[i]); + } } - } } int main(int argc, char **argv) { - // since BASE_POLICY is filled when initializing worker, let’s initialize here + //since BASE_POLICY is filled when initializing worker, let’s initialize here struct BASE_POLICY policy; if (signal(SIGINT, signal_handler) == SIG_ERR) { printf("[ERROR] Failed to set SIGINT handler\n"); @@ -45,6 +43,8 @@ int main(int argc, char **argv) { return 1; } + + struct net_port *port_in = NULL; struct net_port *port_out = NULL; struct net_port *port_exception = NULL; @@ -83,23 +83,24 @@ int main(int argc, char **argv) { port_exception = init_struct_tap_port("tap0", mbuf_pool); + if (!port_in || !port_out || !port_exception) { return 1; } - if (net_port_init(port_in) || net_port_init(port_out) || - net_port_init(port_exception)) { + if (net_port_init(port_in) || net_port_init(port_out) || net_port_init(port_exception)) { return 1; } - if (net_port_start(port_in->port_id) || net_port_start(port_out->port_id) || + if (net_port_start(port_in->port_id) || + net_port_start(port_out->port_id) || net_port_start(port_exception->port_id)) { return 1; } ret = system("sudo ip link set tap0 up && " - "sudo ip addr add 10.0.3.1/24 dev tap0"); - if (ret) { + "sudo ip addr add 10.0.3.1/24 dev tap0"); + if(ret) { printf("[ERROR] Failed to set tap0 up\n"); } @@ -109,8 +110,7 @@ int main(int argc, char **argv) { while (running) { forward_tap_to_out(port_exception, port_in, queue_number); - pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, - pkts, &policy); + pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, pkts, &policy); } // function for save cache info if need From da6b92260280c80661467a77c1d4191183f7b618 Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 23 Apr 2026 03:20:55 +0300 Subject: [PATCH 18/20] fix: fix dockerfile --- worker/Dockerfile.cc_x86_to_x86 | 56 +++++++++++++++------------------ 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/worker/Dockerfile.cc_x86_to_x86 b/worker/Dockerfile.cc_x86_to_x86 index 3557b40..800c2d8 100644 --- a/worker/Dockerfile.cc_x86_to_x86 +++ b/worker/Dockerfile.cc_x86_to_x86 @@ -1,33 +1,27 @@ -FROM ubuntu:22.04 +FROM ubuntu:22.04 AS builder RUN apt-get update && apt-get install -y \ - build-essential \ - cmake \ - curl \ - git \ - wget \ - meson \ - ninja-build \ - libssl-dev \ - protobuf-compiler \ - libprotobuf-dev \ - python3 \ - python3-pip \ - libnuma-dev \ - pkg-config \ - libcurl4-openssl-dev \ - libbpf-dev \ - gcc \ - g++ \ - m4 \ - libpcap-dev \ - libsqlite3-dev \ - libstdc++6 \ - libgcc-s1 \ - libssl3 \ - libcurl4 \ - numactl \ - sqlite3 \ + build-essential=12.9* \ + cmake=3.22* \ + curl=7.81* \ + git=1:2.34* \ + wget=1.21* \ + meson=0.61* \ + ninja-build=1.10* \ + libssl-dev=3.0* \ + protobuf-compiler=3.12* \ + libprotobuf-dev=3.12* \ + python3=3.10* \ + python3-pip=22.0* \ + libnuma-dev=2.0* \ + pkg-config=0.29* \ + libcurl4-openssl-dev=7.81* \ + libbpf-dev=1:0.5* \ + gcc=4:11* \ + g++=4:11* \ + m4=1.4* \ + libpcap-dev=1.10* \ + libsqlite3-dev=3.37* \ && rm -rf /var/lib/apt/lists/* RUN pip3 install pyelftools @@ -41,7 +35,9 @@ RUN wget https://fast.dpdk.org/rel/dpdk-23.11.tar.xz && \ cd dpdk-23.11 && \ meson setup build --libdir=lib && \ ninja -C build && \ - ninja -C build install + ninja -C build install && \ + cd .. && \ + rm -rf dpdk-23.11 dpdk-23.11.tar.xz ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig @@ -64,4 +60,4 @@ WORKDIR /data RUN ldconfig -ENTRYPOINT ["/app/bazel-bin/worker"] \ No newline at end of file +ENTRYPOINT ["/app/bazel-bin/worker"] From a06f32d06069ce75d287772e369cc2f409171d7f Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Thu, 23 Apr 2026 03:32:08 +0300 Subject: [PATCH 19/20] refactor: clang-format --- worker/include/dpdk_filter/filtr_packets.h | 2 +- worker/src/dpdk_filter/main.c | 42 +++++++++++----------- worker/src/worker.cpp | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/worker/include/dpdk_filter/filtr_packets.h b/worker/include/dpdk_filter/filtr_packets.h index ef64ad4..188830b 100644 --- a/worker/include/dpdk_filter/filtr_packets.h +++ b/worker/include/dpdk_filter/filtr_packets.h @@ -2,8 +2,8 @@ #define FILTR_PAK_H #include "constants.h" -#include "types.h" #include "pars_packets.h" +#include "types.h" #include #include diff --git a/worker/src/dpdk_filter/main.c b/worker/src/dpdk_filter/main.c index f947926..36e59b4 100644 --- a/worker/src/dpdk_filter/main.c +++ b/worker/src/dpdk_filter/main.c @@ -1,5 +1,5 @@ -#include "net_port.h" #include "dns_cache.h" +#include "net_port.h" #include "proc_packets.h" #include #include @@ -18,21 +18,23 @@ static void signal_handler(int signum) { } } -void forward_tap_to_out(struct net_port *port_exception, struct net_port *port_in, uint16_t queue_number) { - struct rte_mbuf *tap_pkts[32]; - uint16_t nb_tap = rte_eth_rx_burst(port_exception->port_id, queue_number, tap_pkts, 32); - for (int i = 0; i < nb_tap; i++) { - int ret = rte_eth_tx_burst(port_in->port_id, queue_number, &tap_pkts[i], 1); - if (ret < 1) { - printf("[ERROR] Failed to send packet\n"); - // PLUG (to be added later) - need to add processing for this case - rte_pktmbuf_free(tap_pkts[i]); - } +void forward_tap_to_out(struct net_port *port_exception, + struct net_port *port_in, uint16_t queue_number) { + struct rte_mbuf *tap_pkts[32]; + uint16_t nb_tap = + rte_eth_rx_burst(port_exception->port_id, queue_number, tap_pkts, 32); + for (int i = 0; i < nb_tap; i++) { + int ret = rte_eth_tx_burst(port_in->port_id, queue_number, &tap_pkts[i], 1); + if (ret < 1) { + printf("[ERROR] Failed to send packet\n"); + // PLUG (to be added later) - need to add processing for this case + rte_pktmbuf_free(tap_pkts[i]); } + } } int main(int argc, char **argv) { - //since BASE_POLICY is filled when initializing worker, let’s initialize here + // since BASE_POLICY is filled when initializing worker, let’s initialize here struct BASE_POLICY policy; if (signal(SIGINT, signal_handler) == SIG_ERR) { printf("[ERROR] Failed to set SIGINT handler\n"); @@ -43,8 +45,6 @@ int main(int argc, char **argv) { return 1; } - - struct net_port *port_in = NULL; struct net_port *port_out = NULL; struct net_port *port_exception = NULL; @@ -83,24 +83,23 @@ int main(int argc, char **argv) { port_exception = init_struct_tap_port("tap0", mbuf_pool); - if (!port_in || !port_out || !port_exception) { return 1; } - if (net_port_init(port_in) || net_port_init(port_out) || net_port_init(port_exception)) { + if (net_port_init(port_in) || net_port_init(port_out) || + net_port_init(port_exception)) { return 1; } - if (net_port_start(port_in->port_id) || - net_port_start(port_out->port_id) || + if (net_port_start(port_in->port_id) || net_port_start(port_out->port_id) || net_port_start(port_exception->port_id)) { return 1; } ret = system("sudo ip link set tap0 up && " - "sudo ip addr add 10.0.3.1/24 dev tap0"); - if(ret) { + "sudo ip addr add 10.0.3.1/24 dev tap0"); + if (ret) { printf("[ERROR] Failed to set tap0 up\n"); } @@ -110,7 +109,8 @@ int main(int argc, char **argv) { while (running) { forward_tap_to_out(port_exception, port_in, queue_number); - pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, pkts, &policy); + pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, + pkts, &policy); } // function for save cache info if need diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index b7ee334..b6e89bc 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -1,6 +1,6 @@ #include "worker.hpp" -#include "proc_packets.h" #include "communication.grpc.pb.h" +#include "proc_packets.h" #include #include #include From 5e04ff83542bcdada84ef674dcdb0e64195f09be Mon Sep 17 00:00:00 2001 From: stepanrodimanov Date: Fri, 24 Apr 2026 19:01:04 +0300 Subject: [PATCH 20/20] fix: fix mutex --- worker/src/worker.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/worker/src/worker.cpp b/worker/src/worker.cpp index b6e89bc..0e66607 100644 --- a/worker/src/worker.cpp +++ b/worker/src/worker.cpp @@ -124,7 +124,6 @@ void Worker::requestPolicyFromController() { case GetPolicyResponse::POLICY_PROVIDED: { spdlog::info("Policy received"); const auto &pol = resp.policy(); - current_config_version = resp.policy().config_version(); std::lock_guard lock(policy_mutex); memset(¤t_policy, 0, sizeof(current_policy)); @@ -279,6 +278,7 @@ Worker::~Worker() { } void Worker::MainLoop() { + struct BASE_POLICY local_policy; using namespace std::chrono; last_policy_time = steady_clock::now(); @@ -288,9 +288,13 @@ void Worker::MainLoop() { uint16_t nb_pkts = 32; uint16_t queue_number = 0; while (!stop_flag && GetState() != WorkerState::SHUTTING_DOWN) { + { + std::lock_guard lock(policy_mutex); + local_policy = current_policy; + } forward_to_out(port_exception, port_in, queue_number); pakage_processing(port_in, port_out, port_exception, queue_number, nb_pkts, - pkts, ¤t_policy); + pkts, &local_policy); forward_to_out(port_out, port_in, queue_number); auto now = steady_clock::now(); @@ -310,8 +314,6 @@ void Worker::MainLoop() { policy_interval = MIN_POLICY_TIME + (rand() % (MAX_POLICY_TIME - MIN_POLICY_TIME + 1)); } - - std::this_thread::sleep_for(milliseconds(100)); } if (stop_flag) {