netif_nit_deliver

Взгляд изнутри

Модератор: Модераторы разделов

featurelles
Сообщения: 8

netif_nit_deliver

Сообщение featurelles »

вопрос касается функции netif_nit_deliver ( net/core/dev.c )
Код:

Код: Выделить всё

void netif_nit_deliver(struct sk_buff *skb)
{
    struct packet_type *ptype;

    if (list_empty(&ptype_all))
        return;

    skb_reset_network_header(skb);
    skb_reset_transport_header(skb);
    skb->mac_len = skb->network_header - skb->mac_header;

    rcu_read_lock();
    list_for_each_entry_rcu(ptype, &ptype_all, list) {
        if (!ptype->dev || ptype->dev == skb->dev)
            deliver_skb(skb, ptype, skb->dev);
    }
    rcu_read_unlock();
}

Интересует вот этот участок:
list_for_each_entry_rcu(ptype, &ptype_all, list) {
if (!ptype->dev || ptype->dev == skb->dev)
deliver_skb(skb, ptype, skb->dev);
}

list_for_each_entry_rcu определён как #define в include/linux/rculist.h
Код:

Код: Выделить всё

/**
 * list_for_each_entry_rcu    -    iterate over rcu list of given type
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 *
 * This list-traversal primitive may safely run concurrently with
 * the _rcu list-mutation primitives such as list_add_rcu()
 * as long as the traversal is guarded by rcu_read_lock().
 */
#define list_for_each_entry_rcu(pos, head, member) \
    for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
        prefetch(pos->member.next), &pos->member != (head); \
        pos = list_entry_rcu(pos->member.next, typeof(*pos), member))

теперь посмотрим на структуру struct packet_type
Код:

Код: Выделить всё

struct packet_type {
    __be16            type;    /* This is really htons(ether_type). */
    struct net_device    *dev;    /* NULL is wildcarded here         */
    int            (*func) (struct sk_buff *,
                     struct net_device *,
                     struct packet_type *,
                     struct net_device *);
    struct sk_buff        *(*gso_segment)(struct sk_buff *skb,
                        int features);
    int            (*gso_send_check)(struct sk_buff *skb);
    struct sk_buff        **(*gro_receive)(struct sk_buff **head,
                           struct sk_buff *skb);
    int            (*gro_complete)(struct sk_buff *skb);
    void            *af_packet_priv;
    struct list_head    list;
};

Она содержит struct list_head list значит можем листать связанный список


Меня интересует, вот что.
Почему при компиляции модуля, выдаётся ошибка:
В функции ‘netif_nit_deliver’:
ошибка: ‘struct packet_type’ не содержит элемента с именем ‘next’

и указана строка вот этого участка: list_for_each_entry_rcu(ptype, &ptype_all, list) {

Из определения #define list_for_each_entry_rcu(pos, head, member) видно, что for (pos = list_entry_rcu((head)->next, typeof(*pos), member); Тоесть элемент next выбирается из аргумента ptype структуры struct packet_type, хотя по всей видимости должен выбираться из элемента list. И потому выдаётся ошибка.
Но ведь это код ядра! kernel-linus-2.6.31.6, значит должно быть всё верно. Я совсем запутался, почему такая ошибка вылезает?????


И ещё, я в своём модуле, использую многие функции из /net/core/dev.c , чтоб нормально компилировался модуль. мне приходится копировать данные функции к себе в код(если этого не сделать то, функция будет undefined!!!!). Можно ли сделать так? чтоб при компиляции сборка происходила корректно, и чтоб компилятор, всёже находил нормально тела функций и их прототипы из .c файлов ядра.
Спасибо сказали: