什么是vlan?
VLAN:Virtual Local Area Network即虚拟局域网。是一组逻辑上的设备和用户,这些设备和用户并不受物理位置的限制,可以根据功能、部门及应用等因素将它们组织起来,相互之间的通信就好像它们在同一个网段中一样,由此得名虚拟局域网。VLAN是一种比较新的技术,工作在OSI参考模型的第2层和第3层,一个VLAN就是一个广播域,VLAN之间的通信是通过第3层的路由器来完成的。与传统的局域网技术相比较,VLAN技术更加灵活,它具有以下优点: 网络设备的移动、添加和修改的管理开销减少;可以控制广播活动;可提高网络的安全性。现在使用最广泛的VLAN协议标准是 IEEE 802.1Q。
802.1Q VLAN帧格式
图-1802.1Q数据帧格式
图-2802.1Q TAG域字段
VLAN重要数据结构
/*此结构是用来表示物理设备对应的vlan组*/
structvlan_group {
unsigned int nr_vlan_devs; /*记录的VLAN设备数目*/
struct hlist_node hlist; /* linked list */
struct net_device**vlan_devices_arrays[VLAN_PROTO_NUM]
[VLAN_GROUP_ARRAY_SPLIT_PARTS];
/* 用来保存加入vlan组的vlan设备的指针*/#defineVLAN_GROUP_ARRAY_SPLIT_PARTS 8};
enumvlan_protos {
VLAN_PROTO_8021Q = 0,
VLAN_PROTO_8021AD,
VLAN_PROTO_NUM,};
/*描述vlan设备的私有部分信息*/
structvlan_dev_priv {
unsigned int nr_ingress_mappings;
u32 ingress_priority_map[8];
unsigned int nr_egress_mappings;
struct vlan_priority_tci_mapping *egress_priority_map[16];
__be16 vlan_proto;//区分是802.1Q or AD
u16 vlan_id;
u16 flags;
struct net_device *real_dev;
unsigned char real_dev_addr[ETH_ALEN];
struct proc_dir_entry *dent;
struct vlan_pcpu_stats __percpu *vlan_pcpu_stats;
#ifdefCONFIG_NET_POLL_CONTROLLER
struct netpoll *netpoll;
#endif
unsigned int nest_level;};
VLAN数据结构关系图
VLAN模块初始化
在vlan_proto_init函数中初始化vlan_ioctl_set->vlan_ioctl_hook= vlan_ioctl_handler;; //用来处理用户层的ioctl的函数,主要是添加/删除VLAN等操作
VLAN的添加和删除
1. 添加
vlan_ioctl_handler->register_vlan_device
2. 删除vlan_ioctl_handler->unregister_vlan_device
VLAN报文接收流程(不考虑硬件加速情况)
图-3 VLAN报文接收流程
1. 当收到包时,在netif_receive_skb中根据协议(ETH_P_8021Q、ETH_P_8021AD)将数据包先通过skb_vlan_untag函数设置skb的protocol,同时将vlan头的4个字节覆盖,重新计算校验,然后交给vlan_do_receive。在vlan_do_receive中根据vlan编号和skb的dev(输入设备)来查询vlan设备。
2. 如果没有找到对应的vlan设备,返回netif_receive_skb函数执行后续流程。如果找到了vlan设备将skb的dev设置为vlan设备,返回netif_receive_skb重新进入接收流程(netif_receive_skb中goto语句实现)处理。3. 此时的包的链路层协议是vlan包封装的那个协议,输入设备是vlan虚拟设备。
VLAN报文发送流程(不考虑硬件加速情况)
图-4 VLAN报文发送流程
1.当通过vlan设备发送数据时,会调用vlan设备的发送函数vlan_dev_hard_start_xmit,此函数是在添加vlan设备是设置的,见函数register_vlan_device
2. 在vlan_dev_hard_start_xmit中,如果数据包不是vlan数据包则根据vlan设备的vlan号构建一个vlan包3. 将skb的dev即出口设备设置为vlan设备对应的真实物理设备。并重新调用dev_queue_xmit发送数据