如何在linuxkernel内送一个封包.docVIP

  • 1
  • 0
  • 约7.34千字
  • 约 11页
  • 2018-05-05 发布于天津
  • 举报
如何在linuxkernel内送一个封包

如何在Linux Kernel內送一個封包? 前言 當我們想送一個封包到網路上的時候, 只需要呼叫一個發送的函式即可完成. 然而封包的傳送並不是依照priority決定先後順序, 對於做real time network system的人而言並不是那麼好用. 因此我們要先去了解Linux Kernel內部如何去發送封包, 再去做進一步的改良. 概述(Introduction) 開機時, Linux系統會作初始化的動作, 會針對不同的網路介面卡(network interface card, NIC), 執行對應的驅動程式並設定各個動作的處理函式(handler function), 例如送出或接收封包的處理函式. 另外Linux 系統初始化時會對不同Network Layer protocol (像是IP), 設定創造對應的socket時, 所要呼叫的創建函式(create function). 並且設定與network layer protocal和transport layer protocal相關的變數, 以在應用程式創造socket時使用. 在應用程式作系統呼叫(system call)以送出封包時, 會先經過transport layer的處理函式(以tcp為例則是tcp_sendmsg() )來設定好transport layer相關的標頭(header), 再送交給network layer的處理函式, 此時會作routing和加上對應的標頭, 最後傳送到NIC上的緩衝區, 再發送到網路上. 關於Linux核心與NIC的互動大致上如下圖: 以下是從應用程式開始傳送封包到真的傳到NIC並送到網路上, 這段過程的詳細解釋. 本文 一、 首先send 函式 family會先各自做處理, 接著在kernel內實際上呼叫的就是 sock_sendmsg(sock, msg, len). sock_sendmsg()將一個區域變數iocb初始化後會接著呼叫 __sock_sendmsg(iocb, sock, msg, size), 而__sock_sendmsg()會對iocb略作更動後, 呼叫 sock-ops-sendmsg(). 事實上這裡的sock-ops-sendmsg()以tcp socket為例, 就是tcp_sendmsg(). sock-ops-sendmsg()是在create socket的時候設定. 在__sock_create(family, type, protocol, res, 0)中可以找到net_families[family]-create(sock, protocol), net_families的形態的就是struct net_proto_family的陣列, 這個型態的變數中以inet_family_ops為例, 其中.create = inet_create,因此net_families[family]-create(sock, protocol)即為inet_create. inet_create會依現在需要的protocol來將新的sock中各種handler設好. 作法是比對一個list inetsw[sock-type]中何者protocol符合, 之後將 answer設定為找到的這個element. 而answer的型態為 struct inet_protosw *, 由這個型態中以inetsw_array[]為例子, 這裡面有放著TCP、UDP等, 以TCP為例, 其中很容易發現.ops = inet_stream_ops, 接著找下去就會看到inet_stream_ops其中的.sendmsg = inet_sendmsg, 而inet_sendmsg大致上只是sk-sk_prot-sendmsg的包裹, 回到inetsw_array[]這裡面定義的.prot=tcp_prot, 在tcp_prot的sendmsg欄位被設為tcp_sendmsg, 因此在用TCP的socket連線時, 封包就會被tcp_sendmsg處理. 二、 下一步就是向TCP邁進, 承接上一部份tcp_sendmsg()會呼叫 tcp_push_one(sk, mss_now), tcp_push_one在作了一些測試並且設定time stamp之後呼叫tcp_transmit_skb(sk, skb, 1, sk-sk_allocation), tcp_transmit_skb()大致上將tcp header設定好後,會呼叫icsk-icsk_af_ops-queue_xmit(skb, 0); 在tcp_transmit_skb的開頭中找到const struct ine

您可能关注的文档

文档评论(0)

1亿VIP精品文档

相关文档