@@ -529,3 +529,66 @@ int lkl_if_del_ip(int ifindex, int af, void *addr, unsigned int netprefix_len)
529
529
return ipaddr_modify (LKL_RTM_DELADDR , 0 , ifindex , af ,
530
530
addr , netprefix_len );
531
531
}
532
+
533
+ static int qdisc_add (int cmd , int flags , int ifindex ,
534
+ char * root , char * type )
535
+ {
536
+ struct {
537
+ struct lkl_nlmsghdr n ;
538
+ struct lkl_tcmsg tc ;
539
+ char buf [64 * 1024 ];
540
+ } req = {
541
+ .n .nlmsg_len = LKL_NLMSG_LENGTH (sizeof (struct lkl_tcmsg )),
542
+ .n .nlmsg_flags = LKL_NLM_F_REQUEST |flags ,
543
+ .n .nlmsg_type = cmd ,
544
+ .tc .tcm_family = LKL_AF_UNSPEC ,
545
+ };
546
+ int err , fd ;
547
+
548
+ if (!root || !type ) {
549
+ lkl_printf ("root and type arguments\n" );
550
+ return -1 ;
551
+ }
552
+
553
+ if (strcmp (root , "root" ) == 0 )
554
+ req .tc .tcm_parent = LKL_TC_H_ROOT ;
555
+ req .tc .tcm_ifindex = ifindex ;
556
+
557
+ fd = netlink_sock (0 );
558
+ if (fd < 0 )
559
+ return fd ;
560
+
561
+ // create the qdisc attribute
562
+ addattr_l (& req .n , sizeof (req ), LKL_TCA_KIND , type , 2 );
563
+
564
+ err = rtnl_talk (fd , & req .n );
565
+ lkl_sys_close (fd );
566
+ return err ;
567
+ }
568
+
569
+ int lkl_qdisc_add (int ifindex , char * root , char * type )
570
+ {
571
+ return qdisc_add (LKL_RTM_NEWQDISC , LKL_NLM_F_CREATE | LKL_NLM_F_EXCL ,
572
+ ifindex , root , type );
573
+ }
574
+
575
+ /* Add a qdisc entry for an interface in the form of
576
+ * "root|type;root|type;..."
577
+ */
578
+ void lkl_qdisc_parse_add (int ifindex , char * entries )
579
+ {
580
+ char * token = NULL ;
581
+ char * root = NULL , * type = NULL ;
582
+ int ret = 0 ;
583
+
584
+ for (token = strtok (entries , ";" ); token ; token = strtok (NULL , ";" )) {
585
+ root = strtok (token , "|" );
586
+ type = strtok (NULL , "|" );
587
+ ret = lkl_qdisc_add (ifindex , root , type );
588
+ if (ret ) {
589
+ fprintf (stderr , "Failed to add qdisc entry: %s\n" ,
590
+ lkl_strerror (ret ));
591
+ return ;
592
+ }
593
+ }
594
+ }
0 commit comments