Jump to content
    

Драйвер сетевого устройства linux.

Всем привет! Пришлось писать драйвер сетевого устройства. Тк, в драйверах я новичок, то встал в тупик. Может кто подскажет? В чем суть: в каком-то объеме драйвер написан. Он принимает пакеты от железяки и кладет их в skb. В wireshark-е я эти пакеты вижу, однако, никакая софтина кроме wireshark-а и ostinsto эти пакеты принять не может. Те, как я понимаю, дальше вврерх по сетевому стеку они не идут. Я не понимаю - почему? В чем может быть причина? В какую сторону копать?

Share this post


Link to post
Share on other sites

1 hour ago, makc said:

netif_rx вы вызываете?

Например, как это делается в https://github.com/IMCG/LDD/blob/master/snull/snull.c и описано в https://dmilvdv.narod.ru/Translate/LDD3/ldd_packet_reception.html

Да, конечно. Точнее:

netif_receive_skb и napi_complete_done

 

Share this post


Link to post
Share on other sites

9 часов назад, Vain сказал:

Те, как я понимаю, дальше вврерх по сетевому стеку они не идут. Я не понимаю - почему? В чем может быть причина? В какую сторону копать?

Тогда напрашивается мысль, что могут быть искажены данные в самих пакетах. Вы сравнивали то, что получает Wireshark с тем, что было отправлено? Побайтовое сравнение делали?
PS: Мак-адрес интерфейса на приёме, надеюсь, совпадает с мак-адресом назначения в пакете?

Share this post


Link to post
Share on other sites

Пингов нет,  арп нет, потому что железяка пока не умеет. Пытаюсь прописать mac в arp таблицу вручную arp -s IP_addr MAC_addr, получаю:

SIOCSARP: Недопустимый аргумент
Чего-то в драйвере не хватает. Чего? hard_header вроде переопределил.

Share this post


Link to post
Share on other sites

Покажите, что выдает команда "ip -s l".

5 часов назад, Vain сказал:

SIOCSARP: Недопустимый аргумент
Чего-то в драйвере не хватает. Чего? hard_header вроде переопределил.

Ещё стоит посмотреть, что ядро пишет в dmesg. Приложите лог dmesg в виде файла.

Share this post


Link to post
Share on other sites

ip -s l

7: png0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 9144 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 73:02:01:76:05:04 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast           
          5512      85      0       0       0       0 
    TX:  bytes packets errors dropped carrier collsns           
        523758     638      0       0       0       0 
8: png1: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 9144 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 73:02:01:77:05:04 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast           
        469489     571      0       0       0       0 
    TX:  bytes packets errors dropped carrier collsns           
          2902      18      0       0       0       0 
 

dmesg ничего интересного, там либо сообщения драйвера,  либо если что-то крашется. 

Предполагаю, что не совпадают crc заголовков. Сейчас пытаюсь пересчитать их в ядре.

Share this post


Link to post
Share on other sites

14 минут назад, Vain сказал:

7: png0: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 9144 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000

Меня смущает выделенное жирным. Без ARP у вас сеть работать не будет... Мне кажется нужно копать в этом направлении настройки флагов netdev->features и около.

Share this post


Link to post
Share on other sites

Поправил crc. Ничего не изменилось. Arp в железяке нету. Потому и стоит флаг NO_ARP. Пакеты шлю мультикастовые c адресом 224 и маком 0x01005E. Да, мне тоже не нравится что нет arp, но ни tcp ни udp стека в железяке нету, по сути - это петля, принимает пакеты, меняет в пакете ip адрес, mac и порт, и отправляет на другой интерфейс. Пытался решить проблему отсутствия arp, прописав mac в arp таблицу вручную  arp -s IP_addr MAC_addr, на что получаю SIOCSARP: Недопустимый аргумент. Отсюда вопрос: чего не хватает драйверу что ядро  так ругается на arp -s? Какой метод драйвера должен вызывать запрос arp -s? Ставил prink, ни ndo_eth_ioctl, ни ndo_do_ioctl, ни set_klink_settings при этом не вызываются. Может какой флаг нужен?

Share this post


Link to post
Share on other sites

3 часа назад, Vain сказал:

Поправил crc. Ничего не изменилось. Arp в железяке нету. Потому и стоит флаг NO_ARP.

Я не понимаю, как вы хотите, чтобы работал приём в прикладном ПО, работающем на 99% поверх IP-стека, который без ARP не работает? Сырой прием пакетов у вас отрабатывается нормально, что логично. Но сетевого стека в операционной системе для этого интерфейса как бы нет...

Share this post


Link to post
Share on other sites

2 hours ago, makc said:

который без ARP не работает?

Статическая таблица arp, созданная вручную. Собственно, пакеты пошли, хотя и с потерями, но это баги в драйвере. Поставил флаги неразборчивости и алмультикаст, изменил адрес с мультикастового на обычный. Vlc даже картинку временами пытается показывать. Пока так. Буду дальше разбираться.

Всем спасибо за советы! Но тему не закрываю. Вопросы еще точно  будут.

Share this post


Link to post
Share on other sites

Коллеги! А кто-нибудь знает как задействовать RPS(recive packet steering)? 

У меня сейчас есть проблема с потерями пакетов. Пакеты принимаются от железяки драйвером нормально, кладутся в skb, и отдаются дальше по сетевому стеку, примерно так:

Вариант 1)

// здесь пакеты уже получены и положены в skb 

for(int i = 0; i < num; i++){

      ret = netif_receive_skb(skb);  

}

napi_complete(napi);  

Так пакеты теряются. Если сделать так:

Вариант 2)

// здесь пакеты уже получены и положены в skb 

msleep(num);

for(int i = 0; i < num; i++){

      ret = netif_receive_skb(skb);  

}

msleep(num);

napi_complete(napi);  

То тоже теряются, а если так то все в порядке:

Вариант 3)

// здесь пакеты уже получены и положены в skb 

for(int i = 0; i < num; i++){

      ret = netif_receive_skb(skb);  

     msleep(1);

}

napi_complete(napi);  

Функция netif_receive_skb всегда возвращает RX_SUCCESS, т.е. потери происходят где-то дальше, за функцией  netif_receive_skb. Скорее всего, ядро не поспевает обработать переданные ему пакеты и часть из них отбрасывает. 

Поэтому я стал копать в сторону RPS, но не понимаю как эту технологию задействовать. В файле /sys/class/net/png0/queues/rx-0/rps_cpus  всегда 0. Править файл напрямую - нельзя. В net_device есть поле num_rx_queues, изменял - не помогло.

Правильно я понимаю, нужно в драйвере до регистрации сетевого устройства, где-то подправить атрибут этого устройства? 

Share this post


Link to post
Share on other sites

В структуре net_device есть поля:

    const struct attribute_group *sysfs_groups[4];
    const struct attribute_group *sysfs_rx_queue_group;   

Т.е. исправить атрибуты я не смогу. Тогда совсем непонятно.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...