Немного контекста :
Технология eBPF (extended Berkeley Packet Filter) берет свое начало от классического BPF, разработанного в начале 1990-х годов как механизма фильтрации сетевых пакетов, который впоследствии был реализован в Linux и других UNIX-подобных системах. Со временем возможности BPF значительно расширились, и появился eBPF — универсальная виртуальная машина, позволяющая безопасно выполнять пользовательские программы непосредственно внутри ядра без необходимости разрабатывать отдельные модули ядра. Сегодня eBPF применяется далеко не только для обработки сетевого трафика. Он используется для трассировки, мониторинга производительности, обеспечения безопасности, балансировки нагрузки, реализации сетевых политик и многих других задач. Перед загрузкой программа проходит проверку специальным верификатором ядра, гарантируя ее завершаемость, корректность обращений к памяти и соблюдение требований безопасности ядра. Благодаря этому eBPF позволяет расширять функциональность ядра без необходимости писать или загружать собственные модули ядра. Одной из ключевых особенностей является возможность выполнять программы на различных этапах обработки сетевого трафика. Каждая точка подключения (hook) предоставляет собственный набор возможностей и предназначена для решения определенного класса задач. Выбор подходящего уровня зависит от требований к производительности, доступному контексту пакета и необходимой функциональности. Чтобы наглядно показать, где именно располагаются эти точки подключения, рассмотрим путь сетевого пакета в ядре Linux.

Наиболее ранней точкой обработки является XDP (eXpress Data Path). Программа XDP выполняется между драйвером сетевого устройства и сетевым стеком ядра Linux, еще до выделения структуры sk_buff( socket buffer - это основная структура данных в ядре Linux. Она представляет сетевой пакет на всех этапах его прохождения через сетевой стек.). Благодаря этому XDP обеспечивает минимальную задержку обработки и позволяет эффективно реализовывать высокопроизводительную фильтрацию, ACL, защиту от DDoS и перенаправление пакетов. После формирования sk_buff пакет попадает в сетевой стек Linux, где eBPF-программы могут быть подключены через подсистему Traffic Control (TC). В отличие от XDP, TC работает уже с объектом sk_buff, благодаря чему получает доступ к дополнительному контексту пакета , отсутствующему на уровне XDP, а также тесно интегрирован с механизмами маршрутизации, QoS, conntrack, туннелированием и другими подсистемами ядра. Это делает TC удобным уровнем для реализации NAT, балансировки нагрузки, изменения содержимого пакетов и более сложной обработки сетевого трафика. Помимо XDP и TC, eBPF поддерживает множество других точек подключения. Cgroup hooks позволяют реализовывать политики для процессов и контейнеров, Socket Filter - анализировать трафик отдельных сокетов, а tracepoints, kprobes и uprobes широко используются для трассировки и мониторинга. Несмотря на то что eBPF поддерживает множество точек подключения, они не являются взаимозаменяемыми. Чем раньше программа выполняется в сетевом стеке, тем выше производительность обработки, однако тем меньше информации доступно программе. По мере продвижения пакета по стеку ядро предоставляет все больше контекста и функциональных возможностей, но возрастает стоимость обработки. Поэтому при проектировании современных сетевых решений выбор точки подключения представляет собой компромисс между производительностью и функциональностью.
В рамках проекта Pulsar в качестве основного dataplane был выбран XDP, поскольку именно этот уровень позволяет принимать решение о судьбе пакета максимально рано, еще до прохождения большей части сетевого стека Linux. Это делает XDP оптимальным выбором для реализации высокопроизводительных ACL и других механизмов ранней фильтрации. Вместе с тем архитектура проекта не ограничивается одним уровнем обработки. Функции, которым требуется более богатый контекст пакета или интеграция с подсистемами ядра, планируется реализовать на уровне TC.
Основная часть.
За годы развития сетевого стека Linux появилось множество механизмов управления сетевой политикой. Помимо iptables и nftables существуют firewalld, ufw, Docker, Kubernetes и другие системы, которые предоставляют собственные интерфейсы управления политиками или автоматически изменяют существующие правила фильтрации и маршрутизации. В результате администратору приходится учитывать не только саму сетевую политику, но и особенности её реализации в конкретной системе. Одна и та же политика может быть описана различными способами в зависимости от используемого инструмента. При переходе между различными платформами или внедрении дополнительных компонентов, например Docker или Kubernetes, может изменяться не только синтаксис описания политики, но и точки её применения, порядок обработки трафика и взаимодействие между различными механизмами.
Аналогичная ситуация наблюдается и за пределами Linux: многие BSD-системы и сетевые устройства используют собственные модели описания политики.
Например, одна и та же политика сетевой фильтрации: запретить TCP-трафик от 192.168.0.3 к 192.168.0.202:80 - может выглядеть совершенно по-разному.
В iptables:
iptables -A INPUT -s 192.168.0.3 -d 192.168.0.202 -p tcp --dport 80 -j DROP
В nftables:
ip saddr 192.168.0.3 ip daddr 192.168.0.202 tcp dport 80 drop.
В pf используется уже другой синтаксис:
block in proto tcp from 192.168.0.3 to 192.168.0.202 port 80.
Во всех приведённых примерах описывается одна и та же сетевая политика, однако её представление зависит от конкретного механизма исполнения.
И в разрабатываемом мной dataplane та же политика описывается через собственный единый интерфейс:
./ebpf-ctl acl add drop src 192.168.0.3:any dst 192.168.0.202:80 proto=tcp.
Или через файл конфигурации:
acl: drop: - src: addresses: - 192.168.0.3 dst: addresses: - 192.168.0.202 ports: number: 80 proto: tcp
Цель — не в том, чтобы создать ещё один синтаксис, а в том, чтобы абстрагировать описание политики от механизма исполнения. Пользователь работает с единой декларативной моделью сетевой политики, не зависящей от конкретного механизма её исполнения. Control plane преобразует описание политики во внутреннее представление, используемое dataplane, а CLI и YAML являются лишь различными способами описания одной и той же политики.
Архитектура Pulsar

Основным механизмом взаимодействия control plane и dataplane служат BPF maps, через которые control plane передаёт dataplane подготовленное состояние политики: control plane записывает в них состояние политики, dataplane читает его при обработке пакета. Интерфейсы управления. Описание политики поступает в систему через декларативный конфигурационный файл (config.yml) или клиент командной строки. Оба интерфейса намеренно сделаны «тонкими»: они передают описание политики в daemon и не содержат собственной логики интерпретации. Daemon — ядро control plane. Он преобразует полученное описание во внутреннюю модель политики, выполняет валидацию и нормализацию, после чего компилирует политику в представление, пригодное для dataplane. На последнем этапе готовые структуры записываются в BPF maps. Dataplane. XDP-программа, прикреплённая к интерфейсу, на каждом пакете обращается к BPF maps и принимает решение: пропустить или отбросить пакет, не обращаясь непосредственно к control plane. Поток конфигурации на схеме направлен сверху вниз; в runtime данные движутся иначе: XDP читает политику из карт.
Единая семантика политики
Одна и та же политика должна иметь единое семантическое представление независимо от того, получена ли она через CLI, YAML или другой интерфейс управления. Для этого вся смысловая работа - парсинг, валидация, нормализация, компиляция - сосредоточена в daemon, а интерфейсы управления остаются лишь адаптерами к внутренней модели. Такое разделение позволяет развивать интерфейсы управления независимо от dataplane и в дальнейшем добавлять новые механизмы исполнения, не изменяя саму модель политики. BPF maps как контракт между плоскостями BPF maps в этой архитектуре выступают не просто структурами данных, а контрактом между control plane и dataplane. Dataplane не знает, откуда пришла политика; control plane не знает, как именно будет обработан пакет. Пока обе стороны соблюдают контракт, точку исполнения политики можно заменить (например, реализовать её через TC/eBPF), а набор интерфейсов управления — расширить, не затрагивая соседнюю плоскость. Отсюда следует важное эксплуатационное свойство: отказ control plane не затрагивает dataplane. Если daemon завершится, XDP-программа продолжит применять последние загруженные карты — фильтрация не прекратится.
Пока Pulsar реализует L3/L4 ACL, фильтрацию IPv4 и IPv6, VLAN/QinQ ACL и rate limiting. Управление выполняется через userspace control plane, поддерживающий декларативное описание политики.
Благодаря этому независимо от выбранного интерфейса управления dataplane получает одинаковое представление политики.
Отдельное внимание уделено обработке событий. eBPF dataplane может передавать выбранные события в userspace через Ring Buffer, где они преобразуются в логируемые события. Набор логируемых событий является настраиваемым, что позволяет отделить механизм генерации событий от их конечного представления и хранения. Таким образом, основное отличие Pulsar заключается не в количестве реализованных сетевых функций, а в архитектурном разделении control plane и dataplane. Control plane отвечает за описание, проверку и преобразование политики, тогда как dataplane использует уже подготовленное состояние для обработки пакетов.

Плоскость управления находится в user space: консольный клиент передаёт команды демону через Unix-socket, а daemon записывает правила в BPF-мапы — ACL IP (разрешение или блокировка по адресу), ACL VLAN и Rate Limit (ограничение интенсивности потока). Благодаря этому правила применяются «на лету», без перезагрузки XDP-программы. Через конфигурационную мапу Select Event daemon также управляет логированием: задаёт, какие события должны фиксироваться, и модуль XDP отправляет в Ring Buffer только их, откуда daemon читает и обрабатывает события.
Плоскость данных работает непосредственно на receive path драйвера: пакет с NIC попадает в XDP до выделения sk_buff и до передачи в сетевой стек Linux. Сопоставляя пакет с правилами в мапах, модуль принимает решение. При разрешении пакет передаётся дальше в обычный receive path Linux и продолжает обработку сетевым стеком, где в зависимости от конфигурации может пройти последующие точки обработки, включая TC ingress.При блокировке пакет отбрасывается на максимально раннем этапе, что позволяет выполнять ранний drop и снижать нагрузку на последующие уровни сетевого стека при интенсивном входящем трафике.
Механизмы обработки трафика в XDP
Сейчас основная логика принятия решений в Pulsar реализована в XDP-модуле.При обработке пакета он обращается к подготовленным control plane’ом BPF-мапам и на их основе выполняет проверку и применение политик. Реализованы три базовых механизма: ACL IP, ACL VLAN и Rate Limit.
ACL IP
ACL IP отвечает за фильтрацию трафика на уровне IPv4/IPv6 и параметров L4. Именно этот механизм реализует базовые политики разрешения или запрета трафика между источниками и получателями.
При обработке пакета XDP-модуль извлекает из него необходимые поля и формирует ключ для поиска в ACL-мапе. Для IP-политик такими полями могут быть: source IP address; destination IP address; transport protocol, например TCP или UDP; source port; destination port. На основании найденного правила dataplane принимает решение: разрешить пакет, отбросить его и зафиксировать событие через Ring Buffer, если для данного правила включено логирование.
IPv4 и IPv6 обрабатываются в рамках единой модели политики, а control plane преобразует её в соответствующие записи BPF maps, поэтому dataplane не занимается парсингом конфигурации и работает уже с нормализованным состоянием политики. Важно, что ACL IP в Pulsar является stateless-механизмом: решение по пакету принимается на основании текущих полей пакета и загруженных правил, без обязательного отслеживания состояния соединения. Это позволяет сохранить высокую скорость обработки на уровне XDP.
ACL VLAN
ACL VLAN предназначен для фильтрации трафика по меткам 802.1Q , QinQ. В отличие от IP ACL, этот механизм работает не с IP-адресами и портами, а с VLAN-тегами, которые могут присутствовать в Ethernet-кадре.
Такая фильтрация нужна не только для «учёта VLAN», но и для решения практических задач: Изоляция сетевых сегментов. Если на интерфейс приходит трафик из нескольких VLAN, можно на уровне хоста запретить обработку нежелательных VLAN ещё до входа пакета в сетевой стек. Защита от ошибок конфигурации L2.
Например, если из-за неверной настройки коммутатора трафик одного сегмента неожиданно попал в другой, ACL VLAN позволяет отбросить его на раннем этапе.
Снижение риска VLAN hopping и обработка некорректной QinQ-инкапсуляции. Пакеты с неожидаемыми или запрещёнными VLAN-тегами могут быть отброшены до передачи в сетевой стек Linux.
Единая декларативная политика.
В классическом Linux фильтрация L2 и L3 часто выполняется разными инструментами и с разной семантикой. В Pulsar VLAN-политика описывается в той же модели, что и IP-политика, и загружается в dataplane через общий control plane.
ACL VLAN особенно полезен на bare-metal серверах, гипервизорах, edge-узлах и в инфраструктурах, где один физический или логический интерфейс может получать трафик из нескольких изолированных сегментов.
При этом важно учитывать особенности драйверов сетевых устройств: в некоторых режимах NIC может снимать VLAN-тег аппаратно и передавать информацию о VLAN через метаданные. Поэтому корректная реализация VLAN ACL должна учитывать как наличие тега непосредственно в пакете, так и возможное представление VLAN в контексте XDP. Rate Limit
Rate Limit в Pulsar предназначен для ограничения интенсивности трафика за единицу времени. Для каждого ограничения в BPF map хранится отдельное состояние, связанное с соответствующим правилом политики. В состоянии хранятся параметры, необходимые для расчёта текущего лимита, например количество доступных токенов и временная метка последнего обновления.
Сравнение с существующими решениями : На сегодняшний день существует несколько различных подходов к реализации сетевой фильтрации и программируемых dataplane. К классическим решениям относятся iptables и nftables, а среди современных eBPF-based решений наиболее близкими по архитектуре являются Cilium и Calico. Отдельное место занимают специализированные eBPF dataplane, такие как Katran, ориентированные прежде всего на высокопроизводительную L4-балансировку.
Классические Linux firewall, такие как iptables и nftables, интегрированы с сетевым стеком Linux и используют механизмы подсистемы Netfilter для обработки сетевых пакетов. Управление выполняется через userspace-инструменты, которые преобразуют заданные правила в состояние подсистемы Netfilter. Такой подход является зрелым и хорошо интегрированным в Linux, однако модель правил и механизм их исполнения тесно связаны с конкретной реализацией firewall.
Cilium представляет наиболее близкий к Pulsar пример использования eBPF для построения программируемого сетевого dataplane. Cilium использует eBPF на различных этапах обработки сетевого трафика, включая точки XDP и TC, в зависимости от конкретной функции и конфигурации.
Помимо сетевой политики, Cilium уже реализует NAT, load balancing, routing, service networking и другие функции. Поэтому по количеству реализованных возможностей Pulsar на текущем этапе существенно уступает Cilium.
Calico предоставляет другой пример eBPF-based dataplane. Компоненты управления Calico преобразуют сетевую политику в состояние, используемое dataplane. eBPF используется для реализации filtering, routing и других сетевых функций. Как и Cilium,
Calico является значительно более зрелой платформой и ориентирован в первую очередь на cloud-native и Kubernetes-инфраструктуру.
Katran представляет ещё один интересный пример. В отличие от Cilium и Calico, он не является универсальной системой сетевой безопасности, а представляет собой высокопроизводительный L4 load-balancer dataplane на основе eBPF/XDP. Его архитектура хорошо демонстрирует преимущества переноса части сетевой обработки на ранние этапы packet path, однако основная задача Katran отличается от задачи Pulsar.
На этом фоне Pulsar находится на более раннем этапе развития и пока не пытается конкурировать с существующими платформами по количеству функций. Текущая реализация сосредоточена на построении программируемого security dataplane, в котором политика безопасности отделена от конкретного механизма исполнения. Ключевая идея архитектуры заключается в том, что политика описывается независимо от dataplane, преобразуется control plane в формализованное состояние и затем исполняется непосредственно в eBPF-программе. Это позволяет отделить семантику политики от механизма обработки пакетов и в дальнейшем развивать обе части системы независимо друг от друга.
Тестовый стенд состоял из двух одноплатных компьютеров Orange Pi RV2 и Orange Pi R2S, а также маршрутизатора MikroTik. Обе одноплатные системы используют SoC семейства SpacemiT K1 (Ky X1) и архитектуру RISC-V 64. 1)Orangepi RV2(192.168.0.202 ) –тестовая машина на которой собран и запущен Pulsar . 2)Orangepi R2S – 192.168.0.3-машина без Pulsar .
1.проверяем ,что нет никаких на данных момент правил :
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl list (l4_acl map is empty) root@orangepirv2:/home/orangepi/ebpf#
2.Удостоверяемся,что логирование было выключено :
cat ./test.log 2026-08-13T17:15:32.884095Z WARN ebpf_daemon: Failed to load initial config config2.yml: io error: No such file or directory (os error 2) 2026-08-13T17:15:32.884379Z WARN ebpf_daemon: Starting without configuration. Use 'ebpf-ctl reload <config>' to load later. 2026-08-13T17:15:32.995098Z INFO ebpf_daemon::monitoring: Trying XDP program id: 237 2026-08-13T17:15:33.049185Z INFO ebpf_daemon::monitoring: bpftool prog show id 237: 237: xdp name xdp_dataplane tag fa484001870657d5 loaded_at 2026-08-12T07:52:31+0300 uid 0 xlated 19776B jited 8972B memlock 20480B map_ids 470,471,472,474,480,479 btf_id 351 2026-08-13T17:15:33.103932Z WARN ebpf_daemon::monitoring: Skipping map id 470: Map id 470 is not events ringbuf (name=counters, type=percpu_array) 2026-08-13T17:15:33.158030Z WARN ebpf_daemon::monitoring: Skipping map id 471: Map id 471 is not events ringbuf (name=event_mask, type=array) 2026-08-13T17:15:33.212209Z INFO ebpf_daemon::monitoring: Opened events map 2026-08-13T17:15:33.212382Z INFO ebpf_daemon::monitoring: Events ringbuf size: 16777216 bytes 2026-08-13T17:15:33.219468Z INFO ebpf_daemon::monitoring: Starting ringbuf event loop root@orangepirv2:/home/orangepi/ebpf#
./target/debug/ebpf-ctl event-log list event-log mask: 0x0 enabled events: [ ] PacketDrop [ ] RateLimited [ ] ConntrackMiss [ ] BackendSelected [ ] SlowPath [ ] ServiceMatched [ ] VlanDetected [ ] PacketAllow
./target/debug/ebpf-ctl event-log enable PacketDrop enabled event-log: PacketDrop root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl event-log list event-log mask: 0x2 enabled events: [x] PacketDrop [ ] RateLimited [ ] ConntrackMiss [ ] BackendSelected [ ] SlowPath [ ] ServiceMatched [ ] VlanDetected [ ] PacketAllow
2.Проверяем Deny IP ACL правила
ICMP:
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl add drop src 192.168.0.0/24:any dst 192.168.0.202:any proto icmp ACL rule added added rule Drop: icmp 192.168.0.0:any -> 192.168.0.202:any (prefix_len=304) root@orangepirv2:~sudo tcpdump -ni end0 icmp tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on end0, link-type EN10MB (Ethernet), snapshot length 262144 bytes ^C 0 packets captured 0 packets received by filter 0 packets dropped by kernel
И читаем лог файл:
root@orangepirv2:/home/orangepi/ebpf# cat ./test.log … 2026-08-13T17:21:35.257433Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545048648274746 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T17:21:36.285353Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545049676208365 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T17:21:37.313289Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545050704135651 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T17:21:38.333321Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545051724172595 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T17:21:39.357436Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545052748286770 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T17:21:40.381334Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545053772177407 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T17:21:41.405289Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545054796140251 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T17:21:42.429270Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545055820124679 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T17:21:43.453263Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545056844116064 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0
На самом OrangepiR2S соответственно :
$ ping 192.168.0.202 PING 192.168.0.202 (192.168.0.202) 56(84) bytes of data. From 192.168.0.1: icmp_seq=2 Redirect Host(New nexthop: 192.168.0.202) ^C --- 192.168.0.202 ping statistics --- 9 packets transmitted, 0 received, 100% packet loss, time 8196ms
Проверяем TCP при помощи iperf3 (например будет 80 порт ): На orangepi RV2:
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl add drop src 192.168.0.0/24:any dst 192.168.0.202:80 proto tcp ACL rule added ./target/debug/ebpf-ctl acl list id plen fam src dst proto sport dport rate action 0 304 4 192.168.0.0 192.168.0.202 icmp any any - Drop 1 320 4 192.168.0.0 192.168.0.202 tcp any 80 - Drop root@orangepirv2:~# iperf3 -s -p 80 ----------------------------------------------------------- Server listening on 80 (test #1) ----------------------------------------------------------- ^Ciperf3: interrupt - the server has terminated
root@orangepirv2:/home/orangepi/ebpf# cat ./test.log … src=192.168.0.3 dst=192.168.0.202 src_port=47284 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T17:36:23.293385Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545936684167882 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=47284 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T17:36:24.317258Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545937708103844 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=47284 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T17:36:25.341274Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545938732107054 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=47284 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T17:36:26.365267Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545939756097723 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=47284 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T17:36:27.389307Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545940780144350 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=47284 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T17:36:29.405287Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=545942796125120 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=47284 dst_port=80 protocol=TCP aux0=0 aux1=0 root@orangepirv2:/home/orangepi/ebpf#
естесственно у Orangepi r2s:
root@orangepir2s:/home/orangepi# iperf3 -c 192.168.0.202 -p80 ^C- - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate Retr iperf3: interrupt - the client has terminated
UDP:
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl add drop src 192.168.0.0/24:any dst 192.168.0.202:80 proto udp ACL rule added added rule Drop: udp 192.168.0.0:any -> 192.168.0.202:80 (prefix_len=320) root@orangepirv2:~# iperf3 -s -p 80 ----------------------------------------------------------- Server listening on 80 (test #1) ----------------------------------------------------------- ^Ciperf3: interrupt - the server has terminated
root@orangepirv2:/home/orangepi/ebpf# cat ./test.log … 2026-08-13T17:54:34.709969Z WARN ebpf_daemon::monitoring: Skipping map id 470: Map id 470 is not events ringbuf (name=counters, type=percpu_array) 2026-08-13T17:54:34.763748Z WARN ebpf_daemon::monitoring: Skipping map id 471: Map id 471 is not events ringbuf (name=event_mask, type=array) 2026-08-13T17:54:34.817658Z INFO ebpf_daemon::monitoring: Opened events map 2026-08-13T17:54:34.817834Z INFO ebpf_daemon::monitoring: Events ringbuf size: 16777216 bytes 2026-08-13T17:54:34.825118Z INFO ebpf_daemon::monitoring: Starting ringbuf event loop 2026-08-13T17:54:50.010419Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=547043401254143 event_kind=PacketDrop ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=59158 dst_port=80 protocol=UDP aux0=0 aux1=0 root@orangepirv2:/home/orangepi/ebpf#
OrangePI R2S:
iperf3 -c 192.168.0.202 -p80 -u Connecting to host 192.168.0.202, port 80 iperf3: error - unable to read from stream socket: Resource temporarily unavailable root@orangepir2s:/home/orangepi#
3.Проверяем Allow IP ACL.Здесь мы делаем разрешающее правило ,но уже для конкретного хоста (с rate limit и без): Включаем логирование :
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl event-log enable PacketAllow enabled event-log: PacketAllow root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl event-log list event-log mask: 0x102 enabled events: [x] PacketDrop [ ] RateLimited [ ] ConntrackMiss [ ] BackendSelected [ ] SlowPath [ ] ServiceMatched [ ] VlanDetected [x] PacketAllow
UDP-трафик отдельно не использовался для проверки разрешающего сценария через iperf3, поскольку UDP-тест iperf3 требует дополнительного TCP-соединения для управления сессией. При этом обработка UDP на уровне ACL была непосредственно проверена с помощью правила Drop: в eBPF-журнале зафиксирован пакет protocol=UDP, dst_port=80, после чего пакет был отброшен.
./target/debug/ebpf-ctl acl add allow src 192.168.0.3:any dst 192.168.0.202:80 proto tcp ACL rule added added rule Allow: tcp 192.168.0.3:any -> 192.168.0.202:80 (prefix_len=320) root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl list id plen fam src dst proto sport dport rate action 0 304 4 192.168.0.0 192.168.0.202 icmp any any - Drop 1 320 4 192.168.0.0 192.168.0.202 tcp any 80 - Drop 2 320 4 192.168.0.0 192.168.0.202 udp any 80 - Drop 3 320 4 192.168.0.3 192.168.0.202 tcp any 80 - Allow
root@orangepirv2:/home/orangepi/ebpf# iperf3 -s -p 80 ----------------------------------------------------------- Server listening on 80 (test #1) ----------------------------------------------------------- Accepted connection from 192.168.0.3, port 48720 [ 5] local 192.168.0.202 port 80 connected to 192.168.0.3 port 48730 [ ID] Interval Transfer Bitrate [ 5] 0.00-1.00 sec 58.0 MBytes 486 Mbits/sec [ 5] 1.00-2.00 sec 59.9 MBytes 502 Mbits/sec [ 5] 2.00-3.00 sec 60.1 MBytes 504 Mbits/sec [ 5] 3.00-4.00 sec 59.5 MBytes 499 Mbits/sec [ 5] 4.00-5.00 sec 58.6 MBytes 492 Mbits/sec [ 5] 5.00-6.00 sec 58.5 MBytes 491 Mbits/sec [ 5] 6.00-7.00 sec 59.2 MBytes 497 Mbits/sec [ 5] 7.00-8.00 sec 60.1 MBytes 504 Mbits/sec [ 5] 8.00-9.00 sec 60.2 MBytes 505 Mbits/sec [ 5] 9.00-10.00 sec 59.4 MBytes 498 Mbits/sec [ 5] 10.00-10.02 sec 1.25 MBytes 510 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate [ 5] 0.00-10.02 sec 595 MBytes 498 Mbits/sec receiver ----------------------------------------------------------- Server listening on 80 (test #2) ----------------------------------------------------------- ^Ciperf3: interrupt - the server has terminated
root@orangepirv2:/home/orangepi/ebpf# cat ./test.log | grep "192.168.0.3" … 2026-08-13T18:24:00.442171Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=548786152157138 event_kind=PacketAllow ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=32988 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T18:24:00.442250Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=548786152166221 event_kind=PacketAllow ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=32988 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T18:24:00.442329Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=548786152174721 event_kind=PacketAllow ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=32988 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T18:24:00.442407Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=548786152184263 event_kind=PacketAllow ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=32988 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T18:24:00.442486Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=548786152192096 event_kind=PacketAllow ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=32988 dst_port=80 protocol=TCP aux0=0 aux1=0 2026-08-13T18:24:00.442565Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=548786152200096 event_kind=PacketAllow ifindex=2 src=192.168.0.3 dst=192.168.0.202 src_port=32988 dst_port=80 protocol=TCP aux0=0 aux1=0
По поводу rate limit(здесь просто будет проверка через iperf3):
./target/debug/ebpf-ctl acl list id plen fam src dst proto sport dport rate action 0 304 4 192.168.0.0 192.168.0.202 icmp any any - Drop 1 320 4 192.168.0.0 192.168.0.202 tcp any 80 - Drop 2 320 4 192.168.0.0 192.168.0.202 udp any 80 - Drop 3 320 4 192.168.0.3 192.168.0.202 tcp any 80 - Allow
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl del --id 3 Deleted ACL rule 3 deleted rule id=3
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl add allow src 192.168.0.3:any dst 192.168.0.202:80 proto tcp rate 1 ACL rule added added rule Allow: tcp 192.168.0.3:any -> 192.168.0.202:80 (prefix_len=320 rate=1) root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl list id plen fam src dst proto sport dport rate action 0 304 4 192.168.0.0 192.168.0.202 icmp any any - Drop 1 320 4 192.168.0.0 192.168.0.202 tcp any 80 - Drop 2 320 4 192.168.0.0 192.168.0.202 udp any 80 - Drop 3 320 4 192.168.0.3 192.168.0.202 tcp any 80 1 Allow root@orangepirv2:/home/orangepi/ebpf#
и по тестам тогда будет:
root@orangepirv2:~# iperf3 -s -p 80 ----------------------------------------------------------- Server listening on 80 (test #1) ----------------------------------------------------------- Accepted connection from 192.168.0.3, port 45004 [ 5] local 192.168.0.202 port 80 connected to 192.168.0.3 port 45010 [ ID] Interval Transfer Bitrate [ 5] 0.00-1.00 sec 256 KBytes 2.09 Mbits/sec [ 5] 1.00-2.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 2.00-3.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 3.00-4.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 4.00-5.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 5.00-6.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 6.00-7.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 7.00-8.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 8.00-9.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 9.00-10.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 10.00-10.21 sec 100 KBytes 3.90 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate [ 5] 0.00-10.21 sec 356 KBytes 286 Kbits/sec receiver ----------------------------------------------------------- Server listening on 80 (test #2) -----------------------------------------------------------
Теперь сравните что было ранее на аналогичном тесте.
4.Проверяем Deny и allow VLAN ACL: Для функциональной проверки VLAN ACL достаточно изолированного стенда из двух-трех узлов. Масштабный стенд с большим количеством VLAN, хостов и политик потребовался бы уже для оценки производительности и масштабируемости dataplane при увеличении количества правил и сетевых сегментов. Проверка VLAN выполнялась на физическом интерфейсе end0. VLAN-подинтерфейсы end0.300 и end0.100.200 использовались для настройки IP-адресации и формирования тестового трафика, тогда как обработка VLAN-заголовков выполнялась XDP-программой на входящем трафике физического интерфейса.
Как я настраивал vlan на микротик:
/interface vlan add interface=bridge0 name=vlan300 vlan-id=300 /ip address add address=192.168.100.1/24 interface=vlan300
Как я настраивал vlan на orangepi rv2(На R2S -было настроено по аналогии): Обычный Vlan: ip link add link end0 name end0.300 type vlan id 300 ip addr add 192.168.100.2/24 dev end0.300 ip link set end0.300 up QinQ на микротик: Внешний тег :
/interface vlan add interface=bridge0 name=qinq100 vlan-id=100
Внутренний тег:
interface vlan add interface=qinq100 name=vlan200 vlan-id=200 /ip address add address=192.168.200.1/24 interface=vlan200
На orangepi :
ip link add link end0 name end0.100 type vlan id 100 ip link add link end0.100 name end0.100.200 type vlan id 200 ip addr add 192.168.200.2/24 dev end0.100.200 и получаем на orangepi : 6: end0.100@end0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether c0:74:2b:fa:72:0c brd ff:ff:ff:ff:ff:ff inet6 fe80::c274:2bff:fefa:720c/64 scope link valid_lft forever preferred_lft forever 7: end0.100.200@end0.100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether c0:74:2b:fa:72:0c brd ff:ff:ff:ff:ff:ff inet 192.168.200.2/24 scope global end0.100.200 valid_lft forever preferred_lft forever inet6 fe80::c274:2bff:fefa:720c/64 scope link valid_lft forever preferred_lft forever 9: end0.300@end0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether c0:74:2b:fa:72:0c brd ff:ff:ff:ff:ff:ff inet 192.168.100.2/24 scope global end0.300 valid_lft forever preferred_lft forever inet6 fe80::c274:2bff:fefa:720c/64 scope link valid_lft forever preferred_lft forever
4.1 Deny VLAN ACL:
Для чистоты эксперимента :
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl del --id 0 error: Failed to delete rule: Failed to delete ACL rule root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl list (l4_acl map is empty) root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl vlan list (vlan_acl map is empty)
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl event-log list event-log mask: 0x2 enabled events: [x] PacketDrop [ ] RateLimited [ ] ConntrackMiss [ ] BackendSelected [ ] SlowPath [ ] ServiceMatched [ ] VlanDetected [ ] PacketAllow
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl event-log enable VlanDetected enabled event-log: VlanDetected root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl vlan add 300 drop Added VLAN rule: outer_vlan=300 added vlan rule (outer=300): drop root@orangepirv2:/home/orangepi/ebpf#
cat ./test.log … src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=300 aux1=1 2026-08-13T19:19:27.799742Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552121190282679 event_kind=PacketDrop ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:19:28.813405Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552122204262459 event_kind=VlanDetected ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=300 aux1=1 2026-08-13T19:19:28.813658Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552122204286126 event_kind=PacketDrop ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:19:29.837427Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552123228281300 event_kind=VlanDetected ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=300 aux1=1 2026-08-13T19:19:29.837677Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552123228302716 event_kind=PacketDrop ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:19:30.861526Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552124252362097 event_kind=VlanDetected ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=300 aux1=1 2026-08-13T19:19:30.861864Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552124252401680 event_kind=PacketDrop ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:19:31.885517Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552125276358813 event_kind=VlanDetected ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=300 aux1=1 2026-08-13T19:19:31.885760Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552125276389521 event_kind=PacketDrop ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:19:32.909459Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552126300305529 event_kind=VlanDetected ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=300 aux1=1 2026-08-13T19:19:32.909704Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552126300335362 event_kind=PacketDrop ifindex=2 src=192.168.100.1 dst=192.168.100.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 root@orangepirv2:/home/orangepi/ebpf#
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl vlan add 100 drop inner 200 2026-08-13T19:21:11.197702Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552224588524734 event_kind=VlanDetected ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=100 aux1=2 2026-08-13T19:21:11.198016Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552224588554442 event_kind=PacketDrop ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:21:12.209419Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552225600272714 event_kind=VlanDetected ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=100 aux1=2 2026-08-13T19:21:12.209665Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552225600299630 event_kind=PacketDrop ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:21:13.233435Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552226624286596 event_kind=VlanDetected ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=100 aux1=2 2026-08-13T19:21:13.233753Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552226624313137 event_kind=PacketDrop ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:21:14.257513Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552227648361060 event_kind=VlanDetected ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=100 aux1=2 2026-08-13T19:21:14.257769Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552227648388352 event_kind=PacketDrop ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:21:15.277840Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552228668675580 event_kind=VlanDetected ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=100 aux1=2 2026-08-13T19:21:15.278091Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552228668710455 event_kind=PacketDrop ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:21:16.301488Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552229692338134 event_kind=VlanDetected ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=100 aux1=2 2026-08-13T19:21:16.301757Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552229692367675 event_kind=PacketDrop ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0 2026-08-13T19:21:17.325564Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552230716399223 event_kind=VlanDetected ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=100 aux1=2 2026-08-13T19:21:17.325825Z INFO ebpf_daemon::monitoring: eBPF event timestamp_ns=552230716434556 event_kind=PacketDrop ifindex=2 src=192.168.200.1 dst=192.168.200.2 src_port=0 dst_port=0 protocol=ICMP aux0=0 aux1=0
Проверяем rate лимит на vlan:
./target/debug/ebpf-ctl acl vlan add 100 allow inner 200 rate 1 Added VLAN rule: outer_vlan=100 added vlan rule (outer=100 inner=200 rate=1): allow iperf3 -s -p 80 ----------------------------------------------------------- Server listening on 80 (test #1) ----------------------------------------------------------- Accepted connection from 192.168.200.3, port 39500 [ 5] local 192.168.200.2 port 80 connected to 192.168.200.3 port 39508 [ ID] Interval Transfer Bitrate [ 5] 0.00-1.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 1.00-2.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 2.00-3.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 3.00-4.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 4.00-5.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 5.00-6.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 6.00-7.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 7.00-8.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 8.00-9.00 sec 0.00 Bytes 0.00 bits/sec [ 5] 9.00-10.00 sec 0.00 Bytes 0.00 bits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate [ 5] 0.00-10.00 sec 0.00 Bytes 0.00 bits/sec receiver ----------------------------------------------------------- Server listening on 80 (test #2) -----------------------------------------------------------
6.проверяем применение правил из конфигурационного файла:
cat ./config2.yml
acl: allow: - vlan: - 300 - outer: 200 inner: - 100 - 101 rate: 1 - src: addresses: - 192.168.0.2/32 - 192.168.100.0/24 dst: addresses: 192.168.0.202 ports: number: 80 proto: tcp rate: 1 drop: - vlan: - 300 - outer: 130 inner: - 100 - src: addresses: - fe80::/64 dst: addresses: - fe80::c274:2bff:fefa:720c ports: number: any proto: icmp rate: 1 - src: addresses: - 10.0.0.0/8 - 192.168.200.1/24 dst: addresses: - 192.168.0.2 ports: number: any proto: icmp rate: 1 logging: PacketDrop: true RateLimited: false ConntrackMiss: false BackendSelected: false SlowPath: false ServiceMatched: true VlanDetected: true PacketAllow: false
И так читается уже самим Pulsar:
cat ./test.log 2026-08-13T20:11:00.641182Z INFO ebpf_daemon::manager::maps: rate_limit: global max_tokens=65536, refill_per_sec=64000, per_rule_multiplier=256 2026-08-13T20:11:00.641442Z INFO ebpf_daemon::manager::maps: monitoring: ringbuf_bytes=16777216, poll_interval_ms=100 2026-08-13T20:11:00.641509Z INFO ebpf_daemon::manager::maps: acl.default_action: allow 2026-08-13T20:11:00.760323Z INFO ebpf_daemon::monitoring: Trying XDP program id: 245 2026-08-13T20:11:00.814464Z INFO ebpf_daemon::monitoring: bpftool prog show id 245: 245: xdp name xdp_dataplane tag fa484001870657d5 loaded_at 2026-08-13T23:09:05+0300 uid 0 xlated 19776B jited 9000B memlock 20480B map_ids 483,484,485,487,493,492 btf_id 360 2026-08-13T20:11:00.868271Z WARN ebpf_daemon::monitoring: Skipping map id 483: Map id 483 is not events ringbuf (name=counters, type=percpu_array) 2026-08-13T20:11:00.922074Z WARN ebpf_daemon::monitoring: Skipping map id 484: Map id 484 is not events ringbuf (name=event_mask, type=array) 2026-08-13T20:11:00.975972Z INFO ebpf_daemon::monitoring: Opened events map 2026-08-13T20:11:00.976150Z INFO ebpf_daemon::monitoring: Events ringbuf size: 16777216 bytes 2026-08-13T20:11:00.983324Z INFO ebpf_daemon::monitoring: Starting ringbuf event loop
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl list id plen fam src dst proto sport dport rate action 0 304 4 10.0.0.0 192.168.0.2 icmp any any - Drop 1 320 4 192.168.0.2 192.168.0.202 tcp any 80 1 Allow 2 320 4 192.168.100.0 192.168.0.202 tcp any 80 1 Allow 3 304 4 192.168.200.0 192.168.0.2 icmp any any - Drop 4 304 6 fe80:0:0:0:0:0:0:0 fe80:0:0:0:c274:2bff:fefa:720c icmp any any - Drop root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl acl vlan list id outer_vlan inner_vlan action rate 0 100 101 allow 1 1 130 100 drop 0 2 100 200 allow 1 3 250 - drop 0 4 300 - allow 1
root@orangepirv2:/home/orangepi/ebpf# ./target/debug/ebpf-ctl event-log list event-log mask: 0xc2 enabled events: [x] PacketDrop [ ] RateLimited [ ] ConntrackMiss [ ] BackendSelected [ ] SlowPath [x] ServiceMatched [x] VlanDetected [ ] PacketAllow root@orangepirv2:/home/orangepi/ebpf#
7.Над чем мне пока предстоит поработать :
Ограничения текущей реализации На текущем этапе не завершена реализация событий и функций, связанных с stateful processing:
ConntrackMiss;
BackendSelected;
SlowPath;
ServiceMatched.
Данный функционал связан с состоянием соединения, выбором backend и обработкой сервисного трафика. Его реализация планируется на уровне Traffic Control, где будет выполняться stateful processing, включая conntrack, Load Balancing и NAT. На текущем этапе перечисленные события используются как заглушки и не отражают завершённую реализацию соответствующей логики.
Преокт выложен под открытой лицензией : https://github.com/AlexRoot00/Pulsar/tree/master