简介
     在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实现中:
5988
5989         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         else
5993             vlan_tag = le16_to_cpu(rx_desc->wb.upper.vlan);
5994
5995         total_bytes += skb->len;
5996         total_packets++;
5997
5998         skb->protocol = eth_type_trans(skb, rx_ring->netdev);
5999
6000         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;
5834
5835     if (vlan_tag && adapter->vlgrp)
5836         vlan_gro_receive(&q_vector->napi, adapter->vlgrp,
5837                          vlan_tag, skb);
5838     else
5839         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版 严伟,潘爱民译
posted @ 2015-10-20 17:33 lxgeek 阅读(1568) 评论(1) 推荐(0)
摘要: 在字节缓存中我们需要考虑缓存比,为了达到缓存的效果,我们需要对数据包的内容进行切分。目前学术上的切分方法如下: 上图中的9种方法可以根据方法自身的特性分为三类。第一类:位置分类法,此方法按固定大小将数据切分。其方法的优势的计算开销很小,但是对数据变化很敏感。第二类:取样法,MODP、WINN、M... 阅读全文
posted @ 2015-08-17 15:36 lxgeek 阅读(698) 评论(0) 推荐(0)
摘要: 实验目标: 对数据包负载文件进行分割,可以让分割块近似1000字节。背景: PACK是一种基于接收端的字节缓存算法。核心思想是利用当前的数据预测下一步需要接收的数据。但是数据块不应该被分割的太小,这样的话会耗费过多的内存和磁盘; 当然也不能分割的太大,数据块过大会导致预测的命中率降低。具体的PA... 阅读全文
posted @ 2015-08-10 16:27 lxgeek 阅读(425) 评论(0) 推荐(0)
摘要: 1.字节缓存的基本原理 数据压缩也被称作基本压缩,或无损压缩,一般采用 LZ 系列压缩算法。数据压缩具有自包含性:即对端解压缩方只根据数据包本身:即可进行解压还原,不需要其它任何信息。压缩比因数据类型而异:文本数据压缩比最大,各种网页、Windows office 文件(Excel、word 等等... 阅读全文
posted @ 2015-06-04 16:12 lxgeek 阅读(1565) 评论(0) 推荐(0)
摘要: 简述 MPTCP的拥塞控制对TCP的拥塞控制的线性增加阶段进行了修改,而慢启动,快速重传、快速恢复都没有改变。每条子路径拥有自己的cwnd,MPTCP的拥塞算法主要关心cwnd的改变。拥塞算法设计原则MPTCP的Throughput 要达到MPTCP中所有子路径中最好的一条路径MPTCP应该和普通... 阅读全文
posted @ 2015-03-25 15:13 lxgeek 阅读(3774) 评论(0) 推荐(0)
摘要: 简述 TCP使用定时器函数tcp_retransmit_timer进行数据重发,MPTCP需要重发数据的时候,不仅仅在原路径发送数据,而且会在另外一条子路径进行重发。这样考虑的原因是:考虑网络中间件设备的影响, 保证子路径上数据序列号的完整性。目前的版本0.89依然如此实现,以后应该会优化。内核实... 阅读全文
posted @ 2015-03-25 15:05 lxgeek 阅读(2383) 评论(0) 推荐(0)
摘要: 简述: 在TCP协议中影响数据发送的三个因素分别为:发送端窗口值、接收端窗口值和拥塞窗口值。本文主要分析MPTCP中各个子路径对接收端窗口值rcv_wnd的处理。接收端窗口值的初始化 根据《MPTCP 源码分析(二) 建立子路径》中描述服务端在发送完SYN/ACK并接收到ACK的时候建立新的so... 阅读全文
posted @ 2015-03-11 15:59 lxgeek 阅读(2422) 评论(0) 推荐(0)
摘要: 简述: MPTCP在发送数据方面和TCP的区别是可以从多条路径中选择一条路径来发送数据。MPTCP在接收数据方面与TCP的区别是子路径对无序包进行重排后,MPTCP的mpcb需要多所有子路径的包进行排序。查看图1可知。 +----... 阅读全文
posted @ 2015-03-11 15:46 lxgeek 阅读(3418) 评论(0) 推荐(1)
摘要: 简述: 支持MPTCP的链路中存在多条子路径,因此在发送数据的时候需要选择最优路径来进行操作。MPTCP利用内核通知链对MPTCP中各子路径进行增加路径、删除路径、修改路径优先级的操作。MPTCP根据相应的策略进行路径选择。路径选择的代码实现 路径选择的关键在于从多个子路径中选择其中一个进行数据... 阅读全文
posted @ 2015-03-11 15:42 lxgeek 阅读(3121) 评论(2) 推荐(0)
摘要: 简述 MPTCP在进行三次握手之后,客户端和服务端会进行地址信息的交换,让对方知道彼此未用的地址信息。当客户端知道服务端的地址后就可以建立其他子路径。三次握手和建立子路径的过程如图1: 图1关于Token、随机数R、以及HMAC(Hash-based Messa... 阅读全文
posted @ 2015-03-11 15:13 lxgeek 阅读(3753) 评论(0) 推荐(0)
点击右上角即可分享
微信分享提示