免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 12368 | 回复: 12
打印 上一主题 下一主题

Linux bridge 对802.1q包的处理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-07-17 18:42 |只看该作者 |倒序浏览
在一款switch设置如下:
vconfig add eth0 1
vconfig add eth0 2

brctl addbr br0

brctl addif br0 eth0.1
brctl addif br0 eth0.2

从eth0.1设备上来的数据包都是打上Tag的,那么在bridge中将包从eth0.1转发到eth0.2时,包中的TAG是如何变化的呢?
从源代码来看:
从eth0.1收到的带TAG的数据包,经过br0之后,最后调用eth0.2的vlan_dev_hard_start_xmit()将包从eth0.2真正的物理设备即eth0发送出去。

vlan_dev_hard_start_xmit()中会根据FLAG来判断是否将包打上自己的TAG即VLAN ID为2.
那么我有个疑问就是:
1. 从eth0.1上来的包经br0转发到eth0.2时是否还带了其自己的VLAN ID即1(进入vlan_dev_hard_start_xmit之前)
2. 如果eth0.2强制加上自己的VLAN TAG,那么是否从eth0.2上出来的数据包会生成两层VLAN TAG(即VLAN TAG1和VLAN TAG2)

请大牛帮忙解惑一下?

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
2 [报告]
发表于 2011-07-17 19:32 |只看该作者
1  不会。ETH0.1设备只负责2个功能,接收从EHT0设备上的带TAG1的包,去TAG.从上层发送的包加TAG.加TAG去TAG的功能实际称呼好象叫VLAN隧道. VLAN的详细确切概念可以看 PERLMAN的 网络互连 一书
2 桥只管按MAC地址,带TAG的叫隧道包,他不能做分辨. 所以问题与桥没关系,只是VLAN虚拟设备设计的问题.
代码显示,不会加而是直接透传发送.


int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
        struct net_device_stats *stats = vlan_dev_get_stats(dev);
        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);

        /* Handle non-VLAN frames if they are sent to us, for example by DHCP.
         *
         * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
         * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
         */

        if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) {
                int orig_headroom = skb_headroom(skb);
                unsigned short veth_TCI;

论坛徽章:
0
3 [报告]
发表于 2011-07-17 20:07 |只看该作者
1. 包是从eth0上收上来的,从驱动来看,这个包是带TAG的,驱动收包后调用netif_receive_skb()将包交给协议栈,这是会调用handle_bridge()进入bridge的处理,所以说进入bridge之后包还是带TAG的,具体不知道到何处会将TAG去掉?
2. vlan dev在初始化时,默认的flag为 VLAN_FLAG_REORDER_HDR,从代码中可以看出,会打上TAG
static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
                                            struct net_device *dev)
{
        int i = skb_get_queue_mapping(skb);
        struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
        unsigned int len;
        int ret;

        /* Handle non-VLAN frames if they are sent to us, for example by DHCP.
         *
         * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
         * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
         */
        if (veth->h_vlan_proto != htons(ETH_P_8021Q) ||
            vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) {
                unsigned int orig_headroom = skb_headroom(skb);
                u16 vlan_tci;

                vlan_dev_info(dev)->cnt_encap_on_xmit++;

                vlan_tci = vlan_dev_info(dev)->vlan_id;
                vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
                skb = __vlan_put_tag(skb, vlan_tci);
                if (!skb) {
                        txq->tx_dropped++;
                        return NETDEV_TX_OK;
                }

                if (orig_headroom < VLAN_HLEN)
                        vlan_dev_info(dev)->cnt_inc_headroom_on_tx++;
        }

论坛徽章:
0
4 [报告]
发表于 2011-07-26 01:51 |只看该作者
vlan_dev_hard_start_xmit()中会根据FLAG来判断是否将包打上自己的TAG即VLAN ID为2.
那么我有个疑问就是:
1. 从eth0.1上来的包经br0转发到eth0.2时是否还带了其自己的VLAN ID即1(进入vlan_dev_hard_start_xmit之前)
2. 如果eth0.2强制加上自己的VLAN TAG,那么是否从eth0.2上出来的数据包会生成两层VLAN TAG(即VLAN TAG1和VLAN TAG2)

请大牛帮忙解惑一下?



1,br0v转发时没有,但是,从eth0.2出去时会再次加上
2,只有一层vlan_Tag,因为eth0.1的包进网桥前会去掉vlan tag
在vlan_skb_recv这个函数里去除vlan

type = skb->protocol;
list_for_each_entry_rcu(ptype,
        &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
    if (ptype->type == type &&
        (ptype->dev == null_or_orig || ptype->dev == skb->dev ||
         ptype->dev == orig_dev)) {
        if (pt_prev)
            ret = deliver_skb(skb, pt_prev, orig_dev);
        pt_prev = ptype;
    }
中陷入vlan_skb_recv调用

论坛徽章:
0
5 [报告]
发表于 2011-09-18 18:35 |只看该作者
bridge模块的处理在vlan之前,所以说根本不会进入到vlan_skb_dev这个函数,所以其实在br处理时,skb中其实是带TAG的。br在处理这个数据包时,会先将skb->data指针跳过vlan tag,而进行处理。

论坛徽章:
0
6 [报告]
发表于 2011-10-26 11:42 |只看该作者
帮顶!对于vlan包 先由bridge模块处理后,怎么进入vlan_skb_dev 不清楚。如果是在bridge之前就把vlan tag去掉了的话,具体是在哪里去掉的呢?  vlan_skb_dev 是怎么被调用到的?

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
7 [报告]
发表于 2011-10-26 16:49 |只看该作者
本帖最后由 瀚海书香 于 2011-10-26 18:13 编辑

回复 6# d419192480
vlan函数的处理,跟其他协议是类似的,通过dev_add_pack将vlan的处理函数添加到ptype_base中。
在bridge下的vlan数据包的处理流程:(注意是到本地或者本地发出的数据包,转发的数据包是不会进行tag处理的,只是进行简单的指针加减后处理的。nf_bridge_pull_encap_header_rcsum)

netif_receive_skb--->bridge-->vlan-->netif_rx-->bridge

也就是说,vlan的数据包会两次经过bridge。第一次为带tag的vlan数据包,第二次为去掉tag的普通数据包。

论坛徽章:
0
8 [报告]
发表于 2011-10-26 17:15 |只看该作者
谢谢回复,可否细说一下
bridge--->vlan ? 这个过程 是在哪里发生的呢?
是在 br_handle_frame_finish 里面发生的吗?
还是在 netif_receive_skb函数里面发生的?

根据你的回复,应该是在netif_receive_skb函数里面,bridge处理完成后发生的。但是bridge处理完成后不是直接goto out了吗? bridge不是会直接转发出去?

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
9 [报告]
发表于 2011-10-26 18:09 |只看该作者
回复 8# d419192480
bridge对于转发的VLAN数据包是不做tag处理的。
对于到本地的数据包和从本地发出的数据包才会做tag的处理,需要虚拟设备的支持。
很久之前看的代码了,大体上记得是这样的流程。看代码的时候需要注意:只有到本地或者本地发出的数据包才会处理tag,并且是需要虚拟设备支持的。

论坛徽章:
0
10 [报告]
发表于 2011-12-22 18:51 |只看该作者
这里面东西貌似都没有讨论清楚,楼主你邮箱是多少?有空探讨一下?

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP