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