]>
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
)
29 fprintf(f
, "Usage: ip link { add | set | change | replace | del } NAME\n");
30 fprintf(f
, " type { vti } [ remote ADDR ] [ local ADDR ]\n");
31 fprintf(f
, " [ [i|o]key KEY ]\n");
32 fprintf(f
, " [ dev PHYS_DEV ]\n");
34 fprintf(f
, "Where: NAME := STRING\n");
35 fprintf(f
, " ADDR := { IP_ADDRESS }\n");
36 fprintf(f
, " KEY := { DOTTED_QUAD | NUMBER }\n");
39 static void usage(void) __attribute__((noreturn
));
40 static void usage(void)
46 static int vti_parse_opt(struct link_util
*lu
, int argc
, char **argv
,
54 struct ifinfomsg
*ifi
= (struct ifinfomsg
*)(n
+ 1);
55 struct rtattr
*tb
[IFLA_MAX
+ 1];
56 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
57 struct rtattr
*vtiinfo
[IFLA_VTI_MAX
+ 1];
65 if (!(n
->nlmsg_flags
& NLM_F_CREATE
)) {
66 memset(&req
, 0, sizeof(req
));
68 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(*ifi
));
69 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
70 req
.n
.nlmsg_type
= RTM_GETLINK
;
71 req
.i
.ifi_family
= preferred_family
;
72 req
.i
.ifi_index
= ifi
->ifi_index
;
74 if (rtnl_talk(&rth
, &req
.n
, &req
.n
, sizeof(req
)) < 0) {
77 "Failed to get existing tunnel info.\n");
81 len
= req
.n
.nlmsg_len
;
82 len
-= NLMSG_LENGTH(sizeof(*ifi
));
86 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(&req
.i
), len
);
88 if (!tb
[IFLA_LINKINFO
])
91 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
[IFLA_LINKINFO
]);
93 if (!linkinfo
[IFLA_INFO_DATA
])
96 parse_rtattr_nested(vtiinfo
, IFLA_VTI_MAX
,
97 linkinfo
[IFLA_INFO_DATA
]);
99 if (vtiinfo
[IFLA_VTI_IKEY
])
100 ikey
= *(__u32
*)RTA_DATA(vtiinfo
[IFLA_VTI_IKEY
]);
102 if (vtiinfo
[IFLA_VTI_OKEY
])
103 okey
= *(__u32
*)RTA_DATA(vtiinfo
[IFLA_VTI_OKEY
]);
105 if (vtiinfo
[IFLA_VTI_LOCAL
])
106 saddr
= *(__u32
*)RTA_DATA(vtiinfo
[IFLA_VTI_LOCAL
]);
108 if (vtiinfo
[IFLA_VTI_REMOTE
])
109 daddr
= *(__u32
*)RTA_DATA(vtiinfo
[IFLA_VTI_REMOTE
]);
111 if (vtiinfo
[IFLA_VTI_LINK
])
112 link
= *(__u8
*)RTA_DATA(vtiinfo
[IFLA_VTI_LINK
]);
116 if (!matches(*argv
, "key")) {
120 if (strchr(*argv
, '.'))
121 uval
= get_addr32(*argv
);
123 if (get_unsigned(&uval
, *argv
, 0) < 0) {
125 "Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv
);
132 } else if (!matches(*argv
, "ikey")) {
136 if (strchr(*argv
, '.'))
137 uval
= get_addr32(*argv
);
139 if (get_unsigned(&uval
, *argv
, 0) < 0) {
140 fprintf(stderr
, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv
);
146 } else if (!matches(*argv
, "okey")) {
150 if (strchr(*argv
, '.'))
151 uval
= get_addr32(*argv
);
153 if (get_unsigned(&uval
, *argv
, 0) < 0) {
154 fprintf(stderr
, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv
);
160 } else if (!matches(*argv
, "remote")) {
162 if (!strcmp(*argv
, "any")) {
163 fprintf(stderr
, "invalid value for \"remote\": \"%s\"\n", *argv
);
166 daddr
= get_addr32(*argv
);
168 } else if (!matches(*argv
, "local")) {
170 if (!strcmp(*argv
, "any")) {
171 fprintf(stderr
, "invalid value for \"local\": \"%s\"\n", *argv
);
174 saddr
= get_addr32(*argv
);
176 } else if (!matches(*argv
, "dev")) {
178 link
= if_nametoindex(*argv
);
180 fprintf(stderr
, "Cannot find device \"%s\"\n",
189 addattr32(n
, 1024, IFLA_VTI_IKEY
, ikey
);
190 addattr32(n
, 1024, IFLA_VTI_OKEY
, okey
);
191 addattr_l(n
, 1024, IFLA_VTI_LOCAL
, &saddr
, 4);
192 addattr_l(n
, 1024, IFLA_VTI_REMOTE
, &daddr
, 4);
194 addattr32(n
, 1024, IFLA_VTI_LINK
, link
);
199 static void vti_print_opt(struct link_util
*lu
, FILE *f
, struct rtattr
*tb
[])
203 const char *local
= "any";
204 const char *remote
= "any";
209 if (tb
[IFLA_VTI_REMOTE
]) {
210 unsigned addr
= *(__u32
*)RTA_DATA(tb
[IFLA_VTI_REMOTE
]);
213 remote
= format_host(AF_INET
, 4, &addr
, s1
, sizeof(s1
));
216 fprintf(f
, "remote %s ", remote
);
218 if (tb
[IFLA_VTI_LOCAL
]) {
219 unsigned addr
= *(__u32
*)RTA_DATA(tb
[IFLA_VTI_LOCAL
]);
222 local
= format_host(AF_INET
, 4, &addr
, s1
, sizeof(s1
));
225 fprintf(f
, "local %s ", local
);
227 if (tb
[IFLA_VTI_LINK
] && *(__u32
*)RTA_DATA(tb
[IFLA_VTI_LINK
])) {
228 unsigned link
= *(__u32
*)RTA_DATA(tb
[IFLA_VTI_LINK
]);
229 const char *n
= if_indextoname(link
, s2
);
232 fprintf(f
, "dev %s ", n
);
234 fprintf(f
, "dev %u ", link
);
237 if (tb
[IFLA_VTI_IKEY
]) {
238 inet_ntop(AF_INET
, RTA_DATA(tb
[IFLA_VTI_IKEY
]), s2
, sizeof(s2
));
239 fprintf(f
, "ikey %s ", s2
);
242 if (tb
[IFLA_VTI_OKEY
]) {
243 inet_ntop(AF_INET
, RTA_DATA(tb
[IFLA_VTI_OKEY
]), s2
, sizeof(s2
));
244 fprintf(f
, "okey %s ", s2
);
248 static void vti_print_help(struct link_util
*lu
, int argc
, char **argv
,
254 struct link_util vti_link_util
= {
256 .maxattr
= IFLA_VTI_MAX
,
257 .parse_opt
= vti_parse_opt
,
258 .print_opt
= vti_print_opt
,
259 .print_help
= vti_print_help
,