关闭

Linux协议栈对vlan的处理

4331人阅读 评论(0) 收藏 举报
分类:
(基于linux-2.6.x)

从代码上看,Linux对VLAN的处理方式如下。


1. vlan的处理,主要是依靠网卡本身。
   有的网卡不支持vlan,如老的3com网卡3c501。
   intel的ixgb(PRO/10GbE)和e1000(PRO/1000)网卡是支持vlan的。
   其他的一些网卡驱动,从代码上来看,还未完整支持。
   例如,有个网卡驱动(源码文件:drivers\net\spider_net.c),
   vlan相关代码上的注释上说,/* further enhancement... yet to do */


2. 网卡对vlan的处理
   VLAN tag插入/移除 都是由网卡完成的。
   vlan报文的过滤也是由网卡完成的。
   Linux协议栈通过驱动中的接口,注册vlan相关信息。
   驱动再将这些信息写到芯片中。

   因此,网卡驱动从网卡接收队列中收到的报文,已经不带VLAN tag了。

下面是r8169.c网卡驱动收到报文后,做的部分处理。

由于驱动收到的报文,已经不带vlan tag,因此skb->protocol的值就是普通的以太网类型。

skb->protocol = eth_type_trans(skb, dev);

rtl8169_rx_vlan_tag(desc, skb);

if (likely(polling))
napi_gro_receive(&tp->napi, skb);
else
netif_rx(skb);

dev->stats.rx_bytes += pkt_size;
dev->stats.rx_packets++;

再看看rtl8169_rx_vlan_tag干了什么。下面贴出相关代码:

/**
 * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting
 * @skb: skbuff to tag
 * @vlan_tci: VLAN TCI to insert
 *
 * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest
 */
static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
						     u16 vlan_tci)
{
	skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci;
	return skb;
}

static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
{
	u32 opts2 = le32_to_cpu(desc->opts2);

	if (opts2 & RxVlanTag)
		__vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff));

	desc->opts2 = 0;
}

从注释及代码可以看出,就是将vlan_tci记录到skb中,这样协议栈能知道这个报文的vlan信息,从而进行相应的处理。

因为vlan tag被硬件剥掉了,软件不知道vlan信息,因此这里的代码将剥掉的vlan信息记录到SKB中,供协议栈使用。





3. Linux对vlan报文的处理(VLAN tag已经剥掉了)


   上一步的工作完成后,接下来的工作有两种情况。


   a)报文不是vlan报文,则驱动程序调用netif_receive_skb对报文进行处理。
     其处理流程在《Linux协议栈代码阅读笔记(三)报文接收》中有描述。


   b)报文是vlan报文(不过已经不带VLAN tag了),则驱动程序调用vlan_hwaccel_receive_skb对报文进行处理,vlan tag通过     参数传递给vlan_hwaccel_receive_skb。
     vlan_hwaccel_receive_skb则简单的以如下形式调用__vlan_hwaccel_rx。
     __vlan_hwaccel_rx(skb, grp, vlan_tag, 1);


     __vlan_hwaccel_rx先根据vlan tag为报文做优先级赋值。
     然后将低层代码误以为vlan报文的目的mac不是本机的错误纠正过来。

     接下来,__vlan_hwaccel_rx调用netif_receive_skb。这就将处理流程收敛到与a)相同的路线上去了:)





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:408648次
    • 积分:4579
    • 等级:
    • 排名:第6425名
    • 原创:120篇
    • 转载:2篇
    • 译文:0篇
    • 评论:53条
    最新评论