📄 tc_cbq.c
字号:
return 0; } else { if (cl == NULL) { cl = malloc(sizeof(*cl)); if (cl == NULL) return -1; memset(cl, 0, sizeof(*cl)); cl->lss = cbq->is_g.lss; cl->wrr = cbq->is_g.wrr; cl->rate = cbq->is_g.rate; cl->rate.rate = qi->ai.cl_rate; cl->wrr.weight = (double)qi->ai.cl_rate/qi->wfactor; cl->wrr.priority = 1; cl->lss.flags = 0; cl->lss.change = 2|4|0x10|0x20; cl->lss.maxidle = tc_cbq_calc_maxidle(cbq->lll.rate.rate, cl->rate.rate, cl->lss.avpkt, cl->lss.ewma_log, (double)qi->ai.cl_mem/cl->lss.avpkt); cl->lss.offtime = tc_cbq_calc_offtime(cbq->lll.rate.rate, cl->rate.rate, cl->lss.avpkt, cl->lss.ewma_log, 1); memset(&pol, 0, sizeof(pol)); pol.police = TC_POLICE_RECLASSIFY; tc_calc_rtable(cl->rate.rate, rtab, cl->rate.cell_log, cl->wrr.allot, cl->rate.mpu); rta->rta_type = TCA_OPTIONS; rta->rta_len = RTA_LENGTH(0); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_LSSOPT, &cl->lss, sizeof(cl->lss)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_WRROPT, &cl->wrr, sizeof(cl->wrr)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_RATE, &cl->rate, sizeof(cl->rate)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_RTAB, &rtab, sizeof(rtab)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_POLICE, &pol, sizeof(pol)); if (tc_add_class(qi->link->ifl_index, cbq->is_g.classid, &cl->classid, rta)) { log(LOG_ERR, errno, "tc_add_class\n"); free(cl); return -1; } cl->next = cbq->lll.next; cbq->lll.next = cl; cbq->is_cl = cl; qi->ai.cl_cur_rate = qi->ai.cl_rate; tc_setup_estimator(qi->ai.interval, qi->ai.time_const, &est); if (tc_chg_class(qi->link->ifl_index, cl->classid, NULL, &est)) log(LOG_ERR, errno, "tc_chg_class: set estimator\n"); } else if (qi->ai.cl_rate != qi->ai.cl_cur_rate) { cl->rate.rate = qi->ai.cl_rate; cl->wrr.weight = (double)qi->ai.cl_rate/qi->wfactor; cl->lss.flags = 0; cl->lss.change = 4|0x10; cl->lss.maxidle = tc_cbq_calc_maxidle(cbq->lll.rate.rate, cl->rate.rate, cl->lss.avpkt, cl->lss.ewma_log, (double)qi->ai.cl_mem/cl->lss.avpkt); cl->lss.offtime = tc_cbq_calc_offtime(cbq->lll.rate.rate, cl->rate.rate, cl->lss.avpkt, cl->lss.ewma_log, 1); tc_calc_rtable(cl->rate.rate, rtab, cl->rate.cell_log, cl->wrr.allot, cl->rate.mpu); rta->rta_type = TCA_OPTIONS; rta->rta_len = RTA_LENGTH(0); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_LSSOPT, &cl->lss, sizeof(cl->lss)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_WRROPT, &cl->wrr, sizeof(cl->wrr)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_RATE, &cl->rate, sizeof(cl->rate)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_RTAB, &rtab, sizeof(rtab)); log(LOG_ERR, 0, "rate %d -> %d\n", qi->ai.cl_cur_rate, qi->ai.cl_rate); if (tc_chg_class(qi->link->ifl_index, cl->classid, rta, NULL)) { log(LOG_ERR, errno, "cbq_sync_cl: change failed\n"); return -1; } qi->ai.cl_cur_rate = qi->ai.cl_rate; } } return 0;}int cbq_newflow(rsvp_flow_t *f){ rsvp_qdisc_t *qi = f->qi; struct cbq_qdisc *cbq = qi->data; struct cbq_class *cl; __u32 rtab[256]; char buf[4096]; struct rtattr *rta = (void*)buf; struct tc_cbq_police pol; if (f->ai.admtype == ADM_CL_STAT) { int err; err = cbq_sync_cl(qi); if (err == 0) { f->class = cbq->is_cl; f->classid = cbq->is_cl->classid; } else log(LOG_ERR, errno, "cbq_sync_cl"); return err; } cl = malloc(sizeof(*cl)); if (cl == NULL) return -1; memset(cl, 0, sizeof(*cl)); cl->lss = cbq->is_g.lss; cl->wrr = cbq->is_g.wrr; cl->wrr.weight = (double)f->ai.rate/qi->wfactor; cl->wrr.priority = 1; cl->rate = cbq->is_g.rate; cl->rate.rate = f->ai.rate; /* cl->rate.mpu = f->ai.mpu; */ cl->lss.flags = 0; cl->lss.change = 2|4|0x10|0x20; if (f->policer.action == TC_POLICE_UNSPEC) { cl->lss.maxidle = 0x7FFFFFFF; cl->lss.offtime = 0; } else { cl->lss.maxidle = tc_cbq_calc_maxidle(cbq->lll.rate.rate, cl->rate.rate, cl->lss.avpkt, cl->lss.ewma_log, (double)f->ai.mem/cl->lss.avpkt); cl->lss.offtime = tc_cbq_calc_offtime(cbq->lll.rate.rate, cl->rate.rate, cl->lss.avpkt, cl->lss.ewma_log, 1); } tc_calc_rtable(cl->rate.rate, rtab, 8, cl->wrr.allot, cl->rate.mpu); memset(&pol, 0, sizeof(pol)); pol.police = TC_POLICE_RECLASSIFY; rta->rta_type = TCA_OPTIONS; rta->rta_len = RTA_LENGTH(0); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_LSSOPT, &cl->lss, sizeof(cl->lss)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_WRROPT, &cl->wrr, sizeof(cl->wrr)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_RATE, &cl->rate, sizeof(cl->rate)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_RTAB, &rtab, sizeof(rtab)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_POLICE, &pol, sizeof(pol)); if (tc_add_class(qi->link->ifl_index, cbq->is_g.classid, &cl->classid, rta)) { free(cl); return -1; } if (f->policer.action == TC_POLICE_UNSPEC) tc_add_shaper(qi, &f->policer, cl->classid); f->class = cl; f->classid = cl->classid; cl->next = cbq->lll.next; cbq->lll.next = cl; if (qi->ai.cl_cur_rate != qi->ai.cl_rate) cbq_sync_cl(qi); return 0;}int cbq_delflow(rsvp_flow_t *f){ struct cbq_class *cl = f->class; rsvp_qdisc_t *qi = f->qi; struct cbq_qdisc *cbq = qi->data; if (cl == cbq->is_cl) { f->class = NULL; f->classid = 0; log(LOG_INFO, 0, "cbq_delflow: stat\n"); return cbq_sync_cl(qi); } log(LOG_INFO, 0, "cbq_delflow: det\n"); tc_kill_class(qi->link->ifl_index, cl->classid); cbq_free_class(qi, cl); if (qi->ai.cl_cur_rate != qi->ai.cl_rate) cbq_sync_cl(qi); f->class = NULL; f->classid = 0; return 0;}int cbq_modflow(rsvp_flow_t *f, rsvp_flow_t *new_f){ int err; int o_atype = f->ai.admtype != ADM_CL_STAT ? ADM_G_DET : ADM_CL_STAT; int n_atype = new_f->ai.admtype != ADM_CL_STAT ? ADM_G_DET : ADM_CL_STAT; rsvp_qdisc_t *qi = f->qi; struct cbq_qdisc *cbq = qi->data; struct cbq_class *cl = f->class; if (o_atype == n_atype) { __u32 rtab[256]; char buf[4096]; struct rtattr *rta = (struct rtattr*)buf; struct tc_cbq_lssopt s_lss = cl->lss; struct tc_cbq_wrropt s_wrr = cl->wrr; new_f->class = f->class; new_f->classid = f->classid; if (o_atype == ADM_CL_STAT) { log(LOG_INFO, 0, "cbq_modflow: stat -> stat\n"); return cbq_sync_cl(qi); } log(LOG_INFO, 0, "cbq_modflow: det -> det\n"); cl->wrr.weight = (double)new_f->ai.rate/qi->wfactor; cl->wrr.priority = 1; cl->rate.rate = new_f->ai.rate; /* cl->rate.mpu = new_f->ai.mpu; */ cl->lss.flags = 0; cl->lss.change = 2|4|0x10|0x20; if (f->policer.action == TC_POLICE_UNSPEC) { cl->lss.maxidle = 0x7FFFFFFF; cl->lss.offtime = 0; } else { cl->lss.maxidle = tc_cbq_calc_maxidle(cbq->lll.rate.rate, cl->rate.rate, cl->lss.avpkt, cl->lss.ewma_log, (double)new_f->ai.mem/cl->lss.avpkt); cl->lss.offtime = tc_cbq_calc_offtime(cbq->lll.rate.rate, cl->rate.rate, cl->lss.avpkt, cl->lss.ewma_log, 1); } tc_calc_rtable(cl->rate.rate, rtab, 8, cl->wrr.allot, cl->rate.mpu); rta->rta_type = TCA_OPTIONS; rta->rta_len = RTA_LENGTH(0); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_LSSOPT, &cl->lss, sizeof(cl->lss)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_WRROPT, &cl->wrr, sizeof(cl->wrr)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_RATE, &cl->rate, sizeof(cl->rate)); rta_addattr_l(rta, sizeof(buf), TCA_CBQ_RTAB, &rtab, sizeof(rtab)); if (tc_chg_class(qi->link->ifl_index, f->classid, rta, NULL)) { cl->lss = s_lss; cl->wrr = s_wrr; return -1; } if (new_f->policer.action == TC_POLICE_UNSPEC) tc_add_shaper(qi, &new_f->policer, cl->classid); else if (f->policer.action == TC_POLICE_UNSPEC) tc_del_shaper(qi, &f->policer, cl->classid); if (qi->ai.cl_cur_rate != qi->ai.cl_rate) cbq_sync_cl(qi); return 0; } else { /* More drastic change. */ if (o_atype == ADM_CL_STAT) { log(LOG_INFO, 0, "cbq_modflow: stat -> det\n"); err = cbq_newflow(new_f); if (err == 0) cbq_sync_cl(qi); } else { log(LOG_INFO, 0, "cbq_modflow: det -> stat\n"); err = cbq_sync_cl(qi); if (err == 0) { new_f->class = cbq->is_cl; new_f->classid = cbq->is_cl->classid; if (1) { /* Ugly, ugly, ugly... */ rsvp_filter_t *fh; Chandle saved = f->classid; f->classid = new_f->classid; for (fh = f->filters; fh; fh = fh->next) tc_mod_filter(fh); f->classid = saved; } return cbq_delflow(f); } } return err; }}int cbq_agg_cl_rate(rsvp_qdisc_t *qi){ struct tc_stats st; struct cbq_qdisc *cbq = qi->data; if (cbq->is_cl == NULL) return 0; memset(&st, 0, sizeof(st)); tc_get_stats(qi->link->ifl_index, cbq->is_cl->classid, &st); return st.bps;}struct rsvp_qdisc_ops cbq_qdisc_ops = { "cbq", cbq_alloc, cbq_free, cbq_init, cbq_clear, cbq_agg_cl_rate, cbq_newflow, cbq_modflow, cbq_delflow,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -