Raw Socket получает 1504 байта (MTU = 1500)

В моем приложении я открываю сырой сокет (ядро LINUX 3.8.5) со следующим
инструкция:

::socket( PF_PACKET, SOCK_RAW, htons((uint16_t)ETH_P_ALL));

все работает нормально, я могу получить его и отправить в другой интерфейс.
Однако какое-то время

::recvfrom()

на этом сокете возвращается 1518 (1504 байта полезной нагрузки + 14 ETH_HLEN).

Когда я пытаюсь отправить этот буфер 1518 байтов, однако инструкция

::send(......)

возвращает EMSGSIZE (сообщение слишком длинное).

Обратите внимание, что на моем интерфейсе сетевого адаптера MTU равен 1500, поэтому я ожидал максимум
1514 (полезная нагрузка + ETH_HLEN) байт, полученных с помощью :: recvfrom

Ethtype — 0x0800, поэтому это не фрейм с тегом vlan, следовательно, эти 4 байта «лишние» не связаны с тегом vlan

У вас есть объяснение этому?

1

Решение

Насколько я понимаю, MTU специфичен для соединения, потому что он зависит от всего пути от источника до места назначения, а не только от вашего локального интерфейса. Если вы отправляете на адрес, отличный от того, с которого вы обманули пакет, кажется вполне вероятным, что значения MTU могут отличаться.

Цитируя из Справочные страницы Linux:

Когда обнаружение PMTU включено, ядро ​​автоматически отслеживает MTU пути для каждого хоста назначения. Когда он подключен к определенному одноранговому узлу с помощью connect (2), в настоящее время можно легко получить MTU известного пути, используя опцию сокета IP_MTU (например, после возникновения ошибки EMSGSIZE). Это может измениться со временем. Для сокетов без установления соединения со многими адресатами также можно получить доступ к новому MTU для данного пункта назначения, используя очередь ошибок (см. IP_RECVERR). Новая ошибка будет поставлена ​​в очередь для каждого входящего обновления MTU.

0

Другие решения

Подробнее по этому вопросу, атм для устранения проблемы у меня есть эта конфигурация:

eth0 (Сервер1) —————> eth0 (Сервер2) —— —— НАТ> dummy0 (Сервер2)

между Server1 и Server2 нет переключателя, ничего, просто кабель,
и dummy0 — это NIC, полученный с помощью фиктивного сетевого модуля.

Отнюдь на eth0 (Server1) «TX side» и на eth0 (Server2) «RX side» вот что
Я собираюсь:

Сторона TX:

1514 bytes, sequence number  15476
1514 bytes, sequence number  15477
1514 bytes, sequence number  15478
1514 bytes, sequence number  15479

На стороне RX я бы ожидал того же, но я получаю:

1514 bytes, sequence number 15476
1518 bytes, sequence number 15477
1514 bytes, sequence number 15479

Самое смешное, что пока 15478 не было получено последние 4 байта
в этих 1518 байтах (следующий номер 15477) первые 4 байта в полезной нагрузке
потерянного пакета eth.

РЕШЕНО: Это была опция GRO, действительно благодаря этой опции на :: rcv удалось
чтобы получить 2 или более кадров Ethernet одновременно, поэтому, например, последовательность
«появился» номер отсутствующий (в действительности он был объединен с предыдущим),
тот факт, что для какого-то пакета я получил 1518, был обусловлен размером переданного буфера
на :: rcv, передавая гораздо больший буфер, действительно, я не теряю никакого контента.

0

По вопросам рекламы [email protected]