]> git.ipfire.org Git - thirdparty/iproute2.git/blob - tc/m_connmark.c
tc: make action_util arg const
[thirdparty/iproute2.git] / tc / m_connmark.c
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * m_connmark.c Connection tracking marking import
4 *
5 * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include "utils.h"
13 #include "tc_util.h"
14 #include <linux/tc_act/tc_connmark.h>
15
16 static void
17 explain(void)
18 {
19 fprintf(stderr,
20 "Usage: ... connmark [zone ZONE] [CONTROL] [index <INDEX>]\n"
21 "where :\n"
22 "\tZONE is the conntrack zone\n"
23 "\tCONTROL := reclassify | pipe | drop | continue | ok |\n"
24 "\t goto chain <CHAIN_INDEX>\n");
25 }
26
27 static void
28 usage(void)
29 {
30 explain();
31 exit(-1);
32 }
33
34 static int
35 parse_connmark(const struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
36 struct nlmsghdr *n)
37 {
38 struct tc_connmark sel = {};
39 char **argv = *argv_p;
40 int argc = *argc_p;
41 int ok = 0;
42 struct rtattr *tail;
43
44 while (argc > 0) {
45 if (matches(*argv, "connmark") == 0) {
46 ok = 1;
47 argc--;
48 argv++;
49 } else if (matches(*argv, "help") == 0) {
50 usage();
51 } else {
52 break;
53 }
54
55 }
56
57 if (!ok) {
58 explain();
59 return -1;
60 }
61
62 if (argc) {
63 if (matches(*argv, "zone") == 0) {
64 NEXT_ARG();
65 if (get_u16(&sel.zone, *argv, 10)) {
66 fprintf(stderr, "connmark: Illegal \"zone\"\n");
67 return -1;
68 }
69 argc--;
70 argv++;
71 }
72 }
73
74 parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_PIPE);
75
76 if (argc) {
77 if (matches(*argv, "index") == 0) {
78 NEXT_ARG();
79 if (get_u32(&sel.index, *argv, 10)) {
80 fprintf(stderr, "connmark: Illegal \"index\"\n");
81 return -1;
82 }
83 argc--;
84 argv++;
85 }
86 }
87
88 tail = addattr_nest(n, MAX_MSG, tca_id);
89 addattr_l(n, MAX_MSG, TCA_CONNMARK_PARMS, &sel, sizeof(sel));
90 addattr_nest_end(n, tail);
91
92 *argc_p = argc;
93 *argv_p = argv;
94 return 0;
95 }
96
97 static int print_connmark(const struct action_util *au, FILE *f, struct rtattr *arg)
98 {
99 struct rtattr *tb[TCA_CONNMARK_MAX + 1];
100 struct tc_connmark *ci;
101
102 print_string(PRINT_ANY, "kind", "%s ", "connmark");
103 if (arg == NULL)
104 return 0;
105
106 parse_rtattr_nested(tb, TCA_CONNMARK_MAX, arg);
107 if (tb[TCA_CONNMARK_PARMS] == NULL) {
108 fprintf(stderr, "Missing connmark parameters\n");
109 return -1;
110 }
111
112 ci = RTA_DATA(tb[TCA_CONNMARK_PARMS]);
113
114 print_uint(PRINT_ANY, "zone", "zone %u", ci->zone);
115 print_action_control(f, " ", ci->action, "");
116
117 print_nl();
118 print_uint(PRINT_ANY, "index", "\t index %u", ci->index);
119 print_int(PRINT_ANY, "ref", " ref %d", ci->refcnt);
120 print_int(PRINT_ANY, "bind", " bind %d", ci->bindcnt);
121
122 if (show_stats) {
123 if (tb[TCA_CONNMARK_TM]) {
124 struct tcf_t *tm = RTA_DATA(tb[TCA_CONNMARK_TM]);
125
126 print_tm(f, tm);
127 }
128 }
129 print_nl();
130
131 return 0;
132 }
133
134 struct action_util connmark_action_util = {
135 .id = "connmark",
136 .parse_aopt = parse_connmark,
137 .print_aopt = print_connmark,
138 };