名词解释
PPE-PacketProcessingEngine
FOE-FrameOffloadEngine
PDMA-PacketDMA
背景介绍现在LEDE上已经对UBNTERX支持了,但是其中对性能有很大提高的HNAT(HardwareNAT)功能还没有实现;这里就尝试把HNAT的支持移植到ERX上,以此来了解MT7621的HWNAT功能。
框架结构______________________
CPU
______________________
PDMA
______________________
PPE
______________________
GMAC1|GMAC2
______________________
port6|port5
---------------------------------
port0,1,2,3,4
______________________
在目前的LEDE代码里面只用了GMAC1,也就是port5与GMAC2之间的link是forcedown的
基本工作流程PPEEnabled:GMAC-PPE-CPU
PPEDisabled:GMAC-CPU
第一个包packetflow:
port0(或1,2,3,4)-switch-port6-GMAC1-PPE;到此packet被送到PPE模块;
PPE模块根据packet的,SRCIP:Port和DSTIP:Port,算得一个HASHID,并把该HASHID存到RXBD里面并由后续的驱动存到skb-cb里面,这个HASHID是后面驱动处理的关键信息;
PPE模块里面有4K条FOEentry用来记录每条NATsession;上面算出来的HASHID就是用来索引这里的FOEentry的;同时FOEentry也会记录数据包的SRCIP:Port和DSTIP:Port;
由于这是第一个packet,因此此条flow的状态是未命中,未命中的情况是要送到CPU由软件去处理的;
至此,送至PDMA并产生中断,让CPU来处理这个包;
CPU正常处理该报文,上送协议栈,并做正常的software的NAT,这些没什么不同;
CPU软件的NAT做完之后,要通过以太网再发出去,在以太网驱动的xmit函数里面有个hook_tx,这就是关键所在,重要的工作都是在hook_tx完成的;
在TXhook里面,分析skb的数据,因为此时的skb已经是经过NAT之后的IP和Port了;同时,由于skb是转发的情况,skb的data和header都是zerocopy的,也就意味着可以从skb的cb里面取出在上面存入的HASHID;
根据取出的HASHID通过查找foeentry可以找到该数据包NAT之前的SRCIP:Port和DSTIP:Port,然后根据现在的数据包内的数据可以找出NAT之后的SRCIP:Port和DSTIP:Port;这样NAT之前和之后的SRCIP:Port和DSTIP:Port都有了,这就是一条完整的NATsession了;
PPE也就知道该如何做NAT了,接下来在收到同样的packet,PPE就照葫芦画瓢的做NAT就是了;同时该条FOEentry的状态也会被设置为bind;
FOEentry的一个例子:
[187768.931427]==========FlowTableEntry=2146(af1a9ea0)===============
[187768.944780]-----------------FlowInfo------------------
[187768.955878]InformationBlock1:21515D76
[187768.964014]InformationBlock2:0003F020
[187768.972157]CreateIPv4HNAPTentry
[187768.979273]IPv4OrgIP/Port:172.16.2.8:59188-192.168.31.231:5001
[187768.991922]IPv4NewIP/Port:192.168.31.92:59188-192.168.31.231:5001
[187769.005089]DMAC=94:DE:80:0A:6C:FCSMAC=78:8A:20:09:08:23
[187769.016001]=========================================
[187769.016001]
[187769.029379]==========FlowTableEntry=1970(af1a67a0)===============
[187769.042710]-----------------FlowInfo------------------
[187769.053794]InformationBlock1:21515D76
[187769.061940]InformationBlock2:0003F020
[187769.070084]CreateIPv4HNAPTentry
[187769.077199]IPv4OrgIP/Port:192.168.31.231:5001-192.168.31.92:59188
[187769.090359]IPv4NewIP/Port:192.168.31.231:5001-172.16.2.8:59188
[187769.103002]DMAC=B8:AC:6F:25:8D:8ASMAC=78:8A:20:09:08:22
[187769.113909]=========================================
[187769.113909]
root@asmc:/
bind完成之后的packageflow:
port0(或1,2,3,4)-switch-port6-GMAC1-PPE
PPEcheckthestatus为hitbind,则PPE按照FOEentry里面的描述做对应的NAT,并发送到对应的port(这里是GMAC1);就不必打扰CPU了;