转:http://blog.csdn.net/u010246947/article/details/18224517

4.6、VLAN处理:

4.6.1、vlan原理

对于带vlan的以太网报文,其以太网类型为0x8100,所以链路层中对于带vlan报文的处理就是对于以太网类型为0x8100的报文的处理;

vlan,用于在链路层划分广播域,实现数据在链路层分流,在二层交换机中,vlan实际行使其功能是体现在uni端口上,通过在端口上配置能通过 哪些vlan,实现不同的端口可以通行不同的数据流,比如二层交换机的端口有的是access端口,即配置为只能通过一个vlan,有的是trunk端 口,即配置为可通过多个vlan(很多二层网络设备可能还有其他的叫法,如raisecom设备根据CTC标准端口可配置为透传模式、翻译模式、 trunk模式、tag模式等,但本质含义相似,都是在配置能通过哪些vlan),二层交换机的vlan处理如下图:

在上图中,发出报文带有vlan10、20、30的PC分属不同的广播域,即比如发出报文带vlan20的PC如果连在交换机的红色端口上,那么报
文会被交换机直接过滤掉,因为红色端口不能通过vlan20的报文,所以如果发出报文带vlan20的某蓝色PC发出广播包,那么所有其他的蓝色PC都能
收到这个广播包,而其他PC无法收到,这就是划分广播域。

Linux的vlan处理与之相似,每个接口相当于二层交换机的每个物理端口,同样由用户给不同端口配置其可通过的不同的vlan,当带有某vlan的报文进入某接口时,通过检测该接口是否存在该vlan的vlan子接口决定是否可通行此报文,可以理解为,linux对vlan的处理就是通过vlan子接口的方式,实现二层交换机端口vlan的功能。

4.6.2、linux的vlan处理:

linux的vlan处理源码在代码树net/8021q/目录下,核心文件是vlan.c和vlan_dev.c;

linux的vlan处理和网桥处理很相似,在接收方向上,链路层收到带vlan报文后先进入vlan模块处理,然后在找到对应的vlan子接口后,更新
报文输入接口为vlan子接口并剥除vlan,然后把该报文打回链路层重新处理,上层协议栈可见的是该报文从vlan子接口接收;在发送方向上,上层协议
栈把报文由vlan子接口发送,继而再通过其原始接收的宿主接口发送出去,以带vlan10的报文为例,下图串联了带vlan报文的接收和发送:

vlan模块在内核的初始化由函数vlan_proto_init完成,它包括如下内容:

1、  在内核中注册以太网类型值为0x8100的ptype(处理函数为vlan_skb_recv)

2、  注册linux对于vlan的ioctl接口,典型如vconfig使用它

3、  初始化linux的vlan值集合功能,它用于记录宿主设备的vlan子接口的功能

4、  注册linux的vlan相关的proc接口,即/proc/net/vlan;

5、  注册linux对于vlan相关的routenetlink接口;

6、  注册linux的vlan相关的内核通知链;

我们已经知道linux的vlan处理就是根据二层交换机vlan原理实现的,其本质就是接口的vlan子接口的实现,下面就通过vconfig工具创建vlan子接口的过程描述:

vconfig工具在内核中首先调用vlan_ioctl_handler函数,对于创建vlan子接口的操作,调用函数
register_vlan_device,参数是用户输入的宿主接口和vlan值,如宿主接口是eth0、vlan值是10,那么就是说在接口eth0
中加入一个vlan子接口eth0.10,意思就是说接口eth0允许带vlan10的报文通过;

vlan型接口的私货是结构体vlan_dev_info,它里边最重要的字段就是记录了宿主接口和vlan值,此外和网桥型接口一样,vlan型
接口在内核中也有专用的ops,在vlan_dev.c文件中定义了全局变量vlan_netdev_ops,它规定了vlan型接口的ops,比较需要
注意的就是它的发送方法vlan_dev_hard_start_xmit,其他方法和普通接口区别不大;

创建的vlan子接口继承了其宿主接口的MAC地址、MTU,最终由函数register_vlan_dev把该vlan子接口注册进内核,并且同时在宿主接口中记录该vlan子接口,

这里注意下内核通过结构体vlan_group描述每个宿主接口都有哪些vlan子接口,在vlan模块中通过内部函数
__vlan_find_group查找定位,外部函数__find_vlan_dev供查找某接口是否存在某vlan值的vlan子接口,这就是
vlan报文处理函数vlan_skb_recv一上来就要判断的,判断该宿主接口是否存在该vlan值的子接口,即是否允许带该vlan的报文通过;

如果不允许通过则就此丢弃该报文,否则说明可以通过,先将报文的输入接口(skb->dev重置为vlan子接口),再将vlan标签剥除
(vlan_check_reorder_header),再打回链路层重新处理(netif_rx),这样再处理时上层协议栈认为该报文由vlan子接
口进入的;

所以对于该报文的回复报文,上层协议栈也会把它从该vlan子接口发送,这将调用vlan型接口的发送函数
vlan_dev_hard_start_xmit,它将根据vlan子接口找到其宿主接口,更新报文的出接口(skb->dev)为宿主接口,最
终调用dev_queue_xmit把报文从宿主接口发送出去。

事实上linux只实现了二层交换机的最简单的vlan功能,主要是CPU并不直接做二层转发,二层转发是由硬件完成的,但是二层的很多qos功能由
vlan实现,带不同vlan的报文走不同的业务通道,比如vlan10在二层转发中所走通道比其他vlan更快,那么重要报文会加上vlan10的标
签,也许这样的报文需要上CPU处理,所以linux需要能够识别vlan。

 

linux网络协议栈(四)链路层 vlan处理的更多相关文章

  1. Linux网络协议栈(四)——链路层(1)

    1.接收帧当网络适配器接收到数据帧时,就会触发一个中断,中断处理程序执行一些需要及时处理的任务,然后在下半部进行其它可以延迟的处理.中断处理程序主要进行以下一些操作:(1)    分配sk_buff数 ...

  2. Linux网络协议栈(四)——链路层(2)

    2.协议相关2.1.第3层协议的管理在Linux内核中,有两种不同目的的3层协议:(1)    ptype_all管理的协议主要用于分析目的,它接收所有到达第3层协议的数据包.(2)    ptype ...

  3. 理解 Linux 网络栈(1):Linux 网络协议栈简单总结

    本系列文章总结 Linux 网络栈,包括: (1)Linux 网络协议栈总结 (2)非虚拟化Linux环境中的网络分段卸载技术 GSO/TSO/UFO/LRO/GRO (3)QEMU/KVM + Vx ...

  4. linux网络协议栈--路由流程分析

    转:http://blog.csdn.net/hsly_support/article/details/8797976 来吧,路由 路由是网络的核心,是linux网络协议栈的核心,我们找个入口进去看看 ...

  5. Linux 网络协议栈开发基础篇—— 网桥br0

    一.桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口"连接"起来.其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去.以使得网口之间的报文能够互相转发. 交换机 ...

  6. (转)Linux网络协议栈(三)——网络设备(1)

    网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1)    作为基于硬件的网络适配器与基于软件的协 ...

  7. Linux网络协议栈(三)——网络设备(1)

    网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1)    作为基于硬件的网络适配器与基于软件的协 ...

  8. 由PPPOE看Linux网络协议栈的实现

    http://www.cnblogs.com/zmkeil/archive/2013/05/01/3053545.html 这个标题起得比较纠结,之前熟知的PPPOE是作为PPP协议的底层载体,而实际 ...

  9. Linux网络栈下两层实现

    http://www.cnblogs.com/zmkeil/archive/2013/04/18/3029339.html 1.1简介 VLAN是网络栈的一个附加功能,且位于下两层.首先来学习Linu ...

随机推荐

  1. openstack部署dashboard

    1.下载安装包 yum install openstack-dashboard 2.编辑配置文件 cp /etc/openstack-dashboard/local_settings /etc/ope ...

  2. ssm整合的springmvc.xml的配置

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  3. SpringMVC,SpringBoot上传文件简洁代码

    @RequestMapping("/updateAvatar.html") public String updateHeadUrl(MultipartFile avatar, Mo ...

  4. 状态管理之 Flux、Redux、Vuex、MobX(概念篇)

    本文是对 Flux.Redux.Vuex.MobX 几种常用状态管理模式的总结,偏向于概念层面,不涉及过多代码. 状态管理 什么是状态管理? 状态管理就是,把组件之间需要共享的状态抽取出来,遵循特定的 ...

  5. jQuery之克隆事件--clone()与clone(true)区别

    clone()与clone(true)同为克隆 clone()表示复制标签本身, clone(true)会将标签绑定的事件一起复制 来看案例: <!DOCTYPE html> <ht ...

  6. day32 网络编程之粘包问题

    1.最大半连接数 什么是最大半连接数 半连接:在进行TCP协议通信时,客户端与服务器端进行三次握手建立连接,但是有时客户端与服务器端进行了连接申请,服务器端也同意了申请(既已经完成三次握手的两次),此 ...

  7. HDU1814(Peaceful Commission) 【2-SAT DFS暴力求最小字典序的模板】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1814 题意:给出一个数n,代表有n个党派,每个党派要求派出其中一个人去参加会议,且只能派出一人.给出m ...

  8. VirtualBox本地虚拟机常见问题

    SSH连接本地虚拟机配置 https://www.jianshu.com/p/d59ed9f226d1 开启双向复制https://blog.csdn.net/wcx1293296315/articl ...

  9. 【Python】【demo实验5】【练习实例】【多个数字组合成不重复三位数】

    题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 程序源代码 ...

  10. 使用批处理执行 sql cmd

    当 sql脚本文件太大了, 就可以考虑用这个方式来执行 1.准备好要执行的 sql脚本文件并保存为*.sql格式 2.找到 SQLCMD.EXE 文件所在的路径(每个版本sql路径不一样) C:\Pr ...