下面看一個(gè)特別重要的框架,也可以稱(chēng)為是擁塞控制引擎,如下結(jié)構(gòu)體所示, tcp_congestion_ops描述了一套擁塞控制算法所需要支持的操作 。這個(gè)框架定義了一些鉤子函數(shù),Linux內(nèi)核中不同的擁塞控制算法根據(jù)算法思想實(shí)現(xiàn)以下鉤子函數(shù),然后進(jìn)行注冊(cè)即可完成擁塞控制算法的設(shè)計(jì)。
struct tcp_congestion_ops {
struct list_head list;
u32 key;
u32 flags;
/* initialize private data (optional) */
void (*init)(struct sock *sk);
/* cleanup private data (optional) */
void (*release)(struct sock *sk);
/* return slow start threshold (required) */
u32 (*ssthresh)(struct sock *sk);
/* do new cwnd calculation (required) */
void (*cong_avoid)(struct sock *sk, u32 ack, u32 acked);
/* call before changing ca_state (optional) */
void (*set_state)(struct sock *sk, u8 new_state);
/* call when cwnd event occurs (optional) */
void (*cwnd_event)(struct sock *sk, enum tcp_ca_event ev);
/* call when ack arrives (optional) */
void (*in_ack_event)(struct sock *sk, u32 flags);
/* new value of cwnd after loss (required) */
u32 (*undo_cwnd)(struct sock *sk);
/* hook for packet ack accounting (optional) */
void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample);
/* suggest number of segments for each skb to transmit (optional) */
u32 (*tso_segs_goal)(struct sock *sk);
/* returns the multiplier used in tcp_sndbuf_expand (optional) */
u32 (*sndbuf_expand)(struct sock *sk);
/* call when packets are delivered to update cwnd and pacing rate,
* after all the ca_state processing. (optional)
*/
void (*cong_control)(struct sock *sk, const struct rate_sample *rs);
/* get info for inet_diag (optional) */
size_t (*get_info)(struct sock *sk, u32 ext, int *attr,
union tcp_cc_info *info);
char name[TCP_CA_NAME_MAX];
struct module *owner;
};
用戶(hù)可以通過(guò)自定義以上鉤子函數(shù)實(shí)現(xiàn)定制擁塞控制算法,并進(jìn)行注冊(cè)。以下截取cubic擁塞控制算法對(duì)接口的實(shí)現(xiàn)、注冊(cè)****的代碼片段。 可以注意到cubic只實(shí)現(xiàn)了擁塞控制引擎tcp_congestion_ops的部分鉤子函數(shù),因?yàn)橛幸恍┿^子函數(shù)是必須實(shí)現(xiàn),有一些是根據(jù)算法選擇實(shí)現(xiàn)的。
static struct tcp_congestion_ops cubictcp __read_mostly = {
.init = bictcp_init,
.ssthresh = bictcp_recalc_ssthresh,
.cong_avoid = bictcp_cong_avoid,
.set_state = bictcp_state,
.undo_cwnd = tcp_reno_undo_cwnd,
.cwnd_event = bictcp_cwnd_event,
.pkts_acked = bictcp_acked,
.owner = THIS_MODULE,
.name = "cubic",
};
static int __init cubictcp_register(void)
{
BUILD_BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE);
beta_scale = 8*(BICTCP_BETA_SCALE+beta) / 3
/ (BICTCP_BETA_SCALE - beta);
cube_rtt_scale = (bic_scale * 10); /* 1024*c/rtt */
cube_factor = 1ull < < (10+3*BICTCP_HZ); /* 2^40 */
/* divide by bic_scale and by constant Srtt (100ms) */
do_div(cube_factor, bic_scale * 10);
return tcp_register_congestion_control(&cubictcp);
}
static void __exit cubictcp_unregister(void)
{
tcp_unregister_congestion_control(&cubictcp);
}
module_init(cubictcp_register);
module_exit(cubictcp_unregister);
在Linux用戶(hù)態(tài)可以 通過(guò)參數(shù)查看當(dāng)前使用的擁塞控制算法、當(dāng)前可支持的擁塞控制算法 。如下表所示是兩個(gè)參數(shù)以及含義。
參數(shù) | 含義 |
---|---|
net.ipv4.tcp_congestion_control | 當(dāng)前運(yùn)行的擁塞控制算法 |
net.ipv4.tcp_available_congestion_control | 當(dāng)前可支持的擁塞控制算法 |
具體如下圖所示,通過(guò)參數(shù)看到當(dāng)前可支持的擁塞控制算法以及當(dāng)前使用的擁塞控制算法。可以看到當(dāng)前可支持的擁塞控制算法中包含bbr算法, bbr算法在內(nèi)核版本4.9開(kāi)始支持的。
如果留意的話,在本文開(kāi)始時(shí)提到了很多傳統(tǒng)的擁塞控制算法,那么在上面的命令中沒(méi)有看到,其實(shí)有眾多擁塞控制算法在Linux中沒(méi)有進(jìn)行安裝,如下命令 查看Linux系統(tǒng)中所有已實(shí)現(xiàn)的擁塞控制算法模塊 :
如果想安裝特定的擁塞控制算法可以通過(guò)modprobe命令對(duì)指定的擁塞控制算法進(jìn)行安裝,如下所示安裝了Vegas擁塞控制算法,此時(shí)再查看當(dāng)前系統(tǒng)中可以使用的擁塞控制算法,多了一個(gè)Vegas算法。
除了可以動(dòng)態(tài)查看當(dāng)前Linux系統(tǒng)可用的擁塞控制算法、當(dāng)前使用的擁塞控制算法外還可以動(dòng)態(tài)切換擁塞控制算法。如下所示將默認(rèn)的cubic擁塞控制算法切換為bbr擁塞控制算法。
切換后驗(yàn)證如下,當(dāng)前運(yùn)行的擁塞控制算法由之前的cubic擁塞控制算法切換到了bbr擁塞控制算法。
至此本文關(guān)于Linux內(nèi)核網(wǎng)絡(luò)中擁塞控制的大概框架、原理介紹到這,文中有表達(dá)有誤或者不準(zhǔn)確的地方歡迎指正。關(guān)于具體的每個(gè)擁塞控制算法的實(shí)現(xiàn),將在后續(xù)文章中呈現(xiàn)。
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1360瀏覽量
40185 -
Linux
+關(guān)注
關(guān)注
87文章
11207瀏覽量
208720 -
網(wǎng)絡(luò)
+關(guān)注
關(guān)注
14文章
7485瀏覽量
88541
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論