LINUX.ORG.RU
решено ФорумAdmin

UDP датаграммы приходят не на тот ip адрес

 ,


1

1

Добрый день! Подскажите пожалуйста, как быть с такой проблемой. Требуется осуществить обмен данными через протокол UDP. Имеется обычный компьютер и плата с процом и кучей ethernet контроллеров (5 штук), и там и там стоит линукс. Если отправляю с платы на компьютер через любой ethernet, то вопросов никаких, все отрабатывает четко. А вот если наоборот... Вообщем независимо от того, на какой ip отправляется пакет, дойти он может на любой. Вот ifconfig на плате:

eth0      Link encap:Ethernet  HWaddr ea:8b:91:8f:9c:c3  
          inet addr:192.9.200.1  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::e88b:91ff:fe8f:9cc3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:347318 errors:0 dropped:0 overruns:0 frame:0
          TX packets:47376 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:297398853 (283.6 MiB)  TX bytes:7030948 (6.7 MiB)

eth1      Link encap:Ethernet  HWaddr 3e:a3:fa:68:08:a6  
          inet addr:192.9.200.2  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::3ca3:faff:fe68:8a6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:142316 errors:0 dropped:0 overruns:0 frame:0
          TX packets:74 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:40318502 (38.4 MiB)  TX bytes:9582 (9.3 KiB)

eth2      Link encap:Ethernet  HWaddr a6:72:cf:db:d5:d1  
          inet addr:192.9.200.3  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::a472:cfff:fedb:d5d1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:104902 errors:0 dropped:0 overruns:0 frame:0
          TX packets:72 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:16243422 (15.4 MiB)  TX bytes:9420 (9.1 KiB)

eth3      Link encap:Ethernet  HWaddr 86:12:6d:95:6c:7e  
          inet addr:192.9.200.4  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::8412:6dff:fe95:6c7e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:129954 errors:0 dropped:0 overruns:0 frame:0
          TX packets:74 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:42846621 (40.8 MiB)  TX bytes:9546 (9.3 KiB)

eth4      Link encap:Ethernet  HWaddr 54:4a:16:cd:6e:cc  
          inet addr:192.9.200.5  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::564a:16ff:fecd:6ecc/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:289203 errors:0 dropped:3012 overruns:0 frame:0
          TX packets:57 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:246783569 (235.3 MiB)  TX bytes:8209 (8.0 KiB)
          Interrupt:40

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:112572 errors:0 dropped:0 overruns:0 frame:0
          TX packets:112572 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:50659608 (48.3 MiB)  TX bytes:50659608 (48.3 MiB) 

eth 0..3 - однотипные контроллеры, eth4 - другой.

Соответственно с компа отправляю сообщения таким кодом:

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <pthread.h>

char bufT[8];
FILE *temp;
int end = 0;

void * int_thread (void *arg){ 
    sleep(5);
    end = 1;
}

int main()
{
    int sock_us, sock_pc;
    struct sockaddr_in addr_us;
    struct sockaddr_in addr_pc;
    char buf[16384];
    int bytes_read;
    FILE *test;
    char message[] = "Hello there!\n";
    double var;
    int a, b = 0, c = 0;

/*--  Открытие соккета --*/
    sock_pc = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock_pc < 0)
    {
        perror("socket");
    }


/*--  Настройка соккета --*/
    addr_us.sin_family = AF_INET;
    addr_us.sin_port = htons(35000);
    addr_us.sin_addr.s_addr = inet_addr("192.9.200.2");

/*--  Настройка второго соккета --*/
    addr_pc.sin_family = AF_INET;
    addr_pc.sin_addr.s_addr = htonl(INADDR_ANY);
    addr_pc.sin_addr.s_addr = inet_addr("192.9.200.150");
    b = bind(sock_pc, (struct sockaddr *)&addr_pc, sizeof(addr_pc));

if (b<0)
{
      perror("bind");
}else printf("bind = %d\n", b);
sleep(2);

    pthread_t thread;
      pthread_create (&thread, NULL, int_thread, NULL);
    int bytes, bytes_trans;
int i0 = 0,i1 = 0,i2 = 0;
    while(end == 0){
        i0++;
        if (i0 == 256){
            i0 = 0;
            i1++;
        }
        if (i1 == 256){
            i2++;i1=0;
        }
        buf[0] = i0;
        buf[1] = i1;
        buf[2] = i2;
       
        bytes_trans = sendto(sock_pc, buf, 2048, 0, (struct sockaddr *)&addr_us, sizeof(addr_us));
        bytes = bytes + bytes_trans;
        printf("buf = %x %x %x %x %x %x %x \n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6]);
        printf("send %d bytes\n", bytes);
        usleep(1000);
    }
    return 0;
}

В коде есть некоторые излишки, например bind и другие, потому как перепробовал кучу вариантов и с ними и без них. Чаще всего сообщения адресованные eth0..4 попадают на eth0, но не обязательно, сообщение может придти на любой порт. Куда оно пришло проверяю с помощью ifconfig и проверяю где в поле Rx появились доп мегабайты.

Попробуйте для начала стандартными средствами типа netcat, socat добиться правильного поведения. Для наблюдения за движением пакетов рекомендую использовать «tcpdump -i any port 6666 and udp» или «ngrep -t -e -d any -x port 6666 and udp» (указывая порт, по которому вы шлёте тестовые пакеты).

Andrey_Utkin ★★
()

У тебя все интерфейсы в одной подсети висят. Если нужно получать трафик по всем четырём интерфейсам, лучше сделать bonding. Если не нужно, то оставить только один.

это для начала.

Dark_SavanT ★★★★★
()
Последнее исправление: Dark_SavanT (всего исправлений: 1)
Ответ на: комментарий от LynxChaus

И ТС, скорее всего, получит весёлое кольцо. Не просто ж так, всё в одной подсети они повесил. Хотя, всякое может людям причудиться.

nickleiten ★★★
()

Мало данных, для начала распишите топологию сети. Несколько интерфейсов в одном логической подсети подразумевает общий физический сегмент. Соответственно нужно дать понять системе, что вы от неё хотите. Тут или, как указали выше, бондинг с альясами или ручками маршрутизировать по таблицам.

nickleiten ★★★
()

bind на не локальный адрес можно только с transparent. bind() как раз нужен, чтоб указать явно локальный адрес и/или порт с которого будут передаваться пакеты.

Что у тебя подключено к портам компа ? платы или коммутатор?

vel ★★★★★
()
Ответ на: комментарий от vel

Спасибо всем за ответы! Все пять портов платы и порт компа вставлены в один свитч, от которого так же идет провод во внешнюю сеть.

«tcpdump -i any port 6666 and udp» показывает все как надо, согласно утилите данные приходят на нужный порт, в то время как ifconfig показывает увеличение траффика на другом порте.

Bind нужен если я отправляю с платы, согласен, а с компа то нафига, если на компе всего один интерфейс 192.9.200.150? Добавил на всякий случай конечно, но что с Bind что без него разницы никакой.

Про bonding посмотрел - получается все интерфейсы будут завязаны друг на друге, на данном этапе хотелось бы работать с ними по отдельности.

И подскажите пожалуйста, «ручками маршрутизировать по таблицам» где можно почитать как это делается?

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

Bind нужен если я отправляю с платы, согласен, а с компа то нафига, если на компе всего один интерфейс 192.9.200.150? Добавил на всякий случай конечно, но что с Bind что без него разницы никакой.

Ну это я невнимательно прочитал про конфигурацию.

В твоем случае нужно настраивать всякие arp_filter/arp_announce/arp_accept/rp_filter. Нужно чтоб arp-запросы/ответы строго соответствовали интерфейсам. По-умолчанию ядро использует первый подходящий интерфейс.

«ручками маршрутизировать по таблицам» - зачем оно нужно в данном случае ? Не нужно.

vel ★★★★★
()
Ответ на: комментарий от vel

arp_filter/arp_announce/arp_accept/rp_filter и прочее настроено по умолчанию. Попробовал разные варианты, результат не меняется никак

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

получается все интерфейсы будут завязаны друг на друге

нет, если настроить LACP - всё будет работать, пока жив хотя бы 1 интерфейс

Pinkbyte ★★★★★
()
Ответ на: комментарий от vel

я думаю если у товарища 5 физических интерфейсов, то на управляемый коммутатор с поддержкой LACP он наскребет, не?

Pinkbyte ★★★★★
()
Ответ на: комментарий от Aleksis_92

arp_filter/arp_announce/arp_accept/rp_filter где настраивал ?

Я бы начал с проверки arping-ом c компа на плату, по всем ее адресам. А на плате «tcpdump -nei any arp or udp» смотрел

vel ★★★★★
()
Последнее исправление: vel (всего исправлений: 1)
Ответ на: комментарий от vel

все смотрел/изменял в директории /proc/sys/net/ipv4/conf/eth ок, сейчас гляну команду как с компа чисто arp отправить

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

все смотрел/изменял в директории /proc/sys/net/ipv4/conf/eth

на плате или на компе?

arping - это утилита для выполнения arp-запросов. Единственный недостаток оригинальной версии - нужно явно указывать интерфейс, даже если он в системе один.

vel ★★★★★
()
Ответ на: комментарий от vel
19:40:54.280182  B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
19:40:54.280272 Out 0a:c4:9e:9d:72:f2 ethertype ARP (0x0806), length 44: Reply 192.9.200.1 is-at 0a:c4:9e:9d:72:f2, length 28
19:40:54.280353  B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
19:40:54.280374 Out ea:63:ab:8a:5e:a5 ethertype ARP (0x0806), length 44: Reply 192.9.200.1 is-at ea:63:ab:8a:5e:a5, length 28
19:40:54.280437  B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
19:40:54.280456 Out f6:fe:a2:47:3e:21 ethertype ARP (0x0806), length 44: Reply 192.9.200.1 is-at 0a:f6:fe:a2:47:3e:21, length 28
19:40:54.280520  B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
19:40:54.280539 Out 1a:dd:31:6c:b9:6a ethertype ARP (0x0806), length 44: Reply 192.9.200.1 is-at 1a:dd:31:6c:b9:6a, length 28
19:40:54.280592  B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
19:40:54.280611 Out 54:4a:16:cd:6e:cc ethertype ARP (0x0806), length 44: Reply 192.9.200.1 is-at 54:4a:16:cd:6e:cc, length 28

Приходит запрос, после чего каждый интерфейс на него пытается ответить Mac и IP отправителя определен верно. Откуда взялось ff:ff:ff:ff:ff:ff понятия не имею

Aleksis_92
() автор топика
Ответ на: комментарий от vel

Вот ещё так

 
20:03:54.280592  In 00:1d:60:77:30:1b ethertype ARP (0x0806), length 66: Request who-has 192.9.200.3 (54:4a:16:cd:6e:cc) tell 192.9.200.150, length 50
20:03:54.280611 Out 54:4a:16:cd:6e:cc ethertype ARP (0x0806), length 44: Reply 192.9.200.3 is-at 54:4a:16:cd:6e:cc, length 28
Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

Согласно конфигурации ifconfig 192.9.200.3 не соответствует 54:4a:16:cd:6e:cc, это мак от 192.9.200.5

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

ff:ff:ff:ff:ff:ff - это броадкаст. Без него никак.

То, что ответ приходит с разных МАС-ов - это проблема платы. arp_filter должен быть 1, arp_announce cкорее всего нужно выставить в 2, arp_ignore должно быть 0.

vel ★★★★★
()
Ответ на: комментарий от vel

Настроил arp параметры таким образом, ничего не поменялось. Смотрю arp таблицу, каждый раз создается привязка ip и mac компа к eth0, создаю привязку arp -s 192.9.200.150 mac_pc temp(или pub) -i eth2, после чего автоматически создается ещё одна строка с привязкой к eth0 и все идет на eth0

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

ошибся я - arp_ignore должно быть 1

Я бы на плате выполнил

sysctl net.ipv4.conf.all.arp_filter=1
sysctl net.ipv4.conf.all.arp_announce=2
sysctl net.ipv4.conf.all.arp_ignore=1

(или аналогичные действия в /proc/sys/net/)

vel ★★★★★
()
Последнее исправление: vel (всего исправлений: 1)
Ответ на: комментарий от vel

sysctl net.ipv4.conf.all.arp_filter=1 sysctl net.ipv4.conf.all.arp_announce=2 sysctl net.ipv4.conf.all.arp_ignore=1

Это сделано и all, и по отдельности каждому уже выставлял на всякий

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

Если ты запускаешь tcpdump на компе, то нужно сказать «tcpdump -nei eth0 arp» - для "-i any" там идиотский вывод mac-адресов.

А arping что выводит ?

На плате не плохо бы перед тестами «ip n flush 0/0» делать.

а что за коммутатор в который подключена плата и компом ?

vel ★★★★★
()
Ответ на: комментарий от vel

С новыми настройками при arping на eth0 выдает все нормально, отвечает только тот, кто и должен.Раньше отвечали все.

22:46:24.671635   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
22:46:24.671704   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
22:46:24.671732   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
22:46:24.671757   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
22:46:24.671810 Out ae:fa:1e:a6:6f:69 ethertype ARP (0x0806), length 44: Reply 192.9.200.1 is-at ae:fa:1e:a6:6f:69, length 28
22:46:24.671871   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 66: Request who-has 192.9.200.1 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 50

Однако любые другие интерфейсы (eth1..4) не отвечают вовсе:

22:50:42.070748   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.3 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
22:50:42.070807   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.3 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
22:50:42.070834   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.3 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
22:50:42.070871   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 62: Request who-has 192.9.200.3 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 46
22:50:42.070887   B 00:1d:60:77:30:1b ethertype ARP (0x0806), length 66: Request who-has 192.9.200.3 (ff:ff:ff:ff:ff:ff) tell 192.9.200.150, length 50

ip n flush 0/0 предварительно сделал, разницы не заметил. Planet SW-801 ethernet swith

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

Странный у тебя tcpdump - не показывает mac-и

А если arping запустить на плате ? У него есть возможность указать и устройство и адрес источника.

Отдельно порты на плате проверял ?

vel ★★★★★
()
Ответ на: комментарий от vel

С платы все отправляется верно, с какого порта пишу, с того и идет. (правда для этого приходится делать привязку к маку, в случае кода на си использовать BINDTODEVICE) Для проверки переделал немного топологию - две пары портов замкнул друг на друга (eth5 на eth2, eth3 на eth4), оставшийся порт воткнул в свитч. Все отлично, идет откуда и куда надо, следовательно сами порты работают нормально.

Aleksis_92
() автор топика

Не правильная конфигурация сети. Неясно чего Вы хотели добиться сделав так.

robot12 ★★★★★
()
Ответ на: комментарий от Aleksis_92

А нафига такая хитрая топология? За что идет борьба?

Если хочешь отказоустойчивости, то нужен бондинг (статический или LACP и не забыть про требования к коммутатору ), при этом не нужны адреса на каждый линк (при желании можно повесить несколько алиасов). При этом так же может увеличится пропускная способность.

Либо все линки нужно сделать в отдельных ip-сетях, тогда проблем с ассиметрией не будет.

vel ★★★★★
()

Ну с некоторой точки зрения, проблемы никакой нет. Сообщение доставлено хосту, имеющему указанный IP адрес. IP протокол существует для взаимодействия компьютеров, а интерфейсы лишь средство. Описанная конфигурация, скажем «странная». Если попытаетесь описать конечную цель, то возможно коллективный разум подскажет, как решать задачу. Если же хочется разобраться почему в этой ситуации происходит именно так - это другой вопрос.

Elyas ★★★★★
()
Ответ на: комментарий от vel

На данном этапе задачей является тестирование ethernet модулей, их пропускной способности, плюс загрузки процессора при работе с ними. Я правильно понял, что для решения данной задачи будет иметь смысл разнести интерфейсы по сетям? Пробовал задать интерфейсу ip адрес отличный от остальных полностью, а не только в последнем байте, интерфейс становится недоступным, так как он оказывается в другой сети, и как с ним связаться хз

Aleksis_92
() автор топика
Ответ на: комментарий от Aleksis_92

Пробовал задать интерфейсу ip адрес отличный от остальных полностью, а не только в последнем байте, интерфейс становится недоступным, так как он оказывается в другой сети, и как с ним связаться хз

дык алиас из нужной сети

на плате

ip addr add 10.x.0.1/24 dev eth0
ip addr add 10.x.1.1/24 dev eth1
ip addr add 10.x.2.1/24 dev eth2
ip addr add 10.x.3.1/24 dev eth3
на компе
ip addr add 10.x.0.2/24 dev eth0
ip addr add 10.x.1.2/24 dev eth0
ip addr add 10.x.2.2/24 dev eth0
ip addr add 10.x.3.2/24 dev eth0

vel ★★★★★
()
Ответ на: комментарий от Aleksis_92

Правильным решением будет соединить тестируемую плату с компьютером, имеющим дополнительные 5 сетевых портов(помимо основного рабочего). При прочих вариантах будет не так просто понять, что именно вы тестируете, то ли плату, то ли коммутатор. Если проверять нагрузки вблизи потолка пропускной способности сети не нужно, тогда можно придумать и что-то менее затратное по железу, но более сложное по логике, настройке и интерпретации результатов.

Elyas ★★★★★
()
Ответ на: комментарий от Elyas

Согласен, однако пока такой возможности нет, как промежуточный тест сойдет

Aleksis_92
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.