F-Stack IPv6 的支持与使用

      限于某些原因 F-Stack 项目之前是未对 IPv6 进行支持的,随着 IPv6 需求的增多,近期对 IPv6 进行了支持。本文将简单介绍 F-Stack 支持 IPv6 所做的修改,如何使用以及相关注意事项。

F-Stack 如何支持 IPv6

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

  1. F-Stack 框架支持
    1. Makefile 中定义 IPv6 相关的宏INET6及需要包含编译的文件NETINET6_SRCS
    2. opt/opt_inet6.h中定义#define INET6 1
    3. 对 FreeBSD 代码中部分在 Linux 中不兼容的代码进行修改
    4. ff_api.h中将 AF_INET6重新定义为 FreeBSD 中的值 28, 增加 AF_INET6_LINUX宏定义供应用调用 Linux 系统函数时使用,如inet_pton
    5. 将 F-Stack 胶水代码中的 struct sockaddr相关的所有结构体全部使用struct sockaddr_storage替换并对相关的参数和代码进行修改
    6. 在 F-Stack 胶水代码中 kni 功能的 protocol_filter_ip函数进行修改,支持对 IPv6 包进行匹配,需跳过 IPv6 不同的扩展头,支持 IPv4 over IPv6、IPv6 over IPv4、ICMPv6 等包类型的匹配。
    7. 对于 ICMPv6 包类型中的 ND(邻居发现协议) 相关报文进行深拷贝,并分发到所有进程和 kni 队列
    8. 配置文件config.ini中增加部分 IPv6 相关参数,如配置net.inet6.ip6.auto_linklocal, net.inet6.ip6.accept_rtadv等参数默认开启 IPv6,并接受 RA 组播等
  2. 工具支持 对ifconfigroutenetstat工具进行了修改,以支持 IPv6 相关操作
    1. tools/opts.mk中修改MK_INET6_SUPPORT="yes"开启 IPv6 编译选项
    2. 复制 IPv6 模块缺少的相关头文件到tools/compat/include下相关目录
    3. 修改部分 IPv6 相关系统调用为 hook 过的兼容接口
    4. 工具与 F-Stack 的 IPC 工具及系统调用增加 IPv6 支持
  3. Nginx 支持

因为 Nginx 本身即支持 IPv6, 所以改动较少,仅改动 ff_module模块ngx_ff_module.c下的fstack_territory函数,增加对 AF_INET6的支持即可。

Nginx 并未对绑定到系统 Host 进行 IPv6 的支持,如有需要可自行修改,需在全部判断AF_INET6代码处增加AF_INET6_LINUX的支持,或其他更多修改。

  1. helloworld 支持

example/main.c修改了增加了 IPv6 的服务端 DEMO,自行定义INET6即可开启

F-Stack 在 AWS EC2 运行 IPv6 服务演示

本节给出在 AWS EC2 运行 helloworld的简单演示,及部分相关配置命令

  1. 运行一台 AWS EC2 实例,并在控制台附加额外网络接口和开启 IPv6,配置相关路由和安全组
  2. 在实例中启用 IPv6,并测试可以正常进行 IPv6 通信
  3. 通过以下命令查看和记录系统默认的 IPv4 地址、掩码、广播地址、路由、IPv6 地址及 prefix 等信息 ifconfig route -n route -n6
  4. 按照 F-Stack 教程进行 DPDK、F-Stack、examle的编译和配置,并启动helloworld程序。需注意以下两点:
    1. 因 AWS EC2 主要使用 ixgbevfena两种网卡,而 F-Stack 包含的 dpdk 18.11.2 LTS版本的此两种网卡驱动均不完善(如均不支持设置网卡混杂模式,无法收到 RA 组播;ena网卡驱动无法正常运行多进程模式等),需在 DPDK 官网下载 DPDK 19.05或以上版本替换 F-Stack目录下的 dpdk目录,再行编译。如 EC2 实例使用了ena网卡,且需使用 kni 功能,还需参照 issue #401 对相关代码进行修改。
    2. example/Makefile或相关文件中定义INET6开启helloworld的 IPv6 支持,编译支持 IPv6 的helloworld程序
  5. tools目录下执行make;make install命令编译并安装 F-Stack 相关系统工具
  6. 参考以下命令配置和查看 IPv6 的相关地址和路由信息
# 为 f-stack-0 配置 IPv6 地址
ff_ifconfig f-stack-0 inet6 <记录的IPv6 地址>/<prifixlen> auto_linklocal accept_rtadv autoconf defaultif

# 查看 f-statck-0 网卡的相关信息
ff_ifconfig

# 查看 IPv6 路由信息
ff_route -6 show ::/0

# 查看本机端口监听和连接信息
ff_netstat -na

在 F-Stack 配置了 IPv6 地址后,F-Stack 会发送 MLD 组播侦听报文加入广播组接收路由组播 RA 信息,并且会发送相关 NS 信息,接收路由的 NA 响应信息,所以如果本网络环境支持 MLD 组播(如AWS EC2),则可无需手工配置 IPv6 路由,如在其他环境使用可以使用如下命令配置 IPv6 路由信息

ff_route -6 add ::/0 <网关 IPv6 地址>
  1. 可以从其他 IPv6 客户端访问 F-Stack 服务端进行测试

需要注意的是,在 AWS EC2 环境中使用 F-Stack 的 IPv6 功能,运行一段时间后无法 F-Stack 会收不到网关应发送的 RA 组播信息,且向网关发送 NS 请求,网关也不再回应 NA 应答,IPv6 连接会因无有效的邻居和路由信息而中断,原因尚未明确,但在其他环境运行未发现此问题。

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

  1. F-Stack 当前支持 ICMPv6,包括邻居发现协议(ND)和组播侦听发现协议(MLD),但不支持 DHCPv6,主要是 FreeBSD 本身对 DHCPv6 支持不够好,需要额外使用第三方 dhcpclient 工具进行支持,所以需手工配置指定 IPv6 地址信息
  2. DPDK kni 无法接收 MLD 组播信息,所以如果在 MLD(如AWS EC2) 环境使用 IPv6 时可能无法正常使用 kni 功能
  3. 当 IPv6 测试客户端和服务端的 IPv6 地址在同一 prefixlen 范围内时,需在配置文件或使用ff_sysctl工具配置net.inet.tcp.nolocaltimewait参数的值为0(当前版本已默认配置为0), 否则在 F-Stack 应用程序主动关闭连接时,在接收到对方应答的 fin+ack包后不会发送 last ack包,可能影响对端进行性能测试
  4. 在双栈环境下,F-Stack IPv6 的性能约为 IPv4 的 75% 左右,Linux系统协议栈 IPv6 的性能则为 IPv4 的 87% 左右,但 F-Stack 的性能依然领先

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

原文发表时间:2019-08-16

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

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券