歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

Linux內核網絡棧代碼的准備知識

  一.Linux內核網絡棧代碼的准備知識

  1. Linux內核ipv4網絡部分分層結構:

  BSD socket層: 這一部分處理BSD socket相關操作,每個socket在內核中以struct socket結構體現。這一部分的文件

  主要有:/net/socket.c /net/protocols.c etc

  INET socket層:BSD socket是個可以用於各種網絡協議的接口,而當用於tcp/ip,即建立了AF_INET形式的socket時,

  還需要保留些額外的參數,於是就有了struct sock結構。文件主要

  有:/net/ipv4/protocol.c /net/ipv4/af_inet.c /net/core/sock.c etc

  TCP/UDP層:處理傳輸層的操作,傳輸層用struct inet_protocol和struct proto兩個結構表示。文件主要

  有:/net/ipv4/udp.c /net/ipv4/datagram.c /net/ipv4/tcp.c /net/ipv4/tcp_input.c /net/ipv4//tcp_output.c /net/ipv4/tcp_minisocks.c /net/ipv4/tcp_output.c /net/ipv4/tcp_timer.c

  etc

  IP層:處理網絡層的操作,網絡層用struct packet_type結構表示。文件主要有:/net/ipv4/ip_forward.c

  ip_fragment.c ip_input.c ip_output.c etc.

  數據鏈路層和驅動程序:每個網絡設備以struct net_device表示,通用的處理在dev.c中,驅動程序都在/driver/net目

  錄下。

  2. 兩台主機建立udp通信所走過的函數列表

  ^

  |        sys_read                 fs/read_write.c

  |        sock_read                net/socket.c

  |        sock_recvmsg             net/socket.c

  |        inet_recvmsg             net/ipv4/af_inet.c

  |        udp_recvmsg              net/ipv4/udp.c

  |        skb_recv_datagram        net/core/datagram.c

  |        -------------------------------------------

  |        sock_queue_rcv_skb       include/net/sock.h

  |        udp_queue_rcv_skb        net/ipv4/udp.c

  |        udp_rcv                  net/ipv4/udp.c

  |        ip_local_deliver_finish net/ipv4/ip_input.c

  |        ip_local_deliver         net/ipv4/ip_input.c

  |        ip_recv                  net/ipv4/ip_input.c

  |        net_rx_action            net/dev.c

  |        -------------------------------------------

  |        netif_rx                 net/dev.c

  |        el3_rx                   driver/net/3c309.c

  |        el3_interrupt            driver/net/3c309.c

  ==========================

  |        sys_write                fs/read_write.c

  |        sock_writev              net/socket.c

  |        sock_sendmsg             net/socket.c

  |        inet_sendmsg             net/ipv4/af_inet.c

  |        udp_sendmsg              net/ipv4/udp.c

  |        ip_build_xmit            net/ipv4/ip_output.c

  |        output_maybe_reroute     net/ipv4/ip_output.c

  |        ip_output                net/ipv4/ip_output.c

  |        ip_finish_output         net/ipv4/ip_output.c

  |        dev_queue_xmit           net/dev.c

  |        --------------------------------------------

  |        el3_start_xmit           driver/net/3c309.c

  V

  3. 網絡路徑圖、重要數據結構sk_buffer及路由介紹

  Linux-net.pdf 第2.1章 第2.3章 第2.4章

  4. 從連接、發送、到接收數據包的過程

  Linux-net.pdf 第4、5、6章詳細闡述

  二.Linux的tcp-ip棧代碼的詳細分析

  1.數據結構(msghdr,sk_buff,socket,sock,proto_ops,proto)

  bsd套接字層,操作的對象是socket,數據存放在msghdr這樣的數據結構:

  創建socket需要傳遞family,type,protocol三個參數,創建socket其實就是創建一個socket實例,然後創建一個文件描述符結構,並且互相建立一些關聯,即建立互相連接的指針,並且初始化這些對文件的寫讀操作映射到socket的read,write函數上來。

  同時初始化socket的操作函數(proto_ops結構),如果傳入的type參數是STREAM類型,那麼就初始化為SOCKET->ops為inet_stream_ops,如果是DGRAM類型,則SOCKET-ops為inet_dgram_ops。對於inet_stream_ops其實是一個結構體,包含了stream類型的socket操作的一些入口函數,在這些函數裡主要做的是對socket進行相關的操作,同時通過調用下面提到的sock中的相關操作完成socket到sock層的傳遞。比如在inet_stream_ops裡有個inet_release的操作,這個操作除了釋放socket的類型空間操作外,還通過調用socket連接的sock的close操作,對於stream類型來說,即tcp_close來關閉sock

  釋放sock。

  創建socket同時還創建sock數據空間,初始化sock,初始化過程主要做的事情是初始化三個隊列,receive_queue(接收到的數據包sk_buff鏈表隊列),send_queue(需要發送數據包的sk_buff鏈表隊列),backlog_queue(主要用於tcp中三次握手成功的那些數據包,自己猜的),根據family、type參數,初始化sock的操作,比如對於family為inet類型的,type為stream類型的,sock->proto初始化為tcp_prot.其中包括stream類型的協議sock操作對應的入口函數。

  在一端對socket進行write的過程中,首先會把要write的字符串緩沖區整理成msghdr的數據結構形式(參見Linux內核2.4版源代碼分析大全),然後調用sock_sendmsg把msghdr的數據傳送至inet層,對於msghdr結構中數據區中的每個數據包,創建sk_buff結構,填充數據,掛至發送隊列。一層層往下層協議傳遞。一下每層協議不再對數據進行拷貝。而是對sk_buff結構進行操作。

Copyright © Linux教程網 All Rights Reserved