Merge branch 'unify-tunnel-endpoint-parsing' into next

Serhey Popovych  says:

====================

Use get_addr_rta() helper to unify address retriveal from netlink
message when configuring tunnel and get_addr() to parse endpoint
address into @inet_prefix.

This is next step towards ip and ipv6 tunnel module merge: endpoint
address parsing code will differ only in @family constant being
passed to get_addr_rta() and get_addr().

====================

Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
David Ahern 2018-02-14 09:02:12 -08:00
commit 3ce21b2d84
9 changed files with 176 additions and 144 deletions

View File

@ -65,6 +65,11 @@ enum {
ADDRTYPE_INET_MULTI = ADDRTYPE_INET | ADDRTYPE_MULTI
};
static inline void inet_prefix_reset(inet_prefix *p)
{
p->flags = 0;
}
static inline bool is_addrtype_inet(const inet_prefix *p)
{
return p->flags & ADDRTYPE_INET;

View File

@ -71,7 +71,7 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
bool set_op = (n->nlmsg_type == RTM_NEWLINK &&
!(n->nlmsg_flags & NLM_F_CREATE));
daddr.flags = 0;
inet_prefix_reset(&daddr);
while (argc > 0) {
if (!matches(*argv, "id") ||

View File

@ -74,8 +74,7 @@ static void check_duparg(__u64 *attrs, int type, const char *key,
static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
inet_prefix saddr;
inet_prefix daddr;
inet_prefix saddr, daddr;
__u32 vni = 0;
__u8 learning = 1;
__u16 dstport = 0;
@ -85,7 +84,9 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
!(n->nlmsg_flags & NLM_F_CREATE));
saddr.family = daddr.family = AF_UNSPEC;
saddr.flags = daddr.flags = 0;
inet_prefix_reset(&saddr);
inet_prefix_reset(&daddr);
while (argc > 0) {
if (!matches(*argv, "id") ||

View File

@ -86,8 +86,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
__u16 oflags = 0;
__be32 ikey = 0;
__be32 okey = 0;
unsigned int saddr = 0;
unsigned int daddr = 0;
inet_prefix saddr, daddr;
__u8 pmtudisc = 1;
__u8 ignore_df = 0;
__u8 tos = 0;
@ -104,7 +103,12 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
__u8 erspan_dir = 0;
__u16 erspan_hwid = 0;
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,
@ -130,6 +134,14 @@ get_failed:
parse_rtattr_nested(greinfo, IFLA_GRE_MAX,
linkinfo[IFLA_INFO_DATA]);
rta = greinfo[IFLA_GRE_LOCAL];
if (rta && get_addr_rta(&saddr, rta, AF_INET))
goto get_failed;
rta = greinfo[IFLA_GRE_REMOTE];
if (rta && get_addr_rta(&daddr, rta, AF_INET))
goto get_failed;
if (greinfo[IFLA_GRE_IKEY])
ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]);
@ -142,12 +154,6 @@ get_failed:
if (greinfo[IFLA_GRE_OFLAGS])
oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]);
if (greinfo[IFLA_GRE_LOCAL])
saddr = rta_getattr_u32(greinfo[IFLA_GRE_LOCAL]);
if (greinfo[IFLA_GRE_REMOTE])
daddr = rta_getattr_u32(greinfo[IFLA_GRE_REMOTE]);
if (greinfo[IFLA_GRE_PMTUDISC])
pmtudisc = rta_getattr_u8(
greinfo[IFLA_GRE_PMTUDISC]);
@ -232,10 +238,10 @@ get_failed:
pmtudisc = 1;
} 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 = ll_name_to_index(*argv);
@ -343,17 +349,20 @@ get_failed:
argc--; argv++;
}
if (!ikey && IN_MULTICAST(ntohl(daddr))) {
ikey = daddr;
iflags |= GRE_KEY;
}
if (!okey && IN_MULTICAST(ntohl(daddr))) {
okey = daddr;
oflags |= GRE_KEY;
}
if (IN_MULTICAST(ntohl(daddr)) && !saddr) {
fprintf(stderr, "A broadcast tunnel requires a source address.\n");
return -1;
if (is_addrtype_inet_multi(&daddr)) {
if (!ikey) {
ikey = daddr.data[0];
iflags |= GRE_KEY;
}
if (!okey) {
okey = daddr.data[0];
oflags |= GRE_KEY;
}
if (!is_addrtype_inet_not_unspec(&saddr)) {
fprintf(stderr,
"A broadcast tunnel requires a source address.\n");
return -1;
}
}
if (metadata) {
@ -365,8 +374,10 @@ get_failed:
addattr32(n, 1024, IFLA_GRE_OKEY, okey);
addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
addattr_l(n, 1024, IFLA_GRE_LOCAL, &saddr, 4);
addattr_l(n, 1024, IFLA_GRE_REMOTE, &daddr, 4);
if (is_addrtype_inet(&saddr))
addattr_l(n, 1024, IFLA_GRE_LOCAL, saddr.data, saddr.bytelen);
if (is_addrtype_inet(&daddr))
addattr_l(n, 1024, IFLA_GRE_REMOTE, daddr.data, daddr.bytelen);
addattr_l(n, 1024, IFLA_GRE_PMTUDISC, &pmtudisc, 1);
if (ignore_df)
addattr8(n, 1024, IFLA_GRE_IGNORE_DF, ignore_df & 1);

View File

@ -97,8 +97,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
__u16 oflags = 0;
__be32 ikey = 0;
__be32 okey = 0;
struct in6_addr raddr = IN6ADDR_ANY_INIT;
struct in6_addr laddr = IN6ADDR_ANY_INIT;
inet_prefix saddr, daddr;
__u8 hop_limit = DEFAULT_TNL_HOP_LIMIT;
__u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
__u32 flowinfo = 0;
@ -115,7 +114,12 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
__u8 erspan_dir = 0;
__u16 erspan_hwid = 0;
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,
@ -141,6 +145,14 @@ get_failed:
parse_rtattr_nested(greinfo, IFLA_GRE_MAX,
linkinfo[IFLA_INFO_DATA]);
rta = greinfo[IFLA_GRE_LOCAL];
if (rta && get_addr_rta(&saddr, rta, AF_INET6))
goto get_failed;
rta = greinfo[IFLA_GRE_REMOTE];
if (rta && get_addr_rta(&daddr, rta, AF_INET6))
goto get_failed;
if (greinfo[IFLA_GRE_IKEY])
ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]);
@ -153,12 +165,6 @@ get_failed:
if (greinfo[IFLA_GRE_OFLAGS])
oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]);
if (greinfo[IFLA_GRE_LOCAL])
memcpy(&laddr, RTA_DATA(greinfo[IFLA_GRE_LOCAL]), sizeof(laddr));
if (greinfo[IFLA_GRE_REMOTE])
memcpy(&raddr, RTA_DATA(greinfo[IFLA_GRE_REMOTE]), sizeof(raddr));
if (greinfo[IFLA_GRE_TTL])
hop_limit = rta_getattr_u8(greinfo[IFLA_GRE_TTL]);
@ -236,17 +242,11 @@ get_failed:
} else if (!matches(*argv, "ocsum")) {
oflags |= GRE_CSUM;
} else if (!matches(*argv, "remote")) {
inet_prefix addr;
NEXT_ARG();
get_addr(&addr, *argv, AF_INET6);
memcpy(&raddr, &addr.data, sizeof(raddr));
get_addr(&daddr, *argv, AF_INET6);
} else if (!matches(*argv, "local")) {
inet_prefix addr;
NEXT_ARG();
get_addr(&addr, *argv, AF_INET6);
memcpy(&laddr, &addr.data, sizeof(laddr));
get_addr(&saddr, *argv, AF_INET6);
} else if (!matches(*argv, "dev")) {
NEXT_ARG();
link = ll_name_to_index(*argv);
@ -398,8 +398,10 @@ get_failed:
addattr32(n, 1024, IFLA_GRE_OKEY, okey);
addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
addattr_l(n, 1024, IFLA_GRE_LOCAL, &laddr, sizeof(laddr));
addattr_l(n, 1024, IFLA_GRE_REMOTE, &raddr, sizeof(raddr));
if (is_addrtype_inet(&saddr))
addattr_l(n, 1024, IFLA_GRE_LOCAL, saddr.data, saddr.bytelen);
if (is_addrtype_inet(&daddr))
addattr_l(n, 1024, IFLA_GRE_REMOTE, daddr.data, daddr.bytelen);
if (link)
addattr32(n, 1024, IFLA_GRE_LINK, link);
addattr_l(n, 1024, IFLA_GRE_TTL, &hop_limit, 1);

View File

@ -93,8 +93,7 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
int len;
struct in6_addr laddr = IN6ADDR_ANY_INIT;
struct in6_addr raddr = IN6ADDR_ANY_INIT;
inet_prefix saddr, daddr;
__u8 hop_limit = DEFAULT_TNL_HOP_LIMIT;
__u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
__u32 flowinfo = 0;
@ -108,7 +107,12 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
__u8 metadata = 0;
__u32 fwmark = 0;
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,
@ -134,13 +138,13 @@ get_failed:
parse_rtattr_nested(iptuninfo, IFLA_IPTUN_MAX,
linkinfo[IFLA_INFO_DATA]);
if (iptuninfo[IFLA_IPTUN_LOCAL])
memcpy(&laddr, RTA_DATA(iptuninfo[IFLA_IPTUN_LOCAL]),
sizeof(laddr));
rta = iptuninfo[IFLA_IPTUN_LOCAL];
if (rta && get_addr_rta(&saddr, rta, AF_INET6))
goto get_failed;
if (iptuninfo[IFLA_IPTUN_REMOTE])
memcpy(&raddr, RTA_DATA(iptuninfo[IFLA_IPTUN_REMOTE]),
sizeof(raddr));
rta = iptuninfo[IFLA_IPTUN_REMOTE];
if (rta && get_addr_rta(&daddr, rta, AF_INET6))
goto get_failed;
if (iptuninfo[IFLA_IPTUN_TTL])
hop_limit = rta_getattr_u8(iptuninfo[IFLA_IPTUN_TTL]);
@ -185,17 +189,11 @@ get_failed:
else
invarg("Cannot guess tunnel mode.", *argv);
} else if (strcmp(*argv, "remote") == 0) {
inet_prefix addr;
NEXT_ARG();
get_addr(&addr, *argv, AF_INET6);
memcpy(&raddr, addr.data, sizeof(raddr));
get_addr(&daddr, *argv, AF_INET6);
} else if (strcmp(*argv, "local") == 0) {
inet_prefix addr;
NEXT_ARG();
get_addr(&addr, *argv, AF_INET6);
memcpy(&laddr, addr.data, sizeof(laddr));
get_addr(&saddr, *argv, AF_INET6);
} else if (matches(*argv, "dev") == 0) {
NEXT_ARG();
link = ll_name_to_index(*argv);
@ -322,8 +320,14 @@ get_failed:
return 0;
}
addattr_l(n, 1024, IFLA_IPTUN_LOCAL, &laddr, sizeof(laddr));
addattr_l(n, 1024, IFLA_IPTUN_REMOTE, &raddr, sizeof(raddr));
if (is_addrtype_inet(&saddr)) {
addattr_l(n, 1024, IFLA_IPTUN_LOCAL,
saddr.data, saddr.bytelen);
}
if (is_addrtype_inet(&daddr)) {
addattr_l(n, 1024, IFLA_IPTUN_REMOTE,
daddr.data, daddr.bytelen);
}
addattr8(n, 1024, IFLA_IPTUN_TTL, hop_limit);
addattr8(n, 1024, IFLA_IPTUN_ENCAP_LIMIT, encap_limit);
addattr32(n, 1024, IFLA_IPTUN_FLOWINFO, flowinfo);

View File

@ -90,16 +90,11 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
int len;
__u32 laddr = 0;
__u32 raddr = 0;
inet_prefix saddr, daddr, ip6rdprefix, ip6rdrelayprefix;
__u8 pmtudisc = 1;
__u8 tos = 0;
__u16 iflags = 0;
__u8 ttl = 0;
struct in6_addr ip6rdprefix = {};
__u16 ip6rdprefixlen = 0;
__u32 ip6rdrelayprefix = 0;
__u16 ip6rdrelayprefixlen = 0;
__u8 proto = 0;
__u32 link = 0;
__u16 encaptype = 0;
@ -109,7 +104,15 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
__u8 metadata = 0;
__u32 fwmark = 0;
inet_prefix_reset(&saddr);
inet_prefix_reset(&daddr);
inet_prefix_reset(&ip6rdprefix);
inet_prefix_reset(&ip6rdrelayprefix);
if (!(n->nlmsg_flags & NLM_F_CREATE)) {
const struct rtattr *rta;
if (rtnl_talk(&rth, &req.n, &answer) < 0) {
get_failed:
fprintf(stderr,
@ -135,11 +138,27 @@ get_failed:
parse_rtattr_nested(iptuninfo, IFLA_IPTUN_MAX,
linkinfo[IFLA_INFO_DATA]);
if (iptuninfo[IFLA_IPTUN_LOCAL])
laddr = rta_getattr_u32(iptuninfo[IFLA_IPTUN_LOCAL]);
rta = iptuninfo[IFLA_IPTUN_LOCAL];
if (rta && get_addr_rta(&saddr, rta, AF_INET))
goto get_failed;
if (iptuninfo[IFLA_IPTUN_REMOTE])
raddr = rta_getattr_u32(iptuninfo[IFLA_IPTUN_REMOTE]);
rta = iptuninfo[IFLA_IPTUN_REMOTE];
if (rta && get_addr_rta(&daddr, rta, AF_INET))
goto get_failed;
rta = iptuninfo[IFLA_IPTUN_6RD_PREFIX];
if (rta && get_addr_rta(&ip6rdprefix, rta, AF_INET6))
goto get_failed;
rta = iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX];
if (rta && get_addr_rta(&ip6rdrelayprefix, rta, AF_INET))
goto get_failed;
rta = iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN];
ip6rdprefix.bitlen = rta ? rta_getattr_u16(rta) : 0;
rta = iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN];
ip6rdrelayprefix.bitlen = rta ? rta_getattr_u16(rta) : 0;
if (iptuninfo[IFLA_IPTUN_TTL])
ttl = rta_getattr_u8(iptuninfo[IFLA_IPTUN_TTL]);
@ -168,22 +187,7 @@ get_failed:
encapsport = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_SPORT]);
if (iptuninfo[IFLA_IPTUN_ENCAP_DPORT])
encapdport = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_DPORT]);
if (iptuninfo[IFLA_IPTUN_6RD_PREFIX])
memcpy(&ip6rdprefix,
RTA_DATA(iptuninfo[IFLA_IPTUN_6RD_PREFIX]),
sizeof(laddr));
if (iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN])
ip6rdprefixlen =
rta_getattr_u16(iptuninfo[IFLA_IPTUN_6RD_PREFIXLEN]);
if (iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX])
ip6rdrelayprefix =
rta_getattr_u32(iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIX]);
if (iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN])
ip6rdrelayprefixlen =
rta_getattr_u16(iptuninfo[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]);
if (iptuninfo[IFLA_IPTUN_COLLECT_METADATA])
metadata = 1;
@ -214,10 +218,10 @@ get_failed:
invarg("Cannot guess tunnel mode.", *argv);
} else if (strcmp(*argv, "remote") == 0) {
NEXT_ARG();
raddr = get_addr32(*argv);
get_addr(&daddr, *argv, AF_INET);
} else if (strcmp(*argv, "local") == 0) {
NEXT_ARG();
laddr = get_addr32(*argv);
get_addr(&saddr, *argv, AF_INET);
} else if (matches(*argv, "dev") == 0) {
NEXT_ARG();
link = ll_name_to_index(*argv);
@ -289,29 +293,16 @@ get_failed:
} else if (strcmp(*argv, "external") == 0) {
metadata = 1;
} else if (strcmp(*argv, "6rd-prefix") == 0) {
inet_prefix prefix;
NEXT_ARG();
if (get_prefix(&prefix, *argv, AF_INET6))
if (get_prefix(&ip6rdprefix, *argv, AF_INET6))
invarg("invalid 6rd_prefix\n", *argv);
memcpy(&ip6rdprefix, prefix.data, 16);
ip6rdprefixlen = prefix.bitlen;
} else if (strcmp(*argv, "6rd-relay_prefix") == 0) {
inet_prefix prefix;
NEXT_ARG();
if (get_prefix(&prefix, *argv, AF_INET))
if (get_prefix(&ip6rdrelayprefix, *argv, AF_INET))
invarg("invalid 6rd-relay_prefix\n", *argv);
memcpy(&ip6rdrelayprefix, prefix.data, 4);
ip6rdrelayprefixlen = prefix.bitlen;
} else if (strcmp(*argv, "6rd-reset") == 0) {
inet_prefix prefix;
get_prefix(&prefix, "2002::", AF_INET6);
memcpy(&ip6rdprefix, prefix.data, 16);
ip6rdprefixlen = 16;
ip6rdrelayprefix = 0;
ip6rdrelayprefixlen = 0;
get_prefix(&ip6rdprefix, "2002::/16", AF_INET6);
inet_prefix_reset(&ip6rdrelayprefix);
} else if (strcmp(*argv, "fwmark") == 0) {
NEXT_ARG();
if (get_u32(&fwmark, *argv, 0))
@ -334,8 +325,14 @@ get_failed:
return 0;
}
addattr32(n, 1024, IFLA_IPTUN_LOCAL, laddr);
addattr32(n, 1024, IFLA_IPTUN_REMOTE, raddr);
if (is_addrtype_inet(&saddr)) {
addattr_l(n, 1024, IFLA_IPTUN_LOCAL,
saddr.data, saddr.bytelen);
}
if (is_addrtype_inet(&daddr)) {
addattr_l(n, 1024, IFLA_IPTUN_REMOTE,
daddr.data, daddr.bytelen);
}
addattr8(n, 1024, IFLA_IPTUN_PMTUDISC, pmtudisc);
addattr8(n, 1024, IFLA_IPTUN_TOS, tos);
addattr8(n, 1024, IFLA_IPTUN_TTL, ttl);
@ -349,15 +346,17 @@ get_failed:
if (strcmp(lu->id, "sit") == 0) {
addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags);
if (ip6rdprefixlen) {
if (is_addrtype_inet(&ip6rdprefix)) {
addattr_l(n, 1024, IFLA_IPTUN_6RD_PREFIX,
&ip6rdprefix, sizeof(ip6rdprefix));
ip6rdprefix.data, ip6rdprefix.bytelen);
addattr16(n, 1024, IFLA_IPTUN_6RD_PREFIXLEN,
ip6rdprefixlen);
ip6rdprefix.bitlen);
}
if (is_addrtype_inet(&ip6rdrelayprefix)) {
addattr32(n, 1024, IFLA_IPTUN_6RD_RELAY_PREFIX,
ip6rdrelayprefix);
ip6rdrelayprefix.data[0]);
addattr16(n, 1024, IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
ip6rdrelayprefixlen);
ip6rdrelayprefix.bitlen);
}
}

View File

@ -64,13 +64,17 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
__be32 ikey = 0;
__be32 okey = 0;
unsigned int saddr = 0;
unsigned int daddr = 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,
@ -96,18 +100,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_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]);
@ -129,10 +135,10 @@ get_failed:
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 = ll_name_to_index(*argv);
@ -154,8 +160,10 @@ get_failed:
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(&saddr))
addattr_l(n, 1024, IFLA_VTI_LOCAL, saddr.data, saddr.bytelen);
if (is_addrtype_inet(&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);

View File

@ -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,17 +136,11 @@ 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);
@ -162,8 +162,10 @@ 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 (is_addrtype_inet(&saddr))
addattr_l(n, 1024, IFLA_VTI_LOCAL, saddr.data, saddr.bytelen);
if (is_addrtype_inet(&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);