Skip to content

Commit e7b3474

Browse files
authored
Merge pull request #315 from libos-nuse/feature-qdisc
lkl: add LKL_HIJACK_NET_QDISC to configure qdisc policy
2 parents 615a744 + b376786 commit e7b3474

File tree

7 files changed

+102
-1
lines changed

7 files changed

+102
-1
lines changed

Documentation/lkl.txt

+6
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ are the list of those variable for your environment.
202202
$ LKL_HIJACK_NET_NEIGHBOR="192.168.13.100|12:34:56:78:9a:bc;2001:db8:0:f101::3|12:34:56:78:9a:be"
203203
lkl-hijack.sh ip neighbor show
204204
```
205+
* LKL_HIJACK_NET_QDISC
206+
207+
Add a qdisc entry in the form of "root|type;root|type;...".
208+
```
209+
$ LKL_HIJACK_NET_QDISC="root|fq" lkl-hijack.sh tc qdisc
210+
```
205211
* LKL_HIJACK_DEBUG
206212

207213
Setting it causes some debug information (both from the kernel and the

arch/lkl/Kconfig

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ config LKL
2525
select IP_PNP_DHCP
2626
select TCP_CONG_BBR
2727
select HIGH_RES_TIMERS
28+
select NET_SCHED
29+
select NET_SCH_FQ
2830

2931
config OUTPUTFORMAT
3032
string

arch/lkl/include/uapi/asm/syscalls.h

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ struct sockaddr {
128128
#include <linux/virtio_blk.h>
129129
#include <linux/virtio_net.h>
130130
#include <linux/virtio_ring.h>
131+
#include <linux/pkt_sched.h>
131132

132133
struct user_msghdr {
133134
void __user *msg_name; /* ptr to socket address structure */

tools/lkl/include/lkl.h

+18
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,24 @@ int lkl_if_wait_ipv6_dad(int ifindex, void *addr);
461461
*/
462462
int lkl_set_fd_limit(unsigned int fd_limit);
463463

464+
/**
465+
* lkl_qdisc_add - set qdisc rule onto an interface
466+
*
467+
* @ifindex - the ifindex of the interface
468+
* @root - the name of root class (e.g., "root");
469+
* @type - the type of qdisc (e.g., "fq")
470+
*/
471+
int lkl_qdisc_add(int ifindex, char *root, char *type);
472+
473+
/**
474+
* lkl_qdisc_parse_add - Add a qdisc entry for an interface with strings
475+
*
476+
* @ifindex - the ifindex of the interface
477+
* @entries - strings of qdisc configurations in the form of
478+
* "root|type;root|type;..."
479+
*/
480+
void lkl_qdisc_parse_add(int ifindex, char *entries);
481+
464482
#ifdef __cplusplus
465483
}
466484
#endif

tools/lkl/lib/hijack/init.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ hijack_init(void)
202202
char *mount = getenv("LKL_HIJACK_MOUNT");
203203
struct lkl_netdev_args nd_args;
204204
char *neigh_entries = getenv("LKL_HIJACK_NET_NEIGHBOR");
205+
char *qdisc_entries = getenv("LKL_HIJACK_NET_QDISC");
205206
/* single_cpu mode:
206207
* 0: Don't pin to single CPU (default).
207208
* 1: Pin only LKL kernel threads to single CPU.
@@ -429,8 +430,12 @@ hijack_init(void)
429430
if (mount)
430431
mount_cmds_exec(mount, lkl_mount_fs);
431432

432-
if (nd_ifindex >=0 && neigh_entries)
433+
if (nd_ifindex >= 0 && neigh_entries)
433434
add_neighbor(nd_ifindex, neigh_entries);
435+
436+
if (nd_ifindex >= 0 && qdisc_entries)
437+
lkl_qdisc_parse_add(nd_ifindex, qdisc_entries);
438+
434439
}
435440

436441
void __attribute__((destructor))

tools/lkl/lib/net.c

+63
Original file line numberDiff line numberDiff line change
@@ -529,3 +529,66 @@ int lkl_if_del_ip(int ifindex, int af, void *addr, unsigned int netprefix_len)
529529
return ipaddr_modify(LKL_RTM_DELADDR, 0, ifindex, af,
530530
addr, netprefix_len);
531531
}
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+
}

tools/lkl/tests/hijack-test.sh

+6
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ LKL_HIJACK_OFFLOAD=0x8803 sh ${script_dir}/run_netperf.sh 192.168.13.1 1 0 TCP_M
129129
sh ${script_dir}/run_netperf.sh 192.168.13.1 1 0 TCP_RR
130130
sh ${script_dir}/run_netperf.sh fc03::1 1 0 TCP_STREAM
131131

132+
# QDISC test
133+
qdisc=$(LKL_HIJACK_NET_QDISC="root|fq" ${hijack_script} tc -s -d qdisc show)
134+
echo "$qdisc"
135+
echo "$qdisc" | grep "qdisc fq" > /dev/null
136+
echo "$qdisc" | grep throttled > /dev/null
137+
132138
if [ -z "`printenv CONFIG_AUTO_LKL_VIRTIO_NET_VDE`" ]; then
133139
exit 0
134140
fi

0 commit comments

Comments
 (0)