2 * m_skbedit.c SKB Editing module
4 * Copyright (c) 2008, Intel Corporation.
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.
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
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 * Authors: Alexander Duyck <alexander.h.duyck@intel.com>
29 #include <linux/tc_act/tc_skbedit.h>
34 fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM]>\n"
35 "QM = queue_mapping QUEUE_MAPPING\n"
36 "PM = priority PRIORITY \n"
38 "QUEUE_MAPPING = device transmit queue to use\n"
39 "PRIORITY = classID to assign to priority field\n"
40 "MARK = firewall mark to set\n");
51 parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
55 char **argv = *argv_p;
60 __u32 flags = 0, priority, mark;
61 struct tc_skbedit sel = { 0 };
63 if (matches(*argv, "skbedit") != 0)
69 if (matches(*argv, "queue_mapping") == 0) {
70 flags |= SKBEDIT_F_QUEUE_MAPPING;
72 if (get_unsigned(&tmp, *argv, 10) || tmp > 65535) {
73 fprintf(stderr, "Illegal queue_mapping\n");
78 } else if (matches(*argv, "priority") == 0) {
79 flags |= SKBEDIT_F_PRIORITY;
81 if (get_tc_classid(&priority, *argv)) {
82 fprintf(stderr, "Illegal priority\n");
86 } else if (matches(*argv, "mark") == 0) {
87 flags |= SKBEDIT_F_MARK;
89 if (get_u32(&mark, *argv, 0)) {
90 fprintf(stderr, "Illegal mark\n");
94 } else if (matches(*argv, "help") == 0) {
104 if (matches(*argv, "reclassify") == 0) {
105 sel.action = TC_ACT_RECLASSIFY;
107 } else if (matches(*argv, "pipe") == 0) {
108 sel.action = TC_ACT_PIPE;
110 } else if (matches(*argv, "drop") == 0 ||
111 matches(*argv, "shot") == 0) {
112 sel.action = TC_ACT_SHOT;
114 } else if (matches(*argv, "continue") == 0) {
115 sel.action = TC_ACT_UNSPEC;
117 } else if (matches(*argv, "pass") == 0) {
118 sel.action = TC_ACT_OK;
124 if (matches(*argv, "index") == 0) {
126 if (get_u32(&sel.index, *argv, 10)) {
127 fprintf(stderr, "Pedit: Illegal \"index\"\n");
142 tail = NLMSG_TAIL(n);
143 addattr_l(n, MAX_MSG, tca_id, NULL, 0);
144 addattr_l(n, MAX_MSG, TCA_SKBEDIT_PARMS, &sel, sizeof(sel));
145 if (flags & SKBEDIT_F_QUEUE_MAPPING)
146 addattr_l(n, MAX_MSG, TCA_SKBEDIT_QUEUE_MAPPING,
147 &queue_mapping, sizeof(queue_mapping));
148 if (flags & SKBEDIT_F_PRIORITY)
149 addattr_l(n, MAX_MSG, TCA_SKBEDIT_PRIORITY,
150 &priority, sizeof(priority));
151 if (flags & SKBEDIT_F_MARK)
152 addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK,
153 &mark, sizeof(mark));
154 tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail;
161 static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
163 struct rtattr *tb[TCA_SKBEDIT_MAX + 1];
167 __u16 *queue_mapping;
172 parse_rtattr_nested(tb, TCA_SKBEDIT_MAX, arg);
174 if (tb[TCA_SKBEDIT_PARMS] == NULL) {
175 fprintf(f, "[NULL skbedit parameters]");
179 fprintf(f, " skbedit");
181 if (tb[TCA_SKBEDIT_QUEUE_MAPPING] != NULL) {
182 queue_mapping = RTA_DATA(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
183 fprintf(f, " queue_mapping %u", *queue_mapping);
185 if (tb[TCA_SKBEDIT_PRIORITY] != NULL) {
186 priority = RTA_DATA(tb[TCA_SKBEDIT_PRIORITY]);
187 fprintf(f, " priority %s", sprint_tc_classid(*priority, b1));
189 if (tb[TCA_SKBEDIT_MARK] != NULL) {
190 mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]);
191 fprintf(f, " mark %d", *mark);
195 if (tb[TCA_SKBEDIT_TM]) {
196 struct tcf_t *tm = RTA_DATA(tb[TCA_SKBEDIT_TM]);
204 struct action_util skbedit_action_util = {
206 .parse_aopt = parse_skbedit,
207 .print_aopt = print_skbedit,