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