Linux зеркалирование пакетов с минимальной задержкой
От: Mike  
Дата: 06.03.23 06:04
Оценка:
Простая задача:
— принимаем UDP-пакет, отправляем обратно (100 тыс.пак/сек, но чем больше — тем лучше).

Но в User App есть проблемы:
— задержка получается переменной (и иногда внезапно большой).

Хотелось бы получить минимальную (и стабильную) задержку, плюс из пакета нужно все-таки получать кое-какую информацию (RTP-sequence, например).

Какие способы можно использовать? (Сейчас — старый способ: select/recvfrom/sendto).
linux packet delay
Re: Linux зеркалирование пакетов с минимальной задержкой
От: Слава  
Дата: 06.03.23 07:12
Оценка: +1
Здравствуйте, Mike, Вы писали:

M>Какие способы можно использовать? (Сейчас — старый способ: select/recvfrom/sendto).


FPGA

Ну чтоб уж совсем уж.

PS: вообще можно использовать хотя бы epoll, а то и uring, а то и nftables mirror udp traffic, или даже свой модуль ядра написать.
Re[2]: Linux зеркалирование пакетов с минимальной задержкой
От: Mike  
Дата: 06.03.23 10:47
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте, Mike, Вы писали:


M>>Какие способы можно использовать? (Сейчас — старый способ: select/recvfrom/sendto).


С>FPGA


С>Ну чтоб уж совсем уж.


С>PS: вообще можно использовать хотя бы epoll, а то и uring, а то и nftables mirror udp traffic, или даже свой модуль ядра написать.


FPGA — это мы тоже можем но хотелось бы программно.

Я попробовал копировать пакеты через iptables — стабильности не хватает (и это еще не учитывая, что SrcIP и DstIP не переставляются, а нужно, чтобы переставлялись).

Wanem такое может, и делает как надо. Но вот как?

Можно написать модуль ядра для netfilter — пока склоняюсь к этому варианту.
Re[3]: Linux зеркалирование пакетов с минимальной задержкой
От: Mike  
Дата: 13.03.23 06:02
Оценка:
Мда... сделал через модуль netfilter:
  код хука модуля
uint Hook_Func(uint hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) {
uint res_ret = NF_ACCEPT;

struct iphdr *ip_header;
struct udphdr *udp_header;
int dest_port;
int udp_len;
char *udp_data;
unsigned long flags = 0;

spin_lock_irqsave(&hook_lock, flags);

if (skb->protocol == htons(ETH_P_IP)) {
ip_header = ip_hdr(skb);
if (ip_header->version == 4 && ip_header->protocol == IPPROTO_UDP) {
udp_header = (struct udphdr *) (((char *) ip_header) + 20);
dest_port = ntohs(udp_header->dest);
if (dest_port == SOCK_LOCAL_PORT) {

udp_len = ntohs(udp_header->len) — 8;
udp_data = ((char *) udp_header) + 8;

netpoll_send_udp(tx_back_np.np, udp_data, udp_len);

res_ret = NF_DROP;
}
}
}

spin_unlock_irqrestore(&hook_lock, flags);

return res_ret;
}

Результат:
— нестабильность осталась, но отличается от варианта select/recvfrom/sendto:
— иногда проявляется в netfilter, иногда в select/recvfrom/sendto, иногда одновременно (похоже, что у netfilter приоритет низкий);
— по моим оценкам задержка зеркалированного пакета иногда бывает больше 50 мс (в netfilter — каждые 2-3 часа, в user-app — каждые 10-15 минут,
то есть через netfilter получается лучше, но проблема остается);
— пакеты не теряются ни в user-app, ни в netfilter.

Известно, что WANem использует netem. По netem есть вопросы:
— что за Qdisk?
— netem умеет дублировать пакеты (skb), можно ли при дублировании поменять source/destination?
— можно ли добавить еще один модуль для перехвата skb (типа netem, но только свой)?
Re: Linux зеркалирование пакетов с минимальной задержкой
От: PlushBeaver  
Дата: 16.03.23 09:51
Оценка:
M>- принимаем UDP-пакет, отправляем обратно (100 тыс.пак/сек, но чем больше — тем лучше).
<...>
M>Хотелось бы получить минимальную (и стабильную) задержку, плюс из пакета нужно все-таки получать кое-какую информацию (RTP-sequence, например).

XDP.
Проще и безопаснее, чем модуль ядра.
В native mode работает до сетевого стека.
Разбор пакета писать руками, как в коде фильтра, который ты сделал.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.