LINUX.ORG.RU

Alloc_netdev возвращает битую структуру

 ,


0

2

Всем привет! Столкнулся с проблемой про разработке под Астру 1.6. В точке входа драйвера вызываю ф-ию alloc_netdev, в результате получаю указатель на структуру, в которой поле dev_addr - NULL. Если в дальнейшем передавать ее в ф-ию register_netdev, получаю логичный null reference и сообщение «Убито» в терминале. Подскажите, сталкивался ли кто нибудь с такой проблемой? P.s. пробовал разные вариации аргументов в allo_netdev, результат один и тот же. А еще в астре 1.7 и на других машинах с 1.6 все отрабатывает корректно, а на этой нет.

Ответ на: комментарий от IIIypuk

Если я правильно понял вы пытаетесь работать с сетевым интерфейсом и делаете что-то типа:

static void setup_ether(struct net_device *dev)
{
  dev->needs_free_netdev = true;
}

struct my_device_priv *priv;

dev = alloc_netdev(sizeof(*priv), "eth%d", NET_NAME_UNKNOWN, setup_ether);

Покажите что у вас в setup_ether и какие параметры в alloc_netdev, а то ее по всякому вызывать можно.

Obezyan
()
Ответ на: комментарий от firkax

Убивается insmod если драйвер не инициализируется. Ну типа ядро не прям совсем уж монолитное и «тупое», какие-то классы ошибок в модулях его не прибивают.

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

Фактически, так код и выглядит. Он рабочий, эта проблема проявляется только на некоторых машинах с Астрой 1.6. Я склоняюсь к тому, что какой то компонент Астры убивает сетевой стек, но пока не могу понять, какой.

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

Вы не указали версию ядра. Проверьте, есть ли макрос NET_NAME_UNKNOWN, если нет то попробуйте:

#ifndef NET_NAME_UNKNOWN
    #undef alloc_netdev
    #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
        #define alloc_netdev(sizeof_priv, name, name_assign_type, setup) alloc_netdev(sizeof_priv, name, setup)
    #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
        #define alloc_netdev(sizeof_priv, name, name_assign_type, setup) alloc_netdev_mq(sizeof_priv, name, setup, 1)
    #else
        #define alloc_netdev(sizeof_priv, name, name_assign_type, setup) alloc_netdev_mqs(sizeof_priv, name, setup, 1, 1)
    #endif
#endif

Если же есть и все равно не работает, то попробуйте вручную для теста заполнить dev_addr в setup() функции:

/* Fill in the MAC address with '00:01:02:03:04:05' */
for (i = 0; i < ETH_ALEN; ++i) {
   dev->dev_addr[i] = (char)i;
}

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

Вы также ничего не указали о типе устройства к которому пишете сетевой драйвер, подозреваю что обычный ethernet. В этом случае логично использовать вызов alloc_etherdev() который по идее сам должен вызвать ether_setup() и заполнить dev_addr MAC адресом интерфейса.

И сравните сетевые карты, на машинах там где работает код и там где нет, я к тому что это может влиять.

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

Добрый день! Макрос NET_NAME_UNKNOWN имеется, без него не собрался бы. alloc_etherdev пробовал, результат тот же, dev_addr - Null. В ф—ию setup() сваливается net_device*, у которого поле dev_addr уже null, не могу туда копировать данные. Пробовал аллокировать память вручную, передавал структуру в register_netdev, снова получал null reference, судя по всему какое то другое поле тоже null.

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

Ты уверен, что у тебя ядро соответствует исходникам ядра?

https://wiki.astralinux.ru/pages/viewpage.action?pageId=53646577&ysclid=m...

астра-1.6 это вообще не уточнение. Там ядра от 4.15 до 5.15, а там сетевая часть существенно менялась начиная с 5.10

астра-1.7 - туда же.

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

Добрый день, у вас ядро 4.15.3-1. Для ядер 5.15 и выше есть макрос:

#define dev_addr_set(netdev, ethdata) eth_hw_addr_set(netdev, ethdata)

Сама функция eth_hw_addr_set

До 5.15 использовались костыли с memcpy. Т.к. я ваш код не видел то не знаю использовали ли вы его, скорее всего нет. Ядро 4.15 это как раз до добавления нового уровня абстракции для заполнения dev_addr с помощью хелперов.

Рекомендации:

  1. Сравнить версии ядер там где работает с тем где не работает. Возможно, там ядра версии выше чем 4.15.

  2. Сравните модели сетевых карт (интересуют чипы) там где код работает и там где не работает. Если они отличаются, то рискну предположить что не работает на какой-нибудь карте с чипом типа rtl8192e которые имели проблемы на старых ядрах.

Лично я бы обновился до 5.15 или выше и все бы заработало, но не знаю по какой причине вы этого еще не сделали. Ваше ядро устарело на 2 мажорные версии, это много.

Obezyan
()