Linux網路子系統中鏈路層中GRO的處理

2021-07-02 02:18:46 字數 2436 閱讀 7139

根據上篇博文的介紹,gro需要支援gro的每種協議都要實現自己的報文匹配合併函式和合併完成函式。這裡我們先來看看鏈路層上

實現的自己的gro函式。

鏈路層的接收匹配函式__napi_gro_receive(napi, skb):

該函式對報文進行匹配,並不合併報文。

匹配規則(必須同時滿足以下兩個條件):

1、兩個報文的接收dev必須相同。

2、兩個報文的以太頭必須相同。

static int__napi_gro_receive(struct napi_struct *napi,struct sk_buff *skb)

return dev_gro_receive(napi, skb);

}intdev_gro_receive(struct napi_struct *napi,struct sk_buff *skb)

/*如果是ip 分片報文,不進行gro處理,因為如果報文是經過三層**的報文,不需要重組後再**。

是否需要重組交由ip層進行處理,這裡就不進行gro的處理了。

*/if (skb_is_gso(skb) || skb_has_frags(skb))

/*加rcu讀鎖對 ptype_base hahs 鍊錶進行保護*/

rcu_read_lock();

/*遍歷鍊錶,找到處理該型別報文的ptype,

*並且該型別的ptype  實現了處理gro 的函式

*/list_for_each_entry_rcu(ptype, head, list)

rcu_read_unlock();

/*如果沒找到對該協議型別報文進行處理的gro,不進行gro操作*/

if (&ptype->list == head)

same_flow = napi_gro_cb(skb)->same_flow;

ret = napi_gro_cb(skb)->free ? gro_merged_free :

gro_merged;

/*如果協議的gro處理函式返回了合併後的報文,

*就呼叫napi_gro_complete把報文送進協議棧進行處理

*/if (pp)

/*如果same 被設定了,說明在鍊錶上找到了相匹配的報文了,

*已經合併過了,不再需要快取了

*/if (same_flow)

/*如果沒找到相匹配的報文,需要快取。

*快取前需要判斷佇列是否已滿或該報文是否應該快取

*/if (napi_gro_cb(skb)->flush ||

napi->gro_count >= max_gro_skbs)

/*快取沒有匹配的報文到gro_list,返回值為gro_held*/

napi->gro_count++;

napi_gro_cb(skb)->count = 1;

skb_shinfo(skb)->gso_size = skb_gro_len(skb);

skb->next = napi->gro_list;

napi->gro_list = skb;

ret = gro_held;

pull:

/*經過這個協議棧的gro receive的處理,

*這時napi_gro_cb(skb)->data_offset欄位已經設定好了。

*如果gro需要處理的資料不在skb的線性區,

*把需要的資料copy到線性區,方便以後操作

*/if (skb_headlen(skb) < skb_gro_offset(skb))

}ok:

return ret;

normal:

ret = gro_normal;

goto pull;

}鏈路層的gro完成函式:

合併完成後的報文呼叫該函式來把報文送入協議棧。

static intnapi_gro_complete(struct sk_buff *skb)

/*找到相關協議把報文送給協議的grp_complete函式處理*/

rcu_read_lock();

list_for_each_entry_rcu(ptype, head, list)

rcu_read_unlock();

if (err)

/*各層協議處理完成後,送給協議棧進行處理*/

out:

return netif_receive_skb(skb);

}我們從上面分析看到,鏈路層處理完鏈路層上gro的處理後,會再呼叫網路層上對應得gro處理。每一層協議自己負責自己的gro處理。上次處理完後把處理結果返給下一層。最終由鏈路層來根據處理結果來把報文送給協議棧 。

下文我們分析一下ip層對gro的處理實現。

Linux網路子系統中協議棧的入口處理

網路驅動接收到報文後,會初始化skb protocol 字段。鏈路層的接收函式netif receive skb會根據該字段來確定把報文送給那個協議模組進一步處理。乙太網的裝置呼叫eth type trans 來給skb protocol賦值。be16eth type trans struct sk...

網路子系統在鏈路層的收發過程剖析(四)

5 資料報的傳送 資料報的傳送為接收的反過程,傳送過程較之接收過程的複雜性在於它有乙個流量控制層 trafficing control layer 用於實現 os,但不是本文關注的目標。1 netif schedule 當核心有資料報等待傳送時,它會間接呼叫 netif schedule 去處理這些...

Linux 網路子系統底層機制分析 1

linux 網路子系統底層機制分析 1 網路子系統在linux中的地位非常重要。在如今這個嚴重依賴網際網路,強調協同工作的時代,乙個高效,穩定的網路處理系統是留住使用者群的基本手段。前段時間花了一部分時間學習了一下linux的網路子系統的源 以及一些處理機制。這部分是由於工作的原因,另一部分原因是想...