#include "ip_common.h"
#include "tunnel.h"
-
-static void print_usage(FILE *f)
+static void vti_print_help(struct link_util *lu, int argc, char **argv, FILE *f)
{
fprintf(f,
- "Usage: ... vti [ remote ADDR ]\n"
- " [ local ADDR ]\n"
- " [ [i|o]key KEY ]\n"
- " [ dev PHYS_DEV ]\n"
- " [ fwmark MARK ]\n"
+ "Usage: ... %-4s [ remote ADDR ]\n",
+ lu->id
+ );
+ fprintf(f,
+ " [ local ADDR ]\n"
+ " [ [i|o]key KEY ]\n"
+ " [ dev PHYS_DEV ]\n"
+ " [ fwmark MARK ]\n"
"\n"
- "Where: ADDR := { IP_ADDRESS }\n"
+ );
+ fprintf(f,
+ "Where: ADDR := { IP%s_ADDRESS }\n"
" KEY := { DOTTED_QUAD | NUMBER }\n"
- " MARK := { 0x0..0xffffffff }\n"
+ " MARK := { 0x0..0xffffffff }\n",
+ ""
);
}
-static void usage(void) __attribute__((noreturn));
-static void usage(void)
-{
- print_usage(stderr);
- exit(-1);
-}
-
static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
- struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1);
+ struct ifinfomsg *ifi = NLMSG_DATA(n);
struct {
struct nlmsghdr n;
struct ifinfomsg i;
.i.ifi_family = preferred_family,
.i.ifi_index = ifi->ifi_index,
};
- struct nlmsghdr *answer = NULL;
+ struct nlmsghdr *answer;
struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
- unsigned int ikey = 0;
- unsigned int okey = 0;
- unsigned int saddr = 0;
- unsigned int daddr = 0;
+ __be32 ikey = 0;
+ __be32 okey = 0;
+ inet_prefix saddr, daddr;
unsigned int link = 0;
- unsigned int fwmark = 0;
+ __u32 fwmark = 0;
int len;
+ inet_prefix_reset(&saddr);
+ inet_prefix_reset(&daddr);
+
if (!(n->nlmsg_flags & NLM_F_CREATE)) {
+ const struct rtattr *rta;
+
if (rtnl_talk(&rth, &req.n, &answer) < 0) {
get_failed:
fprintf(stderr,
"Failed to get existing tunnel info.\n");
- free(answer);
return -1;
}
parse_rtattr_nested(vtiinfo, IFLA_VTI_MAX,
linkinfo[IFLA_INFO_DATA]);
+ rta = vtiinfo[IFLA_VTI_LOCAL];
+ if (rta && get_addr_rta(&saddr, rta, AF_INET))
+ goto get_failed;
+
+ rta = vtiinfo[IFLA_VTI_REMOTE];
+ if (rta && get_addr_rta(&daddr, rta, AF_INET))
+ goto get_failed;
+
if (vtiinfo[IFLA_VTI_IKEY])
ikey = rta_getattr_u32(vtiinfo[IFLA_VTI_IKEY]);
if (vtiinfo[IFLA_VTI_OKEY])
okey = rta_getattr_u32(vtiinfo[IFLA_VTI_OKEY]);
- if (vtiinfo[IFLA_VTI_LOCAL])
- saddr = rta_getattr_u32(vtiinfo[IFLA_VTI_LOCAL]);
-
- if (vtiinfo[IFLA_VTI_REMOTE])
- daddr = rta_getattr_u32(vtiinfo[IFLA_VTI_REMOTE]);
-
if (vtiinfo[IFLA_VTI_LINK])
link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]);
while (argc > 0) {
if (!matches(*argv, "key")) {
- unsigned int uval;
-
NEXT_ARG();
- if (strchr(*argv, '.'))
- uval = get_addr32(*argv);
- else {
- if (get_unsigned(&uval, *argv, 0) < 0) {
- fprintf(stderr,
- "Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv);
- exit(-1);
- }
- uval = htonl(uval);
- }
-
- ikey = okey = uval;
+ ikey = okey = tnl_parse_key("key", *argv);
} else if (!matches(*argv, "ikey")) {
- unsigned int uval;
-
NEXT_ARG();
- if (strchr(*argv, '.'))
- uval = get_addr32(*argv);
- else {
- if (get_unsigned(&uval, *argv, 0) < 0) {
- fprintf(stderr, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv);
- exit(-1);
- }
- uval = htonl(uval);
- }
- ikey = uval;
+ ikey = tnl_parse_key("ikey", *argv);
} else if (!matches(*argv, "okey")) {
- unsigned int uval;
-
NEXT_ARG();
- if (strchr(*argv, '.'))
- uval = get_addr32(*argv);
- else {
- if (get_unsigned(&uval, *argv, 0) < 0) {
- fprintf(stderr, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv);
- exit(-1);
- }
- uval = htonl(uval);
- }
- okey = uval;
+ okey = tnl_parse_key("okey", *argv);
} else if (!matches(*argv, "remote")) {
NEXT_ARG();
- daddr = get_addr32(*argv);
+ get_addr(&daddr, *argv, AF_INET);
} else if (!matches(*argv, "local")) {
NEXT_ARG();
- saddr = get_addr32(*argv);
+ get_addr(&saddr, *argv, AF_INET);
} else if (!matches(*argv, "dev")) {
NEXT_ARG();
- link = if_nametoindex(*argv);
- if (link == 0) {
- fprintf(stderr, "Cannot find device \"%s\"\n",
- *argv);
- exit(-1);
- }
+ link = ll_name_to_index(*argv);
+ if (!link)
+ exit(nodev(*argv));
} else if (strcmp(*argv, "fwmark") == 0) {
NEXT_ARG();
if (get_u32(&fwmark, *argv, 0))
invarg("invalid fwmark\n", *argv);
- } else
- usage();
+ } else {
+ vti_print_help(lu, argc, argv, stderr);
+ return -1;
+ }
argc--; argv++;
}
addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
addattr32(n, 1024, IFLA_VTI_OKEY, okey);
- addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, 4);
- addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, 4);
+ if (is_addrtype_inet_not_unspec(&saddr))
+ addattr_l(n, 1024, IFLA_VTI_LOCAL, saddr.data, saddr.bytelen);
+ if (is_addrtype_inet_not_unspec(&daddr))
+ addattr_l(n, 1024, IFLA_VTI_REMOTE, daddr.data, daddr.bytelen);
addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
if (link)
addattr32(n, 1024, IFLA_VTI_LINK, link);
static void vti_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
- const char *local = "any";
- const char *remote = "any";
- __u32 key;
- unsigned int link;
- char s2[IFNAMSIZ];
+ char s2[64];
if (!tb)
return;
- if (tb[IFLA_VTI_REMOTE]) {
- unsigned int addr = rta_getattr_u32(tb[IFLA_VTI_REMOTE]);
-
- if (addr)
- remote = format_host(AF_INET, 4, &addr);
- }
-
- print_string(PRINT_ANY, "remote", "remote %s ", remote);
+ tnl_print_endpoint("remote", tb[IFLA_VTI_REMOTE], AF_INET);
+ tnl_print_endpoint("local", tb[IFLA_VTI_LOCAL], AF_INET);
- if (tb[IFLA_VTI_LOCAL]) {
- unsigned int addr = rta_getattr_u32(tb[IFLA_VTI_LOCAL]);
+ if (tb[IFLA_VTI_LINK]) {
+ __u32 link = rta_getattr_u32(tb[IFLA_VTI_LINK]);
- if (addr)
- local = format_host(AF_INET, 4, &addr);
+ if (link) {
+ print_string(PRINT_ANY, "link", "dev %s ",
+ ll_index_to_name(link));
+ }
}
- print_string(PRINT_ANY, "local", "local %s ", local);
-
- if (tb[IFLA_VTI_LINK] &&
- (link = rta_getattr_u32(tb[IFLA_VTI_LINK]))) {
- const char *n = if_indextoname(link, s2);
+ if (tb[IFLA_VTI_IKEY]) {
+ struct rtattr *rta = tb[IFLA_VTI_IKEY];
+ __u32 key = rta_getattr_u32(rta);
- if (n)
- print_string(PRINT_ANY, "link", "dev %s ", n);
- else
- print_uint(PRINT_ANY, "link_index", "dev %u ", link);
+ if (key && inet_ntop(AF_INET, RTA_DATA(rta), s2, sizeof(s2)))
+ print_string(PRINT_ANY, "ikey", "ikey %s ", s2);
}
- if (tb[IFLA_VTI_IKEY] &&
- (key = rta_getattr_u32(tb[IFLA_VTI_IKEY])))
- print_0xhex(PRINT_ANY, "ikey", "ikey %#x ", ntohl(key));
+ if (tb[IFLA_VTI_OKEY]) {
+ struct rtattr *rta = tb[IFLA_VTI_OKEY];
+ __u32 key = rta_getattr_u32(rta);
-
- if (tb[IFLA_VTI_OKEY] &&
- (key = rta_getattr_u32(tb[IFLA_VTI_OKEY])))
- print_0xhex(PRINT_ANY, "okey", "okey %#x ", ntohl(key));
+ if (key && inet_ntop(AF_INET, RTA_DATA(rta), s2, sizeof(s2)))
+ print_string(PRINT_ANY, "okey", "okey %s ", s2);
+ }
if (tb[IFLA_VTI_FWMARK]) {
__u32 fwmark = rta_getattr_u32(tb[IFLA_VTI_FWMARK]);
if (fwmark) {
- SPRINT_BUF(b1);
-
- snprintf(b1, sizeof(b1), "0x%x", fwmark);
- print_string(PRINT_ANY, "fwmark", "fwmark %s ", s2);
+ print_0xhex(PRINT_ANY,
+ "fwmark", "fwmark 0x%x ", fwmark);
}
}
}
-static void vti_print_help(struct link_util *lu, int argc, char **argv,
- FILE *f)
-{
- print_usage(f);
-}
-
struct link_util vti_link_util = {
.id = "vti",
.maxattr = IFLA_VTI_MAX,