<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                前面已經把分析openVswitch源代碼的基礎([openVswitch(OVS)源代碼分析之數據結構](http://blog.csdn.net/yuzhihui_no1/article/details/39188373))寫得非常清楚了,雖然訪問的人比較少,也因此讓我看到了一個現象:第一篇,[openVswitch(OVS)源代碼分析之簡介](http://blog.csdn.net/yuzhihui_no1/article/details/39161515)其實就是介紹了下有關于云計算現狀和openVswitch的各個組成模塊,還有籠統的介紹了下其工作流程,個人感覺對于學習openVswitch源代碼來說沒有多大含金量。云計算現狀是根據公司發展得到的個人體會,對學習openVswitch源代碼其實沒什么幫助;openVswitch各個組成模塊到網上一搜一大堆,更別說什么含金量了;最后唯一一點還算過的去的就是openVswitch工作流程圖,對從宏觀方面來了解整個openVswitch來說還算是有點幫助的。但整體感覺對于學openVswitch源代碼沒有多少實質性的幫助,可是訪問它的人就比較多。相反,第二篇,[openVswitch(OVS)源代碼分析之數據結構](http://blog.csdn.net/yuzhihui_no1/article/details/39188373)分析了整個openVswitch源代碼中涉及到的主要數據結構,這可是花了我不少精力。它也是分析整個源代碼的重要基礎,更或者說可以把它當做分析openVswitch源代碼的字典工具。可是訪問它的人數卻是少的可憐,為什么會這樣呢? 網上有很多blog寫有關于openVswitch的,但是絕大部分只是介紹openVswitch以及怎么安裝配置它,或者是一些命令的解釋。對于源代碼的分析是非常少的,至少我開始學習openVswitch時在網上搜資料那會是這樣的。因此對于一個開始接觸學習openVswitch源代碼的初學者來說是非常困難的,什么資料都沒有(當然官網上還是有些資料得,如果你英文夠好,看官網的資料也是個不錯的選擇),只得從頭開始去分析,可是要想想openVswitch是由一個世界級的杰出團隊花幾年的時間設計而成的,如果要從零開始學習分析它,要到猴年馬月。所幸的是我開始學的時候,公司前輩們提供了些學習心得以及結構資料,所以在此我也把自己的學習心得和一些理解和大家分享。如有不正確之處,望大家指正,謝謝!!! 言歸正傳,基礎已經學習過了,下面來正真分析下openVswitch的工作流程源代碼。 首先是數據包的接受函數,這是在加載網卡時把網卡綁定到openVswitch端口上(ovs-vsctl add-port br0 eth0),綁定后每當有數據包過來時,都會調用該函數,把數據包傳送給這個函數去處理。而不是像開始那樣(未綁定前)把數據包往內核網絡協議棧中發送,讓內核協議棧去處理。openVswitch中數據包接受函數為:void ovs_vport_receive(struct vport *vport, struct sk_buff *skb);函數,該函數所在位置為:datapath/vport.c中。實現如下: ~~~ // 數據包接受函數,綁定網卡后,所有數據包都是從這個函數作為入口傳入到openVswitch中去處理的, // 可以說這是openVswitch的入口點。參數vport:數據包從哪個端口進來的;參數skb:數據包的地址指針 void ovs_vport_receive(struct vport *vport, struct sk_buff *skb) { struct pcpu_tstats *stats; // 其實這個東西一直沒弄明白,大概作用是維護CPU的鎖狀態 stats = this_cpu_ptr(vport->percpu_stats); // 開始獲取到CPU的鎖狀態,這和linux內核中的自旋鎖類似 u64_stats_update_begin(&stats->syncp); // 開始上鎖 stats->rx_packets++; // 統計數據包的個數 stats->rx_bytes += skb->len; // 記錄數據包中數據的大小 u64_stats_update_end(&stats->syncp);// 結束鎖狀態 if (!(vport->ops->flags & VPORT_F_TUN_ID)) // 這是種狀態處理 OVS_CB(skb)->tun_key = NULL; // 其實呢這個函數中下面這行代碼才是關鍵,如果不是研究openVswitch而是為了工作,個人覺得沒必要(估計也不可能) // 去弄清楚每條代碼的作用。只要知道大概是什么意思,關鍵代碼有什么作用,如果要添加自己的代碼時,該往哪個地方添加就可以了。 // 下面這行代碼是處理數據包的函數調用,是整個openVswitch的核心部分,傳入的參數和接受數據包函數是一樣的。 ovs_dp_process_received_packet(vport, skb); } ~~~ 俗話說有接必有還,有進必有出嘛。上面的是數據包進入openVswitch的函數,那一定有其對應的出openVswitch的函數。數據包進入openVswitch后會調用函數ovs_dp_process_received_packet(vport,skb);對數據包進行處理,到后期會分析到,這個函數對數據包進行流表的匹配,然后執行相應的action。其中action動作會操作對數據包進行一些修改,然后再把數據包發送出去,這時就會調用vport.c中的數據包發送函數:?ovs_vport_send(struct vport *vport, struct sk_buff *skb);來把數據包發送到端口綁定的網卡設備上去,然后網卡驅動就好把數據包中的數據發送出去。當然也有些action會把數據包直接向上層應用發送。下面來分析下數據包發送函數的實現,函數所在位置為:datapath/vport.c中。 ~~~ // 這是數據包發送函數。參數vport:指定由哪個端口發送出去;參數skb:指定把哪個數據包發送出去 int ovs_vport_send(struct vport *vport, struct sk_buff *skb) { // 這是我自己加的代碼,為了過濾掉ARP數據包。這里額外的插一句,不管在什么源代碼中添加自己的代碼時 // 都要在代碼開頭處做上自己的標識,因為這樣不僅便于自己修改和調試、維護,而且也讓其他人便于理解 /*===========yuzhihui:==============*/ if (0x806 == ntohs(skb->protocol)) { arp_proc_send(vport,skb);// 自定義了一個函數處理了ARP數據包 } // 在前篇數據結構中講了ops是vport結構中的一些操作函數的函數指針集合結構體 // 所以vport->ops->send()是函數指針來調用函數,把數據包發送出去 int sent = vport->ops->send(vport, skb); if (likely(sent)) { // 定義了一個判斷宏likely(),如果發送成功執行下面 struct pcpu_tstats *stats; // 下面的這些代碼是不是覺得非常眼熟,沒錯就是接受函數中的那些代碼 stats = this_cpu_ptr(vport->percpu_stats); u64_stats_update_begin(&stats->syncp); stats->tx_packets++; stats->tx_bytes += sent; u64_stats_update_end(&stats->syncp); } return sent; // 返回的sent是已經發送成功的數據長度 } ~~~ 這兩個函數就是openVswitch中收發數據包函數了,對這兩個函數沒有完全去分析它的所有代碼,這也不是我的本意,我只是想讓初學者知道這是數據包進入和離開openVswitch的函數。其實知道了這個是非常有用的,因為不管你是什么數據包,只要是到該主機的(當然了包括主機內的各種虛擬機及服務器),全部都會經過這兩個函數(對于接受的數據時一定要進過接受函數的,但是發送數據包有時候到不了發送函數的),那么要對數據包進行怎么樣的操作那就全看你想要什么操作了。 在這兩個函數中對數據包操作舉例: 數據包接受函數中操作:如果你要阻斷和某個IP主機間的通信(或者對某個IP主機數據包進行特殊處理),那么你可以在數據進入openVswitch的入口函數(ovs_vport_receive(struct vport *vport, struct sk_buff *skb);)中進行處理,判斷數據包中提取到的IP對比,如果是指定IP則把這個數據包直接銷毀掉(也可以自己定義函數做些特殊操作)。這樣就可以對整個數據進行控制。 數據包發送函數中操作:就像上面的函數中我自己寫的那些代碼一樣,提取數據包中數據包類型進行判斷,當判斷如果是ARP數據包時,則調用我自定義的 arp_proc_send(vport,skb);函數進行去處理,而不是貿然的直接把它發送出去,因為你不知道該數據包發送的端口是什么類型的。如果是公網IP端口,那么就在自定義函數中直接把這個數據包掐死掉(ARP數據包是在局域網內作用的,就算發到公網上也會被處理掉的);如果是發送到外層局域網中或者是相連的服務器中,則修改數據包中的目的Mac地址進行洪發;又如果是個ARP請求數據包,則把該數據包修改為應答包,再原路發送回去,等等情況;這些操作控制都是在發送數據包函數中做的手腳。 以上就是openVswitch(OVS)工作流程中的數據包收發函數,經過大概的分析和應用舉例說明,我想對于初學者來說應該知道大概在哪個地方添加自己的代碼,實現自己的功能要求了。 轉載請注明原文出處,原文地址:[http://blog.csdn.net/yuzhihui_no1/article/details/39298321](http://blog.csdn.net/yuzhihui_no1/article/details/39298321) 如有不正確之處,望大家指正,謝謝!!!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看