1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * q_mqprio.c MQ prio qdisc
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Author: John Fastabend, <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker */
11*de1e4e89SAndroid Build Coastguard Worker
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <syslog.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <fcntl.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <sys/socket.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <netinet/in.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <arpa/inet.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
21*de1e4e89SAndroid Build Coastguard Worker
22*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
23*de1e4e89SAndroid Build Coastguard Worker #include "tc_util.h"
24*de1e4e89SAndroid Build Coastguard Worker
explain(void)25*de1e4e89SAndroid Build Coastguard Worker static void explain(void)
26*de1e4e89SAndroid Build Coastguard Worker {
27*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Usage: ... mqprio [num_tc NUMBER] [map P0 P1 ...]\n");
28*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, " [queues count1@offset1 count2@offset2 ...] ");
29*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "[hw 1|0]\n");
30*de1e4e89SAndroid Build Coastguard Worker }
31*de1e4e89SAndroid Build Coastguard Worker
mqprio_parse_opt(struct qdisc_util * qu,int argc,char ** argv,struct nlmsghdr * n)32*de1e4e89SAndroid Build Coastguard Worker static int mqprio_parse_opt(struct qdisc_util *qu, int argc,
33*de1e4e89SAndroid Build Coastguard Worker char **argv, struct nlmsghdr *n)
34*de1e4e89SAndroid Build Coastguard Worker {
35*de1e4e89SAndroid Build Coastguard Worker int idx;
36*de1e4e89SAndroid Build Coastguard Worker struct tc_mqprio_qopt opt = {
37*de1e4e89SAndroid Build Coastguard Worker .num_tc = 8,
38*de1e4e89SAndroid Build Coastguard Worker .prio_tc_map = { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 1, 1, 3, 3, 3, 3 },
39*de1e4e89SAndroid Build Coastguard Worker .hw = 1,
40*de1e4e89SAndroid Build Coastguard Worker .count = { },
41*de1e4e89SAndroid Build Coastguard Worker .offset = { },
42*de1e4e89SAndroid Build Coastguard Worker };
43*de1e4e89SAndroid Build Coastguard Worker
44*de1e4e89SAndroid Build Coastguard Worker while (argc > 0) {
45*de1e4e89SAndroid Build Coastguard Worker idx = 0;
46*de1e4e89SAndroid Build Coastguard Worker if (strcmp(*argv, "num_tc") == 0) {
47*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
48*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&opt.num_tc, *argv, 10)) {
49*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Illegal \"num_tc\"\n");
50*de1e4e89SAndroid Build Coastguard Worker return -1;
51*de1e4e89SAndroid Build Coastguard Worker }
52*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "map") == 0) {
53*de1e4e89SAndroid Build Coastguard Worker while (idx < TC_QOPT_MAX_QUEUE && NEXT_ARG_OK()) {
54*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
55*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&opt.prio_tc_map[idx], *argv, 10)) {
56*de1e4e89SAndroid Build Coastguard Worker PREV_ARG();
57*de1e4e89SAndroid Build Coastguard Worker break;
58*de1e4e89SAndroid Build Coastguard Worker }
59*de1e4e89SAndroid Build Coastguard Worker idx++;
60*de1e4e89SAndroid Build Coastguard Worker }
61*de1e4e89SAndroid Build Coastguard Worker for ( ; idx < TC_QOPT_MAX_QUEUE; idx++)
62*de1e4e89SAndroid Build Coastguard Worker opt.prio_tc_map[idx] = 0;
63*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "queues") == 0) {
64*de1e4e89SAndroid Build Coastguard Worker char *tmp, *tok;
65*de1e4e89SAndroid Build Coastguard Worker
66*de1e4e89SAndroid Build Coastguard Worker while (idx < TC_QOPT_MAX_QUEUE && NEXT_ARG_OK()) {
67*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
68*de1e4e89SAndroid Build Coastguard Worker
69*de1e4e89SAndroid Build Coastguard Worker tmp = strdup(*argv);
70*de1e4e89SAndroid Build Coastguard Worker if (!tmp)
71*de1e4e89SAndroid Build Coastguard Worker break;
72*de1e4e89SAndroid Build Coastguard Worker
73*de1e4e89SAndroid Build Coastguard Worker tok = strtok(tmp, "@");
74*de1e4e89SAndroid Build Coastguard Worker if (get_u16(&opt.count[idx], tok, 10)) {
75*de1e4e89SAndroid Build Coastguard Worker free(tmp);
76*de1e4e89SAndroid Build Coastguard Worker PREV_ARG();
77*de1e4e89SAndroid Build Coastguard Worker break;
78*de1e4e89SAndroid Build Coastguard Worker }
79*de1e4e89SAndroid Build Coastguard Worker tok = strtok(NULL, "@");
80*de1e4e89SAndroid Build Coastguard Worker if (get_u16(&opt.offset[idx], tok, 10)) {
81*de1e4e89SAndroid Build Coastguard Worker free(tmp);
82*de1e4e89SAndroid Build Coastguard Worker PREV_ARG();
83*de1e4e89SAndroid Build Coastguard Worker break;
84*de1e4e89SAndroid Build Coastguard Worker }
85*de1e4e89SAndroid Build Coastguard Worker free(tmp);
86*de1e4e89SAndroid Build Coastguard Worker idx++;
87*de1e4e89SAndroid Build Coastguard Worker }
88*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "hw") == 0) {
89*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
90*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&opt.hw, *argv, 10)) {
91*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Illegal \"hw\"\n");
92*de1e4e89SAndroid Build Coastguard Worker return -1;
93*de1e4e89SAndroid Build Coastguard Worker }
94*de1e4e89SAndroid Build Coastguard Worker idx++;
95*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "help") == 0) {
96*de1e4e89SAndroid Build Coastguard Worker explain();
97*de1e4e89SAndroid Build Coastguard Worker return -1;
98*de1e4e89SAndroid Build Coastguard Worker } else {
99*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Unknown argument\n");
100*de1e4e89SAndroid Build Coastguard Worker return -1;
101*de1e4e89SAndroid Build Coastguard Worker }
102*de1e4e89SAndroid Build Coastguard Worker argc--; argv++;
103*de1e4e89SAndroid Build Coastguard Worker }
104*de1e4e89SAndroid Build Coastguard Worker
105*de1e4e89SAndroid Build Coastguard Worker addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt));
106*de1e4e89SAndroid Build Coastguard Worker return 0;
107*de1e4e89SAndroid Build Coastguard Worker }
108*de1e4e89SAndroid Build Coastguard Worker
mqprio_print_opt(struct qdisc_util * qu,FILE * f,struct rtattr * opt)109*de1e4e89SAndroid Build Coastguard Worker static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
110*de1e4e89SAndroid Build Coastguard Worker {
111*de1e4e89SAndroid Build Coastguard Worker int i;
112*de1e4e89SAndroid Build Coastguard Worker struct tc_mqprio_qopt *qopt;
113*de1e4e89SAndroid Build Coastguard Worker
114*de1e4e89SAndroid Build Coastguard Worker if (opt == NULL)
115*de1e4e89SAndroid Build Coastguard Worker return 0;
116*de1e4e89SAndroid Build Coastguard Worker
117*de1e4e89SAndroid Build Coastguard Worker qopt = RTA_DATA(opt);
118*de1e4e89SAndroid Build Coastguard Worker
119*de1e4e89SAndroid Build Coastguard Worker fprintf(f, " tc %u map ", qopt->num_tc);
120*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i <= TC_PRIO_MAX; i++)
121*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%u ", qopt->prio_tc_map[i]);
122*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "\n queues:");
123*de1e4e89SAndroid Build Coastguard Worker for (i = 0; i < qopt->num_tc; i++)
124*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "(%u:%u) ", qopt->offset[i],
125*de1e4e89SAndroid Build Coastguard Worker qopt->offset[i] + qopt->count[i] - 1);
126*de1e4e89SAndroid Build Coastguard Worker return 0;
127*de1e4e89SAndroid Build Coastguard Worker }
128*de1e4e89SAndroid Build Coastguard Worker
129*de1e4e89SAndroid Build Coastguard Worker struct qdisc_util mqprio_qdisc_util = {
130*de1e4e89SAndroid Build Coastguard Worker .id = "mqprio",
131*de1e4e89SAndroid Build Coastguard Worker .parse_qopt = mqprio_parse_opt,
132*de1e4e89SAndroid Build Coastguard Worker .print_qopt = mqprio_print_opt,
133*de1e4e89SAndroid Build Coastguard Worker };
134