我有一个在用户空间中运行的缓存应用程序。通常,它使用DPDK直接与NIC交互,而无需内核交互,从数据包中抓取数据包,然后将其传递,从缓存生成响应,或者在某些情况下将其阻塞。它对端点是透明的,并且可以直接从NIC写入以处理原始数据包数据。值得注意的是,我在这里没有进行普通的套接字编程-一切都在数据包级别进行,无需与TCP / IP堆栈进行交互。
出于冗长而无聊的原因,我想添加一些NAT功能。作为概念验证,我希望使用iptables / netfilter在我的应用程序中放置一个前端。因此,我使用以下命令执行了NAT部分:
sudo iptables --table nat --append PREROUTING --in-interface seg1a -j DNAT --to-destination $SERVERIP
sudo iptables --table nat --append POSTROUTING --out-interface seg1b -j MASQUERADE
sudo route add $SERVERIP seg1b
这对我来说很有效。客户端现在连接到我系统上的接口,但是其流量被重定向到服务器。我保证他们的流量会通过我的系统,所以一切都很好。
但是要用作缓存,我需要能够响应来自客户端的某些请求。我以为我可以将NFQUEUE用于一个小型应用程序,该应用程序从netfilter队列中读取数据,并通过IPC将数据包与我的应用程序传递。我使用了这样的iptables规则:
sudo iptables --table mangle --append FORWARD -j NFQUEUE
只要我的应用程序不响应任何内容,此方法就可以正常工作。但是,当我的缓存尝试响应来自端点之一的某些内容时,事情就出错了。缓存会反转所有L2-4标头,管理序列和ack编号等。但是数据包不会返回到客户端。
我认为正在发生的事情是,在将数据包发送到NFQUEUE之前,已经为它做出了路由决策。因此,即使缓存返回的源IP地址和目标IP地址都被颠倒的东西,也与数据包的路由无关。
我尝试了很多方法来更改响应数据包的路由,但是似乎没有任何效果。如何更改从netfilter队列读取的数据包的路由?失败了,是否有一种很好的方法将数据包从netfilter队列中注入到网络上?如果可行,我可以阻止原始请求,然后将缓存的回复作为全新内容发送。
提前感谢您的任何建议。