基于Linux内核新特性的网关设计实践(3)
问题定位:查看代码发现,原方向和反方向首报文进入协议堆栈后 skb->dev 会设置为 vrf device user1,创建流卸载规则的 提交补丁:
最终,我们根据两个方向查找路由的结果,设置流卸载规则的 6、VRF PREROUTING 钩子重入问题问题描述:配置网卡加入 VRF,防火墙 ingress 方向规则为接收目的地址 2.2.2.11 、TCP 目的端口 22 的报文,egress 方向规则为丢弃 TCP 目的端口 22 的报文。出现异常结果: 收到目的地址 2.2.2.11 TCP 22 目的端口的报文却被丢弃。 问题定位:研究发现网卡加入 VRF 后收到的报文会两次进入 PREROUTING 钩子,因为在进入 IP 栈时会进第一次PREROUTING 钩子,然后被 VRF 设备接管后会再次进入 PREROUTING 钩子。上述规则第一次在 rule-1000-ingress chain中 dst nat 为 10.0.0.7,第二次由于报文被 DNAT 后会错误的进入 rule-1000-egress,导致报文被丢弃。 提交补丁:我们给内核加了一个支持判断网卡类型的 match 项目,让用户态避免可知的第二次无效重入,内核态和用户态 nftables 分别提交了如下的补丁:
使用方法:
原型验证最终,我们成功地利用 lwtunnel、VRF 和流卸载实现多租户外网网关的原型验证。验证过程如下: 1、首先创建原型环境a. netns cl 模拟外网客户端,地址为 1.1.1.7,隧道源地址 172.168.0.7,配置发送路由; 原型环境图如下: 2、创建防火墙规则a. 租户 1 入向允许 TCP 目的端口 22 和 ICMP 访问,出向禁止访问外部 TCP 22 目的端口; 最终,客户端可以通过 2.2.2.11 成功访问 user1 tcp 22 端口服务,user1 不能访问客户端 tcp 22 端口服务;客户端可以通过 2.2.2.12 成功访问 user2 tcp 23 端口服务,user1 不能访问客户端 tcp 23 端口服务。 在后续硬件功能完善以及网卡厂商支持后,我们还会做进一步的开发验证。 写在最后以上是本项目涉及的部分核心问题,这些补丁特性都可以在 Linux 内核 5.0 版本里获取。我们把这期间为 Linux 内核社区贡献的补丁整理成了一份列表,希望能为开发者提供帮助,读者可以点击阅览。 Linux 作为成熟的开源套件,一直是云厂商使用的主流操作系统,但在技术的更新迭代过程中,一些新特性在实际应用上也会存在稳定性、兼容性等方面的问题。我们在研究使用上游技术的同时,也一直积极探索、丰富开源技术功能,帮助提高开源技术稳定性。并将产出持续回馈给社区,与社区共同构建一个繁荣的开源生态。 【编辑推荐】
点赞 0 (编辑:ASP站长网) |