Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set up netem qdisc and tbf qdisc using libnl-route?

I'm trying to do network emulation on ubuntu 12.04 while the shell commands work:

tc qdisc add dev eth1 root handle 1:0 tbf rate 200kbit buffer 1600 limit 3000

or

tc qdisc change dev eth0 root netem loss 0.1%

Now I want to do the same things in c code and i found libnl.

I have successfully added prio & htb qdisc using the doc

http://www.carisma.slowglass.com/~tgr/libnl/doc/route.html#tc_qdisc

but when I did the netem qdisc, it returned "Invalid input data or parameter", and "Missing attribute" in tbf qdisc case. My codes is as follows:

  1. netem

    q = rtnl_qdisc_alloc();
    rtnl_tc_set_ifindex(TC_CAST(q), 2);
    rtnl_tc_set_parent(TC_CAST(q), TC_H_ROOT);
    rtnl_tc_set_handle(TC_CAST(q), TC_HANDLE(1, 0));
    rtnl_tc_set_kind(TC_CAST(q), "netem");
    
    rtnl_netem_set_delay(q, 100);
    rtnl_netem_set_loss(q, 10);
    
    int err = rtnl_qdisc_add(sock, q, NLM_F_CREATE);
    if(err<0){
      printf("netem error: %s\n", nl_geterror(err));
    }
    
  2. tbf

    q = rtnl_qdisc_alloc();
    rtnl_tc_set_ifindex(TC_CAST(q), 2);
    rtnl_tc_set_parent(TC_CAST(q), TC_H_ROOT);
    rtnl_tc_set_handle(TC_CAST(q), TC_HANDLE(1, 0));
    rtnl_tc_set_kind(TC_CAST(q), "tbf");
    
    rtnl_qdisc_tbf_set_limit(q, 1000);
    rtnl_qdisc_tbf_set_rate(q, 1000, 1000, 8);
    
    int err = rtnl_qdisc_add(sock, q, NLM_F_CREATE);
    if(err<0){
      printf("tbf error: %s\n", nl_geterror(err));
    }
    

I have tried all the corresponding functions the api ref refers, but always have the same errors "Invalid input data or parameter" and "Missing attribute", and googled with no help.

I have got stuck with the problem for more than a week, i need your help.

like image 372
bigtit Avatar asked Oct 21 '22 18:10

bigtit


1 Answers

I looked over your code, but I miss some parameters. Like versions of your libraries and gcc flags you are using. So I decided to give you an example code and you can compare what are the difference to your system/code.

All the libraries on my system have the version 3.2.24-1 (debian unstable); Libraries you need:

  • libnl-3-dev
  • libnl-cli-3-dev
  • libnl-genl-3-dev
  • libnl-nf-3-dev
  • libnl-route-3-dev
  • libnl-3-200
  • libnl-cli-3-200
  • libnl-genl-3-200
  • libnl-nf-3-200
  • libnl-route-3-200
  • libnl-utils

To compile the code use this command. You can adjust if you want, but "-lnl-genl-3 -lnl-3 -lnl-route-3" is mandatory

"gcc -lnl-genl-3 -lnl-3 -lnl-route-3 -fpermissive --pedantic-errors -Wall -Wextra -ftabstop=4 -march=native -fshow-column -ftabstop=4 -frounding-math -pipe -ggdb3 -O0 main.c -o your_qdisc_app"

#include <libnl3/netlink/route/tc.h>
#include <libnl3/netlink/route/qdisc.h>
#include <libnl3/netlink/route/qdisc/netem.h>
#include <libnl3/netlink/route/qdisc/tbf.h>

int main(int argc, char ** argv)
{
  struct nl_sock *sock;
  struct rtnl_qdisc *q;
  struct nl_cache *cache;
  struct rtnl_link *link;
  int if_index;


  sock = nl_socket_alloc();

  nl_connect(sock, NETLINK_ROUTE);
  rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache);
  link = rtnl_link_get_by_name(cache, "eth0");
  if_index = rtnl_link_get_ifindex(link);

  q = rtnl_qdisc_alloc();               

  rtnl_tc_set_ifindex(TC_CAST(q), if_index);
  rtnl_tc_set_parent(TC_CAST(q), TC_H_ROOT);
  rtnl_tc_set_handle(TC_CAST(q), TC_HANDLE(1, 0));
  rtnl_tc_set_kind(TC_CAST(q), "tbf"); 

  /*
   * netem okay, htb okay, please comment 
   * and uncomment the special parameters for the qdiscs
  */
  rtnl_qdisc_tbf_set_limit(q, 1000);
  rtnl_qdisc_tbf_set_rate(q, 1000, 1000, 8);
  /*
   * rtnl_netem_set_delay(q, 100);
   * rtnl_netem_set_loss(q, 10);
  */

  rtnl_qdisc_add(sock, q, NLM_F_CREATE);

  rtnl_qdisc_put(q);
  nl_socket_free(sock);
  rtnl_link_put(link);
  nl_cache_put(cache);

  return 0;
}

I left out all the checks with "if" to minimize the lines. The checks can be added if necessary. If you have further question, get in touch with me.

cya, Philipp

like image 113
EgOPhil Avatar answered Oct 23 '22 06:10

EgOPhil