2 * m_tunnel_key.c ip tunnel manipulation module
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.
9 * Authors: Amir Vadai <amir@vadai.me>
16 #include <linux/if_ether.h>
20 #include <linux/tc_act/tc_tunnel_key.h>
22 static void explain(void)
24 fprintf(stderr
, "Usage: tunnel_key unset\n");
25 fprintf(stderr
, " tunnel_key set <TUNNEL_KEY>\n");
27 "Where TUNNEL_KEY is a combination of:\n"
28 "id <TUNNELID> (mandatory)\n"
29 "src_ip <IP> (mandatory)\n"
30 "dst_ip <IP> (mandatory)\n"
31 "dst_port <UDP_PORT>\n"
32 "csum | nocsum (default is \"csum\")\n");
35 static void usage(void)
41 static int tunnel_key_parse_ip_addr(const char *str
, int addr4_type
,
42 int addr6_type
, struct nlmsghdr
*n
)
47 ret
= get_addr(&addr
, str
, AF_UNSPEC
);
51 addattr_l(n
, MAX_MSG
, addr
.family
== AF_INET
? addr4_type
: addr6_type
,
52 addr
.data
, addr
.bytelen
);
57 static int tunnel_key_parse_key_id(const char *str
, int type
,
63 ret
= get_be32(&key_id
, str
, 10);
65 addattr32(n
, MAX_MSG
, type
, key_id
);
70 static int tunnel_key_parse_dst_port(char *str
, int type
, struct nlmsghdr
*n
)
75 ret
= get_be16(&dst_port
, str
, 10);
79 addattr16(n
, MAX_MSG
, type
, dst_port
);
84 static int parse_tunnel_key(struct action_util
*a
, int *argc_p
, char ***argv_p
,
85 int tca_id
, struct nlmsghdr
*n
)
87 struct tc_tunnel_key parm
= {};
88 char **argv
= *argv_p
;
98 if (matches(*argv
, "tunnel_key") != 0)
101 tail
= NLMSG_TAIL(n
);
102 addattr_l(n
, MAX_MSG
, tca_id
, NULL
, 0);
107 if (matches(*argv
, "unset") == 0) {
109 fprintf(stderr
, "unexpected \"%s\" - action already specified\n",
114 action
= TCA_TUNNEL_KEY_ACT_RELEASE
;
115 } else if (matches(*argv
, "set") == 0) {
117 fprintf(stderr
, "unexpected \"%s\" - action already specified\n",
122 action
= TCA_TUNNEL_KEY_ACT_SET
;
123 } else if (matches(*argv
, "src_ip") == 0) {
125 ret
= tunnel_key_parse_ip_addr(*argv
,
126 TCA_TUNNEL_KEY_ENC_IPV4_SRC
,
127 TCA_TUNNEL_KEY_ENC_IPV6_SRC
,
130 fprintf(stderr
, "Illegal \"src_ip\"\n");
134 } else if (matches(*argv
, "dst_ip") == 0) {
136 ret
= tunnel_key_parse_ip_addr(*argv
,
137 TCA_TUNNEL_KEY_ENC_IPV4_DST
,
138 TCA_TUNNEL_KEY_ENC_IPV6_DST
,
141 fprintf(stderr
, "Illegal \"dst_ip\"\n");
145 } else if (matches(*argv
, "id") == 0) {
147 ret
= tunnel_key_parse_key_id(*argv
, TCA_TUNNEL_KEY_ENC_KEY_ID
, n
);
149 fprintf(stderr
, "Illegal \"id\"\n");
153 } else if (matches(*argv
, "dst_port") == 0) {
155 ret
= tunnel_key_parse_dst_port(*argv
,
156 TCA_TUNNEL_KEY_ENC_DST_PORT
, n
);
158 fprintf(stderr
, "Illegal \"dst port\"\n");
161 } else if (matches(*argv
, "csum") == 0) {
163 } else if (matches(*argv
, "nocsum") == 0) {
165 } else if (matches(*argv
, "help") == 0) {
173 addattr8(n
, MAX_MSG
, TCA_TUNNEL_KEY_NO_CSUM
, !csum
);
175 parse_action_control_dflt(&argc
, &argv
, &parm
.action
,
180 if (matches(*argv
, "index") == 0) {
182 if (get_u32(&parm
.index
, *argv
, 10)) {
183 fprintf(stderr
, "tunnel_key: Illegal \"index\"\n");
191 if (action
== TCA_TUNNEL_KEY_ACT_SET
&&
192 (!has_src_ip
|| !has_dst_ip
|| !has_key_id
)) {
193 fprintf(stderr
, "set needs tunnel_key parameters\n");
198 parm
.t_action
= action
;
199 addattr_l(n
, MAX_MSG
, TCA_TUNNEL_KEY_PARMS
, &parm
, sizeof(parm
));
200 tail
->rta_len
= (char *)NLMSG_TAIL(n
) - (char *)tail
;
208 static void tunnel_key_print_ip_addr(FILE *f
, const char *name
,
217 len
= RTA_PAYLOAD(attr
);
226 fprintf(f
, "\n\t%s %s", name
, rt_addr_n2a_rta(family
, attr
));
229 static void tunnel_key_print_key_id(FILE *f
, const char *name
,
234 fprintf(f
, "\n\t%s %d", name
, rta_getattr_be32(attr
));
237 static void tunnel_key_print_dst_port(FILE *f
, char *name
,
242 fprintf(f
, "\n\t%s %d", name
, rta_getattr_be16(attr
));
245 static void tunnel_key_print_flag(FILE *f
, const char *name_on
,
246 const char *name_off
,
251 fprintf(f
, "\n\t%s", rta_getattr_u8(attr
) ? name_on
: name_off
);
254 static int print_tunnel_key(struct action_util
*au
, FILE *f
, struct rtattr
*arg
)
256 struct rtattr
*tb
[TCA_TUNNEL_KEY_MAX
+ 1];
257 struct tc_tunnel_key
*parm
;
262 parse_rtattr_nested(tb
, TCA_TUNNEL_KEY_MAX
, arg
);
264 if (!tb
[TCA_TUNNEL_KEY_PARMS
]) {
265 fprintf(f
, "[NULL tunnel_key parameters]");
268 parm
= RTA_DATA(tb
[TCA_TUNNEL_KEY_PARMS
]);
270 fprintf(f
, "tunnel_key");
272 switch (parm
->t_action
) {
273 case TCA_TUNNEL_KEY_ACT_RELEASE
:
274 fprintf(f
, " unset");
276 case TCA_TUNNEL_KEY_ACT_SET
:
278 tunnel_key_print_ip_addr(f
, "src_ip",
279 tb
[TCA_TUNNEL_KEY_ENC_IPV4_SRC
]);
280 tunnel_key_print_ip_addr(f
, "dst_ip",
281 tb
[TCA_TUNNEL_KEY_ENC_IPV4_DST
]);
282 tunnel_key_print_ip_addr(f
, "src_ip",
283 tb
[TCA_TUNNEL_KEY_ENC_IPV6_SRC
]);
284 tunnel_key_print_ip_addr(f
, "dst_ip",
285 tb
[TCA_TUNNEL_KEY_ENC_IPV6_DST
]);
286 tunnel_key_print_key_id(f
, "key_id",
287 tb
[TCA_TUNNEL_KEY_ENC_KEY_ID
]);
288 tunnel_key_print_dst_port(f
, "dst_port",
289 tb
[TCA_TUNNEL_KEY_ENC_DST_PORT
]);
290 tunnel_key_print_flag(f
, "nocsum", "csum",
291 tb
[TCA_TUNNEL_KEY_NO_CSUM
]);
294 print_action_control(f
, " ", parm
->action
, "");
296 fprintf(f
, "\n\tindex %d ref %d bind %d", parm
->index
, parm
->refcnt
,
300 if (tb
[TCA_TUNNEL_KEY_TM
]) {
301 struct tcf_t
*tm
= RTA_DATA(tb
[TCA_TUNNEL_KEY_TM
]);
312 struct action_util tunnel_key_action_util
= {
314 .parse_aopt
= parse_tunnel_key
,
315 .print_aopt
= print_tunnel_key
,