blob: 9ba288c075e08a11aa4fd1a2411678bb32cf003e [file] [log] [blame]
Alexander Duyckf72a7aa2009-01-06 19:27:03 -08001/*
2 * m_skbedit.c SKB Editing module
3 *
4 * Copyright (c) 2008, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
Stephen Hemminger4d98ab02013-12-06 15:05:07 -080015 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses>.
Alexander Duyckf72a7aa2009-01-06 19:27:03 -080017 *
18 * Authors: Alexander Duyck <alexander.h.duyck@intel.com>
19 *
20 */
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <string.h>
26#include "utils.h"
27#include "tc_util.h"
28#include <linux/tc_act/tc_skbedit.h>
29
30static void
31explain(void)
32{
Stephen Hemminger3d0b7432014-12-20 15:47:17 -080033 fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM]>\n"
Jamal Hadi Salime04dd302009-12-26 11:12:43 -080034 "QM = queue_mapping QUEUE_MAPPING\n"
Stephen Hemminger32a121c2016-03-21 11:48:36 -070035 "PM = priority PRIORITY\n"
36 "MM = mark MARK\n"
Jamal Hadi Salime04dd302009-12-26 11:12:43 -080037 "QUEUE_MAPPING = device transmit queue to use\n"
38 "PRIORITY = classID to assign to priority field\n"
39 "MARK = firewall mark to set\n");
Alexander Duyckf72a7aa2009-01-06 19:27:03 -080040}
41
42static void
43usage(void)
44{
45 explain();
46 exit(-1);
47}
48
49static int
50parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
51 struct nlmsghdr *n)
52{
Alexander Duyckf72a7aa2009-01-06 19:27:03 -080053 int argc = *argc_p;
54 char **argv = *argv_p;
55 int ok = 0;
56 struct rtattr *tail;
57 unsigned int tmp;
58 __u16 queue_mapping;
Jamal Hadi Salime04dd302009-12-26 11:12:43 -080059 __u32 flags = 0, priority, mark;
Stephen Hemminger46a65732009-02-19 08:59:06 -080060 struct tc_skbedit sel = { 0 };
Alexander Duyckf72a7aa2009-01-06 19:27:03 -080061
62 if (matches(*argv, "skbedit") != 0)
63 return -1;
64
65 NEXT_ARG();
66
67 while (argc > 0) {
68 if (matches(*argv, "queue_mapping") == 0) {
69 flags |= SKBEDIT_F_QUEUE_MAPPING;
70 NEXT_ARG();
71 if (get_unsigned(&tmp, *argv, 10) || tmp > 65535) {
72 fprintf(stderr, "Illegal queue_mapping\n");
73 return -1;
74 }
75 queue_mapping = tmp;
76 ok++;
77 } else if (matches(*argv, "priority") == 0) {
78 flags |= SKBEDIT_F_PRIORITY;
79 NEXT_ARG();
80 if (get_tc_classid(&priority, *argv)) {
81 fprintf(stderr, "Illegal priority\n");
82 return -1;
83 }
84 ok++;
Jamal Hadi Salime04dd302009-12-26 11:12:43 -080085 } else if (matches(*argv, "mark") == 0) {
86 flags |= SKBEDIT_F_MARK;
87 NEXT_ARG();
jamale9069752010-02-15 01:51:01 +000088 if (get_u32(&mark, *argv, 0)) {
Jamal Hadi Salime04dd302009-12-26 11:12:43 -080089 fprintf(stderr, "Illegal mark\n");
90 return -1;
91 }
92 ok++;
Alexander Duyckf72a7aa2009-01-06 19:27:03 -080093 } else if (matches(*argv, "help") == 0) {
94 usage();
95 } else {
96 break;
97 }
98 argc--;
99 argv++;
100 }
101
Jamal Hadi Salim64b7db42013-12-21 16:38:36 -0500102 sel.action = TC_ACT_PIPE;
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800103 if (argc) {
104 if (matches(*argv, "reclassify") == 0) {
105 sel.action = TC_ACT_RECLASSIFY;
106 NEXT_ARG();
107 } else if (matches(*argv, "pipe") == 0) {
108 sel.action = TC_ACT_PIPE;
109 NEXT_ARG();
110 } else if (matches(*argv, "drop") == 0 ||
111 matches(*argv, "shot") == 0) {
112 sel.action = TC_ACT_SHOT;
113 NEXT_ARG();
114 } else if (matches(*argv, "continue") == 0) {
115 sel.action = TC_ACT_UNSPEC;
116 NEXT_ARG();
Jamal Hadi Salim43726b72016-05-07 09:39:36 -0400117 } else if (matches(*argv, "pass") == 0 ||
118 matches(*argv, "ok") == 0) {
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800119 sel.action = TC_ACT_OK;
120 NEXT_ARG();
121 }
122 }
123
124 if (argc) {
125 if (matches(*argv, "index") == 0) {
126 NEXT_ARG();
127 if (get_u32(&sel.index, *argv, 10)) {
128 fprintf(stderr, "Pedit: Illegal \"index\"\n");
129 return -1;
130 }
131 argc--;
132 argv++;
133 ok++;
134 }
135 }
136
137 if (!ok) {
138 explain();
139 return -1;
140 }
141
142
143 tail = NLMSG_TAIL(n);
144 addattr_l(n, MAX_MSG, tca_id, NULL, 0);
145 addattr_l(n, MAX_MSG, TCA_SKBEDIT_PARMS, &sel, sizeof(sel));
146 if (flags & SKBEDIT_F_QUEUE_MAPPING)
147 addattr_l(n, MAX_MSG, TCA_SKBEDIT_QUEUE_MAPPING,
148 &queue_mapping, sizeof(queue_mapping));
149 if (flags & SKBEDIT_F_PRIORITY)
150 addattr_l(n, MAX_MSG, TCA_SKBEDIT_PRIORITY,
151 &priority, sizeof(priority));
Jamal Hadi Salime04dd302009-12-26 11:12:43 -0800152 if (flags & SKBEDIT_F_MARK)
153 addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK,
154 &mark, sizeof(mark));
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800155 tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail;
156
157 *argc_p = argc;
158 *argv_p = argv;
159 return 0;
160}
161
162static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
163{
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800164 struct rtattr *tb[TCA_SKBEDIT_MAX + 1];
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700165
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800166 SPRINT_BUF(b1);
167 __u32 *priority;
Jamal Hadi Salime04dd302009-12-26 11:12:43 -0800168 __u32 *mark;
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800169 __u16 *queue_mapping;
Jamal Hadi Salim02b1d342013-12-21 16:38:37 -0500170 struct tc_skbedit *p = NULL;
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800171
172 if (arg == NULL)
173 return -1;
174
175 parse_rtattr_nested(tb, TCA_SKBEDIT_MAX, arg);
176
177 if (tb[TCA_SKBEDIT_PARMS] == NULL) {
178 fprintf(f, "[NULL skbedit parameters]");
179 return -1;
180 }
Jamal Hadi Salim02b1d342013-12-21 16:38:37 -0500181 p = RTA_DATA(tb[TCA_SKBEDIT_PARMS]);
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800182
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800183 fprintf(f, " skbedit");
184
185 if (tb[TCA_SKBEDIT_QUEUE_MAPPING] != NULL) {
186 queue_mapping = RTA_DATA(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
187 fprintf(f, " queue_mapping %u", *queue_mapping);
188 }
189 if (tb[TCA_SKBEDIT_PRIORITY] != NULL) {
190 priority = RTA_DATA(tb[TCA_SKBEDIT_PRIORITY]);
191 fprintf(f, " priority %s", sprint_tc_classid(*priority, b1));
192 }
Jamal Hadi Salime04dd302009-12-26 11:12:43 -0800193 if (tb[TCA_SKBEDIT_MARK] != NULL) {
194 mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]);
195 fprintf(f, " mark %d", *mark);
196 }
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800197
Jamal Hadi Salim02b1d342013-12-21 16:38:37 -0500198 fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt);
199
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800200 if (show_stats) {
201 if (tb[TCA_SKBEDIT_TM]) {
202 struct tcf_t *tm = RTA_DATA(tb[TCA_SKBEDIT_TM]);
Stephen Hemminger32a121c2016-03-21 11:48:36 -0700203
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800204 print_tm(f, tm);
205 }
206 }
207
Jamal Hadi Salim02b1d342013-12-21 16:38:37 -0500208 fprintf(f, "\n ");
209
Alexander Duyckf72a7aa2009-01-06 19:27:03 -0800210 return 0;
211}
212
213struct action_util skbedit_action_util = {
214 .id = "skbedit",
215 .parse_aopt = parse_skbedit,
216 .print_aopt = print_skbedit,
217};