У меня есть проект 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
Настройка MTU пространства имен сети в C по сравнению с утилитой «ip» с большими кадрами Ethernet ⇐ Linux
1765456692
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;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79843746/network-namespace-mtu-setting-in-c-vs-the-ip-utility-with-big-ethernet-frames[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия