Netmap (by luigi rizzo) простой и удобный opensource фреймворк для...

34
NETMAP (от Luigi Rizzo) Простой и удобный открытый фреймворк для обработки трафика на скоростях 10 Gbit/s или 14 Mpps Евгений Ёрхов Компания IXI

Transcript of Netmap (by luigi rizzo) простой и удобный opensource фреймворк для...

Page 1: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

NETMAP (от Luigi Rizzo)Простой и удобный открытый фреймворк для обработки трафика на скоростях 10Gbit/s или

14 Mpps

Евгений Ёрхов

Компания IXI

Page 2: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Структура доклада

• Анализ проблемы производительности стеков TCP/IP в OS общего назначения

• Краткий обзор известных подходов по увеличению производительности на больших скоростях

• Быстрое введение в Netmap, архитектура, основные операции

• Примеры: генератор трафика, компонент подсистемы DDOS защиты

• Обзор производительности

Page 3: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

ОСНОВНЫЕ ПРОБЛЕМЫ ПРИ СКОРОСТНОЙ ОБРАБОТКЕ ПАКЕТОВ

Анализ overhead’ов в стеках OS общего назначения

Page 4: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Структуры данных NIC и их взаимосвязь со структурами данных OS

Page 5: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Вычисляем наносекунды

KERNEL SPACE#define D(format, ...)

do {

struct timespec __xxts;

nanotime(&__xxts);

printf("%03d.%09d %s [%d]

"format "\n",

(int)__xxts.tv_sec %

1000, (int)__xxts.tv_nsec,

__FUNCTION__, __LINE__,

##__VA_ARGS__);

} while (0)

USER SPACE#define D(format, ...)

do {

if (!verbose) break;

struct timespec _xxts;

clock_gettime(CLOCK_REALTIME,

&_xxts)

fprintf(stderr, "%03d.%09d %s

[%d] " format

"\n”,(int)_xxts.tv_sec

%1000, \ (int)_xxts.tv_nsec,

__FUNCTION__, __LINE__,

##__VA_ARGS__);

} while (0)

Page 6: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Путешествие к центру ядра через API

File Function / description Time ns Delta ns

user_program sendto() system call 8 96

uipc_syscalls.c

uipc_socket.c

sys_sendto()

sendit()

kern_sendit()

sosend()

sosend_dgram()

sockbuf locking, mbuf allocation, copying

104

111

118

---

146

137

udp_usrreq.c udp_send()

udp_output() 273 57

ip_output.c Ip_output()

Route lookup, ip header setup

330 198

if_ethersubr.c Ether_output

MAC header lookup and copy, loopback

ether_output_frame

528

690

162

ixgbe.c ixgbe_mq_start()

ixgbe_mq_start_locked()

ixgbe_xmit

698

720

730

220

- On wire 950

Page 7: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Современные техники увеличения производительности

• Socket API: BPF (FreeBSD), AF_PACKET (Linux)

• Packet filter hooks: Netgraph (FreeBSD), Netfilter (Linux), Ndis miniport drivers (MS Windows)

• Direct buffer access: PF_RING_DNA (Linux), PACKET_MMAP (Linux), UIO-IXGBE (Linux)

Page 8: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

АРХИТЕКТУРА NETMAPСтруктуры данных, основные операции, примитивы и особенности

Page 9: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Подход NETMAP к обработке пакетов на больших скоростях

• Доступ к NIC в обход стека OS

• Защита памяти в хрупком kernel space

• Zero copy операции при форвардингепакетов

• Линейные, лёгкие структуры данных

• pre-alloceted буферы для пакетов и метаданных

• Поддержка множественных очередей NIC

Page 10: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Схема взаимодействия NETMAP, NIC и OS

NIC пересылает данные между сетью и оперативной памятью

ядро OS выполняет защиту памяти

ядро OS обеспечивает многозадачность и синхронизацию

NETMAP обеспечивает механизмы управления и доступа к данным для приложения

Page 11: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Структуры данных NETMAP экспортируемые в user space

Пакетные буферы ( packet buffers )

Кольцевые буферы-очереди ( netmap rings )

Дескриптор интерфейса( netmap_if )

Page 12: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Разделение ответственности

Приложение user space

• Управляет слотами в «netmap_ring»

• Управляет текущей позицией (номер слота) в «netmap_ring»

• Заполняет/читает пакетные буферы, начиная с позиции «cur» по «cur + avail -1»

• Управляет полем «netmap_ring->avail»

Ядерная часть

• NETMAP управляет границами в netmap_rings

• NIC DMA engine заполняет/читает пакетные буферы в позициях кроме как начиная с «cur» по «cur + avail»

• NETMAP управляет синхронизацией метаданных в «netmap_rings» и структур NIC

Page 13: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

NETMAP API Основные операции

• /dev/netmap• ioctl(…, NIOCREGIF, arg) • ioctl (…, NIOCTXSYNC) – синхронизация очередей

(netmap rings) для отправки с соответствующими очередями сетевой карты, что эквивалентно отправке пакетов в сеть, синхронизация начинается с позиции cur

• ioctl (…, NIOCRXSYNC) – синхронизация очередей сетевой карты с соответствующими очередями netmap rings, для получения пакетов, поступивших из сети. Запись осуществляется начиная с позиции cur

Page 14: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Примитивы блокирования

Используются стандартные механизмы OS

• select()• poll()

Результат:• Отсутствие нагрузки на CPU• Обработка несколько пакетов за

проход

Page 15: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Дополнительные особенности

Поддержка множественных очередей NIC

Передача/приём пакетов в/из host stack

Защита памяти

Zero copy packet forwarding

Page 16: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Zero copy packet forwarding

...

ns_src = &src_nr_rx->slot[i]; /* locate src and dst slots */

ns_dst = &dst_nr_tx->slot[j];

/* swap the buffers */

tmp = ns_dst->buf_index;

ns_dst->buf_index = ns_src->buf_index;

ns_src->buf_index = tmp;

/* update length and flags */

ns_dst->len = ns_src->len;

ns_src->len = 0;

/* tell kernel to update addresses in the NIC rings */

ns_dst->flags = ns_src->flags = BUF_CHANGED;

dst_nr_tx->avail--; // Для большей ясности кода проверка

src_nr_rx->avail--; // avail > 0 не сделана

...

Page 17: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

NETMAP ПРИМЕРЫ

Прототипы: генератор трафика, компонент подсистемы очистки трафика в системе DDOS защиты

Page 18: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Прототип генератора трафикаfds.fd = open("/dev/netmap", O_RDWR);

strcpy(nmr.nm_name, "ix0");

ioctl(fds.fd, NIOCREG, &nmr);

p = mmap(0, nmr.memsize, fds.fd);

nifp = NETMAP_IF(p, nmr.offset);

fds.events = POLLOUT;

for (;;) {

poll(fds, 1, -1);

for (r = 0; r < nmr.num_queues; r++) {

ring = NETMAP_TXRING(nifp, r);

while (ring->avail-- > 0) {

i = ring->cur;

buf = NETMAP_BUF(ring, ring->slot[i].buf_index);

//... store the payload into buf ...

ring->slot[i].len = ... // set packet length

ring->cur = NETMAP_NEXT(ring, i);

}

}

}

Page 19: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

NETMAP API в подсистеме очистки трафика DDOS

Основными требованиями к подсистеме очистки трафика выбраны

• возможность фильтрации пакетов на предельных скоростях

• возможности по обработке пакетов в системе фильтров, реализующие различные, известные на сегодняшний день техники противодействия DDOS атакам

Page 20: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Подготовка и включение режима NETMAP

struct nmreq nmr;

for (i=0, i < MAX_THREADS, i++) {

targ[i]->nmr.ringid = i | NETMAP_HW_RING;

ioctl(targ[i].fd, NIOCREGIF, &targ[i]->nmr);

targ[i]->mem = mmap(0, targ[i]->nmr.nr_memsize,

PROT_WRITE | PROT_READ, MAP_SHARED, targ[i].fd, 0);

targ[i]->nifp = NETMAP_IF(targ[i]->mem, targ[i]->nmr.nr_offset);

targ[i]->nr_tx = NETMAP_TXRING(targ[i]->nifp, i);

targ[i]->nr_rx = NETMAP_RXRING(targ[i]->nifp, i);

}

Page 21: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Открываем очереди для обмена с host stack

struct nmreq nmr;

/* NETMAP ассоциирует netmap ring с наибольшим ringid с

сетевым стеком */

targ->nmr.ringid = stack_ring_id | NETMAP_SW_RING;

ioctl(targ.fd, NIOCREGIF, &targ->nmr);

Page 22: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Стартуем thread’ы каждая из которых работает со своей очередью

for ( i = 0; i < MAX_THREADS; i++ ) {

/* start first rx thread */

targs[i].used = 1;

if (pthread_create(&targs[i].thread, NULL, rx_thread, &targs[i]) == -1) {

D("Unable to create thread %d", i);

exit(-1);

}

}

/* Wait until threads will finish their loops */

for ( i = 0; i < MAX_THREAD; i++ ) {

if( pthread_join(targs[i].thread, NULL) ) {

ioctl(targs[i].fd, NIOCUNREGIF, &targs[i].nmr);

close(targs[i].fd);

}

}

Page 23: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Ожидание пакетов в rx_thread()while(targ->used) {

ret = poll(fds, 2, 1 * 100);

if (ret <= 0)

continue;

/* run rings processing */

for ( i = targ->begin; i < targ->end; i++) {

ioctl(targ->fd, NIOCTXSYNC, 0);

ioctl(targ->fd_stack, NIOCTXSYNC, 0);

targ->rx = NETMAP_RXRING(targ->nifp, i);

targ->tx = NETMAP_TXRING(targ->nifp, i);

if (targ->rx->avail > 0)

{

/* process ring */

cnt = process_incoming(targ->id, targ->rx, targ->tx,

targ->stack_rx, targ->stack_tx);

}

}

Page 24: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Получение доступа к raw пакетам process_incoming()

limit = nic_rx->avail;

while ( limit-- > 0 ) {

struct netmap_slot *rs = &nic_rx->slot[j]; // rx slot

struct netmap_slot *ts = &nic_tx->slot[k]; // tx slot

eth = (struct ether_header *)NETMAP_BUF(nic_rx,

rs->buf_idx);

if (eth->ether_type != htons(ETHERTYPE_IP)) {

goto next_packet; // pass non-ip packet

}

/* get ip header of the packet */

iph = (struct ip *)(eth + 1);

}

Page 25: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

ПРОИЗВОДИТЕЛЬНОСТЬ

Page 26: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Метрики

Per-bytes

• Измерение осуществляется на основе отношения показателей к передаваемым полезным данным (payload)

• Поскольку NETMAP использует zero copy forwarding – результат очевиден

Per-packets

• Измерение осуществляется на основе отношения показателей к количеству обрабатываемых пакетов

• Интересно измерить загрузку CPU в отношении к количеству обрабатываемых 64-байтовых пакетов

Page 27: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Тестовое железо и OS

i7-870 4-core 2.93GHz CPU (3.2 GHz в режиме turbo-boost), оперативная память на частоте 1.33GHz, в систему установлена двухпортоваясетевая карта на базе чипсета Intel 82599

FreeBSD HEAD/amd64, Апрель 2012 г.

Page 28: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Скорость в зависимости от частоты процессора, ядер и т.п.

Page 29: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Загрузка процессора на одном ядре

Частота Средняя загрузка CPU

900 MHz 100%

1.2 GHz 80%

3GHz 55%

Page 30: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Скорость передачи/приёма, в зависимости от размера пакета

Page 31: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Скорость в зависимости от количества пакетов за один системный вызов

Page 32: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Скорости фильтрации flood-атак сервером очистки трафика RUSCREEN

Наименование атаки(на случайном распределении src_addr)

Способ противодействия Скорости обработки

Synflood SYNCOOKIE 12 883 408 pps

UDP flood PPS limiting, blacklisting,greylisting

13 854 096 pps

ICMP flood PPS limiting, blacklisting,greylisting

13 780 314 pps

Смешанный flood SYNCOOKIE, statefulinspection, PPS limiting, blacklisting, greylisting

11 083 147 pps

Page 33: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

Заключение

• В докладе рассмотрены основные возможности NETMAP по обработке трафика на скоростях 10Gbit/s

• Сделан сравнительный анализ NETMAP с другими системами скоростной обработки пакетов

• Подтверждены тесты производительности, сделанные автором NETMAP – Luigi Rizzo

• Продемонстрированы основные приёмы использования NETMAP на примерах прототипов генератора трафика и подсистемы очистки трафика.

Благодаря подходу, реализованному в NETMAP, автору доклада удалось добиться нужно производительности при фильтрации трафика в проекте DDOS-защиты RUSCREEN, позволяющей работать на скоростях 14Mpps.

Page 34: Netmap (by luigi rizzo)   простой и удобный opensource фреймворк для обработки трафика.(Евгений Ёрхов)

БОЛЬШОЕ СПАСИБО ЗА ВНИМАНИЕ !