Код:
Код: Выделить всё
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 файлов ядра.