]> git.proxmox.com Git - mirror_iproute2.git/blame - ip/link_iptnl.c
mptcp: show all endpoints when no ID is specified
[mirror_iproute2.git] / ip / link_iptnl.c
CommitLineData
1ce2de97
ND
1/*
2 * link_iptnl.c ipip and sit driver module
3 *
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.
8 *
9 * Authors: Nicolas Dichtel <nicolas.dichtel@6wind.com>
10 *
11 */
12
13#include <string.h>
14#include <net/if.h>
15#include <sys/types.h>
16#include <sys/socket.h>
17#include <arpa/inet.h>
18
f005b700 19#include <linux/in.h>
1ce2de97
ND
20#include <linux/ip.h>
21#include <linux/if_tunnel.h>
22#include "rt_names.h"
23#include "utils.h"
24#include "ip_common.h"
25#include "tunnel.h"
26
06e3975f
SP
27static void iptunnel_print_help(struct link_util *lu, int argc, char **argv,
28 FILE *f)
1ce2de97 29{
06e3975f 30 const char *mode;
8b471354 31
06e3975f 32 if (strcmp(lu->id, "sit") == 0) {
8589eb4e
MC
33 mode = "{ ip6ip | ipip | mplsip | any } ]\n"
34 " [ isatap";
288c28bc 35 } else {
06e3975f 36 mode = "{ ipip | mplsip | any }";
77620be8 37 }
8589eb4e 38
06e3975f 39 fprintf(f,
8589eb4e
MC
40 "Usage: ... %-6s [ remote ADDR ]\n"
41 " [ local ADDR ]\n"
42 " [ ttl TTL ]\n"
43 " [ tos TOS ]\n"
44 " [ [no]pmtudisc ]\n"
45 " [ 6rd-prefix ADDR ]\n"
46 " [ 6rd-relay_prefix ADDR ]\n"
47 " [ 6rd-reset ]\n"
48 " [ dev PHYS_DEV ]\n"
49 " [ fwmark MARK ]\n"
50 " [ external ]\n"
51 " [ noencap ]\n"
52 " [ encap { fou | gue | none } ]\n"
53 " [ encap-sport PORT ]\n"
54 " [ encap-dport PORT ]\n"
55 " [ [no]encap-csum ]\n"
56 " [ [no]encap-csum6 ]\n"
57 " [ [no]encap-remcsum ]\n"
58 " [ mode %s ]\n"
59 "\n"
60 "Where: ADDR := { IP_ADDRESS | any }\n"
61 " TOS := { NUMBER | inherit }\n"
62 " TTL := { 1..255 | inherit }\n"
63 " MARK := { 0x0..0xffffffff }\n",
64 lu->id, mode);
1ce2de97
ND
65}
66
67static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
68 struct nlmsghdr *n)
69{
28254695 70 struct ifinfomsg *ifi = NLMSG_DATA(n);
1ce2de97
ND
71 struct {
72 struct nlmsghdr n;
73 struct ifinfomsg i;
d17b136f
PS
74 } req = {
75 .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
76 .n.nlmsg_flags = NLM_F_REQUEST,
77 .n.nlmsg_type = RTM_GETLINK,
78 .i.ifi_family = preferred_family,
79 .i.ifi_index = ifi->ifi_index,
80 };
08ede25f 81 struct nlmsghdr *answer;
1ce2de97
ND
82 struct rtattr *tb[IFLA_MAX + 1];
83 struct rtattr *linkinfo[IFLA_INFO_MAX+1];
84 struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
85 int len;
7bda9fd3 86 inet_prefix saddr, daddr, ip6rdprefix, ip6rdrelayprefix;
1ce2de97 87 __u8 pmtudisc = 1;
5bd93795 88 __u8 tos = 0;
1ce2de97 89 __u16 iflags = 0;
5bd93795 90 __u8 ttl = 0;
5bd93795
SP
91 __u8 proto = 0;
92 __u32 link = 0;
c1159152
TH
93 __u16 encaptype = 0;
94 __u16 encapflags = 0;
95 __u16 encapsport = 0;
96 __u16 encapdport = 0;
4bfe6825 97 __u8 metadata = 0;
ad4b1425 98 __u32 fwmark = 0;
1ce2de97 99
7bda9fd3
SP
100 inet_prefix_reset(&saddr);
101 inet_prefix_reset(&daddr);
102
103 inet_prefix_reset(&ip6rdprefix);
104 inet_prefix_reset(&ip6rdrelayprefix);
105
1ce2de97 106 if (!(n->nlmsg_flags & NLM_F_CREATE)) {
7bda9fd3
SP
107 const struct rtattr *rta;
108
86bf43c7 109 if (rtnl_talk(&rth, &req.n, &answer) < 0) {
1ce2de97
ND
110get_failed:
111 fprintf(stderr,
112 "Failed to get existing tunnel info.\n");
113 return -1;
114 }
115
86bf43c7 116 len = answer->nlmsg_len;
1ce2de97
ND
117 len -= NLMSG_LENGTH(sizeof(*ifi));
118 if (len < 0)
119 goto get_failed;
120
86bf43c7 121 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)), len);
1ce2de97
ND
122
123 if (!tb[IFLA_LINKINFO])
124 goto get_failed;
125
126 parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
127
128 if (!linkinfo[IFLA_INFO_DATA])
129 goto get_failed;
130
131 parse_rtattr_nested(iptuninfo, IFLA_IPTUN_MAX,
132 linkinfo[IFLA_INFO_DATA]);
133
7bda9fd3
SP
134 rta = iptuninfo[IFLA_IPTUN_LOCAL];
135 if (rta && get_addr_rta(&saddr, rta, AF_INET))
136 goto get_failed;
137
138 rta = iptuninfo[IFLA_IPTUN_REMOTE];
139 if (rta && get_addr_rta(&daddr, rta, AF_INET))
140 goto get_failed;
141
142 rta = iptuninfo[IFLA_IPTUN_6RD_PREFIX];
143 if (rta && get_addr_rta(&ip6rdprefix, rta, AF_INET6))
144 goto get_failed;
145
146 rta = iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX];
147 if (rta && get_addr_rta(&ip6rdrelayprefix, rta, AF_INET))
148 goto get_failed;
149
150 rta = iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN];
151 ip6rdprefix.bitlen = rta ? rta_getattr_u16(rta) : 0;
1ce2de97 152
7bda9fd3
SP
153 rta = iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN];
154 ip6rdrelayprefix.bitlen = rta ? rta_getattr_u16(rta) : 0;
1ce2de97
ND
155
156 if (iptuninfo[IFLA_IPTUN_TTL])
157 ttl = rta_getattr_u8(iptuninfo[IFLA_IPTUN_TTL]);
158
1ce2de97
ND
159 if (iptuninfo[IFLA_IPTUN_PMTUDISC])
160 pmtudisc =
161 rta_getattr_u8(iptuninfo[IFLA_IPTUN_PMTUDISC]);
162
5bd93795
SP
163 if (iptuninfo[IFLA_IPTUN_TOS])
164 tos = rta_getattr_u8(iptuninfo[IFLA_IPTUN_TOS]);
165
1ce2de97
ND
166 if (iptuninfo[IFLA_IPTUN_FLAGS])
167 iflags = rta_getattr_u16(iptuninfo[IFLA_IPTUN_FLAGS]);
168
169 if (iptuninfo[IFLA_IPTUN_LINK])
170 link = rta_getattr_u32(iptuninfo[IFLA_IPTUN_LINK]);
171
77620be8
ND
172 if (iptuninfo[IFLA_IPTUN_PROTO])
173 proto = rta_getattr_u8(iptuninfo[IFLA_IPTUN_PROTO]);
174
c1159152
TH
175 if (iptuninfo[IFLA_IPTUN_ENCAP_TYPE])
176 encaptype = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_TYPE]);
177 if (iptuninfo[IFLA_IPTUN_ENCAP_FLAGS])
178 encapflags = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_FLAGS]);
179 if (iptuninfo[IFLA_IPTUN_ENCAP_SPORT])
180 encapsport = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_SPORT]);
181 if (iptuninfo[IFLA_IPTUN_ENCAP_DPORT])
182 encapdport = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_DPORT]);
7bda9fd3 183
4bfe6825
AS
184 if (iptuninfo[IFLA_IPTUN_COLLECT_METADATA])
185 metadata = 1;
ad4b1425
CG
186
187 if (iptuninfo[IFLA_IPTUN_FWMARK])
188 fwmark = rta_getattr_u32(iptuninfo[IFLA_IPTUN_FWMARK]);
189
86bf43c7 190 free(answer);
1ce2de97
ND
191 }
192
193 while (argc > 0) {
5bd93795
SP
194 if (strcmp(*argv, "mode") == 0) {
195 NEXT_ARG();
196 if (strcmp(lu->id, "sit") == 0 &&
197 (strcmp(*argv, "ipv6/ipv4") == 0 ||
198 strcmp(*argv, "ip6ip") == 0))
199 proto = IPPROTO_IPV6;
200 else if (strcmp(*argv, "ipv4/ipv4") == 0 ||
201 strcmp(*argv, "ipip") == 0 ||
202 strcmp(*argv, "ip4ip4") == 0)
203 proto = IPPROTO_IPIP;
204 else if (strcmp(*argv, "mpls/ipv4") == 0 ||
205 strcmp(*argv, "mplsip") == 0)
206 proto = IPPROTO_MPLS;
207 else if (strcmp(*argv, "any/ipv4") == 0 ||
208 strcmp(*argv, "any") == 0)
209 proto = 0;
210 else
211 invarg("Cannot guess tunnel mode.", *argv);
212 } else if (strcmp(*argv, "remote") == 0) {
1ce2de97 213 NEXT_ARG();
7bda9fd3 214 get_addr(&daddr, *argv, AF_INET);
1ce2de97
ND
215 } else if (strcmp(*argv, "local") == 0) {
216 NEXT_ARG();
7bda9fd3 217 get_addr(&saddr, *argv, AF_INET);
1ce2de97
ND
218 } else if (matches(*argv, "dev") == 0) {
219 NEXT_ARG();
7a14358b 220 link = ll_name_to_index(*argv);
fe99adbc
SP
221 if (!link)
222 exit(nodev(*argv));
1ce2de97 223 } else if (strcmp(*argv, "ttl") == 0 ||
c4743c4d
SP
224 strcmp(*argv, "hoplimit") == 0 ||
225 strcmp(*argv, "hlim") == 0) {
1ce2de97
ND
226 NEXT_ARG();
227 if (strcmp(*argv, "inherit") != 0) {
228 if (get_u8(&ttl, *argv, 0))
229 invarg("invalid TTL\n", *argv);
230 } else
231 ttl = 0;
232 } else if (strcmp(*argv, "tos") == 0 ||
233 strcmp(*argv, "tclass") == 0 ||
5bd93795 234 strcmp(*argv, "tc") == 0 ||
1ce2de97
ND
235 matches(*argv, "dsfield") == 0) {
236 __u32 uval;
56f5daac 237
1ce2de97
ND
238 NEXT_ARG();
239 if (strcmp(*argv, "inherit") != 0) {
240 if (rtnl_dsfield_a2n(&uval, *argv))
241 invarg("bad TOS value", *argv);
242 tos = uval;
243 } else
244 tos = 1;
245 } else if (strcmp(*argv, "nopmtudisc") == 0) {
246 pmtudisc = 0;
247 } else if (strcmp(*argv, "pmtudisc") == 0) {
248 pmtudisc = 1;
249 } else if (strcmp(lu->id, "sit") == 0 &&
250 strcmp(*argv, "isatap") == 0) {
251 iflags |= SIT_ISATAP;
c1159152
TH
252 } else if (strcmp(*argv, "noencap") == 0) {
253 encaptype = TUNNEL_ENCAP_NONE;
254 } else if (strcmp(*argv, "encap") == 0) {
255 NEXT_ARG();
256 if (strcmp(*argv, "fou") == 0)
257 encaptype = TUNNEL_ENCAP_FOU;
258 else if (strcmp(*argv, "gue") == 0)
259 encaptype = TUNNEL_ENCAP_GUE;
260 else if (strcmp(*argv, "none") == 0)
261 encaptype = TUNNEL_ENCAP_NONE;
262 else
263 invarg("Invalid encap type.", *argv);
264 } else if (strcmp(*argv, "encap-sport") == 0) {
265 NEXT_ARG();
266 if (strcmp(*argv, "auto") == 0)
267 encapsport = 0;
268 else if (get_u16(&encapsport, *argv, 0))
269 invarg("Invalid source port.", *argv);
270 } else if (strcmp(*argv, "encap-dport") == 0) {
271 NEXT_ARG();
272 if (get_u16(&encapdport, *argv, 0))
273 invarg("Invalid destination port.", *argv);
274 } else if (strcmp(*argv, "encap-csum") == 0) {
275 encapflags |= TUNNEL_ENCAP_FLAG_CSUM;
276 } else if (strcmp(*argv, "noencap-csum") == 0) {
277 encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM;
278 } else if (strcmp(*argv, "encap-udp6-csum") == 0) {
279 encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
280 } else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
281 encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM6;
858dbb20
TH
282 } else if (strcmp(*argv, "encap-remcsum") == 0) {
283 encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM;
284 } else if (strcmp(*argv, "noencap-remcsum") == 0) {
285 encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM;
4bfe6825
AS
286 } else if (strcmp(*argv, "external") == 0) {
287 metadata = 1;
1ce2de97 288 } else if (strcmp(*argv, "6rd-prefix") == 0) {
1ce2de97 289 NEXT_ARG();
7bda9fd3 290 if (get_prefix(&ip6rdprefix, *argv, AF_INET6))
1ce2de97 291 invarg("invalid 6rd_prefix\n", *argv);
1ce2de97 292 } else if (strcmp(*argv, "6rd-relay_prefix") == 0) {
1ce2de97 293 NEXT_ARG();
7bda9fd3 294 if (get_prefix(&ip6rdrelayprefix, *argv, AF_INET))
1ce2de97 295 invarg("invalid 6rd-relay_prefix\n", *argv);
1ce2de97 296 } else if (strcmp(*argv, "6rd-reset") == 0) {
7bda9fd3
SP
297 get_prefix(&ip6rdprefix, "2002::/16", AF_INET6);
298 inet_prefix_reset(&ip6rdrelayprefix);
ad4b1425
CG
299 } else if (strcmp(*argv, "fwmark") == 0) {
300 NEXT_ARG();
301 if (get_u32(&fwmark, *argv, 0))
302 invarg("invalid fwmark\n", *argv);
06e3975f
SP
303 } else {
304 iptunnel_print_help(lu, argc, argv, stderr);
305 return -1;
306 }
1ce2de97
ND
307 argc--, argv++;
308 }
309
310 if (ttl && pmtudisc == 0) {
30d07e9e 311 fprintf(stderr, "ttl != 0 and nopmtudisc are incompatible\n");
1ce2de97
ND
312 exit(-1);
313 }
314
68a7f5ed 315 addattr8(n, 1024, IFLA_IPTUN_PROTO, proto);
4bfe6825
AS
316 if (metadata) {
317 addattr_l(n, 1024, IFLA_IPTUN_COLLECT_METADATA, NULL, 0);
318 return 0;
319 }
320
fa1e658e 321 if (is_addrtype_inet_not_unspec(&saddr)) {
7bda9fd3
SP
322 addattr_l(n, 1024, IFLA_IPTUN_LOCAL,
323 saddr.data, saddr.bytelen);
324 }
fa1e658e 325 if (is_addrtype_inet_not_unspec(&daddr)) {
7bda9fd3
SP
326 addattr_l(n, 1024, IFLA_IPTUN_REMOTE,
327 daddr.data, daddr.bytelen);
328 }
1ce2de97 329 addattr8(n, 1024, IFLA_IPTUN_PMTUDISC, pmtudisc);
5bd93795
SP
330 addattr8(n, 1024, IFLA_IPTUN_TOS, tos);
331 addattr8(n, 1024, IFLA_IPTUN_TTL, ttl);
332 addattr32(n, 1024, IFLA_IPTUN_LINK, link);
ad4b1425 333 addattr32(n, 1024, IFLA_IPTUN_FWMARK, fwmark);
c1159152
TH
334
335 addattr16(n, 1024, IFLA_IPTUN_ENCAP_TYPE, encaptype);
336 addattr16(n, 1024, IFLA_IPTUN_ENCAP_FLAGS, encapflags);
337 addattr16(n, 1024, IFLA_IPTUN_ENCAP_SPORT, htons(encapsport));
338 addattr16(n, 1024, IFLA_IPTUN_ENCAP_DPORT, htons(encapdport));
339
1ce2de97
ND
340 if (strcmp(lu->id, "sit") == 0) {
341 addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags);
7bda9fd3 342 if (is_addrtype_inet(&ip6rdprefix)) {
1ce2de97 343 addattr_l(n, 1024, IFLA_IPTUN_6RD_PREFIX,
7bda9fd3 344 ip6rdprefix.data, ip6rdprefix.bytelen);
1ce2de97 345 addattr16(n, 1024, IFLA_IPTUN_6RD_PREFIXLEN,
7bda9fd3
SP
346 ip6rdprefix.bitlen);
347 }
348 if (is_addrtype_inet(&ip6rdrelayprefix)) {
1ce2de97 349 addattr32(n, 1024, IFLA_IPTUN_6RD_RELAY_PREFIX,
7bda9fd3 350 ip6rdrelayprefix.data[0]);
1ce2de97 351 addattr16(n, 1024, IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
7bda9fd3 352 ip6rdrelayprefix.bitlen);
1ce2de97
ND
353 }
354 }
355
356 return 0;
357}
358
359static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
360{
1ce2de97 361 char s2[64];
bad76e6b 362 __u16 prefixlen;
375560c4 363 __u8 ttl = 0;
3caa526c 364 __u8 tos = 0;
1ce2de97
ND
365
366 if (!tb)
367 return;
368
00ff4b8e 369 if (tb[IFLA_IPTUN_COLLECT_METADATA]) {
d6abae5a 370 print_bool(PRINT_ANY, "external", "external ", true);
00ff4b8e
SP
371 return;
372 }
7b178324 373
d9aefbc0
SP
374 if (tb[IFLA_IPTUN_PROTO]) {
375 switch (rta_getattr_u8(tb[IFLA_IPTUN_PROTO])) {
376 case IPPROTO_IPIP:
377 print_string(PRINT_ANY, "proto", "%s ", "ipip");
378 break;
379 case IPPROTO_IPV6:
380 print_string(PRINT_ANY, "proto", "%s ", "ip6ip");
381 break;
382 case IPPROTO_MPLS:
383 print_string(PRINT_ANY, "proto", "%s ", "mplsip");
384 break;
385 case 0:
386 print_string(PRINT_ANY, "proto", "%s ", "any");
387 break;
388 }
389 }
390
b761fc41
SP
391 tnl_print_endpoint("remote", tb[IFLA_IPTUN_REMOTE], AF_INET);
392 tnl_print_endpoint("local", tb[IFLA_IPTUN_LOCAL], AF_INET);
1ce2de97 393
45d3a6ef 394 if (tb[IFLA_IPTUN_LINK]) {
5bd93795 395 __u32 link = rta_getattr_u32(tb[IFLA_IPTUN_LINK]);
1ce2de97 396
45d3a6ef
SP
397 if (link) {
398 print_string(PRINT_ANY, "link", "dev %s ",
399 ll_index_to_name(link));
400 }
1ce2de97
ND
401 }
402
375560c4
SP
403 if (tb[IFLA_IPTUN_TTL])
404 ttl = rta_getattr_u8(tb[IFLA_IPTUN_TTL]);
405 if (is_json_context() || ttl)
406 print_uint(PRINT_ANY, "ttl", "ttl %u ", ttl);
407 else
2539a407 408 print_string(PRINT_FP, NULL, "ttl %s ", "inherit");
1ce2de97 409
3caa526c
SP
410 if (tb[IFLA_IPTUN_TOS])
411 tos = rta_getattr_u8(tb[IFLA_IPTUN_TOS]);
412 if (tos) {
413 if (is_json_context() || tos != 1)
90c5c969 414 print_0xhex(PRINT_ANY, "tos", "tos %#llx ", tos);
3caa526c
SP
415 else
416 print_string(PRINT_FP, NULL, "tos %s ", "inherit");
1ce2de97
ND
417 }
418
419 if (tb[IFLA_IPTUN_PMTUDISC] && rta_getattr_u8(tb[IFLA_IPTUN_PMTUDISC]))
2539a407 420 print_bool(PRINT_ANY, "pmtudisc", "pmtudisc ", true);
1ce2de97 421 else
2539a407 422 print_bool(PRINT_ANY, "pmtudisc", "nopmtudisc ", false);
1ce2de97
ND
423
424 if (tb[IFLA_IPTUN_FLAGS]) {
195f0f62 425 __u16 iflags = rta_getattr_u16(tb[IFLA_IPTUN_FLAGS]);
1ce2de97 426
195f0f62 427 if (iflags & SIT_ISATAP)
2539a407 428 print_bool(PRINT_ANY, "isatap", "isatap ", true);
1ce2de97
ND
429 }
430
431 if (tb[IFLA_IPTUN_6RD_PREFIXLEN] &&
9f1370c0 432 (prefixlen = rta_getattr_u16(tb[IFLA_IPTUN_6RD_PREFIXLEN]))) {
1ce2de97
ND
433 __u16 relayprefixlen =
434 rta_getattr_u16(tb[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]);
435 __u32 relayprefix =
436 rta_getattr_u32(tb[IFLA_IPTUN_6RD_RELAY_PREFIX]);
437
2539a407
JF
438 const char *prefix = inet_ntop(AF_INET6,
439 RTA_DATA(tb[IFLA_IPTUN_6RD_PREFIX]),
e97ad3d2 440 s2, sizeof(s2));
2539a407
JF
441
442 if (is_json_context()) {
443 print_string(PRINT_JSON, "prefix", NULL, prefix);
444 print_int(PRINT_JSON, "prefixlen", NULL, prefixlen);
445 if (relayprefix) {
446 print_string(PRINT_JSON,
447 "relay_prefix",
448 NULL,
449 format_host(AF_INET,
450 4,
451 &relayprefix));
452 print_int(PRINT_JSON,
453 "relay_prefixlen",
454 NULL,
455 relayprefixlen);
456 }
457 } else {
458 printf("6rd-prefix %s/%u ", prefix, prefixlen);
459 if (relayprefix) {
460 printf("6rd-relay_prefix %s/%u ",
461 format_host(AF_INET, 4, &relayprefix),
462 relayprefixlen);
463 }
1ce2de97
ND
464 }
465 }
c1159152 466
e97ad3d2
SP
467 if (tb[IFLA_IPTUN_FWMARK]) {
468 __u32 fwmark = rta_getattr_u32(tb[IFLA_IPTUN_FWMARK]);
469
470 if (fwmark) {
471 print_0xhex(PRINT_ANY,
90c5c969 472 "fwmark", "fwmark %#llx ", fwmark);
e97ad3d2
SP
473 }
474 }
475
bad76e6b
SP
476 tnl_print_encap(tb,
477 IFLA_IPTUN_ENCAP_TYPE,
478 IFLA_IPTUN_ENCAP_FLAGS,
479 IFLA_IPTUN_ENCAP_SPORT,
480 IFLA_IPTUN_ENCAP_DPORT);
1ce2de97
ND
481}
482
483struct link_util ipip_link_util = {
484 .id = "ipip",
485 .maxattr = IFLA_IPTUN_MAX,
486 .parse_opt = iptunnel_parse_opt,
487 .print_opt = iptunnel_print_opt,
561e650e 488 .print_help = iptunnel_print_help,
1ce2de97
ND
489};
490
491struct link_util sit_link_util = {
492 .id = "sit",
493 .maxattr = IFLA_IPTUN_MAX,
494 .parse_opt = iptunnel_parse_opt,
495 .print_opt = iptunnel_print_opt,
561e650e 496 .print_help = iptunnel_print_help,
1ce2de97 497};