linux kernel notes

linux 内核源码阅读记录

所有记录都是参考 linux-3.19.5源码

1 net/socket.c

应用层和内核是通过socket来交互的,系统调用是socketcall,在 net/socket.c里面定义。

->
 161 // The protocol list. Each protocol is registered in here. 
 164 static DEFINE_SPINLOCK(net_family_lock);
 165 static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;


-> sock_register 用于各个协议栈注册协议到socket
-> sock_init
  -> net_sysctl_init 初始化配置参数
  -> skb_init  sk buffer初始化
  -> init_inodecache
  -> register_filesystem 将协议栈注册到文件系统

2 结构在 include/linux/net.h

struct socket{
   ...
   struct sock     *sk;
   const struct proto_ops  *ops;
   ...
};

--sock always refers to struct socket

struct proto_ops {}

3 include/net/sock.h

struct sock{} 结构是传输层socket的抽象,sk always refers to struct sock。network layer 
representation of sockets
struct sock {
  /*
   * Now struct inet_timewait_sock also uses sock_common, so please just
   * don't add nothing before this first member (__sk_common) --acme
   */
  struct sock_common  __sk_common;

  // sock 接收队列
  struct sk_buff_head sk_receive_queue;
  // 接收队列的上限,单位是字节
  int         sk_rcvbuf;
  // sock 异步接收队列,启动DMA才生效?

#ifdef CONFIG_NET_DMA
struct sk_buff_head sk_async_wait_queue;
#endif

  // sock 发送队列
  struct sk_buff_head sk_write_queue;
  // 发送队列的上限,单位是字节
  int         sk_sndbuf;
  // 发送队列缓存的数据,单位是字节
  int         sk_wmem_queued;
  // 当前发送的skb
  struct sk_buff      *sk_send_head;
}


struct sock_common {
   struct proto        *skc_prot;
}

struct proto {} 结构是 socket layer -> transport layer interface

4 net/ipv4/af_inet.c

此文件是实现ipv4的主要逻辑。

-> inet_init ipv4协议族的初始化工作
  -> rc = proto_register(&tcp_prot, 1); 注册tcp协议的proto结构
  -> rc = proto_register(&udp_prot, 1); 注册udp协议的proto结构
  -> rc = proto_register(&raw_prot, 1); 注册原生协议的proto结构
  -> rc = proto_register(&ping_prot, 1); 注册ping协议的proto结构
  -> (void)sock_register(&inet_family_ops); 注册ipv4协议族到socket
  -> inet_add_protocol() 将icmp,udp,tcp,igmp 的net_protocol结构加入到inet_protos数组里
  -> inet_register_protosw() 将inetsw_array数组中定义的tcp,udp,icmp,raw结构注册到inetsw列表
  -> /*
  ->  *  Set the IP module up
  ->  */
  ->
  -> ip_init();
  ->
  -> tcp_v4_init();
  ->
  -> /* Setup TCP slab cache for open requests. */
  -> tcp_init();
  ->
  -> /* Setup UDP memory threshold */
  -> udp_init();
  ->
  -> /* Add UDP-Lite (RFC 3828) */
  -> udplite4_register();
  ->
  -> ping_init();

-> ipv4协议族 
static const struct net_proto_family inet_family_ops = {
  .family = PF_INET,
  .create = inet_create,
  .owner  = THIS_MODULE,
};

-> 
 // The inetsw table contains everything that inet_create needs to build a new socket.
static struct list_head inetsw[SOCK_MAX];
static DEFINE_SPINLOCK(inetsw_lock);

-> 记录了tcp、udp、icmp、raw
static struct inet_protosw inetsw_array[];

->
const struct proto_ops inet_stream_ops; tcp协议的ops
const struct proto_ops inet_dgram_ops; udp协议的ops

5 include/net/protocol.h

struct net_protocol {} 这是一个反向接口吗?当ip layer->transport layer interface

struct inet_protosw {} /* This is used to register socket interfaces for IP protocols. */

6 net/ipv4/protocol.c

-> 保存net_protocol结构的静态数组
const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly;
const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;

7 net/ipv4/tcp_ipv4.c

-> struct proto tcp_prot

-> tcp_v4_init_sock 对tcp的收发buffer、窗口、拥塞控制相关变量进行初始化

8 net/ipv4/udp.c

-> struct proto udp_prot = {

9 include/net/inet_sock.h

struct inet_sock {
    ...
    /* sk and pinet6 has to be the first two members of inet_sock */
    struct sock     sk;
    #if IS_ENABLED(CONFIG_IPV6)
        struct ipv6_pinfo   *pinet6;
    #endif

};

10 include/linux/tcp.h

struct tcp_sock {
 /* inet_connection_sock has to be the first member of tcp_sock */
 struct inet_connection_sock inet_conn;
};

11 include/net/inet_connection_sock.h

struct inet_connection_sock {
    /* inet_sock has to be the first member! */
    struct inet_sock      icsk_inet;
    // 拥塞控制算法相关函数
    const struct tcp_congestion_ops *icsk_ca_ops;
};

12 net/ipv4/tcp.c

-> tcp_init
  -> tcp_register_congestion_control(&tcp_reno); //注册拥塞控制算法,默认是reno算法

13 include/net/tcp.h

/* sysctl variables for tcp */
extern int sysctl_tcp_timestamps;
extern int sysctl_tcp_window_scaling;
extern int sysctl_tcp_sack;

13 TCP接收过程主要函数调用

-> tcp_v4_rcv         net/ipv4/tcp_ipv4.c
  -> tcp_v4_do_rcv    net/ipv4/tcp_ipv4.c
    -> tcp_rcv_established     net/ipv4/tcp_input.c
      -> tcp_ack               net/ipv4/tcp_input.c
        -> tcp_ack_update_window     net/ipv4/tcp_input.c;更新窗口主要是snd_wl1, snd_wnd
          -> tcp_may_update_window   net/ipv4/tcp_input.c;窗口更新的检测条件
          —> tcp_fast_path_check     net/ipv4/tcp_input.c;检测是否打开快速路径 

14 TCP数据发送函数调用

-> tcp_sendmsg          net/ipv4/tcp.c
  -> tcp_push           net/ipv4/tcp.c
    -> __tcp_push_pending_frames          net/ipv4/tcp_output.c
      -> tcp_write_xmit
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值