Linux协议栈对vlan的处理

原创 2013年12月02日 16:11:00
(基于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)相同的路线上去了:)





版权声明:本文没有任何版权限制,任何人可以以任何方式使用本文。

linux内核网络协议栈学习笔记:vlan

这篇是我临时加的,本来不打算放在整个内核协议栈分析的系列里的,但我现在觉得vlan还是蛮重要的,而且讨论vlan源码的文章很少,不知道我这篇算不算第一篇 :D vlan的代码都在net/8021q/...

Linux 802.1Q VLAN网络报文收发分析

 前段时间对新版Linux Kernel处理VLAN网络报文存在些疑惑,现对linux-4.4.4内核VLAN处理粗略的分析解除疑惑,即新版Linux内核在__netif_receive_s...

TCPDump抓取vlan/pppoe等数据帧的规则

http://lumte.com:84/archives/2014/05/19/422.html TCPDump抓取vlan/pppoe等数据帧的规则 撰写于2014-05-19 17:08...

linux VLAN配置(vconfig)

1.安装vlan(vconfig)和加载8021q模块 #aptitude install vlan #modprobe 8021q 或: #yum install vconfig #modpro...

Linux实现的IEEE 802.1Q VLAN

第一部分:VLAN的核心概念说起IEEE 802.1q,都知道是VLAN,说起VLAN,基本上也没有盲区,网络基础。然而说到配置,基本所有人都能顺口溜一样说出Cisco或者H3C设备的配置命令,对于L...
  • dog250
  • dog250
  • 2012年03月14日 21:12
  • 34530

Linux bridge和vlan配置案例

linux bridge

Linux下VLAN功能的实现

1.Linux网络栈下两层实现 1.1简介     VLAN是网络栈的一个附加功能,且位于下两层。首先来学习Linux中网络栈下两层的实现,再去看如何把VLAN这个...

网络数据包接收之GRO处理

驱动把数据包上传到GSO处理时,调用流量调度算法

linux VLAN配置(vconfig)

1.安装vlan(vconfig)和加载8021q模块  #aptitude install vlan  #modprobe 8021q 或: #yum install vconfig #m...

Linux vlan 功能模块分析

Vlan即虚拟局域网,一个vlan能够模拟一个常规的交换网络,实现了将一个物理的交换机划分成多个逻辑的交换网络。而不同的vlan之间如果要进行通信就要通过三层协议来实现。   在linux中vlan的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux协议栈对vlan的处理
举报原因:
原因补充:

(最多只允许输入30个字)