歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> linux kernel2.4裡面接收數據分組的過程和體會

linux kernel2.4裡面接收數據分組的過程和體會

日期:2017/2/27 9:46:42   编辑:更多Linux
  最近一個科研項目的需要,在Linux 下面寫了一些代碼。其中要涉及到接收處理一個特殊的分組。這個分組的頭部(IPv6+UDP)由於某種需要而被壓縮改變了。我的代碼要完成的工作之一就是根據某些信息恢復出原始的頭標。如何接收這個分組呢? 一個想法就是,發送分組的時候把以太祯的類型設置為IPv6,這樣內核接收到該分組後,會提交給ip6_rcv(),然後我們在ip6_rcv()函數的開始處,嵌入自己的代碼進行頭標的恢復。但是這樣做總感覺不是很好,我的想法是完成一個相對獨立的LKM,而不需要修改內核的源代碼。 經過分析發現,內核處理接收數據的流程是,網卡驅動把接收到的數據組織好,然後提取以太祯中的協議類型域,然後填寫skb,最後調用netif_rx()把這個skb 放到內核接收隊列裡面。然後系統在自己的軟中斷中通過net_rx_action()查看這個skb 隊列,如果有數據就提取出來,根據skb->protocol來調用相應的處理函數,例如如果是IPV6的話,就調用ip6_rcv(). ip6_rcv()就是整個內核中IPv6協議的一個入口點。 經過這個分析後,我采用了如下的方法來實現我前面的需求。我在內核裡面注冊了一種新的分組協議和該協議的對應的接收處理函數。這樣,當內核接收到我所關心的特殊分組後,在net_rx_action裡面就會尋找到我這個對應的接收處理函數。我在處理函數裡面對IPv6+UDP頭部進行恢復。然後如何提交給ip6入口點呢?呵呵,我這裡采用的是將skb->protocol 域置為 IPv6,然後再次調用netif_rx(),把分組放到接收隊列裡面。這樣在下一個軟中斷到來的時候,我們修改恢復後的IPv6分組就可以被正常接收了。:)) 這裡在實際編程中發現,如果在我的接收函數裡面,如果直接修改內核調用傳入的skb,然後把這個skb再次放到netif_rx()調用後的隊列裡面,會不時出現kernel panic 。後來我采用的是先skb_clone一個sk_buff,然後對這個新buff操作,並將這個新buff放到隊列裡面,而在我的接受函數裡面是把這個原來的skb free掉。現在是OK了。:)) 由於我正在自己的機器上進一步測試我的代碼,現在無聊,就來這裡發了這篇帖子, 也算是一種處理方法把。不知道這個處理方法是否非常OLD :):)




Copyright © Linux教程網 All Rights Reserved