ovs vlan tag管理

本文详细探讨了OpenvSwitch(OVS)如何在虚拟机网络中处理内部和外部VLAN转换。通过分析br-int和br0-ovs桥的流表规则,揭示了OVS如何在收到外部报文时转换VLAN信息,并在虚机向外发送报文时进行内部VLAN到外部VLAN的转换。mod_vlan_vid动作用于修改流信息中的VLAN标记,而xlate_normal过程则涉及VLAN校验、内部VLAN转换、MAC学习以及根据目的MAC确定输出端口。这一机制确保了VLAN信息在不同网络环境下的正确传递。

1、背景

当使用ovs管理虚机的网络时,ovs会为虚机的tap设备添加一个内部的vlan tag,如下图所示,存在两个bridge,br0-ovs、br-int,其中br0-ovs挂载物理网卡设备eth2,br-int挂载虚机tatp设备,br0-ovs与br-int之间通过一对patch口连接,ovs为tap设备分配了内部vlan 2和内部vlan 3,本文主要描述ovs是如何完成这些内部vlan与外部vlan的转换。

2、流表规则

首先看一下br-int的流表规则,可以看到从int-br0-ovs这个patch进来的外部报文,分成两种情况,如果收到的报文没有vlan,则添加一个内部vlan 2,然后normal查询actiton动作,如果收到的报文带vlan 1049,则转换成内部vlan 3,然后normal查找actiton动作;

然后看一下br0-ovs的流表规则,从phy-br0-ovs这个patch收到的报文,再发出去之前判断如果带内部vlan 2,则把vlan信息剥离,如果带内部vlan 3,则添加外部vlan 1049,然后normal查询action动作;

从这两个桥的流表规则大致可以看出,是在br-int收到外部报文时,将其vlan信息转成内部vlan,br0-ovs收到虚机往外发的报文时,将内部vlan转化成外部vlan;既然br-int收到的发往虚机的报文,无论是不是有vlan,都会添加一个内部vlan,那为什么在虚机内部转包的时候又没有vlan信息呢?这个mod_vlan_vid究竟是做什么用呢?

3、mod_vlan_vid

首先先看一下ovs的mod_vlan_vid的动作,看ovs的upcall流程里,mod_vlan_vid的时候是会修改ctx->xin->flow的vlan信息,当ovs触发upcall时,ovs会将skb的流信息保存到ctx->xin->flow里,然后通过用户态的流表规则修改flow信息(在recv_upcalls->dpif_recv->odp_flow_key_to_flow流程里赋值的),最终匹配好actiton动作后再通知给datapath处理,从这个mod_vlan_vid的处理逻辑看,应该是修改了flow的vlan信息;

do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
                 struct xlate_ctx *ctx, bool is_last_action,
                 bool group_bucket_action)
{
    struct flow_wildcards *wc = ctx->wc;
    struct flow *flow = &ctx->xin->flow;
    const struct ofpact *a;
     ...   
        case OFPACT_SET_VLAN_VID:
            wc->masks.vlans[0].tci |= htons(VLAN_VID_MASK | VLAN_CFI);
            if (flow->vlans[0].tci & htons(VLAN_CFI) ||
                ofpact_get_SET_VLAN_VID(a)->push_vlan_if_needed) {
                if (!flow->vlans[0].tpid) {
                    flow->vlans[0].tpid = htons(ETH_TYPE_VLAN);
                }
                flow->vlans[0].tci &= ~htons(VLAN_VID_MASK);
                flow->vlans[0].tci |=
                    (htons(ofpact_get_SET_VLAN_VID(a)->vlan_vid) |
                     htons(VLAN_CFI));
            }
            break;

    ...
}

4、xlate_normal

以br-int的流表规则为例,mod_vlan_vid之后就是normal查询:

static void
xlate_normal(struct xlate_ctx *ctx)
{
 
	/*校验flow的vlan信息与in_bound口是否匹配*/
    /* Check VLAN. */
	xvlan_extract(flow, &in_xvlan);
    if (!input_vid_is_valid(ctx, in_xvlan.v[0].vid, in_xbundle)) {
        xlate_report(ctx, OFT_WARN,
                     "disallowed VLAN VID for this input port, dropping");
        return;
    }
	
	/*根据in_xbound类型,做内部vlan转换*/
    xvlan_input_translate(in_xbundle, &in_xvlan, &xvlan);
    vlan = xvlan.v[0].vid;

    /* Check other admissibility requirements. */
    if (in_port && !is_admissible(ctx, in_port, vlan)) {
        return;
    }

    /* Learn source MAC. */
    bool is_grat_arp = is_gratuitous_arp(flow, wc);
    if (ctx->xin->allow_side_effects
        && flow->packet_type == htonl(PT_ETH)
        && in_port->pt_mode != NETDEV_PT_LEGACY_L3
    ) {
        update_learning_table(ctx, in_xbundle, flow->dl_src, vlan,
                              is_grat_arp);
    }
    if (ctx->xin->xcache && in_xbundle != &ofpp_none_bundle) {
        struct xc_entry *entry;

        /* Save just enough info to update mac learning table later. */
        entry = xlate_cache_add_e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值