Настройка MTU пространства имен сети в C по сравнению с утилитой «ip» с большими кадрами EthernetLinux

Ответить
Anonymous
 Настройка MTU пространства имен сети в C по сравнению с утилитой «ip» с большими кадрами Ethernet

Сообщение Anonymous »

У меня есть проект Linux C, который (среди прочих) отправляет (размером более 1500 байт) необработанные кадры Ethernet между сетевыми интерфейсами различных процессов. У меня есть несколько системных тестов, в которых эта функциональность проверяется с использованием сетевых пространств имен. У меня нет привычки допускать провалы тестов, поэтому пять лет назад все эти тесты прошли успешно.
Из-за разных приоритетов я оставил проект в покое в 2022 году и начал его несколько недель назад. Поэтому я запускаю системные тесты, которые написал для них, и все они проваливаются. Поэтому я начал расследование.
Я обнаружил, что все работает нормально, за исключением этих больших кадров Ethernet. Они в обязательном порядке вызывали код ошибки 105 или 90; коды ошибок, относящиеся к слишком большому размеру пакетов или слишком маленькому буферу. Я проверил свой код, и вроде бы он все делает правильно: он устанавливает MTU интерфейса с помощью обычных вызовов ioctl.
ifr.ifr_mtu = 9000;
if (ioctl(rawsock, SIOCSIFMTU, (caddr_t)&ifr) < 0) {
DBGMSG("NETP Could not set MTU %u to device '%s'\n", mtu, device);
return -1;
}

Я даже это добавил:
setsockopt(rawsock, SOL_SOCKET, SO_SNDBUF, (void*)&mtu, sizeof(mtu));
setsockopt(rawsock, SOL_SOCKET, SO_RCVBUF, (void*)&mtu, sizeof(mtu));

Ничего не получилось. Затем я просто установил MTU интерфейса в тестовом скрипте, используя «ip», и все снова заработало:
ip netns exec core2 ip link set core2red mtu 9000

Кто-нибудь знает, что здесь произошло? То есть я могу снова работать и развиваться над этим проектом, но меня это все равно беспокоит. Что произошло за последние пять лет, что установка MTU через C не так хороша, как то, что делает утилита 'ip'?

В ответ на ответы всех этих замечательных людей я вставляю сюда всю функцию:
int RawSocket_new(char* device, unsigned mtu, int protocol)
{
int rawsock = 0;
struct sockaddr_ll sll = { 0 };
struct ifreq ifr = { 0 };

if((rawsock = socket(PF_PACKET, SOCK_RAW, htons(protocol)))== -1)
{
DBGMSG("NETP Could not create socket for device '%s'\n", device);
return -1;
}

strncpy((char *)ifr.ifr_name, device, IFNAMSIZ - 1);
if((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1)
{
DBGMSG("NETP Device '%s' not found\n", device);
return -1; /* device not found */
}

sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(protocol);

if((bind(rawsock, (struct sockaddr *)&sll, sizeof(sll)))== -1)
{
DBGMSG("NETP Could not bind socket to device '%s'\n", device);
return -1;
}
ifr.ifr_mtu = mtu;
if (ioctl(rawsock, SIOCSIFMTU, &ifr) < 0) {
DBGMSG("NETP Could not set MTU %u to device '%s'\n", mtu, device);
return -1;
}

DBGMSG("Setting PACKET_AUXDATA on socket.\n");
int option = 1;
if (setsockopt(rawsock, SOL_PACKET, PACKET_AUXDATA, &option, sizeof(option)) == -1) {
DBGMSG("Setting PACKET_AUXDATA on socket failed.\n");
}

return rawsock;
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... net-frames
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»