cs8900网卡驱动简要解析(6)

是时候讲解数据收发的时候了。用来接收数据的函数是cs8900_receive,它在上文中出现过。那么数据如何处理的?简单的说,1)把数据放到skb中,2)执行netif_rx 函数。

skb又是什么?它是网络设备驱动中,和net_device一样重要的数据结构。skb就是sk_buff结构,也就是套接字缓冲区。它在skbuff.h中定义。有多重要呢?不描述了,干脆把代码列出来,虽然有点长,但毕竟也不是书,大家就忍了吧。反正这个结构是必须清楚的。

 

struct sk_buff {

         /* These two members must be first. */

         struct sk_buff               *next;

         struct sk_buff               *prev;

 

         struct sock                    *sk;

         ktime_t                          tstamp;

         struct net_device           *dev;

 

         struct  dst_entry          *dst;

         struct sec_path              *sp;

 

         /*

          * This is the control buffer. It is free to use for every

          * layer. Please put your private variables there. If you

          * want to keep them across layers you have to do a skb_clone()

          * first. This is owned by whoever has the skb queued ATM.

          */

         char                     cb[48];

 

         unsigned int         len,

                                     data_len;

         __u16                  mac_len,

                                     hdr_len;

         union {

                   __wsum     csum;

                   struct {

                            __u16         csum_start;

                            __u16         csum_offset;

                   };

         };

         __u32                  priority;

         __u8                    local_df:1,

                                     cloned:1,

                                     ip_summed:2,

                                     nohdr:1,

                                     nfctinfo:3;

         __u8                    pkt_type:3,

                                     fclone:2,

                                     ipvs_property:1,

                                     peeked:1,

                                     nf_trace:1;

         __be16                protocol;

 

         void                     (*destructor)(struct sk_buff *skb);

#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)

         struct nf_conntrack       *nfct;

         struct sk_buff               *nfct_reasm;

#endif

#ifdef CONFIG_BRIDGE_NETFILTER

         struct nf_bridge_info    *nf_bridge;

#endif

 

         int                        iif;

#ifdef CONFIG_NETDEVICES_MULTIQUEUE

         __u16                           queue_mapping;

#endif

#ifdef CONFIG_NET_SCHED

         __u16                           tc_index;    /* traffic control index */

#ifdef CONFIG_NET_CLS_ACT

         __u16                           tc_verd;      /* traffic control verdict */

#endif

#endif

         /* 2 byte hole */

 

#ifdef CONFIG_NET_DMA

         dma_cookie_t               dma_cookie;

#endif

#ifdef CONFIG_NETWORK_SECMARK

         __u32                           secmark;

#endif

 

         __u32                           mark;

 

         sk_buff_data_t              transport_header;

         sk_buff_data_t              network_header;

         sk_buff_data_t              mac_header;

         /* These elements must be at the end, see alloc_skb() for details.  */

         sk_buff_data_t              tail;

         sk_buff_data_t              end;

         unsigned char               *head,

                                              *data;

         unsigned int                  truesize;

         atomic_t                        users;

};

 

也许你看到这个庞大的结构(实际上它并不是很庞大)有些晕!但是更令人晕的是内核把sk_buff组织成一个双向链表。而且这个链表的结构要比常见的双向链表的结构还要复杂。sk_buff中用两个指针(nextprev)表示前后一个节点。这个链表还有另一个需求:每个sk_buff结构都必须能够很快找到链表头节点。为了满足这个需求,在第一个节点前面会插入另一个结构sk_buff_head,这是一个辅助节点。在Linux内核世界中,图示永远比代码好理解,所以你要善于看图说话。

本来我很想多介绍一下skb,但是又怕那将令大家再一次陷入内核的迷雾,所以还是见好就收吧。你现在知道,网卡传输数据离不开skb,因此我们需要填充这个skb。当skb搞定后,只要下面一句就可以:

    netif_rx (skb);

它把skb扔到了上层。netif_rx函数原型在net/core/dev.c中,它有两个返回值:

NET_RX_SUCCESS  (no congestion)

NET_RX_DROP     (packet was dropped)

 

一句话总结:网卡的数据接收是通过netif_rx完成的,而传递给netif_rx的是一个包含数据的socket buffer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值