F-Stack vlan 的支持与使用

       限于 Vlan 测试环境的缺失, F-Stack 项目初期未对 Vlan 进行完全的支持,仅支持配置是否进行 Vlan 的硬件卸载,当交换机配置了服务器返回的包无需打 Vlan tag 时可以正常使用,但如果交换机要求回报需要打 Vlan tag 则无法正常工作。

      近期收到了网易 dragonorloong 同学关于 Vlan 的 Pull request,并且找到了 Vlan 测试环境对 Vlan 进行了完整的支持和测试,对以上问题进行了修复。本文将简单介绍 F-Stack 支持 Vlan 所做的修改,如何使用以及相关注意事项。

F-Stack 如何支持 Vlan

 以下所列为 F-Stack 支持 Vlan 所进行的修改,具体改动细节可查看 github 相关 commits。

  1. F-Stack 框架支持
    1. ff_veth.c中增加胶水函数ff_mbuf_set_vlan_info用于将在开启vlan_strip选项时将 DPDK mbuf 中的 vlan tci 信息传递给 BSD 内核, 并在ff_api.symlist增加该接口
voidff_mbuf_set_vlan_info(void *hdr, uint16_t vlan_tci) {    struct mbuf *m = (struct mbuf *)hdr;    m->m_pkthdr.ether_vtag = vlan_tci;    m->m_flags |= M_VLANTAG;    return;}

    b. 在protocol_filter中定义增加 Vlan 头的兼容处理,用于在关闭vlan_strip时可以正确匹配 TCP/UDP 的端口号,解决 kni 端口号匹配失效的问题

uint16_t ether_type = rte_be_to_cpu_16(hdr->ether_type);data += ETHER_HDR_LEN;len -= ETHER_HDR_LEN;
if (ether_type == ETHER_TYPE_VLAN) {    vlanhdr = (struct vlan_hdr *)data;    ether_type = rte_be_to_cpu_16(vlanhdr->eth_proto);    data += sizeof(struct vlan_hdr);    len -= sizeof(struct vlan_hdr);}

  c. 对通过ff_regist_packet_dispatcher注册的packet_dispatcher函数的返回值进行处理,在该包需要直接应答,并且开启了vlan_strip选项时,需要在数据包中增加已卸载了的 Vlan tci 信息

int ret = (*packet_dispatcher)(data, &len, queue_id, nb_queues);if (ret == FF_DISPATCH_RESPONSE) {    rte_pktmbuf_pkt_len(rtem) = rte_pktmbuf_data_len(rtem) = len;
    /*    * We have not support vlan out strip    */    if (rtem->vlan_tci) {        data = rte_pktmbuf_prepend(rtem, sizeof(struct vlan_hdr));        if (data != NULL) {            memmove(data, data + sizeof(struct vlan_hdr), ETHER_HDR_LEN);            struct ether_hdr *etherhdr = (struct ether_hdr *)data;            struct vlan_hdr *vlanhdr = (struct vlan_hdr *)(data + ETHER_HDR_LEN);            vlanhdr->vlan_tci = rte_cpu_to_be_16(rtem->vlan_tci);            vlanhdr->eth_proto = etherhdr->ether_type;            etherhdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_VLAN);        }    }    send_single_packet(rtem, port_id);    continue;}

【注意1】在初始化 DPDK 的 memory pool 时,每个 mbuf 都预留了128字节的空闲的 HEADROOM 空间,可供在原有数据之前附加少量信息而无需挪动整个数据包

【注意2】此处 F-Stack 并未支持 Vlan out strip, 所以需要将 Vlan tci 信息加回到报文中,否则不需要

2. 工具支持

原有 ifconfig等工具已经支持 Vlan 配置,无需修改

F-Stack 如何使用 Vlan

      下面给出 F-Stack 和 KNI 分别配置 Vlan 的命令参考,供参考并根据自己的网络情况实际进行配置。

假设有两个Vlan 10 和 Vlan 20,分别处理 IPv4 和 IPv6,可以按如下步骤配置

# 创建 vlan 10 并配置 IPv4 地址和路由信息
ff_ifconfig f-stack-0.10 create
ff_ifconfig f-stack-0.10 inet <ip address> netmask <netmask>
# 清除原网卡上的 IP 信息,或者原网卡配置的是无效 IP 则不必处理
ff_ifconfig f-stack-0 inet <ip address> remove
# 重新添加默认路由
ff_route add 0.0.0.0 <gw address>

# 创建 vlan 20 并配置 IPv6 地址和路由信息
ff_ifconfig f-stack-0.20 create
ff_ifconfig f-stack-0.20 inet6 <ipv6 address> autoconf defaultif auto_linklocal accept_rtadv
ff_route -6 add ::/0 <ipv6 gw address>

   如需使用 kni,可参考如下命令在系统上进行 Vlan 相关配置

ifconfig veth0 up
vconfig add veth0 10
vconfig set_flag veth0.10 1 1
ifconfig veth0.10 <ip address> netmask <netmask> broadcast <broadcast> up
route add -net 0.0.0.0 gw <gw address> dev veth0.10

vconfig add veth0 20
vconfig set_flag veth0.20 1 1
ifconfig veth0.20 inet6 add <ipv6 address>/<prefix len> up
route -6 add ::/0 gw <ipv6 address> dev veth0.20

echo 1 > /sys/class/net/veth0/carrier

其他在F-Stack 使用 IPv6 的注意事项

  1. 只有当交换机配置了服务器回包必须打 Vlan 信息时才需要在 F-Stack 上配置 Vlan,否则只需要设置开启vlan_strip=1选项即可,其他可以考虑不必处理,即保持 Vlan 相关的 commits 提交之前的状态
  2. KNI 不支持将卸载的 Vlan tci 信息转到系统内核,所以如果需要在系统内核也同时配置 Vlan 使用时,需修改配置vlan_strip=0关闭 Vlan 卸载

原文发布于微信公众号 - FStack(F-Stack)

原文发表时间:2019-09-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券