博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vlan 介绍
阅读量:6711 次
发布时间:2019-06-25

本文共 2653 字,大约阅读时间需要 8 分钟。

简介
     在Linux中安装了802.1Q标签VLAN功能。VLAN是虚拟分配以太网的功能。
使用VLAN ID从物理上将一个以太网分割开。在VLAN环境下,具有相同VLAN ID
就可以相互通信,但是即使将LAN线连接到相同集线器或交换机上,VLAN ID不同
也不能相互通信。
 
802.1Q的以太帧格式
 
由上图,唯一的变化是加入了一对2字节字段。第一个2字节是VLAN协议标识符,
它的值总是0x8100.由于这个数值大于1500,因此,所有的以太网卡都不会将
它解释成类型(type),而不是长度。第二个2字节包含三个子字段。最主要的是
VLAN标识符字段,它占用低12位。优先级和CFI的作用不明显,具体可以参考【1】的第4.8.5一节。
 
vlan在网卡驱动及协议栈的处理
     以igb网卡为例,从napi的poll函数开始调用情况如下:
igb_poll
     ==》
          igb_clean_rx_irq
          ==》
               igb_receive_skb
             
在igb_clean_rx_irq实现中:
59885989         if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) &&5990             test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &rx_ring->flags))5991             vlan_tag = be16_to_cpu(rx_desc->wb.upper.vlan);5992         else5993             vlan_tag = le16_to_cpu(rx_desc->wb.upper.vlan);59945995         total_bytes += skb->len;5996         total_packets++;59975998         skb->protocol = eth_type_trans(skb, rx_ring->netdev);59996000         igb_receive_skb(q_vector, skb, vlan_tag);6001
View Code

第5989到5993行会读取vlan_tag。

函数igb_receive_skb的实现如下:

5829 static void igb_receive_skb(struct igb_q_vector *q_vector,5830                             struct sk_buff *skb,5831                             u16 vlan_tag)5832 {5833     struct igb_adapter *adapter = q_vector->adapter;58345835     if (vlan_tag && adapter->vlgrp)5836         vlan_gro_receive(&q_vector->napi, adapter->vlgrp,5837                          vlan_tag, skb);5838     else5839         napi_gro_receive(&q_vector->napi, skb);5840 }
View Code
内核模块捕获VLAN
     通过 vlan_gro_receive 和  napi_gro_receive的数据帧是有区别的。当我们使用命令
vconfig add eth1 22 创建vlan设备后,数据帧将会通过vlan_gro_receive,否则将会通过
napi_gro_receive到达netif_receive_skb。
     对于依然带有VLAN信息的数据包,捕获相应的数据包可采用jprobe的方法,按如下实现:
int jpf_netif_receive_skb(struct sk_buff *skb){        unsigned short sport, dport;        __be32 saddr, daddr;        char dsthost[16];        struct iphdr *iph;        struct tcphdr *tcph;        skb_linearize(skb);        iph = (struct iphdr *)(skb->data + 4);        tcph = (struct tcphdr *)((skb->data + 4) + (iph->ihl << 2));        if (iph->protocol == IPPROTO_TCP) {                sport = tcph->source;                dport = tcph->dest;                saddr = iph->saddr;                daddr = iph->daddr;               snprintf(dsthost, 16, "%pI4", &daddr);               printk(KERN_INFO "ip is:%s", dsthost);        }        jprobe_return();        return 0;} struct jprobe jps_netif_receive_skb = {    .entry = jpf_netif_receive_skb,    .kp = {        .symbol_name = "netif_receive_skb",    }, };
View Code
如果vconfig的方式创建了VLAN设备,那么不需要对skb->data进行4字节的偏移就可以捕获到想要的数据包。
 
参考资料
【0】LINUX内核精髓(精通LINUX内核必会的75个技巧)
【1】计算机网络 第5版 严伟,潘爱民译

转载于:https://www.cnblogs.com/lxgeek/p/4895464.html

你可能感兴趣的文章
别开心太早,Python 官方文档的翻译差远了
查看>>
如何利用并发性加速你的python程序(二):I/O 绑定程序加速 ...
查看>>
一个BAT老程序员的忠告!
查看>>
Spring Boot 的 10 个核心模块
查看>>
我30岁了,转行学编程可以吗? 排除法告诉你答案
查看>>
Python进阶:全面解读高级特性之切片!
查看>>
社交大战升级,语音新物种“听途听app”获数百万天使轮融资
查看>>
C#并行开发_Thread/ThreadPool, Task/TaskFactory, Parallel
查看>>
主要的编程范型
查看>>
Centos-Mysql复制备份还原数据库
查看>>
Javascript操作DOM常用API总结
查看>>
零基础入门—网站建站教程(新手必备)
查看>>
小鹏汽车开设六城服务中心,今年内将交付4万辆车,运营200座超充站
查看>>
C++面向对象高级编程(上) 第一周 侯捷
查看>>
Android Dagger2依赖注入
查看>>
FullPage.js全屏插件文档及使用方法
查看>>
修改chrome插件
查看>>
Spring Boot(06)——参数配置机制
查看>>
【WPF】右下角弹出自定义通知样式(Notification)——简单教程
查看>>
keras 使用笔记
查看>>