1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| /* application 呼叫 send */
send(clientfd, buffer, sizeof(buffer), 0); /* send 會先在 family 處理完後呼叫 sock_sendmsg */
/* socket 處置 */
sock_sendmsg() /* 設置好 iocb 之後就送交 __sock_sendmsg */
__sock_sendmsg(&iocb, sock, msg, size); /* 將 iocb 再稍做處理後呼叫 sock->ops->sendmsg */
sock->ops->sendmsg(iocb, sock, msg, size);
/* sock->ops->sendmsg 要從 net/socket.c 的 __sock_create() 開始看 */
/* pf = rcu_dereference(net_families[family]); 又是 RCU,這次看的是 inet */
/* pf->create(net, sock, protocol); 所以 pf->create 會指向 inet_create */
/* 看到 net/ipv4/af_inet.c 裡面的 inet_create() 從 list_for_each_entry_rcu(answer, &inetsw[sock->type], list) */
/* 會在 list 找到 inetsw[sock->type] 對應的內容(這次看的還是 tcp),設定到 answer,*/
/* sock->ops = answer->ops; 指向 inet_stream_ops 在 /net/ipv4/af_inet.c 定義 .sendmsg = tcp_sendmsg */
/* 所以 sock->ops->sendmsg 最終指向 tcp_sendmsg() */
/* TCP/IP 處置 */
tcp_sendmsg() /* net/ipv4/tcp.c */
tcp_push_one(sk, mss_now); /* net/ipv4/tcp_output.c */
tcp_write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, sk->sk_allocation); /* */
tcp_transmit_skb(sk, skb, 1, gfp) /* */
icsk->icsk_af_ops->queue_xmit(skb, 0); /* */
/* struct inet_connection_sock 在 include/net/inet_connection_sock.h */
/* 跟 socket 那段搜尋 sock->ops->sendmsg 方法一樣 */
/* 在 net/net/ipv4/tcp_ipv4.c 的 struct inet_connection_sock_af_ops ipv4_specific = { */
/* .queue_xmit = ip_queue_xmit, */
ip_queue_xmit() /* /net/ipv4/ip_ouput.c */
/* ip_route_output_flow() 在 net/ipv4/route.c */
/* __ip_route_output_key() */
/* ip_route_output_slow() */
/* ip_mkroute_input() */
/* __mkroute_output() { rth->u.dst.output=ip_output; } */
ip_local_out(skb);
__ip_local_out(skb);
nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
/* 會去執行 dst_output,要回到 ip_queue_xmit() 的 ip_route_output_flow 開始找 */
/* 最後得知 dst_output = ip_output */
ip_output() /* net/ipv4/ip_output.c */
ip_finish_output()
ip_finish_output2()
neigh_hh_output(dst->hh, skb); /* include/net/neighbour.h */
hh->hh_output(skb); /* 沒有頭緒,全文搜索結果指向 dev_queue_xmit */
/* 裝置處理 */
dev_queue_xmit() /* net/core/dev.c */
dev_hard_start_xmit(skb, dev, txq)
ops->ndo_start_xmit(skb, dev); /* 指向 driver/net/rtl819x/rtl_nic.c 的 re865x_start_xmit */
|
1 則留言:
sock->ops->sendmsg 最終會指向哪個 function 可以從開 socket 呼叫的 socket() 第一個參數來確定。
張貼留言