1、使用五元組創建session,即內網報文的源ip、源port、協議、目的ip、目的port作為key值創建hash表項,結構體如下,其中fib_index是客戶所在vrf。
struct
{
ip4_address_t l_addr;
ip4_address_t r_addr;
u32 proto:8, fib_index:24;
u16 l_port;
u16 r_port;
};
2、cpe接收到報文先查找hash表,如果沒有查找到表示沒有session,通過上訴五元組創建hash,value值是session在pool中的位置。同時建立反向的hash表,反向hash表的五元組是公網ip,轉換后的port,協議,目的ip,目的port。當接收到后續報文時,可直接查找hash表,提取出session做快轉發。
3、如果只用內網五元組作為hash表key值,還有可能有沖突,復用的port可能已經被其他session使用,舉例說明:
nat 公網ip:172.168.0.1,如果只選取內網報文的五元組,則有可能出現以下情況:
第一條流:tcp 1.1.1.1:100->8.8.8.8:50 修改成 172.168.0.1:300->8.8.8.8:50
第二條流:tcp 1.1.1.1:200->8.8.8.8:50 修改成 172.168.0.1:300->8.8.8.8:50
假如只用內網五元組區分可用port,上面的情況nat之后的信息完全一致,返程報文無法區分。所以在選取port的時候,還需建立一個記錄flow的hash表項。報文選取port規則:隨機在每線程可用的port中選取一個port,將nat 公網ip、選取的port、目的ip、目的port、協議做為新的五元組進行查找,如果hash表中沒有,則這個port是可用的,如果hash表中存在,則表明這個port不可用,需要再次查找,查找每線程可用port一定次數后若找不到可用的session,則不做nat轉換(防止沒有可用的port而進入死循環)。
如果新的五元組總數超過65535的話,port也會占用完,極限情況如果所有流量訪問同一個目的ip、目的port,最多只能有65535個會話。在老化和刪除session的時候需要刪除這個新的五元組來釋放port。
通過上訴方法,可建立百萬級別的并發,支撐客戶高并發訪問外網的場景。