I have two network namespaces (red at 192.168.15.1 and blue at 192.168.15.2) connected by a virtual ethernet cable. Red side, the device is named veth-red, blue side, it is named veth-blue. Now i want to add a "plug" qdisc to veth-blue, I'm doing it with the following command lines (using libnl):
ip netns exec blue nl-qdisc-add --dev veth-blue --parent root --id 1: plug --limit 32000
ip netns exec blue nl-qdisc-add --dev veth-blue --parent root --id 1: --update plug --release-indefinite
When I'm buffering the qdisc with : ip netns exec blue nl-qdisc-add --dev veth-blue --parent root --id 1: --update plug --buffer
, the traffic between the network namespaces is stopped, which is what I need, my configuration works.
Now, I want to be able to "buffer" and "release" my qdisc from a C program. My code looks like that :
#include <stdio.h>
#include <stdlib.h>
#include <libnl3/netlink/route/link.h>
#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(){
struct nl_sock *sock;
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, "veth-blue");
if_index = rtnl_link_get_ifindex(link);
struct nl_cache *qdisc_cache;
struct rtnl_qdisc *q;
uint32_t handle = (1 << 16) | (0);
rtnl_qdisc_alloc_cache(sock, &qdisc_cache);
q = rtnl_qdisc_get(qdisc_cache, if_index, handle);
rtnl_qdisc_plug_buffer(q);
rtnl_qdisc_add(sock, q, NLM_F_CREATE);
/* some code */
rtnl_qdisc_plug_release_indefinite(q);
rtnl_qdisc_add(sock, q, NLM_F_CREATE);
return 0;
}
My code works fine, my only problem is that I want to be absolutely sure to execute the /* some code */
part once the qdisc is "buffered" and not before. So the question is, is there a way to check the state of the qdisc to see whether it is in "buffer" state or "released" ?