Manual page ip-link(8) states that both local and remote accept IPADDR not PREFIX. Use get_addr() instead of get_prefix() to parse local/remote endpoint address correctly.
Force corresponding address family instead of using preferred_family to catch weired cases as shown below. Before this patch it is possible to create tunnel with commands: ip li add dev ip6gre2 type ip6gre local fe80::1/64 remote fe80::2/64 ip -4 li add dev ip6gre2 type ip6gre local 10.0.0.1/24 remote 10.0.0.2/24 Signed-off-by: Serhey Popovych <serhe.popov...@gmail.com> --- ip/ip6tunnel.c | 8 ++------ ip/link_gre6.c | 8 ++------ ip/link_ip6tnl.c | 12 ++++-------- ip/link_vti6.c | 8 ++++---- 4 files changed, 12 insertions(+), 24 deletions(-) diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c index 4563e1e..b8db49c 100644 --- a/ip/ip6tunnel.c +++ b/ip/ip6tunnel.c @@ -170,17 +170,13 @@ static int parse_args(int argc, char **argv, int cmd, struct ip6_tnl_parm2 *p) inet_prefix raddr; NEXT_ARG(); - get_prefix(&raddr, *argv, preferred_family); - if (raddr.family == AF_UNSPEC) - invarg("\"remote\" address family is AF_UNSPEC", *argv); + get_addr(&raddr, *argv, AF_INET6); memcpy(&p->raddr, &raddr.data, sizeof(p->raddr)); } else if (strcmp(*argv, "local") == 0) { inet_prefix laddr; NEXT_ARG(); - get_prefix(&laddr, *argv, preferred_family); - if (laddr.family == AF_UNSPEC) - invarg("\"local\" address family is AF_UNSPEC", *argv); + get_addr(&laddr, *argv, AF_INET6); memcpy(&p->laddr, &laddr.data, sizeof(p->laddr)); } else if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); diff --git a/ip/link_gre6.c b/ip/link_gre6.c index 0a82eae..c22fded 100644 --- a/ip/link_gre6.c +++ b/ip/link_gre6.c @@ -257,17 +257,13 @@ get_failed: inet_prefix addr; NEXT_ARG(); - get_prefix(&addr, *argv, preferred_family); - if (addr.family == AF_UNSPEC) - invarg("\"remote\" address family is AF_UNSPEC", *argv); + get_addr(&addr, *argv, AF_INET6); memcpy(&raddr, &addr.data, sizeof(raddr)); } else if (!matches(*argv, "local")) { inet_prefix addr; NEXT_ARG(); - get_prefix(&addr, *argv, preferred_family); - if (addr.family == AF_UNSPEC) - invarg("\"local\" address family is AF_UNSPEC", *argv); + get_addr(&addr, *argv, AF_INET6); memcpy(&laddr, &addr.data, sizeof(laddr)); } else if (!matches(*argv, "dev")) { NEXT_ARG(); diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c index 43287ab..4ab337f 100644 --- a/ip/link_ip6tnl.c +++ b/ip/link_ip6tnl.c @@ -184,18 +184,14 @@ get_failed: inet_prefix addr; NEXT_ARG(); - get_prefix(&addr, *argv, preferred_family); - if (addr.family == AF_UNSPEC) - invarg("\"remote\" address family is AF_UNSPEC", *argv); - memcpy(&raddr, addr.data, addr.bytelen); + get_addr(&addr, *argv, AF_INET6); + memcpy(&raddr, addr.data, sizeof(raddr)); } else if (strcmp(*argv, "local") == 0) { inet_prefix addr; NEXT_ARG(); - get_prefix(&addr, *argv, preferred_family); - if (addr.family == AF_UNSPEC) - invarg("\"local\" address family is AF_UNSPEC", *argv); - memcpy(&laddr, addr.data, addr.bytelen); + get_addr(&addr, *argv, AF_INET6); + memcpy(&laddr, addr.data, sizeof(laddr)); } else if (matches(*argv, "dev") == 0) { NEXT_ARG(); link = if_nametoindex(*argv); diff --git a/ip/link_vti6.c b/ip/link_vti6.c index f665520..84824a5 100644 --- a/ip/link_vti6.c +++ b/ip/link_vti6.c @@ -164,14 +164,14 @@ get_failed: inet_prefix addr; NEXT_ARG(); - get_prefix(&addr, *argv, AF_INET6); - memcpy(&daddr, addr.data, addr.bytelen); + get_addr(&addr, *argv, AF_INET6); + memcpy(&daddr, addr.data, sizeof(daddr)); } else if (!matches(*argv, "local")) { inet_prefix addr; NEXT_ARG(); - get_prefix(&addr, *argv, AF_INET6); - memcpy(&saddr, addr.data, addr.bytelen); + get_addr(&addr, *argv, AF_INET6); + memcpy(&saddr, addr.data, sizeof(saddr)); } else if (!matches(*argv, "dev")) { NEXT_ARG(); link = if_nametoindex(*argv); -- 1.7.10.4