Немного о реализации сетевых драйверов в линукс.

Как протестировать сетевую часть процессора на максимальное быстродействие?

Тестирование, конечно, лучше производить с помощью какого-нибудь аппаратного сетевого тестера, как правило, это тестеры jdsu. Или, как вариант, это написание простой утилиты, которая бы непрерывно посылала трафик в сеть.

Самый простейший пример такой программы:

  while (number > 0) {
    c = sendto(fd, file_buf, frameLen, 0, (struct sockaddr *)&sa, sizeof (sa));
    number --;
  }

Что должен делать процессор с поступающим трафиком?

Поскольку нас интересует именно максимальное быстродействие, то нам не нужно, чтобы входящий пакет попадал в ядро и разбирался там на всех сетевых уровнях.

Нам требуется сделать заворот прямо в прерывании по приёму и отправить его обратно в сеть. По-научному, наверное, это будет называться loop.

Сетевой стек линукса очень крут, и поэтому решить поставленную задачу довольно просто и при этом данное решение не будет привязано к какой-то определенной архитектуре процессоров и сетевых плат.

Сетевые драйвера находятся здесь:
kernel/drivers/net/ethernet

Чтобы сделать заворот пакета, нужно найти функцию прерывания по приёму и там принятый пакет отправить обратно в сеть. Как правило, каждый приём пакета заканчивается вызовом функции netif_receive_skb, которая передаёт принятый пакет ядру.

Запускаем поиск по функции netif_receive_skb. То место, откуда она вызывается, как правило, и есть функция-обработчик прерывания по приёму.

Прямо перед вызовом netif_receive_skb делаем отправку пакета обратно в сеть, а вызов netif_receive_skb отключаем.

  if (dev_queue_xmit(skb)){
    dev_kfree_skb(skb);
  }
//			netif_receive_skb(skb);

Также нужно найти место, где удаляется начальный заголовок, обычно это выглядит вот так:

skb->protocol = eth_type_trans(skb, mp->dev);

И тоже его закомментировать:

//skb->protocol = eth_type_trans(skb, mp->dev);

Всё, теперь все поступающие пакеты будут мгновенно отправляться обратно в сеть, не попадая в ядро.