aboutsummaryrefslogtreecommitdiffstats
path: root/ip/link_vti6.c
diff options
context:
space:
mode:
Diffstat (limited to 'ip/link_vti6.c')
-rw-r--r--ip/link_vti6.c87
1 files changed, 55 insertions, 32 deletions
diff --git a/ip/link_vti6.c b/ip/link_vti6.c
index c146f791..8198d468 100644
--- a/ip/link_vti6.c
+++ b/ip/link_vti6.c
@@ -32,41 +32,42 @@ static void usage(void)
fprintf(stderr, " type { vti6 } [ remote ADDR ] [ local ADDR ]\n");
fprintf(stderr, " [ [i|o]key KEY ]\n");
fprintf(stderr, " [ dev PHYS_DEV ]\n");
+ fprintf(stderr, " [ fwmark MARK ]\n");
fprintf(stderr, "\n");
fprintf(stderr, "Where: NAME := STRING\n");
fprintf(stderr, " ADDR := { IPV6_ADDRESS }\n");
fprintf(stderr, " KEY := { DOTTED_QUAD | NUMBER }\n");
+ fprintf(stderr, " MARK := { 0x0..0xffffffff }\n");
exit(-1);
}
static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
+ struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1);
struct {
struct nlmsghdr n;
struct ifinfomsg i;
char buf[1024];
- } req;
- struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1);
+ } req = {
+ .n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)),
+ .n.nlmsg_flags = NLM_F_REQUEST,
+ .n.nlmsg_type = RTM_GETLINK,
+ .i.ifi_family = preferred_family,
+ .i.ifi_index = ifi->ifi_index,
+ };
struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
- struct in6_addr saddr;
- struct in6_addr daddr;
- unsigned ikey = 0;
- unsigned okey = 0;
- unsigned link = 0;
+ struct in6_addr saddr = IN6ADDR_ANY_INIT;
+ struct in6_addr daddr = IN6ADDR_ANY_INIT;
+ unsigned int ikey = 0;
+ unsigned int okey = 0;
+ unsigned int link = 0;
+ __u32 fwmark = 0;
int len;
if (!(n->nlmsg_flags & NLM_F_CREATE)) {
- memset(&req, 0, sizeof(req));
-
- req.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = RTM_GETLINK;
- req.i.ifi_family = preferred_family;
- req.i.ifi_index = ifi->ifi_index;
-
if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) {
get_failed:
fprintf(stderr,
@@ -106,11 +107,14 @@ get_failed:
if (vtiinfo[IFLA_VTI_LINK])
link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]);
+
+ if (vtiinfo[IFLA_VTI_FWMARK])
+ fwmark = rta_getattr_u32(vtiinfo[IFLA_VTI_FWMARK]);
}
while (argc > 0) {
if (!matches(*argv, "key")) {
- unsigned uval;
+ unsigned int uval;
NEXT_ARG();
if (strchr(*argv, '.'))
@@ -126,7 +130,7 @@ get_failed:
ikey = okey = uval;
} else if (!matches(*argv, "ikey")) {
- unsigned uval;
+ unsigned int uval;
NEXT_ARG();
if (strchr(*argv, '.'))
@@ -140,7 +144,7 @@ get_failed:
}
ikey = uval;
} else if (!matches(*argv, "okey")) {
- unsigned uval;
+ unsigned int uval;
NEXT_ARG();
if (strchr(*argv, '.'))
@@ -160,6 +164,7 @@ get_failed:
exit(-1);
} else {
inet_prefix addr;
+
get_prefix(&addr, *argv, AF_INET6);
memcpy(&daddr, addr.data, addr.bytelen);
}
@@ -170,6 +175,7 @@ get_failed:
exit(-1);
} else {
inet_prefix addr;
+
get_prefix(&addr, *argv, AF_INET6);
memcpy(&saddr, addr.data, addr.bytelen);
}
@@ -178,6 +184,10 @@ get_failed:
link = if_nametoindex(*argv);
if (link == 0)
exit(-1);
+ } else if (strcmp(*argv, "fwmark") == 0) {
+ NEXT_ARG();
+ if (get_u32(&fwmark, *argv, 0))
+ invarg("invalid fwmark\n", *argv);
} else
usage();
argc--; argv++;
@@ -185,8 +195,12 @@ get_failed:
addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
addattr32(n, 1024, IFLA_VTI_OKEY, okey);
- addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr));
- addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr));
+
+ if (memcmp(&saddr, &in6addr_any, sizeof(in6addr_any)))
+ addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr));
+ if (memcmp(&daddr, &in6addr_any, sizeof(in6addr_any)))
+ addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr));
+ addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
if (link)
addattr32(n, 1024, IFLA_VTI_LINK, link);
@@ -195,12 +209,12 @@ get_failed:
static void vti6_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
- char s1[1024];
- char s2[64];
const char *local = "any";
const char *remote = "any";
struct in6_addr saddr;
struct in6_addr daddr;
+ unsigned int link;
+ char s2[64];
if (!tb)
return;
@@ -208,37 +222,46 @@ static void vti6_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
if (tb[IFLA_VTI_REMOTE]) {
memcpy(&daddr, RTA_DATA(tb[IFLA_VTI_REMOTE]), sizeof(daddr));
- remote = format_host(AF_INET6, 16, &daddr, s1, sizeof(s1));
+ remote = format_host(AF_INET6, 16, &daddr);
}
- fprintf(f, "remote %s ", remote);
+ print_string(PRINT_ANY, "remote", "remote %s ", remote);
if (tb[IFLA_VTI_LOCAL]) {
memcpy(&saddr, RTA_DATA(tb[IFLA_VTI_LOCAL]), sizeof(saddr));
- local = format_host(AF_INET6, 16, &saddr, s1, sizeof(s1));
+ local = format_host(AF_INET6, 16, &saddr);
}
- fprintf(f, "local %s ", local);
+ print_string(PRINT_ANY, "local", "local %s ", local);
- if (tb[IFLA_VTI_LINK] && *(__u32 *)RTA_DATA(tb[IFLA_VTI_LINK])) {
- unsigned link = *(__u32 *)RTA_DATA(tb[IFLA_VTI_LINK]);
+ if (tb[IFLA_VTI_LINK] && (link = rta_getattr_u32(tb[IFLA_VTI_LINK]))) {
const char *n = if_indextoname(link, s2);
if (n)
- fprintf(f, "dev %s ", n);
+ print_string(PRINT_ANY, "link", "dev %s ", n);
else
- fprintf(f, "dev %u ", link);
+ print_uint(PRINT_ANY, "link_index", "dev %u ", link);
}
if (tb[IFLA_VTI_IKEY]) {
inet_ntop(AF_INET, RTA_DATA(tb[IFLA_VTI_IKEY]), s2, sizeof(s2));
- fprintf(f, "ikey %s ", s2);
+ print_string(PRINT_ANY, "ikey", "ikey %s ", s2);
}
if (tb[IFLA_VTI_OKEY]) {
inet_ntop(AF_INET, RTA_DATA(tb[IFLA_VTI_OKEY]), s2, sizeof(s2));
- fprintf(f, "okey %s ", 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) {
+ snprintf(s2, sizeof(s2), "0x%x", fwmark);
+
+ print_string(PRINT_ANY, "fwmark", "fwmark %s ", s2);
+ }
}
}