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 id TUNNELID src_ip IP dst_ip IP dst_port UDP_PORT\n");
28 static void usage(void)
34 static int tunnel_key_parse_ip_addr(const char *str
, int addr4_type
,
35 int addr6_type
, struct nlmsghdr
*n
)
40 ret
= get_addr(&addr
, str
, AF_UNSPEC
);
44 addattr_l(n
, MAX_MSG
, addr
.family
== AF_INET
? addr4_type
: addr6_type
,
45 addr
.data
, addr
.bytelen
);
50 static int tunnel_key_parse_key_id(const char *str
, int type
,
56 ret
= get_be32(&key_id
, str
, 10);
58 addattr32(n
, MAX_MSG
, type
, key_id
);
63 static int tunnel_key_parse_dst_port(char *str
, int type
, struct nlmsghdr
*n
)
68 ret
= get_be16(&dst_port
, str
, 10);
72 addattr16(n
, MAX_MSG
, type
, dst_port
);
77 static int parse_tunnel_key(struct action_util
*a
, int *argc_p
, char ***argv_p
,
78 int tca_id
, struct nlmsghdr
*n
)
80 struct tc_tunnel_key parm
= { .action
= TC_ACT_PIPE
};
81 char **argv
= *argv_p
;
90 if (matches(*argv
, "tunnel_key") != 0)
94 addattr_l(n
, MAX_MSG
, tca_id
, NULL
, 0);
99 if (matches(*argv
, "unset") == 0) {
101 fprintf(stderr
, "unexpected \"%s\" - action already specified\n",
106 action
= TCA_TUNNEL_KEY_ACT_RELEASE
;
107 } else if (matches(*argv
, "set") == 0) {
109 fprintf(stderr
, "unexpected \"%s\" - action already specified\n",
114 action
= TCA_TUNNEL_KEY_ACT_SET
;
115 } else if (matches(*argv
, "src_ip") == 0) {
117 ret
= tunnel_key_parse_ip_addr(*argv
,
118 TCA_TUNNEL_KEY_ENC_IPV4_SRC
,
119 TCA_TUNNEL_KEY_ENC_IPV6_SRC
,
122 fprintf(stderr
, "Illegal \"src_ip\"\n");
126 } else if (matches(*argv
, "dst_ip") == 0) {
128 ret
= tunnel_key_parse_ip_addr(*argv
,
129 TCA_TUNNEL_KEY_ENC_IPV4_DST
,
130 TCA_TUNNEL_KEY_ENC_IPV6_DST
,
133 fprintf(stderr
, "Illegal \"dst_ip\"\n");
137 } else if (matches(*argv
, "id") == 0) {
139 ret
= tunnel_key_parse_key_id(*argv
, TCA_TUNNEL_KEY_ENC_KEY_ID
, n
);
141 fprintf(stderr
, "Illegal \"id\"\n");
145 } else if (matches(*argv
, "dst_port") == 0) {
147 ret
= tunnel_key_parse_dst_port(*argv
,
148 TCA_TUNNEL_KEY_ENC_DST_PORT
, n
);
150 fprintf(stderr
, "Illegal \"dst port\"\n");
153 } else if (matches(*argv
, "help") == 0) {
161 if (argc
&& !action_a2n(*argv
, &parm
.action
, false))
165 if (matches(*argv
, "index") == 0) {
167 if (get_u32(&parm
.index
, *argv
, 10)) {
168 fprintf(stderr
, "tunnel_key: Illegal \"index\"\n");
176 if (action
== TCA_TUNNEL_KEY_ACT_SET
&&
177 (!has_src_ip
|| !has_dst_ip
|| !has_key_id
)) {
178 fprintf(stderr
, "set needs tunnel_key parameters\n");
183 parm
.t_action
= action
;
184 addattr_l(n
, MAX_MSG
, TCA_TUNNEL_KEY_PARMS
, &parm
, sizeof(parm
));
185 tail
->rta_len
= (char *)NLMSG_TAIL(n
) - (char *)tail
;
193 static void tunnel_key_print_ip_addr(FILE *f
, const char *name
,
202 len
= RTA_PAYLOAD(attr
);
211 fprintf(f
, "\n\t%s %s", name
, rt_addr_n2a_rta(family
, attr
));
214 static void tunnel_key_print_key_id(FILE *f
, const char *name
,
219 fprintf(f
, "\n\t%s %d", name
, rta_getattr_be32(attr
));
222 static void tunnel_key_print_dst_port(FILE *f
, char *name
,
227 fprintf(f
, "\n\t%s %d", name
, rta_getattr_be16(attr
));
230 static int print_tunnel_key(struct action_util
*au
, FILE *f
, struct rtattr
*arg
)
232 struct rtattr
*tb
[TCA_TUNNEL_KEY_MAX
+ 1];
233 struct tc_tunnel_key
*parm
;
238 parse_rtattr_nested(tb
, TCA_TUNNEL_KEY_MAX
, arg
);
240 if (!tb
[TCA_TUNNEL_KEY_PARMS
]) {
241 fprintf(f
, "[NULL tunnel_key parameters]");
244 parm
= RTA_DATA(tb
[TCA_TUNNEL_KEY_PARMS
]);
246 fprintf(f
, "tunnel_key");
248 switch (parm
->t_action
) {
249 case TCA_TUNNEL_KEY_ACT_RELEASE
:
250 fprintf(f
, " unset");
252 case TCA_TUNNEL_KEY_ACT_SET
:
254 tunnel_key_print_ip_addr(f
, "src_ip",
255 tb
[TCA_TUNNEL_KEY_ENC_IPV4_SRC
]);
256 tunnel_key_print_ip_addr(f
, "dst_ip",
257 tb
[TCA_TUNNEL_KEY_ENC_IPV4_DST
]);
258 tunnel_key_print_ip_addr(f
, "src_ip",
259 tb
[TCA_TUNNEL_KEY_ENC_IPV6_SRC
]);
260 tunnel_key_print_ip_addr(f
, "dst_ip",
261 tb
[TCA_TUNNEL_KEY_ENC_IPV6_DST
]);
262 tunnel_key_print_key_id(f
, "key_id",
263 tb
[TCA_TUNNEL_KEY_ENC_KEY_ID
]);
264 tunnel_key_print_dst_port(f
, "dst_port",
265 tb
[TCA_TUNNEL_KEY_ENC_DST_PORT
]);
268 fprintf(f
, " %s", action_n2a(parm
->action
));
270 fprintf(f
, "\n\tindex %d ref %d bind %d", parm
->index
, parm
->refcnt
,
274 if (tb
[TCA_TUNNEL_KEY_TM
]) {
275 struct tcf_t
*tm
= RTA_DATA(tb
[TCA_TUNNEL_KEY_TM
]);
286 struct action_util tunnel_key_action_util
= {
288 .parse_aopt
= parse_tunnel_key
,
289 .print_aopt
= print_tunnel_key
,