X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ip%2Flink_vti6.c;h=f13c08583103a5f0a67e0fec5c31a600ac13dfd8;hb=c2f9dc14c41f388764f7634d36c3d05e354f053a;hp=d1fbec543480909a576b59059b4bee96279954d5;hpb=28254695d1f33ed45f7e5dfe3bffe9f94bf6ab18;p=mirror_iproute2.git diff --git a/ip/link_vti6.c b/ip/link_vti6.c index d1fbec54..f13c0858 100644 --- a/ip/link_vti6.c +++ b/ip/link_vti6.c @@ -24,28 +24,28 @@ #include "ip_common.h" #include "tunnel.h" -static void print_usage(FILE *f) +static void vti6_print_help(struct link_util *lu, int argc, char **argv, + FILE *f) { fprintf(f, - "Usage: ... vti6 [ remote ADDR ]\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 := { IPV6_ADDRESS }\n" + ); + fprintf(f, + "Where: ADDR := { IP%s_ADDRESS }\n" " KEY := { DOTTED_QUAD | NUMBER }\n" - " MARK := { 0x0..0xffffffff }\n" + " MARK := { 0x0..0xffffffff }\n", + "V6" ); } -static void usage(void) __attribute__((noreturn)); -static void usage(void) -{ - print_usage(stderr); - exit(-1); -} - static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, struct nlmsghdr *n) { @@ -64,15 +64,19 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; - struct in6_addr saddr = IN6ADDR_ANY_INIT; - struct in6_addr daddr = IN6ADDR_ANY_INIT; __be32 ikey = 0; __be32 okey = 0; + inet_prefix saddr, daddr; unsigned int link = 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, @@ -98,18 +102,20 @@ get_failed: parse_rtattr_nested(vtiinfo, IFLA_VTI_MAX, linkinfo[IFLA_INFO_DATA]); + rta = vtiinfo[IFLA_VTI_LOCAL]; + if (rta && get_addr_rta(&saddr, rta, AF_INET6)) + goto get_failed; + + rta = vtiinfo[IFLA_VTI_REMOTE]; + if (rta && get_addr_rta(&daddr, rta, AF_INET6)) + 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]) - memcpy(&saddr, RTA_DATA(vtiinfo[IFLA_VTI_LOCAL]), sizeof(saddr)); - - if (vtiinfo[IFLA_VTI_REMOTE]) - memcpy(&daddr, RTA_DATA(vtiinfo[IFLA_VTI_REMOTE]), sizeof(daddr)); - if (vtiinfo[IFLA_VTI_LINK]) link = rta_getattr_u8(vtiinfo[IFLA_VTI_LINK]); @@ -130,38 +136,33 @@ get_failed: NEXT_ARG(); okey = tnl_parse_key("okey", *argv); } else if (!matches(*argv, "remote")) { - inet_prefix addr; - NEXT_ARG(); - get_addr(&addr, *argv, AF_INET6); - memcpy(&daddr, addr.data, sizeof(daddr)); + get_addr(&daddr, *argv, AF_INET6); } else if (!matches(*argv, "local")) { - inet_prefix addr; - NEXT_ARG(); - get_addr(&addr, *argv, AF_INET6); - memcpy(&saddr, addr.data, sizeof(saddr)); + get_addr(&saddr, *argv, AF_INET6); } else if (!matches(*argv, "dev")) { NEXT_ARG(); link = ll_name_to_index(*argv); - if (link == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", - *argv); - exit(-1); - } + 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 { + vti6_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, sizeof(saddr)); - addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr)); + 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); @@ -180,7 +181,7 @@ static void vti6_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) tnl_print_endpoint("local", tb[IFLA_VTI_LOCAL], AF_INET6); if (tb[IFLA_VTI_LINK]) { - unsigned int link = rta_getattr_u32(tb[IFLA_VTI_LINK]); + __u32 link = rta_getattr_u32(tb[IFLA_VTI_LINK]); if (link) { print_string(PRINT_ANY, "link", "dev %s ", @@ -209,17 +210,11 @@ static void vti6_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) if (fwmark) { print_0xhex(PRINT_ANY, - "fwmark", "fwmark 0x%x ", fwmark); + "fwmark", "fwmark %#llx ", fwmark); } } } -static void vti6_print_help(struct link_util *lu, int argc, char **argv, - FILE *f) -{ - print_usage(f); -} - struct link_util vti6_link_util = { .id = "vti6", .maxattr = IFLA_VTI_MAX,