Linux系统内核接收以太帧的处理程序

文章作者 100test 发表时间 2007:03:14 16:55:51
来源 100Test.Com百考试题网


1. 前言

以太头中除了6字节目的MAC地址、6字节源MAC地址外,还有两字节的以太帧类型值,如IPv4为0x0800,ARP为0x0806等,网卡驱动收到以太帧后通过接口函数netif_receive_skb()(netif_rx实际最后也是调用netif_receive_skb)交到上层,而这个接口函数就完成对以太帧类型的区分,交到不同的协议处理程序。如果想自己编写某一以太类型帧的处理程序,需要自己添加相应的代码。以下为Linux内核2.6代码。

2. 数据结构

每种协议都要定义一个packet_type结构,引导进入相关的协议数据处理函数,所有节点组成一个链表(HASH链表)。


/* include/linux/netdevice.h */

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 *).

void *af_packet_priv.

struct list_head list.

            }.

参数说明:

type:以太帧类型,16位。

dev:所附着的网卡设备,如果为NULL则匹配全部网卡。

func:协议入口接收处理函数。

af_packet_priv:协议私有数据。

list:链表扣。

一般各协议的packet_type结构都是静态存在,初始化时只提供type和func两个参数就可以了,每个协议在初始化时都要将此结构加入到系统类型链表中。

3. 处理函数

3.1 添加节点

/* net/core/dev.c */

/**

* dev_add_pack - add packet handler

* @pt: packet type declaration

*

* Add a protocol handler to the networking stack. The passed &.packet_type

* is linked into kernel lists and may not be freed until it has been

* removed from the kernel lists.

*

* This call does not sleep therefore it can not 

* guarantee all CPUs that are in middle of receiving packets

* will see the new packet type (until the next received packet).

*/

void dev_add_pack(struct packet_type *pt)

{

int hash.

spin_lock_bh(&.ptype_lock).

// 如果类型是全部以太类型,则节点链接到ptype_all链

if (pt->type == htons(ETH_P_ALL)) {

netdev_nit  .

list_add_rcu(&.pt->list, &.ptype_all).

} else {

// 根据协议类型取个HASH,共15个HASH链表

hash = ntohs(pt->type) &. 15.

// 将节点链接到HASH链表中,list_add_rcu是加了smp_wmb()保护的list_add链表操作

list_add_rcu(&.pt->list, &.ptype_base[hash]).

}

spin_unlock_bh(&.ptype_lock).

            }


相关文章


嵌入式Linux系统的GDB远程调试的实现
用命令行加挂Linux的文件系统简介
Linux系统内核接收以太帧的处理程序
Linux系统利用SSH远程控制安全问题
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛