xref: /aosp_15_r20/external/iproute2/tc/m_tunnel_key.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker  * m_tunnel_key.c	ip tunnel manipulation module
3*de1e4e89SAndroid Build Coastguard Worker  *
4*de1e4e89SAndroid Build Coastguard Worker  *              This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker  *              modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker  *              as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker  *              2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker  *
9*de1e4e89SAndroid Build Coastguard Worker  * Authors:     Amir Vadai <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker  */
11*de1e4e89SAndroid Build Coastguard Worker 
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_ether.h>
17*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
18*de1e4e89SAndroid Build Coastguard Worker #include "rt_names.h"
19*de1e4e89SAndroid Build Coastguard Worker #include "tc_util.h"
20*de1e4e89SAndroid Build Coastguard Worker #include <linux/tc_act/tc_tunnel_key.h>
21*de1e4e89SAndroid Build Coastguard Worker 
explain(void)22*de1e4e89SAndroid Build Coastguard Worker static void explain(void)
23*de1e4e89SAndroid Build Coastguard Worker {
24*de1e4e89SAndroid Build Coastguard Worker 	fprintf(stderr, "Usage: tunnel_key unset\n");
25*de1e4e89SAndroid Build Coastguard Worker 	fprintf(stderr, "       tunnel_key set <TUNNEL_KEY>\n");
26*de1e4e89SAndroid Build Coastguard Worker 	fprintf(stderr,
27*de1e4e89SAndroid Build Coastguard Worker 		"Where TUNNEL_KEY is a combination of:\n"
28*de1e4e89SAndroid Build Coastguard Worker 		"id <TUNNELID> (mandatory)\n"
29*de1e4e89SAndroid Build Coastguard Worker 		"src_ip <IP> (mandatory)\n"
30*de1e4e89SAndroid Build Coastguard Worker 		"dst_ip <IP> (mandatory)\n"
31*de1e4e89SAndroid Build Coastguard Worker 		"dst_port <UDP_PORT>\n"
32*de1e4e89SAndroid Build Coastguard Worker 		"csum | nocsum (default is \"csum\")\n");
33*de1e4e89SAndroid Build Coastguard Worker }
34*de1e4e89SAndroid Build Coastguard Worker 
usage(void)35*de1e4e89SAndroid Build Coastguard Worker static void usage(void)
36*de1e4e89SAndroid Build Coastguard Worker {
37*de1e4e89SAndroid Build Coastguard Worker 	explain();
38*de1e4e89SAndroid Build Coastguard Worker 	exit(-1);
39*de1e4e89SAndroid Build Coastguard Worker }
40*de1e4e89SAndroid Build Coastguard Worker 
tunnel_key_parse_ip_addr(const char * str,int addr4_type,int addr6_type,struct nlmsghdr * n)41*de1e4e89SAndroid Build Coastguard Worker static int tunnel_key_parse_ip_addr(const char *str, int addr4_type,
42*de1e4e89SAndroid Build Coastguard Worker 				    int addr6_type, struct nlmsghdr *n)
43*de1e4e89SAndroid Build Coastguard Worker {
44*de1e4e89SAndroid Build Coastguard Worker 	inet_prefix addr;
45*de1e4e89SAndroid Build Coastguard Worker 	int ret;
46*de1e4e89SAndroid Build Coastguard Worker 
47*de1e4e89SAndroid Build Coastguard Worker 	ret = get_addr(&addr, str, AF_UNSPEC);
48*de1e4e89SAndroid Build Coastguard Worker 	if (ret)
49*de1e4e89SAndroid Build Coastguard Worker 		return ret;
50*de1e4e89SAndroid Build Coastguard Worker 
51*de1e4e89SAndroid Build Coastguard Worker 	addattr_l(n, MAX_MSG, addr.family == AF_INET ? addr4_type : addr6_type,
52*de1e4e89SAndroid Build Coastguard Worker 		  addr.data, addr.bytelen);
53*de1e4e89SAndroid Build Coastguard Worker 
54*de1e4e89SAndroid Build Coastguard Worker 	return 0;
55*de1e4e89SAndroid Build Coastguard Worker }
56*de1e4e89SAndroid Build Coastguard Worker 
tunnel_key_parse_key_id(const char * str,int type,struct nlmsghdr * n)57*de1e4e89SAndroid Build Coastguard Worker static int tunnel_key_parse_key_id(const char *str, int type,
58*de1e4e89SAndroid Build Coastguard Worker 				   struct nlmsghdr *n)
59*de1e4e89SAndroid Build Coastguard Worker {
60*de1e4e89SAndroid Build Coastguard Worker 	__be32 key_id;
61*de1e4e89SAndroid Build Coastguard Worker 	int ret;
62*de1e4e89SAndroid Build Coastguard Worker 
63*de1e4e89SAndroid Build Coastguard Worker 	ret = get_be32(&key_id, str, 10);
64*de1e4e89SAndroid Build Coastguard Worker 	if (!ret)
65*de1e4e89SAndroid Build Coastguard Worker 		addattr32(n, MAX_MSG, type, key_id);
66*de1e4e89SAndroid Build Coastguard Worker 
67*de1e4e89SAndroid Build Coastguard Worker 	return ret;
68*de1e4e89SAndroid Build Coastguard Worker }
69*de1e4e89SAndroid Build Coastguard Worker 
tunnel_key_parse_dst_port(char * str,int type,struct nlmsghdr * n)70*de1e4e89SAndroid Build Coastguard Worker static int tunnel_key_parse_dst_port(char *str, int type, struct nlmsghdr *n)
71*de1e4e89SAndroid Build Coastguard Worker {
72*de1e4e89SAndroid Build Coastguard Worker 	int ret;
73*de1e4e89SAndroid Build Coastguard Worker 	__be16 dst_port;
74*de1e4e89SAndroid Build Coastguard Worker 
75*de1e4e89SAndroid Build Coastguard Worker 	ret = get_be16(&dst_port, str, 10);
76*de1e4e89SAndroid Build Coastguard Worker 	if (ret)
77*de1e4e89SAndroid Build Coastguard Worker 		return -1;
78*de1e4e89SAndroid Build Coastguard Worker 
79*de1e4e89SAndroid Build Coastguard Worker 	addattr16(n, MAX_MSG, type, dst_port);
80*de1e4e89SAndroid Build Coastguard Worker 
81*de1e4e89SAndroid Build Coastguard Worker 	return 0;
82*de1e4e89SAndroid Build Coastguard Worker }
83*de1e4e89SAndroid Build Coastguard Worker 
parse_tunnel_key(struct action_util * a,int * argc_p,char *** argv_p,int tca_id,struct nlmsghdr * n)84*de1e4e89SAndroid Build Coastguard Worker static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
85*de1e4e89SAndroid Build Coastguard Worker 			    int tca_id, struct nlmsghdr *n)
86*de1e4e89SAndroid Build Coastguard Worker {
87*de1e4e89SAndroid Build Coastguard Worker 	struct tc_tunnel_key parm = {};
88*de1e4e89SAndroid Build Coastguard Worker 	char **argv = *argv_p;
89*de1e4e89SAndroid Build Coastguard Worker 	int argc = *argc_p;
90*de1e4e89SAndroid Build Coastguard Worker 	struct rtattr *tail;
91*de1e4e89SAndroid Build Coastguard Worker 	int action = 0;
92*de1e4e89SAndroid Build Coastguard Worker 	int ret;
93*de1e4e89SAndroid Build Coastguard Worker 	int has_src_ip = 0;
94*de1e4e89SAndroid Build Coastguard Worker 	int has_dst_ip = 0;
95*de1e4e89SAndroid Build Coastguard Worker 	int has_key_id = 0;
96*de1e4e89SAndroid Build Coastguard Worker 	int csum = 1;
97*de1e4e89SAndroid Build Coastguard Worker 
98*de1e4e89SAndroid Build Coastguard Worker 	if (matches(*argv, "tunnel_key") != 0)
99*de1e4e89SAndroid Build Coastguard Worker 		return -1;
100*de1e4e89SAndroid Build Coastguard Worker 
101*de1e4e89SAndroid Build Coastguard Worker 	tail = NLMSG_TAIL(n);
102*de1e4e89SAndroid Build Coastguard Worker 	addattr_l(n, MAX_MSG, tca_id, NULL, 0);
103*de1e4e89SAndroid Build Coastguard Worker 
104*de1e4e89SAndroid Build Coastguard Worker 	NEXT_ARG();
105*de1e4e89SAndroid Build Coastguard Worker 
106*de1e4e89SAndroid Build Coastguard Worker 	while (argc > 0) {
107*de1e4e89SAndroid Build Coastguard Worker 		if (matches(*argv, "unset") == 0) {
108*de1e4e89SAndroid Build Coastguard Worker 			if (action) {
109*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "unexpected \"%s\" - action already specified\n",
110*de1e4e89SAndroid Build Coastguard Worker 					*argv);
111*de1e4e89SAndroid Build Coastguard Worker 				explain();
112*de1e4e89SAndroid Build Coastguard Worker 				return -1;
113*de1e4e89SAndroid Build Coastguard Worker 			}
114*de1e4e89SAndroid Build Coastguard Worker 			action = TCA_TUNNEL_KEY_ACT_RELEASE;
115*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "set") == 0) {
116*de1e4e89SAndroid Build Coastguard Worker 			if (action) {
117*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "unexpected \"%s\" - action already specified\n",
118*de1e4e89SAndroid Build Coastguard Worker 					*argv);
119*de1e4e89SAndroid Build Coastguard Worker 				explain();
120*de1e4e89SAndroid Build Coastguard Worker 				return -1;
121*de1e4e89SAndroid Build Coastguard Worker 			}
122*de1e4e89SAndroid Build Coastguard Worker 			action = TCA_TUNNEL_KEY_ACT_SET;
123*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "src_ip") == 0) {
124*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
125*de1e4e89SAndroid Build Coastguard Worker 			ret = tunnel_key_parse_ip_addr(*argv,
126*de1e4e89SAndroid Build Coastguard Worker 						       TCA_TUNNEL_KEY_ENC_IPV4_SRC,
127*de1e4e89SAndroid Build Coastguard Worker 						       TCA_TUNNEL_KEY_ENC_IPV6_SRC,
128*de1e4e89SAndroid Build Coastguard Worker 						       n);
129*de1e4e89SAndroid Build Coastguard Worker 			if (ret < 0) {
130*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "Illegal \"src_ip\"\n");
131*de1e4e89SAndroid Build Coastguard Worker 				return -1;
132*de1e4e89SAndroid Build Coastguard Worker 			}
133*de1e4e89SAndroid Build Coastguard Worker 			has_src_ip = 1;
134*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "dst_ip") == 0) {
135*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
136*de1e4e89SAndroid Build Coastguard Worker 			ret = tunnel_key_parse_ip_addr(*argv,
137*de1e4e89SAndroid Build Coastguard Worker 						       TCA_TUNNEL_KEY_ENC_IPV4_DST,
138*de1e4e89SAndroid Build Coastguard Worker 						       TCA_TUNNEL_KEY_ENC_IPV6_DST,
139*de1e4e89SAndroid Build Coastguard Worker 						       n);
140*de1e4e89SAndroid Build Coastguard Worker 			if (ret < 0) {
141*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "Illegal \"dst_ip\"\n");
142*de1e4e89SAndroid Build Coastguard Worker 				return -1;
143*de1e4e89SAndroid Build Coastguard Worker 			}
144*de1e4e89SAndroid Build Coastguard Worker 			has_dst_ip = 1;
145*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "id") == 0) {
146*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
147*de1e4e89SAndroid Build Coastguard Worker 			ret = tunnel_key_parse_key_id(*argv, TCA_TUNNEL_KEY_ENC_KEY_ID, n);
148*de1e4e89SAndroid Build Coastguard Worker 			if (ret < 0) {
149*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "Illegal \"id\"\n");
150*de1e4e89SAndroid Build Coastguard Worker 				return -1;
151*de1e4e89SAndroid Build Coastguard Worker 			}
152*de1e4e89SAndroid Build Coastguard Worker 			has_key_id = 1;
153*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "dst_port") == 0) {
154*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
155*de1e4e89SAndroid Build Coastguard Worker 			ret = tunnel_key_parse_dst_port(*argv,
156*de1e4e89SAndroid Build Coastguard Worker 							TCA_TUNNEL_KEY_ENC_DST_PORT, n);
157*de1e4e89SAndroid Build Coastguard Worker 			if (ret < 0) {
158*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "Illegal \"dst port\"\n");
159*de1e4e89SAndroid Build Coastguard Worker 				return -1;
160*de1e4e89SAndroid Build Coastguard Worker 			}
161*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "csum") == 0) {
162*de1e4e89SAndroid Build Coastguard Worker 			csum = 1;
163*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "nocsum") == 0) {
164*de1e4e89SAndroid Build Coastguard Worker 			csum = 0;
165*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "help") == 0) {
166*de1e4e89SAndroid Build Coastguard Worker 			usage();
167*de1e4e89SAndroid Build Coastguard Worker 		} else {
168*de1e4e89SAndroid Build Coastguard Worker 			break;
169*de1e4e89SAndroid Build Coastguard Worker 		}
170*de1e4e89SAndroid Build Coastguard Worker 		NEXT_ARG_FWD();
171*de1e4e89SAndroid Build Coastguard Worker 	}
172*de1e4e89SAndroid Build Coastguard Worker 
173*de1e4e89SAndroid Build Coastguard Worker 	addattr8(n, MAX_MSG, TCA_TUNNEL_KEY_NO_CSUM, !csum);
174*de1e4e89SAndroid Build Coastguard Worker 
175*de1e4e89SAndroid Build Coastguard Worker 	parse_action_control_dflt(&argc, &argv, &parm.action,
176*de1e4e89SAndroid Build Coastguard Worker 				  false, TC_ACT_PIPE);
177*de1e4e89SAndroid Build Coastguard Worker 
178*de1e4e89SAndroid Build Coastguard Worker 	if (argc) {
179*de1e4e89SAndroid Build Coastguard Worker 		if (matches(*argv, "index") == 0) {
180*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
181*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&parm.index, *argv, 10)) {
182*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "tunnel_key: Illegal \"index\"\n");
183*de1e4e89SAndroid Build Coastguard Worker 				return -1;
184*de1e4e89SAndroid Build Coastguard Worker 			}
185*de1e4e89SAndroid Build Coastguard Worker 
186*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG_FWD();
187*de1e4e89SAndroid Build Coastguard Worker 		}
188*de1e4e89SAndroid Build Coastguard Worker 	}
189*de1e4e89SAndroid Build Coastguard Worker 
190*de1e4e89SAndroid Build Coastguard Worker 	if (action == TCA_TUNNEL_KEY_ACT_SET &&
191*de1e4e89SAndroid Build Coastguard Worker 	    (!has_src_ip || !has_dst_ip || !has_key_id)) {
192*de1e4e89SAndroid Build Coastguard Worker 		fprintf(stderr, "set needs tunnel_key parameters\n");
193*de1e4e89SAndroid Build Coastguard Worker 		explain();
194*de1e4e89SAndroid Build Coastguard Worker 		return -1;
195*de1e4e89SAndroid Build Coastguard Worker 	}
196*de1e4e89SAndroid Build Coastguard Worker 
197*de1e4e89SAndroid Build Coastguard Worker 	parm.t_action = action;
198*de1e4e89SAndroid Build Coastguard Worker 	addattr_l(n, MAX_MSG, TCA_TUNNEL_KEY_PARMS, &parm, sizeof(parm));
199*de1e4e89SAndroid Build Coastguard Worker 	tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail;
200*de1e4e89SAndroid Build Coastguard Worker 
201*de1e4e89SAndroid Build Coastguard Worker 	*argc_p = argc;
202*de1e4e89SAndroid Build Coastguard Worker 	*argv_p = argv;
203*de1e4e89SAndroid Build Coastguard Worker 
204*de1e4e89SAndroid Build Coastguard Worker 	return 0;
205*de1e4e89SAndroid Build Coastguard Worker }
206*de1e4e89SAndroid Build Coastguard Worker 
tunnel_key_print_ip_addr(FILE * f,const char * name,struct rtattr * attr)207*de1e4e89SAndroid Build Coastguard Worker static void tunnel_key_print_ip_addr(FILE *f, const char *name,
208*de1e4e89SAndroid Build Coastguard Worker 				     struct rtattr *attr)
209*de1e4e89SAndroid Build Coastguard Worker {
210*de1e4e89SAndroid Build Coastguard Worker 	int family;
211*de1e4e89SAndroid Build Coastguard Worker 	size_t len;
212*de1e4e89SAndroid Build Coastguard Worker 
213*de1e4e89SAndroid Build Coastguard Worker 	if (!attr)
214*de1e4e89SAndroid Build Coastguard Worker 		return;
215*de1e4e89SAndroid Build Coastguard Worker 
216*de1e4e89SAndroid Build Coastguard Worker 	len = RTA_PAYLOAD(attr);
217*de1e4e89SAndroid Build Coastguard Worker 
218*de1e4e89SAndroid Build Coastguard Worker 	if (len == 4)
219*de1e4e89SAndroid Build Coastguard Worker 		family = AF_INET;
220*de1e4e89SAndroid Build Coastguard Worker 	else if (len == 16)
221*de1e4e89SAndroid Build Coastguard Worker 		family = AF_INET6;
222*de1e4e89SAndroid Build Coastguard Worker 	else
223*de1e4e89SAndroid Build Coastguard Worker 		return;
224*de1e4e89SAndroid Build Coastguard Worker 
225*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f, "\n\t%s %s", name, rt_addr_n2a_rta(family, attr));
226*de1e4e89SAndroid Build Coastguard Worker }
227*de1e4e89SAndroid Build Coastguard Worker 
tunnel_key_print_key_id(FILE * f,const char * name,struct rtattr * attr)228*de1e4e89SAndroid Build Coastguard Worker static void tunnel_key_print_key_id(FILE *f, const char *name,
229*de1e4e89SAndroid Build Coastguard Worker 				    struct rtattr *attr)
230*de1e4e89SAndroid Build Coastguard Worker {
231*de1e4e89SAndroid Build Coastguard Worker 	if (!attr)
232*de1e4e89SAndroid Build Coastguard Worker 		return;
233*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f, "\n\t%s %d", name, rta_getattr_be32(attr));
234*de1e4e89SAndroid Build Coastguard Worker }
235*de1e4e89SAndroid Build Coastguard Worker 
tunnel_key_print_dst_port(FILE * f,char * name,struct rtattr * attr)236*de1e4e89SAndroid Build Coastguard Worker static void tunnel_key_print_dst_port(FILE *f, char *name,
237*de1e4e89SAndroid Build Coastguard Worker 				      struct rtattr *attr)
238*de1e4e89SAndroid Build Coastguard Worker {
239*de1e4e89SAndroid Build Coastguard Worker 	if (!attr)
240*de1e4e89SAndroid Build Coastguard Worker 		return;
241*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f, "\n\t%s %d", name, rta_getattr_be16(attr));
242*de1e4e89SAndroid Build Coastguard Worker }
243*de1e4e89SAndroid Build Coastguard Worker 
tunnel_key_print_flag(FILE * f,const char * name_on,const char * name_off,struct rtattr * attr)244*de1e4e89SAndroid Build Coastguard Worker static void tunnel_key_print_flag(FILE *f, const char *name_on,
245*de1e4e89SAndroid Build Coastguard Worker 				  const char *name_off,
246*de1e4e89SAndroid Build Coastguard Worker 				  struct rtattr *attr)
247*de1e4e89SAndroid Build Coastguard Worker {
248*de1e4e89SAndroid Build Coastguard Worker 	if (!attr)
249*de1e4e89SAndroid Build Coastguard Worker 		return;
250*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f, "\n\t%s", rta_getattr_u8(attr) ? name_on : name_off);
251*de1e4e89SAndroid Build Coastguard Worker }
252*de1e4e89SAndroid Build Coastguard Worker 
print_tunnel_key(struct action_util * au,FILE * f,struct rtattr * arg)253*de1e4e89SAndroid Build Coastguard Worker static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg)
254*de1e4e89SAndroid Build Coastguard Worker {
255*de1e4e89SAndroid Build Coastguard Worker 	struct rtattr *tb[TCA_TUNNEL_KEY_MAX + 1];
256*de1e4e89SAndroid Build Coastguard Worker 	struct tc_tunnel_key *parm;
257*de1e4e89SAndroid Build Coastguard Worker 
258*de1e4e89SAndroid Build Coastguard Worker 	if (!arg)
259*de1e4e89SAndroid Build Coastguard Worker 		return -1;
260*de1e4e89SAndroid Build Coastguard Worker 
261*de1e4e89SAndroid Build Coastguard Worker 	parse_rtattr_nested(tb, TCA_TUNNEL_KEY_MAX, arg);
262*de1e4e89SAndroid Build Coastguard Worker 
263*de1e4e89SAndroid Build Coastguard Worker 	if (!tb[TCA_TUNNEL_KEY_PARMS]) {
264*de1e4e89SAndroid Build Coastguard Worker 		fprintf(f, "[NULL tunnel_key parameters]");
265*de1e4e89SAndroid Build Coastguard Worker 		return -1;
266*de1e4e89SAndroid Build Coastguard Worker 	}
267*de1e4e89SAndroid Build Coastguard Worker 	parm = RTA_DATA(tb[TCA_TUNNEL_KEY_PARMS]);
268*de1e4e89SAndroid Build Coastguard Worker 
269*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f, "tunnel_key");
270*de1e4e89SAndroid Build Coastguard Worker 
271*de1e4e89SAndroid Build Coastguard Worker 	switch (parm->t_action) {
272*de1e4e89SAndroid Build Coastguard Worker 	case TCA_TUNNEL_KEY_ACT_RELEASE:
273*de1e4e89SAndroid Build Coastguard Worker 		fprintf(f, " unset");
274*de1e4e89SAndroid Build Coastguard Worker 		break;
275*de1e4e89SAndroid Build Coastguard Worker 	case TCA_TUNNEL_KEY_ACT_SET:
276*de1e4e89SAndroid Build Coastguard Worker 		fprintf(f, " set");
277*de1e4e89SAndroid Build Coastguard Worker 		tunnel_key_print_ip_addr(f, "src_ip",
278*de1e4e89SAndroid Build Coastguard Worker 					 tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC]);
279*de1e4e89SAndroid Build Coastguard Worker 		tunnel_key_print_ip_addr(f, "dst_ip",
280*de1e4e89SAndroid Build Coastguard Worker 					 tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]);
281*de1e4e89SAndroid Build Coastguard Worker 		tunnel_key_print_ip_addr(f, "src_ip",
282*de1e4e89SAndroid Build Coastguard Worker 					 tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC]);
283*de1e4e89SAndroid Build Coastguard Worker 		tunnel_key_print_ip_addr(f, "dst_ip",
284*de1e4e89SAndroid Build Coastguard Worker 					 tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]);
285*de1e4e89SAndroid Build Coastguard Worker 		tunnel_key_print_key_id(f, "key_id",
286*de1e4e89SAndroid Build Coastguard Worker 					tb[TCA_TUNNEL_KEY_ENC_KEY_ID]);
287*de1e4e89SAndroid Build Coastguard Worker 		tunnel_key_print_dst_port(f, "dst_port",
288*de1e4e89SAndroid Build Coastguard Worker 					  tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
289*de1e4e89SAndroid Build Coastguard Worker 		tunnel_key_print_flag(f, "nocsum", "csum",
290*de1e4e89SAndroid Build Coastguard Worker 				      tb[TCA_TUNNEL_KEY_NO_CSUM]);
291*de1e4e89SAndroid Build Coastguard Worker 		break;
292*de1e4e89SAndroid Build Coastguard Worker 	}
293*de1e4e89SAndroid Build Coastguard Worker 	print_action_control(f, " ", parm->action, "");
294*de1e4e89SAndroid Build Coastguard Worker 
295*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f, "\n\tindex %d ref %d bind %d", parm->index, parm->refcnt,
296*de1e4e89SAndroid Build Coastguard Worker 		parm->bindcnt);
297*de1e4e89SAndroid Build Coastguard Worker 
298*de1e4e89SAndroid Build Coastguard Worker 	if (show_stats) {
299*de1e4e89SAndroid Build Coastguard Worker 		if (tb[TCA_TUNNEL_KEY_TM]) {
300*de1e4e89SAndroid Build Coastguard Worker 			struct tcf_t *tm = RTA_DATA(tb[TCA_TUNNEL_KEY_TM]);
301*de1e4e89SAndroid Build Coastguard Worker 
302*de1e4e89SAndroid Build Coastguard Worker 			print_tm(f, tm);
303*de1e4e89SAndroid Build Coastguard Worker 		}
304*de1e4e89SAndroid Build Coastguard Worker 	}
305*de1e4e89SAndroid Build Coastguard Worker 
306*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f, "\n ");
307*de1e4e89SAndroid Build Coastguard Worker 
308*de1e4e89SAndroid Build Coastguard Worker 	return 0;
309*de1e4e89SAndroid Build Coastguard Worker }
310*de1e4e89SAndroid Build Coastguard Worker 
311*de1e4e89SAndroid Build Coastguard Worker struct action_util tunnel_key_action_util = {
312*de1e4e89SAndroid Build Coastguard Worker 	.id = "tunnel_key",
313*de1e4e89SAndroid Build Coastguard Worker 	.parse_aopt = parse_tunnel_key,
314*de1e4e89SAndroid Build Coastguard Worker 	.print_aopt = print_tunnel_key,
315*de1e4e89SAndroid Build Coastguard Worker };
316