2019-03-29 17:26:33 +01:00
# include <inttypes.h>
2017-06-14 15:16:15 +02:00
# include <netlink/cache.h>
# include <netlink/cli/utils.h>
# include <netlink/cli/tc.h>
# include <netlink/cli/qdisc.h>
# include <netlink/cli/link.h>
# include <netlink/route/qdisc/plug.h>
/*
* XXX Please , first note that this code is not safe . XXX
* It was developed fast so that to reproduce a bug .
* You will certainly have to adapt it to your application .
2020-03-23 22:28:40 +05:00
* But at least it gives an idea about how to programmatically use plug
2017-06-14 15:16:15 +02:00
* queueing disciplines .
*/
static struct nl_sock * nl_sock ;
static struct nl_cache * link_cache ;
static struct rtnl_qdisc * qdisc ;
static struct rtnl_tc * tc ;
static int qdisc_init ( void )
{
nl_sock = nl_cli_alloc_socket ( ) ;
nl_cli_connect ( nl_sock , NETLINK_ROUTE ) ;
link_cache = nl_cli_link_alloc_cache ( nl_sock ) ;
qdisc = nl_cli_qdisc_alloc ( ) ;
tc = ( struct rtnl_tc * ) qdisc ;
return 0 ;
}
/* Stop buffering and release all buffered and incoming 'qdisc'
* queueing discipline traffic .
*/
int plug_qdisc_release_indefinite_buffer ( void )
{
rtnl_qdisc_plug_release_indefinite ( qdisc ) ;
return rtnl_qdisc_add ( nl_sock , qdisc , 0 ) ;
}
/* Start buffering incoming 'qdisc' queueing discipline traffic. */
int plug_qdisc_plug_buffer ( void )
{
rtnl_qdisc_plug_buffer ( qdisc ) ;
return rtnl_qdisc_add ( nl_sock , qdisc , 0 ) ;
}
/* Create a plug qdisc attached to 'device' network device with 'parent'
* as parent , with ' id ' as ID and ' limit ' as buffer size .
* This is equivalent to use nl - qdisc - add tool like that :
* $ nl - qdisc - add - - dev = < device > - - parent = < parent > - - id = < id > plug - - limit < limit >
* $ nl - qdisc - add - - dev = < device > - - parent = < parent > - - id = < id > - - update plug - - release - indefinite
*/
int plug_qdisc_attach ( char * device , char * parent , char * id , uint32_t limit )
{
int ret ;
if ( ! tc & & qdisc_init ( ) = = - 1 )
return - 1 ;
nl_cli_tc_parse_dev ( tc , link_cache , device ) ;
nl_cli_tc_parse_parent ( tc , parent ) ;
if ( ! rtnl_tc_get_ifindex ( tc ) )
return - 1 ;
if ( ! rtnl_tc_get_parent ( tc ) )
return - 1 ;
if ( id )
nl_cli_tc_parse_handle ( tc , id , 1 ) ;
rtnl_tc_set_kind ( tc , " plug " ) ;
if ( limit )
rtnl_qdisc_plug_set_limit ( qdisc , limit ) ;
ret = rtnl_qdisc_add ( nl_sock , qdisc , NLM_F_CREATE ) ;
if ( ret < 0 ) {
fprintf ( stderr , " Could add attach qdisc: %s \n " , nl_geterror ( ret ) ) ;
return - 1 ;
}
/* Release buffer. */
plug_qdisc_release_indefinite_buffer ( ) ;
return 0 ;
}