第1章 引言 1
1.1 TCP/IP協議棧概述 2
1.1.1 沿協議棧嚮下的處理過程 2
1.1.2 沿協議棧嚮上的處理過程 4
1.2 Linux 2.4.20的源碼組織結構 6
1.3 TCP/IP協議棧和內核控製路徑 9
1.4 版本2.4之後Linux內核的可搶占性 10
1.4.1 Linux係統調用 13
1.4.2 添加新的係統調用 14
1.5 Linux進程和綫程 16
1.5.1 fork() 17
1.5.2 綫程 17
1.5.3 內核綫程 18
1.6 內核同步機製 20
1.6.1 信號量 20
1.6.2 原子操作 21
1.6.3 鏇轉鎖 21
1.7 TCP/IP應用編程接口 22
1.7.1 服務器應用 23
1.7.2 客戶端應用 25
1.7.3 套接字選項 27
1.7.4 選項值 27
1.8 Shutdown 33
1.8.1 關閉功能在內核的實現 33
1.8.2 發送關閉 33
1.8.3 接收關閉 34
1.9 I/O 35
1.9.1 read() 35
1.9.2 write() 35
1.9.3 recv() 35
1.9.4 send() 35
1.9.5 select() 36
1.10 TCP狀態 36
1.10.1 部分關閉 41
1.10.2 部分關閉的tcpdump輸齣 43
1.11 本章總結 43
第2章 協議基礎 45
2.1 TCP 46
2.2 TCP選項(RFC 1323) 49
2.2.1 mss選項 50
2.2.2 窗口縮放選項 50
2.2.3 時間戳選項 51
2.2.4 有選擇確認選項 51
2.3 TCP數據流 53
2.4 延時確認 60
2.5 Nagle算法(RFC 896) 62
2.6 TCP滑動窗口協議 64
2.7 最大化TCP吞吐量 71
2.8 TCP定時器 73
2.8.1 重傳定時器 73
2.8.2 persistent定時器 74
2.8.3 keepalive定時器 75
2.8.4 TIME_WAIT定時器 75
2.9 TCP擁塞控製 76
2.10 TCP性能和可靠性 76
2.10.1 RTTD 77
2.10.2 SACK/DSACK 77
2.10.3 窗口縮放 77
2.11 IP(Internet協議) 78
2.12 路由 79
2.13 netstat 80
2.14 traceroute 81
2.15 ICMP 84
2.16 Ping 84
2.17 ARP/RARP 86
2.18 本章總結 88
第3章 套接字的內核實現 89
3.1 套接字層 90
3.2 VFS和套接字 91
3.3 協議套接字注冊 92
3.4 結構inet_protosw 94
3.5 內核中的套接字組織結構 95
3.6 socket 96
3.7 inet_create(見源碼3-4) 97
3.8 套接字調用流程圖 104
3.9 本章總結 105
第4章 TCP連接設置的內核實現 107
4.1 連接設置 108
4.1.1 服務器端設置 108
4.1.2 服務器端操作 109
4.2 BIND 109
4.2.1 套接字BIND相關的數據結構 110
4.2.2 TCP bind的hash桶 110
4.2.3 tcp_ehash 111
4.2.4 tcp_listening_hash 112
4.2.5 tcp_bhash 112
4.2.6 tcp_hashinfo 113
4.2.7 tcp_bind_hashbucket(見圖4-6) 114
4.2.8 tcp_bind_bucket 114
4.2.9 bind() 115
4.2.10 sys_bind() 115
4.2.11 sockfd_lookup() 116
4.2.12 fget() 116
4.2.13 inet_bind() 116
4.2.14 tcp_v4_get_port() 117
4.2.15 tcp_bind_conflict() 119
4.3 LISTEN 121
4.3.1 sys_listen() 122
4.3.2 inet_listen() 122
4.3.3 tcp_listen_start() 122
4.3.4 listen控製流 125
4.3.5 結構open_request 126
4.3.6 accept隊列已滿 131
4.3.7 鏈接在tcp_ehash hash錶中的已建立套接字 134
4.3.8 當三次握手未完成時連接請求的狀態 134
4.3.9 當三次握手完成後連接請求的狀態 135
4.4 內核對連接請求的處理 136
4.4.1 SYN隊列處理 137
4.4.2 accept隊列處理 138
4.4.3 處理新連接請求的流程 140
4.5 ACCEPT 140
4.5.1 inet_accept() 143
4.5.2 當三次握手完成且應用程序接受後鏈接inode和套接字數據結構 143
4.5.3 新連接已建立後鏈接VFS和內核套接字數據結構 146
4.5.4 新已接受連接套接字的文件錶入口項 146
4.5.5 接受新建立連接的流控製 147
4.6 客戶端設置 147
4.6.1 客戶端操作 147
4.6.2 connect 147
4.6.3 tcp_v4_connect() 148
4.6.4 ip_route_connect() 148
4.6.5 生成連接請求的流控製 149
4.6.6 tcp_v4_hash_connect() 151
4.6.7 __tcp_v4_check_established() 152
4.6.8 tcp_connect() 155
4.6.9 tcp_transmit_skb() 157
4.7 本章總結 159
第5章 sk_buff和協議頭 161
5.1 結構sk_buff 162
5.2 結構skb_shared_info(見圖5-3) 166
5.3 sk_buff和DMA-skb_frag_struct 166
5.3.1 DMA和分段sk_buff 167
5.3.2 sk_buff和IP分段 167
5.3.3 sk_buff和分段 169
5.4 sk_buff的例程操作 169
5.4.1 alloc_skb() 169
5.4.2 skb_reserve() 170
5.4.3 skb_put() 171
5.4.4 skb_push() 173
5.4.5 skb_pull() 174
5.5 構建嚮下遍曆協議層時的協議頭 175
5.5.1 TCP頭的添加 175
5.5.2 IP頭的添加 176
5.5.3 鏈路層頭的添加 177
5.6 解析嚮上遍曆協議層時的協議頭 178
5.6.1 sk_buff指嚮鏈路層驅動要處理的鏈路層頭 178
5.6.2 sk_buff指嚮IP層要處理的IP頭 179
5.6.3 sk_buff指嚮TCP層要處理的TCP頭 180
5.7 本章總結 181
第6章 sk_buff在不同協議層的處理 183
6.1 TCP/IP協議棧嚮下的報文處理 184
6.1.1 從套接字層到設備的報文傳輸路徑 185
6.1.2 TCP報文沿協議棧嚮下處理的內核路徑 187
6.2 準備傳輸的報文 192
6.3 報文嚮下處理的內核流 193
6.4 協議棧嚮上的報文處理過程 195
6.4.1 從設備(接收)到套接字層的報文處理路徑 198
6.4.2 TCP報文沿協議棧嚮上的內核處理路徑 198
6.5 沿協議棧嚮上的報文內核流程 205
6.6 本章總結 205
第7章 TCP發送 207
7.1 TCP分段單元 207
7.1.1 無分散-聚集支持下的分段單元處理 208
7.1.2 無分散-聚集支持的分段處理 210
7.1.3 通過套接字寫1 mss字節的數據 211
7.2 分散-聚集支持的分段處理 212
7.2.1 有分散-聚集支持的分段處理 215
7.2.2 應用程序嚮套接字寫Y字節的數據 216
7.2.3 can_coalesce() 216
7.2.4 tcp_copy_to_page() 217
7.2.5 tcp_mark_push() 217
7.2.6 forced_push() 218
7.2.7 tcp_push() 218
7.2.8 __tcp_push_pending_frames() 219
7.2.9 tcp_snd_test() 220
7.2.10 tcp_nagle_check() 220
7.2.11 tcp_minshall_check() 221
7.2.12 tcp_write_xmit() 221
7.2.13 update_send_head() 223
7.2.14 tcp_push_one() 224
7.2.15 skb_entail() 224
7.3 發送OOB數據 225
7.4 TCP分段單元和發送處理流程 226
7.5 分段和發送機製的函數調用流 227
7.6 本章總結 229
第8章 TCP接收 231
8.1 排隊機製 231
8.1.1 tcp_rcv_established()的處理 232
8.1.2 tcp_prequeue() 234
8.1.3 隊列處理 235
8.1.4 tcp_data_wait() 239
8.1.5 tcp_prequeue_process() 240
8.1.6 lock_sock() 241
8.1.7 __lock_sock() 241
8.1.8 release_sock() 242
8.1.9 __release_sock() 242
8.2 接收隊列中TCP數據的處理 243
8.2.1 cleanup_rbuf() 246
8.2.2 skb_copy_datagram_iovec() 248
8.2.3 從接收緩衝區讀取無分頁的數據 250
8.2.4 應用程序讀取X個字節 250
8.2.5 應用程序讀取n個字節(1 mss = n) 251
8.2.6 應用程序讀取n–X個字節 252
8.2.7 從分頁緩衝區讀取數據 253
8.2.8 應用程序讀取n個字節 253
8.2.9 應用程序讀取1頁的數據 254
8.3 TCP緊急數據處理 255
8.3.1 緊急字節讀取的OOB數據模式 255
8.3.2 tcp_recv_urg() 256
8.3.3 緊急模式處理和緊急字節讀取的內聯數據模式 257
8.4 通過TCP套接字接收數據的數據流圖 260
8.5 本章總結 266
第9章 TCP內存管理 267
9.1 發送端TCP內存管理 267
9.1.1 select_size() 270
9.1.2 tcp_alloc_pskb() 271
9.1.3 alloc_skb() 272
9.1.4 tcp_alloc_page() 273
9.1.5 skb_charge() 274
9.1.6 tcp_mem_schedule() 274
9.1.7 tcp_free_skb() 276
9.1.8 sock_wfree() 277
9.1.9 tcp_write_space() 277
9.1.10 tcp_mem_reclaim() 278
9.1.11 __tcp_mem_reclaim() 279
9.1.12 wait_for_tcp_memory() 279
9.2 接收端TCP內存管理 282
9.2.1 tcp_prune_queue() 285
9.2.2 tcp_clamp_window() 286
9.2.3 tcp_collapse_ofo_queue() 288
9.2.4 tcp_collapse() 289
9.2.5 __skb_queue_purge() 296
9.3 接收緩衝區內存釋放 296
9.4 TCP內存管理中的係統級控製參數 296
9.5 本章總結 298
第10章 TCP定時器 299
10.1 Linux中的定時器 300
10.1.1 mod_timer() 300
10.1.2 detach_timer() 301
10.1.3 del_timer() 301
10.1.4 執行定時器例程的時機 302
10.2 TCP重傳定時器 302
10.2.1 安裝重傳定時器的時機 302
10.2.2 重置或者取消重傳定時器的時機 303
10.2.3 tcp_enter_loss() 306
10.2.4 tcp_retransmit_skb() 308
10.2.5 tcp_retrans_try_collapse() 309
10.2.6 skb_cloned() 311
10.3 零窗口探測定時器 312
10.3.1 首次安裝探測定時器的時機 312
10.3.2 取消連接探測定時器的時機 313
10.3.3 tcp_ack_probe() 313
10.3.4 窗口探測定時器的工作原理 314
10.3.5 tcp_probe_timer() 314
10.3.6 tcp_send_probe0() 315
10.3.7 tcp_write_wakeup() 316
10.4 延時確認定時器 318
10.4.1 ACK的調度時機 319
10.4.2 ACK數據段的發送時機和發送處理過程 320
10.4.3 快速ACK模式 321
10.4.4 __tcp_ack_snd_check() 321
10.4.5 tcp_ack_snd_check() 322
10.4.6 tcp_send_delayed_ack() 323
10.4.7 tcp_delack_timer() 324
10.4.8 tcp_reset_xmit_timer() 326
10.4.9 tcp_write_timer() 327
10.4.10 tcp_clear_xmit_timer() 328
10.5 keepalive定時器 329
10.5.1 激活keepalive定時器的時機 330
10.5.2 如何重置定時器 330
10.5.3 tcp_keepalive_timer() 330
10.6 SYN-ACK定時器 333
10.6.1 SYN-ACK定時器激活的時機 333
10.6.2 SYN-ACK定時器停止的時機 333
10.6.3 tcp_synack_timer() 334
10.7 TIME_WAIT定時器 338
10.7.1 TIME_WAIT定時器的觸發時機 338
10.7.2 tcp_time_wait() 338
10.7.3 tcp_tw_schedule() 339
10.7.4 非再生模式 341
10.7.5 再生模式 342
10.7.6 tcp_twkill() 345
10.7.7 tcp_twcal_tick() 347
10.7.8 __tcp_tw_hashdance() 350
10.8 本章總結 352
第11章 TCP核心處理 353
11.1 傳入TCP數據段處理 354
11.1.1 預測標誌 354
11.1.2 構建預測標誌 355
11.1.3 使用快速路徑的條件 357
11.1.4 使用慢速路徑的時機 357
11.1.5 使用快速路徑的時機 358
11.1.6 與預測標誌相關的注意點 358
11.2 快速路徑處理 359
11.3 慢速路徑處理 362
11.3.1 tcp_sequence() 363
11.3.2 tcp_replace_ts_recent() 364
11.3.3 tcp_event_data_recv() 365
11.3.4 tcp_incr_quickack() 367
11.3.5 tcp_grow_window() 367
11.3.6 __tcp_grow_window() 369
11.3.7 計算通告窗口 370
11.3.8 tcp_receive_window() 370
11.3.9 tcp_select_window() 371
11.3.10 tcp_space() 372
11.3.11 tcp_data_snd_check() 372
11.3.12 __tcp_data_snd_check() 373
11.3.13 tcp_paws_discard() 373
11.4 傳入ACK的處理 375
11.4.1 tcp_packets_in_flight() 378
11.4.2 tcp_ack_is_dubious() 379
11.4.3 tcp_cong_avoid() 380
11.4.4 tcp_ack_update_window() 381
11.4.5 tcp_may_update_window() 382
11.4.6 tcp_clean_rtx_queue() 382
11.5 處理SACK塊 385
11.6 重定序長度 392
11.7 處理TCP緊急指針 395
11.8 在慢速路徑中處理數據段 99
11.8.1 tcp_sack_new_ofo_skb() 407
11.8.2 tcp_sack_maybe_coalesce() 409
11.8.3 tcp_sack_extend() 410
11.8.4 tcp_ofo_queue() 411
11.8.5 tcp_sack_remove() 415
11.9 TCP核心處理 417
11.10 本章總結 418
第12章 TCP狀態處理 419
12.1 擁塞狀態處理概述 420
12.2 TCP狀態 422
12.2.1 TCP_CA_CWR 422
12.2.2 從TCP_CA_CWR狀態撤消 423
12.3 在恢復狀態中處理重復/部分確認 423
12.3.1 tcp_remove_reno_sacks() 424
12.3.2 tcp_try_undo_partial() 425
12.4 在丟失狀態中處理重復/部分確認 426
12.4.1 tcp_try_undo_loss() 427
12.4.2 tcp_check_sack_reneging() 429
12.5 TCP狀態的默認處理 429
12.5.1 tcp_time_to_recover() 432
12.5.2 tcp_head_timedout() 434
12.5.3 tcp_try_to_open() 435
12.5.4 tcp_update_scoreboard() 436
12.5.5 tcp_xmit_retransmit_queue() 438
12.5.6 tcp_packet_delayed() 440
12.6 當確認超過tp→high_seq時TCP非正常狀態的處理 440
12.6.1 TCP_CA_Loss 441
12.6.2 TCP_CA_CWR 441
12.6.3 TCP_CA_Disorder 443
12.6.4 tcp_try_undo_dsack 444
12.6.5 TCP_CA_Recovery 444
12.6.6 tcp_add_reno_sack() 446
12.6.7 tcp_check_reno_reordering() 446
12.6.8 tcp_may_undo() 447
12.6.9 tcp_packet_delayed() 447
12.6.10 tcp_undo_cwr() 448
12.6.11 tcp_mark_head_lost() 449
12.6.12 tcp_sync_left_out() 450
12.7 本章總結 450
第13章 netlink套接字 453
13.1 netlink套接字介紹 453
13.2 啓動時netlink套接字的注冊和初始化 454
13.3 內核netlink套接字的創建 455
13.4 用戶netlink套接字的創建 457
13.5 netlink數據結構 459
13.5.1 nl_table 459
13.5.2 rtnetlink_link 460
13.6 其他重要的數據結構 463
13.6.1 nlmsghdr結構 463
13.6.2 msghdr結構 463
13.7 netlink報文格式 464
13.8 netlink套接字例子—— 添加qdisc的tc命令 465
13.8.1 用戶空間中添加qdisc的tc命令流 465
13.8.2 內核空間的tc命令 466
13.9 內核空間中的tc命令流程圖 470
13.10 本章總結 471
第14章 IP路由 473
14.1 路由 475
14.2 基於策略的路由 477
14.3 多路徑 478
14.4 記錄路由選項(RFC 791)以及Linux棧的處理 482
14.5 源路由 483
14.5.1 嚴格記錄路由 483
14.5.2 鬆散記錄路由 483
14.5.3 SRR處理實現 484
14.6 路由錶和路由緩存的Linux內核實現 490
14.7 路由緩存實現概述 491
14.8 管理路由緩存 496
14.8.1 本地連接的路由緩存 498
14.8.2 __sk_dst_check() 499
14.8.3 鏈接失效並報告給路由子係統 500
14.8.4 dst_link_failure() 501
14.8.5 ipv4_link_failure() 501
14.8.6 dst_set_expires() 501
14.8.7 傳入報文的路由緩存 502
14.8.8 路由緩存計數器 503
14.8.9 rt_periodic_timer 504
14.8.10 rt_may_expire() 506
14.8.11 dst_free() 507
14.8.12 __dst_free() 508
14.8.13 dst_destroy() 509
14.8.14 dst_run_gc() 509
14.8.15 關閉接口和rt_flush_timer 511
14.8.16 rt_cashe_flush() 512
14.9 轉發信息庫的實現概述 513
14.9.1 結構fib_table 515
14.9.2 結構fn_hash 516
14.9.3 結構fn_zone 516
14.9.4 結構fib_node 517
14.9.5 結構fib_info 519
14.9.6 結構fib_nh 520
14.9.7 結構fib_rule 521
14.10 使用ip命令在路由錶中添加新的錶項(RT Netlink接口) 522
14.10.1 當使用嚮路由錶中添加一個錶項的路由選項運行ip命令時的情況 523
14.10.2 inet_rtm_newroute() 523
14.10.3 結構rtmsg 524
14.10.4 結構kern_rta 525
14.10.5 fn_hash_insert() 525
14.10.6 fn_new_zone() 528
14.10.7 fib_create_info() 530
14.10.8 fn_hash_insert() 531
14.11 當使用嚮路由錶中添加一個錶項的規則選項運行ip命令時的情況 532
14.11.1 inet_rtm_newrule() 532
14.11.2 FIB初始化 534
14.12 FIB遍曆流程圖 538
14.12.1 ip_route_output() 539
14.12.2 ip_route_output_key() 539
14.12.3 ip_route_output_slow() 540
14.12.4 ip_dev_find() 551
14.12.5 __in_dev_get() 552
14.12.6 inet_select_addr() 553
14.12.7 路由範圍 554
14.12.8 fib_lookup() 555
14.13 本章總結 563
第15章 Linux中的IP服務質量(IP QoS) 565
15.1 簡介 565
15.2 Linux流量控製的基本組件 566
15.3 Linux中pfifo_fast排隊規則的實現 567
15.4 排隊規則數據結構 570
15.4.1 結構Qdisc 570
15.4.2 結構Qdisc_ops 571
15.4.3 結構Qdisc_class_ops 572
15.4.4 結構cbq_class 573
15.5 tc用戶程序及其內核實現細節 575
15.5.1 tc_modify_qdisc() 576
15.5.2 qdisc_create() 578
15.5.3 cbq_init() 579
15.5.4 qdisc_graft() 580
15.5.5 dev_graft_ qdisc() 581
15.6 為CBQ創建類彆層次的tc命令 582
15.6.1 tc_ctl_tclass() 582
15.6.2 cbq_change_class() 584
15.7 過濾器 585
15.8 u32過濾器實現 589
15.9 路由過濾器實現 592
15.10 enqueue 596
15.10.1 cbq_enqueue() 596
15.10.2 cbq_classify() 597
15.10.3 cbq_enqueue()函數概述 598
15.11 CBQ的Linux實現概述 599
15.12 cbq_dequeue() 599
15.12.1 從net/dev/core.c 601
15.12.2 qdisc_run() 602
15.12.3 qdisc_ restart () 603
15.12.4 cbq_dequeue () 604
15.12.5 cbq_dequeue_1() 605
15.12.6 cbq_dequeue_prio() 605
15.13 本章總結 609
第16章 IP Filter防火牆 611
16.1 Netfilter Hook框架 612
16.2 IP協議棧上的Netfilter Hook 613
16.2.1 用於傳齣報文的鈎子 614
16.2.2 用於傳入報文的鈎子 615
16.3 Netfilter Hook注冊 616
16.4 Netfilter Hook處理 618
16.4.1 nf_hook_slow() 618
16.4.2 nf_iterate() 619
16.4.3 結構nf_hook_ops 620
16.5 兼容性框架 620
16.6 ipchains 624
16.6.1 使用ipchains過濾 625
16.6.2 ipchains的規則鏈 626
16.6.3 結構ipchain 626
16.6.4 結構ip_fwkernel 627
16.6.5 結構ip_reent 627
16.6.6 結構ip_fw 628
16.6.7 ipchains中錶的組織結構 628
16.7 使用ipchains過濾報文 629
16.7.1 ip_fw_check() 629
16.7.2 ip_rule_match() 632
16.8 iptables 634
16.9 iptables過濾規則和目標組織 635
16.9.1 結構ipt_table 636
16.9.2 結構ipt_table_info 636
16.9.3 結構ipt_entry 638
16.9.4 結構ipt_entry_match 639
16.9.5 結構ipt_tcp 640
16.9.6 結構ipt_entry_target 641
16.9.7 結構ipt_standard_target 641
16.10 iptables過濾規則和目標的組織結構 641
16.11 使用iptables過濾報文 641
16.11.1 ipt_do_table() 642
16.11.2 IPT_MATCH_ITERATE 645
16.12 本章總結 646
第17章 網絡軟中斷 647
17.1 使用軟中斷的原因和觸發機製 648
17.1.1 傳輸 648
17.1.2 接收 648
17.2 處理軟中斷 651
17.3 軟中斷的注冊 654
17.4 報文接收以及Rx軟中斷的延遲處理 655
17.5 網絡Rx軟中斷的處理 659
17.6 報文傳輸與軟中斷 663
17.7 本章總結 672
第18章 報文的傳輸和接收 675
18.1 傳輸和接收報文的DMA環緩衝區 675
18.2 報文接收處理 676
18.2.1 支持DMA的報文接收處理流程 677
18.2.2 環緩衝區的接收處理 677
18.3 報文傳輸處理 679
18.3.1 DMA支持的報文傳輸處理過程 679
18.3.2 傳輸環緩衝區 680
18.4 報文傳輸和接收的實現 682
18.4.1 struct etrax_eth_descr 683
18.4.2 struct etrax_dma_descr 683
18.4.3 設備的初始化 684
18.4.4 DMA傳輸環緩衝區的初始化 685
18.4.5 DMA接收環緩衝區的初始化 686
18.5 處理報文接收的Rx中斷 688
18.5.1 Rx DMA緩衝區的初始化 689
18.5.2 e100_rx() 689
18.5.3 産生Rx中斷前DMA緩衝區接收到三個報文時的Rx描述符 690
18.5.4 從DMA緩衝區中取齣第一個報文交給操作係統Rx中斷處理程序後的Rx描述符 691
18.6 報文傳輸 693
18.6.1 e100_send_packet() 693
18.6.2 初始化後的Tx DMA環緩衝區描述符 694
18.6.3 e100_hardware_send_packet() 696
18.6.4 設備DMA Tx環緩衝區中有兩個報文時的處理 696
18.6.5 e100tx_interrupt() 697
18.6.6 傳輸瞭第一個報文並且中斷已産生時的情形 698
18.7 本章總結 699
第19章 lkcd和TCP/IP協議棧的調試 701
19.1 lkcd源碼和補丁 702
19.2 套接字 702
19.3 查看接收套接字緩衝區 704
19.4 查看發送套接字緩衝區 705
19.5 TCP分段單元 708
19.6 發送擁塞窗口和ssthresh 709
19.7 重傳和路由 711
19.8 查看連接隊列和SYN隊列 712
19.9 使用lcrash來查看路由和IP服務質量 715
19.10 使用lcrash調試CBQ(基於類彆的)排隊規則 717
19.11 u32過濾器 718
19.12 路由過濾器 724
19.13 FIB錶的lcrash輸齣 724
19.14 使用tc命令建立路由過濾器 728
19.15 NETLINK數據結構 731
19.15.1 nl_table 731
19.15.2 rtnetlink_link 732
19.16 本章總結 733
第20章 展望 735
· · · · · · (
收起)