1. 单速率CAR
单速率rate,两个令牌桶C和E,桶深分别为,CBS(Committed Burst Size),EBS(Excess Burst Size);
添加令牌过程:
以rate 速率添加令牌,首先往令牌桶C添加,如果C添加满,再添加E,直到E添满为止。
报文发送流程(色盲模式):
报文长度为B,检查桶C,如果Tc>=B,则标记报文为绿色,Tc-=B;
否则检查桶E,如果Te>=B,则标记报文为黄色,Te-=B;
否则标记报文为红色
注意还有一个非色盲模式,其实就是报文过程中添加对于报文之前的颜色处理,
如果之前标记绿色才检查桶C,如果之前标记绿色或黄色者检查桶E,
如果之前标记为红色则直接标记报文为红色。
可以将色盲模式视为非色盲模式的一个特例,即色盲模式时将报文之前的颜色均以绿色对待。(在双速率CAR中的色盲、非色盲含义和此相同)
伪码实现时,使用时间戳来处理“令牌添加”过程,即令牌添加由报文触发,实现如下:
1. 整个系统保存一个时钟,该时钟会定期更新;
2. 每个CAR保存一个时间戳(双速率CAR需要保存两个,每个令牌桶一个),记录上一次报文发送的时刻。
3. 报文到达时,查看上一次报文发送的时间戳和系统时钟间的时间差,计算这段时间可以添加的令牌数。
伪码实现时考虑了非色盲模式,请参考,谢谢!
CAR_one_rate(B, pre_color) { tokens = rate * (Time_now - Time_pre); Tc_now = MIN(CBS, (Tc + tokens)); Te_now = MIN(EBS, Te + (tokens - (Tc_now - Tc))); if (Tc_now >= B && pre_color == green) { mark the packet as green; Tc_now -= B; Time_pre = Time_now; } else if (Te_now >= B && (pre_color == green || pre_color == yellow)) { mark the packet as yellow; Te_now -= B; Time_pre = Time_now; } else { mark the packet as red; } }
2. 双速率CAR
两个令牌桶C和P,桶C容量为CBS(Committed Burst Size),添加速率为cir;
桶P容量为PBS(Peak Burst Size),添加速率为pir;
添加令牌过程:
同时往桶C、桶P添加令牌
桶C以cir 速率添加令牌,直到桶C满为止
桶P以pir 速率添加令牌,直到桶P满为止
报文发送流程(色盲模式):
报文长度为B,检查桶P,如果Tp < B,则标记报文为红色;
否则检查桶C,如果Tc < B,则标记报文为黄色,Tp -= B;
否则标记报文为绿色,Tc -= B;Tp -= B;
CAR_two_rate(B, pre_color) { /* mark red if pre color is red or Tp is not enough */ if (pre_color == red) { mark the packet as red; return } tokens = pir * (Time_now - Time_pir); Tp_now = MIN(PBS, (Tp + tokens)); if (Tp_now < B) { mark the packet as red; return } /* mark yellow if pre color is yellow or Tc is not enough */ tokens = cir * (Time_now - Time_cir); Tc_now = MIN(CBS, (Tc + tokens)); if (pre_color == yellow || Tc_now < B) { mark the packet as yellow; Tp_now -= B; Time_pir = Time_now; return } else { mark the packet as green; Tc_now -= B; Tp_now -= B; Time_cir = Time_now; Time_pir = Time_now; return; } }