OVS packet處理流程(三十二)

2021-10-07 05:17:26 字數 3330 閱讀 2430

這來主要看看ovs從網路介面收到packet後的一系列操作。

在核心模組啟動的時候會初始化vport子系統(ovs_vport_init),各種vport型別,那麼什麼時候會呼叫相應的函式與實際網路裝置建立聯絡?其實當我們在為網橋增設埠的時候,就會進入ovs_netdev_vport_ops中的create方法,進而 註冊網路裝置。

看ovs-vsctl add-port br0 eth1 實際做了什麼?

struct netdev_vport 

;const

struct vport_ops ovs_netdev_vport_ops =

;--datapath/vport-netdev.c

static

struct vport *

netdev_create

(const

struct vport_parms *parms)

//不是環迴介面;而且底層鏈路層是乙太網;netdev->netdev_ops == &internal_dev_netdev_ops 顯然為false

err =

netdev_rx_handler_register

(netdev_vport->dev, netdev_frame_hook, vport);[

//核心,收到packet後會呼叫]() netdev_frame_hook處理;

dev_set_promiscuity

(netdev_vport->dev,1)

;//設定為混雜模式;

netdev_vport->dev->priv_flags |

= iff_ovs_datapath;

//設定netdevice私有區域的標識;

return vport;

}--datapath/vport.h 建立vport所需要的引數結構

struct vport_parms

;

函式netdev_rx_handler_register(struct net_device *dev,rx_handler_func_t *rx_handler, void *rx_handler_data)定義在 linux/netdevice.h 實現在 net/core/dev.c 中,為網路裝置dev註冊乙個receive handler,rx_handler_data指向的是這個receive handler是用的記憶體區域(這裡存的是vport,裡面有datapath的相關資訊)。這個handler 以後會被 __netif_receive_skb() 呼叫,實際就是更新netdevice中的兩個指標域,rcu_assign_pointer(dev->rx_handler_data, rx_handler_data), rcu_assign_pointer(dev->rx_handler, rx_handler) 。

netif_receive_skb(struct sk_buff *skb)從網路中接收資料,它是主要的接收資料處理函式,總是成功,這個buffer在擁塞處理或協議層的時候可能被丟棄。這個函式只能從軟中斷環境(softirq context)中呼叫,並且中斷允許。返回值 net_rx_success表示沒有擁塞,net_rx_drop包丟棄。(實現細節暫時沒看)

接下來進入我們的鉤子函式 netdev_frame_hook(datapath/vport-netdev.c)這裡主要看核心版本》=2.6.39的實現。

static rx_handler_result_t netdev_frame_hook

(struct sk_buff *

*pskb)

函式 netdev_port_receive 首先得到乙個packet的拷貝,否則會損壞先於我們而來的packet使用者 (e.g. tcpdump via af_packet),我們之後沒有這種情況,因為會告知handle_bridge()我們獲得了那個packet 。

skb_push是將skb的資料區向後移動*_hlen長度,為了存入幀頭;而skb_put是擴充套件資料區後面為存資料memcpy做準備。

static

void

netdev_port_receive

(struct vport *vport,

struct sk_buff *skb)

接下來將收到的packet傳給datapath處理(datapath/vport.c),引數vport是收到這個包的vport(表徵物理介面和datapath),skb是收到的資料。讀的時候要用rcu_read_lock,這個包不能被共享而且skb->data 應該指向乙太網頭域,而且呼叫者要確保已經執行過 compute_ip_summed() 初始化那些校驗和域。

void

ovs_vport_receive

(struct vport *vport,

struct sk_buff *skb)

接下來我們的datapath模組來處理傳上來的packet(datapath/datapath.c),首先我們要判斷如果存在skb->cb域中的ovs data sw_flow 是空的話,就要從packet中提攜構造;函式 ovs_flow_extract 從乙太網幀中構造 sw_flow_key,為接下來的流表查詢做準備;流表結構struct flow_table定義在flow.h中,流表實在ovs_flow_init的時候初始化的?? 如果沒有match成功,就會upcall遞交給使用者空間處理(見vswitchd模組分析),匹配成功的話執行flow action(接下來就是openflow相關)。

void

ovs_dp_process_received_packet

(struct vport *p,

struct sk_buff *skb)

ovs_cb

(skb)

->flow = flow;

}

stats_counter =

&stats->n_hit;

ovs_flow_used

(ovs_cb

(skb)

->flow, skb)

;ovs_execute_actions

(dp, skb)

;

out:

/* update datapath statistics. */

u64_stats_update_begin

(&stats->sync);(

*stats_counter)++;

u64_stats_update_end

(&stats->sync)

;}

springmvc三十 異常處理流程

handlerexceptionresolvers 異常解析也是springmvc的9大元件之一。org.springframework.web.servlet.handlerexceptionresolver org.springframework.web.servlet.mvc.method.a...

IRP 處理流程

本文通過開啟乙個檔案物件為例子,描述了乙個帶有兩個i o stack location的irp的詳細處理過程。當然乙個irp可以有多個i o stack location,具體個數取決於將要處理該請求的驅動的層數。下圖詳細描述了驅動程式是如何通過使用i o支援例程 io routines 來處理ir...

異常處理流程

異常類結構 來觀察兩個異常類的繼承關係 可以發現所有的異常型別最高的繼承類是throwable,並且通過doc文件可以發現在throwable下有兩個子類 error 指的是jvm錯誤,這個時候的程式並沒有執行,無法處理 exception 指的是程式執行中產生的異常,使用者可以使用異常處理格式處理...