我有一个FQ Qdisc,我想以毫秒为单位更新。我当前的方法是直接使用tc命令,但这太慢了:
char tc_cmd[200];
snprintf(tc_cmd, 200,"tc qdisc change dev %s root fq maxrate %.3fmbit &", net_dev, tx_rate / 10e5);
err = system(tc_cmd);
if (err) {
perror(stderr,"Problem with tc qdisc change");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
我想使用libnl或netlink实现此代码片段。不幸的是,尽管libnl-route支持variety的qdiscs,但它尚不支持公平排队的qdiscs。我真正想要做的唯一一件事就是发送一条更新消息,以更改活动FQ qdisc的限制。但是,我对netlink和libnl实现的了解不多,我不确定如何制作这样的消息。
作为参考,这是我使用libnl设置和更改htb qdisc的方式。我想为fq qdisc实现类似的功能:
struct rtnl_qdisc *tbf_qdisc;
int if_index;
int err = 0;
char *netdev = "eth0"
uint64_t tx_rate = 10e6;
uint64_t burst = 12000;
uint64_t limit = 5000;
fprintf(stderr, "Kernel Clock Rate: %d\n", nl_get_user_hz());
qdisc_sock = nl_socket_alloc();
nl_connect(qdisc_sock, NETLINK_ROUTE);
if_index = if_nametoindex(netdev);
// Allocate and configure the qdisc
fq_qdisc = rtnl_qdisc_alloc();
rtnl_tc_set_ifindex(TC_CAST(tbf_qdisc), if_index);
rtnl_tc_set_parent(TC_CAST(tbf_qdisc), TC_H_ROOT);
rtnl_tc_set_handle(TC_CAST(tbf_qdisc), TC_HANDLE(1,0));
err = rtnl_tc_set_kind(TC_CAST(tbf_qdisc), "tbf");
if (err) {
fprintf(stderr,"Can not allocate TBF: %s\n", nl_geterror(err));
return NULL;
}
rtnl_qdisc_tbf_set_rate(tbf_qdisc, (uint64_t) tx_rate, burst , 0);
rtnl_qdisc_tbf_set_limit(tbf_qdisc, limit);
rtnl_qdisc_tbf_set_peakrate(tbf_qdisc, (uint64_t) tx_rate, burst, 0);
// Add it to the interface
err = rtnl_qdisc_add(qdisc_sock, tbf_qdisc, NLM_F_CREATE);
if (err) {
fprintf(stderr,"Can not set TBF: %s\n", nl_geterror(err));
return NULL;
// Update the rate of the qdisc
rate = 1e6;
rtnl_qdisc_tbf_set_rate(tbf_qdisc, (uint64_t) tx_rate, burst , 0);
rtnl_qdisc_tbf_set_peakrate(tbf_qdisc, (uint64_t) tx_rate, burst, 0);
rtnl_qdisc_tbf_set_limit(tbf_qdisc, limit);
err = rtnl_qdisc_add(qdisc_sock, tbf_qdisc, NLM_F_REPLACE);
if(err) {
fprintf(stderr,"Rate %lu qdisc_add: %s\n", tx_rate, nl_geterror(err));
return NULL;
}