网桥VLAN与tunnel隧道映射

VLAN tunnel隧道映射根据tunnel id为数据包添加vlan信息。 以下bridge配置命令采用iproute2的版本4.17.0,低版本bridge命令可能不完全支持vlan_tunnel功能。

使能接口eth0的vlan与tunnel映射功能:
bridge link set dev eth0 vlan_tunnel on
或者:
ip link set dev eth0 type bridge_slave vlan_tunnel on


配置一个l2tp的控制隧道,隧道ID为1000,自此隧道接收到的数据包,如果没有vlan id,自动增加vlan id 20,如下:

ip l2tp add tunnel tunnel_id 2000 peer_tunnel_id 2000 encap udp local 192.168.1.1 remote 192.168.2.1 udp_sport 3300 udp_dport 5500
bridge vlan add dev eth0 vid 20 tunnel_info 2000


在接收网桥的数据包接收函数br_handle_frame中,调用br_handle_ingress_vlan_tunnel函数处理tunnel与vlan的映射关系。


rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
{
    struct net_bridge_port *p;
    struct sk_buff *skb = *pskb;

    p = br_port_get_rcu(skb->dev);
    if (p->flags & BR_VLAN_TUNNEL) {
        if (br_handle_ingress_vlan_tunnel(skb, p, nbp_vlan_group_rcu(p)))
            goto drop;
    }
}


br_handle_ingress_vlan_tunnel函数为没有vlan信息的数据包添加vlan id。首先从skb的dst路由缓存中取得tunnel id信息,之后根据tunnel id在接口的vlan group的隧道hash列表中查找vlan信息。最后将找到的vlan id设置给skb。


int br_handle_ingress_vlan_tunnel(struct sk_buff *skb, struct net_bridge_port *p, struct net_bridge_vlan_group *vg)
{
    if (skb_vlan_tagged(skb))
        return 0;

    vlan = br_vlan_tunnel_lookup(&vg->tunnel_hash, tinfo->key.tun_id);
    skb_dst_drop(skb);

    __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, vlan->vid);
}


在数据包离开网桥的两个点(br_pass_frame_up和__br_forward)调用br_handle_egress_vlan_tunnel函数,处理vlan信息的剥离。

int br_handle_egress_vlan_tunnel(struct sk_buff *skb, struct net_bridge_vlan *vlan)
{
    if (!vlan || !vlan->tinfo.tunnel_id)
        return 0;

    if (unlikely(!skb_vlan_tag_present(skb)))
        return 0;

    skb_dst_drop(skb);
    err = skb_vlan_pop(skb);

    skb_dst_set(skb, dst_clone(&vlan->tinfo.tunnel_dst->dst));
}


内核版本

linux-4.15


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值