]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/link_vti.c
2 * link_vti.c VTI driver 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: Herbert Xu <herbert@gondor.apana.org.au>
10 * Saurabh Mohan <saurabh.mohan@vyatta.com> Modified link_gre.c for VTI
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <arpa/inet.h>
20 #include <linux/if_tunnel.h>
23 #include "ip_common.h"
27 static void print_usage(FILE *f
)
30 "Usage: ... vti [ remote ADDR ]\n"
36 "Where: ADDR := { IP_ADDRESS }\n"
37 " KEY := { DOTTED_QUAD | NUMBER }\n"
38 " MARK := { 0x0..0xffffffff }\n"
42 static void usage(void) __attribute__((noreturn
));
43 static void usage(void)
49 static int vti_parse_opt(struct link_util
*lu
, int argc
, char **argv
,
52 struct ifinfomsg
*ifi
= (struct ifinfomsg
*)(n
+ 1);
58 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(*ifi
)),
59 .n
.nlmsg_flags
= NLM_F_REQUEST
,
60 .n
.nlmsg_type
= RTM_GETLINK
,
61 .i
.ifi_family
= preferred_family
,
62 .i
.ifi_index
= ifi
->ifi_index
,
64 struct rtattr
*tb
[IFLA_MAX
+ 1];
65 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
66 struct rtattr
*vtiinfo
[IFLA_VTI_MAX
+ 1];
67 unsigned int ikey
= 0;
68 unsigned int okey
= 0;
69 unsigned int saddr
= 0;
70 unsigned int daddr
= 0;
71 unsigned int link
= 0;
72 unsigned int fwmark
= 0;
75 if (!(n
->nlmsg_flags
& NLM_F_CREATE
)) {
76 if (rtnl_talk(&rth
, &req
.n
, &req
.n
, sizeof(req
)) < 0) {
79 "Failed to get existing tunnel info.\n");
83 len
= req
.n
.nlmsg_len
;
84 len
-= NLMSG_LENGTH(sizeof(*ifi
));
88 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(&req
.i
), len
);
90 if (!tb
[IFLA_LINKINFO
])
93 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
[IFLA_LINKINFO
]);
95 if (!linkinfo
[IFLA_INFO_DATA
])
98 parse_rtattr_nested(vtiinfo
, IFLA_VTI_MAX
,
99 linkinfo
[IFLA_INFO_DATA
]);
101 if (vtiinfo
[IFLA_VTI_IKEY
])
102 ikey
= rta_getattr_u32(vtiinfo
[IFLA_VTI_IKEY
]);
104 if (vtiinfo
[IFLA_VTI_OKEY
])
105 okey
= rta_getattr_u32(vtiinfo
[IFLA_VTI_OKEY
]);
107 if (vtiinfo
[IFLA_VTI_LOCAL
])
108 saddr
= rta_getattr_u32(vtiinfo
[IFLA_VTI_LOCAL
]);
110 if (vtiinfo
[IFLA_VTI_REMOTE
])
111 daddr
= rta_getattr_u32(vtiinfo
[IFLA_VTI_REMOTE
]);
113 if (vtiinfo
[IFLA_VTI_LINK
])
114 link
= rta_getattr_u8(vtiinfo
[IFLA_VTI_LINK
]);
116 if (vtiinfo
[IFLA_VTI_FWMARK
])
117 fwmark
= rta_getattr_u32(vtiinfo
[IFLA_VTI_FWMARK
]);
121 if (!matches(*argv
, "key")) {
125 if (strchr(*argv
, '.'))
126 uval
= get_addr32(*argv
);
128 if (get_unsigned(&uval
, *argv
, 0) < 0) {
130 "Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv
);
137 } else if (!matches(*argv
, "ikey")) {
141 if (strchr(*argv
, '.'))
142 uval
= get_addr32(*argv
);
144 if (get_unsigned(&uval
, *argv
, 0) < 0) {
145 fprintf(stderr
, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv
);
151 } else if (!matches(*argv
, "okey")) {
155 if (strchr(*argv
, '.'))
156 uval
= get_addr32(*argv
);
158 if (get_unsigned(&uval
, *argv
, 0) < 0) {
159 fprintf(stderr
, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv
);
165 } else if (!matches(*argv
, "remote")) {
167 if (!strcmp(*argv
, "any")) {
168 fprintf(stderr
, "invalid value for \"remote\": \"%s\"\n", *argv
);
171 daddr
= get_addr32(*argv
);
173 } else if (!matches(*argv
, "local")) {
175 if (!strcmp(*argv
, "any")) {
176 fprintf(stderr
, "invalid value for \"local\": \"%s\"\n", *argv
);
179 saddr
= get_addr32(*argv
);
181 } else if (!matches(*argv
, "dev")) {
183 link
= if_nametoindex(*argv
);
185 fprintf(stderr
, "Cannot find device \"%s\"\n",
189 } else if (strcmp(*argv
, "fwmark") == 0) {
191 if (get_u32(&fwmark
, *argv
, 0))
192 invarg("invalid fwmark\n", *argv
);
198 addattr32(n
, 1024, IFLA_VTI_IKEY
, ikey
);
199 addattr32(n
, 1024, IFLA_VTI_OKEY
, okey
);
200 addattr_l(n
, 1024, IFLA_VTI_LOCAL
, &saddr
, 4);
201 addattr_l(n
, 1024, IFLA_VTI_REMOTE
, &daddr
, 4);
202 addattr32(n
, 1024, IFLA_VTI_FWMARK
, fwmark
);
204 addattr32(n
, 1024, IFLA_VTI_LINK
, link
);
209 static void vti_print_opt(struct link_util
*lu
, FILE *f
, struct rtattr
*tb
[])
211 const char *local
= "any";
212 const char *remote
= "any";
220 if (tb
[IFLA_VTI_REMOTE
]) {
221 unsigned int addr
= rta_getattr_u32(tb
[IFLA_VTI_REMOTE
]);
224 remote
= format_host(AF_INET
, 4, &addr
);
227 print_string(PRINT_ANY
, "remote", "remote %s ", remote
);
229 if (tb
[IFLA_VTI_LOCAL
]) {
230 unsigned int addr
= rta_getattr_u32(tb
[IFLA_VTI_LOCAL
]);
233 local
= format_host(AF_INET
, 4, &addr
);
236 print_string(PRINT_ANY
, "local", "local %s ", local
);
238 if (tb
[IFLA_VTI_LINK
] &&
239 (link
= rta_getattr_u32(tb
[IFLA_VTI_LINK
]))) {
240 const char *n
= if_indextoname(link
, s2
);
243 print_string(PRINT_ANY
, "link", "dev %s ", n
);
245 print_uint(PRINT_ANY
, "link_index", "dev %u ", link
);
248 if (tb
[IFLA_VTI_IKEY
] &&
249 (key
= rta_getattr_u32(tb
[IFLA_VTI_IKEY
])))
250 print_0xhex(PRINT_ANY
, "ikey", "ikey %#x ", ntohl(key
));
253 if (tb
[IFLA_VTI_OKEY
] &&
254 (key
= rta_getattr_u32(tb
[IFLA_VTI_OKEY
])))
255 print_0xhex(PRINT_ANY
, "okey", "okey %#x ", ntohl(key
));
257 if (tb
[IFLA_VTI_FWMARK
]) {
258 __u32 fwmark
= rta_getattr_u32(tb
[IFLA_VTI_FWMARK
]);
263 snprintf(b1
, sizeof(b1
), "0x%x", fwmark
);
264 print_string(PRINT_ANY
, "fwmark", "fwmark %s ", s2
);
269 static void vti_print_help(struct link_util
*lu
, int argc
, char **argv
,
275 struct link_util vti_link_util
= {
277 .maxattr
= IFLA_VTI_MAX
,
278 .parse_opt
= vti_parse_opt
,
279 .print_opt
= vti_print_opt
,
280 .print_help
= vti_print_help
,