📄 mytcp_cong.c
字号:
static DEFINE_SPINLOCK( mytcp_cong_list_lock );static LIST_HEAD( mytcp_cong_list );extern int mysysctl_tcp_abc;u32 mytcp_reno_ssthresh(struct sock *sk){ const struct tcp_sock *tp = tcp_sk(sk); return max(tp->snd_cwnd >> 1U, 2U);}static inline int mytcp_is_cwnd_limited(const struct sock *sk, u32 in_flight){ const struct tcp_sock *tp = tcp_sk(sk); u32 left; //printk(KERN_INFO "%s:%d: %d, %d\n", __FUNCTION__, __LINE__, in_flight, tp->snd_cwnd ); if( in_flight >= tp->snd_cwnd ) return 1; //printk(KERN_INFO "%s:%d: the route caps: %x\n", __FUNCTION__, __LINE__, sk->sk_route_caps ); //if (!(sk->sk_route_caps & NETIF_F_TSO)) // return 0; left = tp->snd_cwnd - in_flight; //printk(KERN_INFO "%s:%d: %d\n", __FUNCTION__, __LINE__, left ); if( mysysctl_tcp_tso_win_divisor ){ return left * mysysctl_tcp_tso_win_divisor < tp->snd_cwnd; }else return left <= tcp_max_burst(tp);}void mytcp_slow_start(struct tcp_sock *tp){ //printk(KERN_INFO "sysctl abc: %d\n", mysysctl_tcp_abc ); if( mysysctl_tcp_abc ){ if( tp->bytes_acked < tp->mss_cache ) return; if( mysysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) { if (tp->snd_cwnd < tp->snd_cwnd_clamp) tp->snd_cwnd++; } } tp->bytes_acked = 0; //printk(KERN_INFO "%s:%d: the clamp: %d\n", __FUNCTION__, __LINE__, tp->snd_cwnd_clamp ); if (tp->snd_cwnd < tp->snd_cwnd_clamp) tp->snd_cwnd++;}void mytcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 rtt, u32 in_flight, int flag){ struct tcp_sock *tp = tcp_sk(sk); //printk(KERN_INFO "%s:%d: cwnd: %d, ssthresh: %d\n", __FUNCTION__, __LINE__, tp->snd_cwnd, // tp->snd_ssthresh ); if( !mytcp_is_cwnd_limited(sk, in_flight) ) return; if( tp->snd_cwnd <= tp->snd_ssthresh ) mytcp_slow_start(tp); else if( mysysctl_tcp_abc ){ if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) { tp->bytes_acked -= tp->snd_cwnd*tp->mss_cache; if (tp->snd_cwnd < tp->snd_cwnd_clamp) tp->snd_cwnd++; } }else{ if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { if (tp->snd_cwnd < tp->snd_cwnd_clamp) tp->snd_cwnd++; tp->snd_cwnd_cnt = 0; } else tp->snd_cwnd_cnt++; } //printk(KERN_INFO "%s:%d: the cwnd: %d\n", __FUNCTION__, __LINE__, tp->snd_cwnd );}u32 mytcp_reno_min_cwnd(struct sock *sk){ return 0;}struct tcp_congestion_ops mytcp_reno = { .name = "myreno", .owner = THIS_MODULE, .ssthresh = mytcp_reno_ssthresh, .cong_avoid = mytcp_reno_cong_avoid, .min_cwnd = mytcp_reno_min_cwnd,};int mytcp_register_congestion_control(struct tcp_congestion_ops *ca){ return 0;}void mytcp_unregister_congestion_control(struct tcp_congestion_ops *ca){}struct tcp_congestion_ops mytcp_init_congestion_ops = { .name = "", .owner = THIS_MODULE, .ssthresh = mytcp_reno_ssthresh, .cong_avoid = mytcp_reno_cong_avoid, .min_cwnd = mytcp_reno_min_cwnd,};void mytcp_init_congestion_control(struct sock *sk){ return; struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_congestion_ops *ca; if( icsk->icsk_ca_ops != &mytcp_init_congestion_ops ) return; rcu_read_lock(); list_for_each_entry_rcu(ca, &mytcp_cong_list, list) { if (try_module_get(ca->owner)) { icsk->icsk_ca_ops = ca; break; } } rcu_read_unlock(); if (icsk->icsk_ca_ops->init) icsk->icsk_ca_ops->init(sk);}void mytcp_cleanup_congestion_control(struct sock *sk){ return; struct inet_connection_sock *icsk = inet_csk(sk); if (icsk->icsk_ca_ops->release) icsk->icsk_ca_ops->release(sk); module_put(icsk->icsk_ca_ops->owner);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -