Merge branch 'master' into net-next

Conflicts:
	man/man8/ip-link.8.in

Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
David Ahern 2018-01-08 10:10:45 -08:00
commit 6a21ca8a4a
29 changed files with 274 additions and 356 deletions

View File

@ -1,10 +1,12 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
include ../config.mk include ../config.mk
TARGETS :=
ifeq ($(HAVE_MNL),y) ifeq ($(HAVE_MNL),y)
DEVLINKOBJ = devlink.o mnlg.o DEVLINKOBJ = devlink.o mnlg.o
TARGETS=devlink TARGETS += devlink
CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags) CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
LDLIBS += $(shell $(PKG_CONFIG) libmnl --libs) LDLIBS += $(shell $(PKG_CONFIG) libmnl --libs)

View File

@ -170,17 +170,13 @@ static int parse_args(int argc, char **argv, int cmd, struct ip6_tnl_parm2 *p)
inet_prefix raddr; inet_prefix raddr;
NEXT_ARG(); NEXT_ARG();
get_prefix(&raddr, *argv, preferred_family); get_addr(&raddr, *argv, AF_INET6);
if (raddr.family == AF_UNSPEC)
invarg("\"remote\" address family is AF_UNSPEC", *argv);
memcpy(&p->raddr, &raddr.data, sizeof(p->raddr)); memcpy(&p->raddr, &raddr.data, sizeof(p->raddr));
} else if (strcmp(*argv, "local") == 0) { } else if (strcmp(*argv, "local") == 0) {
inet_prefix laddr; inet_prefix laddr;
NEXT_ARG(); NEXT_ARG();
get_prefix(&laddr, *argv, preferred_family); get_addr(&laddr, *argv, AF_INET6);
if (laddr.family == AF_UNSPEC)
invarg("\"local\" address family is AF_UNSPEC", *argv);
memcpy(&p->laddr, &laddr.data, sizeof(p->laddr)); memcpy(&p->laddr, &laddr.data, sizeof(p->laddr));
} else if (strcmp(*argv, "dev") == 0) { } else if (strcmp(*argv, "dev") == 0) {
NEXT_ARG(); NEXT_ARG();

View File

@ -285,11 +285,13 @@ static void iplink_parse_vf_vlan_info(int vf, int *argcp, char ***argvp,
{ {
int argc = *argcp; int argc = *argcp;
char **argv = *argvp; char **argv = *argvp;
unsigned int vci;
NEXT_ARG(); NEXT_ARG();
if (get_unsigned(&ivvip->vlan, *argv, 0)) if (get_unsigned(&vci, *argv, 0) || vci > 4095)
invarg("Invalid \"vlan\" value\n", *argv); invarg("Invalid \"vlan\" value\n", *argv);
ivvip->vlan = vci;
ivvip->vf = vf; ivvip->vf = vf;
ivvip->qos = 0; ivvip->qos = 0;
ivvip->vlan_proto = htons(ETH_P_8021Q); ivvip->vlan_proto = htons(ETH_P_8021Q);
@ -593,8 +595,10 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
*name = *argv; *name = *argv;
} else if (strcmp(*argv, "index") == 0) { } else if (strcmp(*argv, "index") == 0) {
NEXT_ARG(); NEXT_ARG();
if (*index)
duparg("index", *argv);
*index = atoi(*argv); *index = atoi(*argv);
if (*index < 0) if (*index <= 0)
invarg("Invalid \"index\" value", *argv); invarg("Invalid \"index\" value", *argv);
} else if (matches(*argv, "link") == 0) { } else if (matches(*argv, "link") == 0) {
NEXT_ARG(); NEXT_ARG();
@ -775,11 +779,12 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
argc--; argv++; argc--; argv++;
break; break;
} else if (matches(*argv, "alias") == 0) { } else if (matches(*argv, "alias") == 0) {
len = strlen(*argv);
if (len >= IFALIASZ)
invarg("alias too long\n", *argv);
NEXT_ARG(); NEXT_ARG();
addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS,
*argv, strlen(*argv)); *argv, len);
argc--; argv++;
break;
} else if (strcmp(*argv, "group") == 0) { } else if (strcmp(*argv, "group") == 0) {
NEXT_ARG(); NEXT_ARG();
if (*group != -1) if (*group != -1)
@ -913,7 +918,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
char *name = NULL; char *name = NULL;
char *link = NULL; char *link = NULL;
char *type = NULL; char *type = NULL;
int index = -1; int index = 0;
int group; int group;
struct link_util *lu = NULL; struct link_util *lu = NULL;
struct iplink_req req = { struct iplink_req req = {
@ -949,7 +954,6 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
return -1; return -1;
} }
req.i.ifi_index = 0;
addattr32(&req.n, sizeof(req), IFLA_GROUP, group); addattr32(&req.n, sizeof(req), IFLA_GROUP, group);
if (rtnl_talk(&rth, &req.n, NULL) < 0) if (rtnl_talk(&rth, &req.n, NULL) < 0)
return -2; return -2;
@ -963,7 +967,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
"Not enough information: \"dev\" argument is required.\n"); "Not enough information: \"dev\" argument is required.\n");
exit(-1); exit(-1);
} }
if (cmd == RTM_NEWLINK && index != -1) { if (cmd == RTM_NEWLINK && index) {
fprintf(stderr, fprintf(stderr,
"index can be used only when creating devices.\n"); "index can be used only when creating devices.\n");
exit(-1); exit(-1);
@ -991,10 +995,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
addattr_l(&req.n, sizeof(req), IFLA_LINK, &ifindex, 4); addattr_l(&req.n, sizeof(req), IFLA_LINK, &ifindex, 4);
} }
if (index == -1) req.i.ifi_index = index;
req.i.ifi_index = 0;
else
req.i.ifi_index = index;
} }
if (name) { if (name) {

View File

@ -38,7 +38,7 @@ static int vxcan_parse_opt(struct link_util *lu, int argc, char **argv,
char *link = NULL; char *link = NULL;
char *type = NULL; char *type = NULL;
int index = 0; int index = 0;
int err, len; int err;
struct rtattr *data; struct rtattr *data;
int group; int group;
struct ifinfomsg *ifm, *peer_ifm; struct ifinfomsg *ifm, *peer_ifm;
@ -65,11 +65,12 @@ static int vxcan_parse_opt(struct link_util *lu, int argc, char **argv,
if (err < 0) if (err < 0)
return err; return err;
if (type)
duparg("type", argv[err]);
if (name) { if (name) {
len = strlen(name) + 1; addattr_l(hdr, 1024,
if (len > IFNAMSIZ) IFLA_IFNAME, name, strlen(name) + 1);
invarg("\"name\" too long\n", *argv);
addattr_l(hdr, 1024, IFLA_IFNAME, name, len);
} }
peer_ifm = RTA_DATA(data); peer_ifm = RTA_DATA(data);

View File

@ -126,6 +126,7 @@ static struct
int oif, oifmask; int oif, oifmask;
int mark, markmask; int mark, markmask;
int realm, realmmask; int realm, realmmask;
__u32 metric, metricmask;
inet_prefix rprefsrc; inet_prefix rprefsrc;
inet_prefix rvia; inet_prefix rvia;
inet_prefix rdst; inet_prefix rdst;
@ -190,20 +191,42 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
return 0; return 0;
if ((filter.tos^r->rtm_tos)&filter.tosmask) if ((filter.tos^r->rtm_tos)&filter.tosmask)
return 0; return 0;
if (filter.rdst.family && if (filter.rdst.family) {
(r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len)) if (r->rtm_family != filter.rdst.family ||
return 0; filter.rdst.bitlen > r->rtm_dst_len)
if (filter.mdst.family && return 0;
(r->rtm_family != filter.mdst.family || } else if (filter.rdst.flags & PREFIXLEN_SPECIFIED) {
(filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len))) if (filter.rdst.bitlen > r->rtm_dst_len)
return 0; return 0;
if (filter.rsrc.family && }
(r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len)) if (filter.mdst.family) {
return 0; if (r->rtm_family != filter.mdst.family ||
if (filter.msrc.family && (filter.mdst.bitlen >= 0 &&
(r->rtm_family != filter.msrc.family || filter.mdst.bitlen < r->rtm_dst_len))
(filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len))) return 0;
return 0; } else if (filter.mdst.flags & PREFIXLEN_SPECIFIED) {
if (filter.mdst.bitlen >= 0 &&
filter.mdst.bitlen < r->rtm_dst_len)
return 0;
}
if (filter.rsrc.family) {
if (r->rtm_family != filter.rsrc.family ||
filter.rsrc.bitlen > r->rtm_src_len)
return 0;
} else if (filter.rsrc.flags & PREFIXLEN_SPECIFIED) {
if (filter.rsrc.bitlen > r->rtm_src_len)
return 0;
}
if (filter.msrc.family) {
if (r->rtm_family != filter.msrc.family ||
(filter.msrc.bitlen >= 0 &&
filter.msrc.bitlen < r->rtm_src_len))
return 0;
} else if (filter.msrc.flags & PREFIXLEN_SPECIFIED) {
if (filter.msrc.bitlen >= 0 &&
filter.msrc.bitlen < r->rtm_src_len)
return 0;
}
if (filter.rvia.family) { if (filter.rvia.family) {
int family = r->rtm_family; int family = r->rtm_family;
@ -220,7 +243,9 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
if (tb[RTA_DST]) if (tb[RTA_DST])
memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len+7)/8); memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len+7)/8);
if (filter.rsrc.family || filter.msrc.family) { if (filter.rsrc.family || filter.msrc.family ||
filter.rsrc.flags & PREFIXLEN_SPECIFIED ||
filter.msrc.flags & PREFIXLEN_SPECIFIED) {
if (tb[RTA_SRC]) if (tb[RTA_SRC])
memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), (r->rtm_src_len+7)/8); memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), (r->rtm_src_len+7)/8);
} }
@ -240,15 +265,18 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8); memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8);
} }
if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen)) if ((filter.rdst.family || filter.rdst.flags & PREFIXLEN_SPECIFIED) &&
inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
return 0; return 0;
if (filter.mdst.family && filter.mdst.bitlen >= 0 && if ((filter.mdst.family || filter.mdst.flags & PREFIXLEN_SPECIFIED) &&
inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len)) inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len))
return 0; return 0;
if (filter.rsrc.family && inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen)) if ((filter.rsrc.family || filter.rsrc.flags & PREFIXLEN_SPECIFIED) &&
inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen))
return 0; return 0;
if (filter.msrc.family && filter.msrc.bitlen >= 0 && if ((filter.msrc.family || filter.msrc.flags & PREFIXLEN_SPECIFIED) &&
filter.msrc.bitlen >= 0 &&
inet_addr_match(&src, &filter.msrc, r->rtm_src_len)) inet_addr_match(&src, &filter.msrc, r->rtm_src_len))
return 0; return 0;
@ -288,6 +316,14 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
if ((mark ^ filter.mark) & filter.markmask) if ((mark ^ filter.mark) & filter.markmask)
return 0; return 0;
} }
if (filter.metricmask) {
__u32 metric = 0;
if (tb[RTA_PRIORITY])
metric = rta_getattr_u32(tb[RTA_PRIORITY]);
if ((metric ^ filter.metric) & filter.metricmask)
return 0;
}
if (filter.flushb && if (filter.flushb &&
r->rtm_family == AF_INET6 && r->rtm_family == AF_INET6 &&
r->rtm_dst_len == 0 && r->rtm_dst_len == 0 &&
@ -441,7 +477,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, "src %s ", fprintf(fp, "src %s ",
rt_addr_n2a_rta(r->rtm_family, tb[RTA_PREFSRC])); rt_addr_n2a_rta(r->rtm_family, tb[RTA_PREFSRC]));
} }
if (tb[RTA_PRIORITY]) if (tb[RTA_PRIORITY] && filter.metricmask != -1)
fprintf(fp, "metric %u ", rta_getattr_u32(tb[RTA_PRIORITY])); fprintf(fp, "metric %u ", rta_getattr_u32(tb[RTA_PRIORITY]));
if (r->rtm_flags & RTNH_F_DEAD) if (r->rtm_flags & RTNH_F_DEAD)
fprintf(fp, "dead "); fprintf(fp, "dead ");
@ -1518,6 +1554,16 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
if (get_unsigned(&mark, *argv, 0)) if (get_unsigned(&mark, *argv, 0))
invarg("invalid mark value", *argv); invarg("invalid mark value", *argv);
filter.markmask = -1; filter.markmask = -1;
} else if (matches(*argv, "metric") == 0 ||
matches(*argv, "priority") == 0 ||
strcmp(*argv, "preference") == 0) {
__u32 metric;
NEXT_ARG();
if (get_u32(&metric, *argv, 0))
invarg("\"metric\" value is invalid\n", *argv);
filter.metric = metric;
filter.metricmask = -1;
} else if (strcmp(*argv, "via") == 0) { } else if (strcmp(*argv, "via") == 0) {
int family; int family;

View File

@ -127,16 +127,10 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
p->iph.frag_off = htons(IP_DF); p->iph.frag_off = htons(IP_DF);
} else if (strcmp(*argv, "remote") == 0) { } else if (strcmp(*argv, "remote") == 0) {
NEXT_ARG(); NEXT_ARG();
if (strcmp(*argv, "any")) p->iph.daddr = get_addr32(*argv);
p->iph.daddr = get_addr32(*argv);
else
p->iph.daddr = htonl(INADDR_ANY);
} else if (strcmp(*argv, "local") == 0) { } else if (strcmp(*argv, "local") == 0) {
NEXT_ARG(); NEXT_ARG();
if (strcmp(*argv, "any")) p->iph.saddr = get_addr32(*argv);
p->iph.saddr = get_addr32(*argv);
else
p->iph.saddr = htonl(INADDR_ANY);
} else if (strcmp(*argv, "dev") == 0) { } else if (strcmp(*argv, "dev") == 0) {
NEXT_ARG(); NEXT_ARG();
medium = *argv; medium = *argv;

View File

@ -43,6 +43,7 @@ static void print_usage(FILE *f)
" [ [no]encap-csum ]\n" " [ [no]encap-csum ]\n"
" [ [no]encap-csum6 ]\n" " [ [no]encap-csum6 ]\n"
" [ [no]encap-remcsum ]\n" " [ [no]encap-remcsum ]\n"
" [ external ]\n"
" [ fwmark MARK ]\n" " [ fwmark MARK ]\n"
" [ erspan_ver version ]\n" " [ erspan_ver version ]\n"
" [ erspan IDX ]\n" " [ erspan IDX ]\n"
@ -79,14 +80,14 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
.i.ifi_family = preferred_family, .i.ifi_family = preferred_family,
.i.ifi_index = ifi->ifi_index, .i.ifi_index = ifi->ifi_index,
}; };
struct nlmsghdr *answer = NULL; struct nlmsghdr *answer;
struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *greinfo[IFLA_GRE_MAX + 1]; struct rtattr *greinfo[IFLA_GRE_MAX + 1];
__u16 iflags = 0; __u16 iflags = 0;
__u16 oflags = 0; __u16 oflags = 0;
unsigned int ikey = 0; __be32 ikey = 0;
unsigned int okey = 0; __be32 okey = 0;
unsigned int saddr = 0; unsigned int saddr = 0;
unsigned int daddr = 0; unsigned int daddr = 0;
unsigned int link = 0; unsigned int link = 0;
@ -111,7 +112,6 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
get_failed: get_failed:
fprintf(stderr, fprintf(stderr,
"Failed to get existing tunnel info.\n"); "Failed to get existing tunnel info.\n");
free(answer);
return -1; return -1;
} }
@ -162,7 +162,7 @@ get_failed:
tos = rta_getattr_u8(greinfo[IFLA_GRE_TOS]); tos = rta_getattr_u8(greinfo[IFLA_GRE_TOS]);
if (greinfo[IFLA_GRE_LINK]) if (greinfo[IFLA_GRE_LINK])
link = rta_getattr_u8(greinfo[IFLA_GRE_LINK]); link = rta_getattr_u32(greinfo[IFLA_GRE_LINK]);
if (greinfo[IFLA_GRE_ENCAP_TYPE]) if (greinfo[IFLA_GRE_ENCAP_TYPE])
encaptype = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_TYPE]); encaptype = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_TYPE]);
@ -200,53 +200,18 @@ get_failed:
while (argc > 0) { while (argc > 0) {
if (!matches(*argv, "key")) { if (!matches(*argv, "key")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
iflags |= GRE_KEY; iflags |= GRE_KEY;
oflags |= GRE_KEY; oflags |= GRE_KEY;
if (strchr(*argv, '.')) ikey = okey = tnl_parse_key("key", *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;
} else if (!matches(*argv, "ikey")) { } else if (!matches(*argv, "ikey")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
iflags |= GRE_KEY; iflags |= GRE_KEY;
if (strchr(*argv, '.')) ikey = tnl_parse_key("ikey", *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;
} else if (!matches(*argv, "okey")) { } else if (!matches(*argv, "okey")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
oflags |= GRE_KEY; oflags |= GRE_KEY;
if (strchr(*argv, '.')) okey = tnl_parse_key("okey", *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;
} else if (!matches(*argv, "seq")) { } else if (!matches(*argv, "seq")) {
iflags |= GRE_SEQ; iflags |= GRE_SEQ;
oflags |= GRE_SEQ; oflags |= GRE_SEQ;
@ -267,12 +232,10 @@ get_failed:
pmtudisc = 1; pmtudisc = 1;
} else if (!matches(*argv, "remote")) { } else if (!matches(*argv, "remote")) {
NEXT_ARG(); NEXT_ARG();
if (strcmp(*argv, "any")) daddr = get_addr32(*argv);
daddr = get_addr32(*argv);
} else if (!matches(*argv, "local")) { } else if (!matches(*argv, "local")) {
NEXT_ARG(); NEXT_ARG();
if (strcmp(*argv, "any")) saddr = get_addr32(*argv);
saddr = get_addr32(*argv);
} else if (!matches(*argv, "dev")) { } else if (!matches(*argv, "dev")) {
NEXT_ARG(); NEXT_ARG();
link = if_nametoindex(*argv); link = if_nametoindex(*argv);
@ -335,11 +298,11 @@ get_failed:
} else if (strcmp(*argv, "encap-udp6-csum") == 0) { } else if (strcmp(*argv, "encap-udp6-csum") == 0) {
encapflags |= TUNNEL_ENCAP_FLAG_CSUM6; encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
} else if (strcmp(*argv, "noencap-udp6-csum") == 0) { } else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
encapflags |= ~TUNNEL_ENCAP_FLAG_CSUM6; encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM6;
} else if (strcmp(*argv, "encap-remcsum") == 0) { } else if (strcmp(*argv, "encap-remcsum") == 0) {
encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM;
} else if (strcmp(*argv, "noencap-remcsum") == 0) { } else if (strcmp(*argv, "noencap-remcsum") == 0) {
encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM; encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM;
} else if (strcmp(*argv, "external") == 0) { } else if (strcmp(*argv, "external") == 0) {
metadata = 1; metadata = 1;
} else if (strcmp(*argv, "ignore-df") == 0) { } else if (strcmp(*argv, "ignore-df") == 0) {

View File

@ -90,14 +90,14 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
.i.ifi_family = preferred_family, .i.ifi_family = preferred_family,
.i.ifi_index = ifi->ifi_index, .i.ifi_index = ifi->ifi_index,
}; };
struct nlmsghdr *answer = NULL; struct nlmsghdr *answer;
struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *greinfo[IFLA_GRE_MAX + 1]; struct rtattr *greinfo[IFLA_GRE_MAX + 1];
__u16 iflags = 0; __u16 iflags = 0;
__u16 oflags = 0; __u16 oflags = 0;
unsigned int ikey = 0; __be32 ikey = 0;
unsigned int okey = 0; __be32 okey = 0;
struct in6_addr raddr = IN6ADDR_ANY_INIT; struct in6_addr raddr = IN6ADDR_ANY_INIT;
struct in6_addr laddr = IN6ADDR_ANY_INIT; struct in6_addr laddr = IN6ADDR_ANY_INIT;
unsigned int link = 0; unsigned int link = 0;
@ -122,7 +122,6 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
get_failed: get_failed:
fprintf(stderr, fprintf(stderr,
"Failed to get existing tunnel info.\n"); "Failed to get existing tunnel info.\n");
free(answer);
return -1; return -1;
} }
@ -212,53 +211,18 @@ get_failed:
while (argc > 0) { while (argc > 0) {
if (!matches(*argv, "key")) { if (!matches(*argv, "key")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
iflags |= GRE_KEY; iflags |= GRE_KEY;
oflags |= GRE_KEY; oflags |= GRE_KEY;
if (strchr(*argv, '.')) ikey = okey = tnl_parse_key("key", *argv);
uval = get_addr32(*argv);
else {
if (get_unsigned(&uval, *argv, 0) < 0) {
fprintf(stderr,
"Invalid value for \"key\"\n");
exit(-1);
}
uval = htonl(uval);
}
ikey = okey = uval;
} else if (!matches(*argv, "ikey")) { } else if (!matches(*argv, "ikey")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
iflags |= GRE_KEY; iflags |= GRE_KEY;
if (strchr(*argv, '.')) ikey = tnl_parse_key("ikey", *argv);
uval = get_addr32(*argv);
else {
if (get_unsigned(&uval, *argv, 0) < 0) {
fprintf(stderr, "invalid value of \"ikey\"\n");
exit(-1);
}
uval = htonl(uval);
}
ikey = uval;
} else if (!matches(*argv, "okey")) { } else if (!matches(*argv, "okey")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
oflags |= GRE_KEY; oflags |= GRE_KEY;
if (strchr(*argv, '.')) okey = tnl_parse_key("okey", *argv);
uval = get_addr32(*argv);
else {
if (get_unsigned(&uval, *argv, 0) < 0) {
fprintf(stderr, "invalid value of \"okey\"\n");
exit(-1);
}
uval = htonl(uval);
}
okey = uval;
} else if (!matches(*argv, "seq")) { } else if (!matches(*argv, "seq")) {
iflags |= GRE_SEQ; iflags |= GRE_SEQ;
oflags |= GRE_SEQ; oflags |= GRE_SEQ;
@ -277,17 +241,13 @@ get_failed:
inet_prefix addr; inet_prefix addr;
NEXT_ARG(); NEXT_ARG();
get_prefix(&addr, *argv, preferred_family); get_addr(&addr, *argv, AF_INET6);
if (addr.family == AF_UNSPEC)
invarg("\"remote\" address family is AF_UNSPEC", *argv);
memcpy(&raddr, &addr.data, sizeof(raddr)); memcpy(&raddr, &addr.data, sizeof(raddr));
} else if (!matches(*argv, "local")) { } else if (!matches(*argv, "local")) {
inet_prefix addr; inet_prefix addr;
NEXT_ARG(); NEXT_ARG();
get_prefix(&addr, *argv, preferred_family); get_addr(&addr, *argv, AF_INET6);
if (addr.family == AF_UNSPEC)
invarg("\"local\" address family is AF_UNSPEC", *argv);
memcpy(&laddr, &addr.data, sizeof(laddr)); memcpy(&laddr, &addr.data, sizeof(laddr));
} else if (!matches(*argv, "dev")) { } else if (!matches(*argv, "dev")) {
NEXT_ARG(); NEXT_ARG();
@ -311,12 +271,12 @@ get_failed:
__u8 uval; __u8 uval;
NEXT_ARG(); NEXT_ARG();
flowinfo &= ~IP6_FLOWINFO_TCLASS;
if (strcmp(*argv, "inherit") == 0) if (strcmp(*argv, "inherit") == 0)
flags |= IP6_TNL_F_USE_ORIG_TCLASS; flags |= IP6_TNL_F_USE_ORIG_TCLASS;
else { else {
if (get_u8(&uval, *argv, 16)) if (get_u8(&uval, *argv, 16))
invarg("invalid TClass", *argv); invarg("invalid TClass", *argv);
flowinfo &= ~IP6_FLOWINFO_TCLASS;
flowinfo |= htonl((__u32)uval << 20) & IP6_FLOWINFO_TCLASS; flowinfo |= htonl((__u32)uval << 20) & IP6_FLOWINFO_TCLASS;
flags &= ~IP6_TNL_F_USE_ORIG_TCLASS; flags &= ~IP6_TNL_F_USE_ORIG_TCLASS;
} }
@ -325,6 +285,7 @@ get_failed:
__u32 uval; __u32 uval;
NEXT_ARG(); NEXT_ARG();
flowinfo &= ~IP6_FLOWINFO_FLOWLABEL;
if (strcmp(*argv, "inherit") == 0) if (strcmp(*argv, "inherit") == 0)
flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL; flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL;
else { else {
@ -332,7 +293,6 @@ get_failed:
invarg("invalid Flowlabel", *argv); invarg("invalid Flowlabel", *argv);
if (uval > 0xFFFFF) if (uval > 0xFFFFF)
invarg("invalid Flowlabel", *argv); invarg("invalid Flowlabel", *argv);
flowinfo &= ~IP6_FLOWINFO_FLOWLABEL;
flowinfo |= htonl(uval) & IP6_FLOWINFO_FLOWLABEL; flowinfo |= htonl(uval) & IP6_FLOWINFO_FLOWLABEL;
flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL; flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
} }

View File

@ -83,13 +83,13 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
.i.ifi_family = preferred_family, .i.ifi_family = preferred_family,
.i.ifi_index = ifi->ifi_index, .i.ifi_index = ifi->ifi_index,
}; };
struct nlmsghdr *answer = NULL; struct nlmsghdr *answer;
struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1]; struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
int len; int len;
struct in6_addr laddr = {}; struct in6_addr laddr = IN6ADDR_ANY_INIT;
struct in6_addr raddr = {}; struct in6_addr raddr = IN6ADDR_ANY_INIT;
__u8 hop_limit = DEFAULT_TNL_HOP_LIMIT; __u8 hop_limit = DEFAULT_TNL_HOP_LIMIT;
__u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT; __u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
__u32 flowinfo = 0; __u32 flowinfo = 0;
@ -108,7 +108,6 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
get_failed: get_failed:
fprintf(stderr, fprintf(stderr,
"Failed to get existing tunnel info.\n"); "Failed to get existing tunnel info.\n");
free(answer);
return -1; return -1;
} }
@ -184,18 +183,14 @@ get_failed:
inet_prefix addr; inet_prefix addr;
NEXT_ARG(); NEXT_ARG();
get_prefix(&addr, *argv, preferred_family); get_addr(&addr, *argv, AF_INET6);
if (addr.family == AF_UNSPEC) memcpy(&raddr, addr.data, sizeof(raddr));
invarg("\"remote\" address family is AF_UNSPEC", *argv);
memcpy(&raddr, addr.data, addr.bytelen);
} else if (strcmp(*argv, "local") == 0) { } else if (strcmp(*argv, "local") == 0) {
inet_prefix addr; inet_prefix addr;
NEXT_ARG(); NEXT_ARG();
get_prefix(&addr, *argv, preferred_family); get_addr(&addr, *argv, AF_INET6);
if (addr.family == AF_UNSPEC) memcpy(&laddr, addr.data, sizeof(laddr));
invarg("\"local\" address family is AF_UNSPEC", *argv);
memcpy(&laddr, addr.data, addr.bytelen);
} else if (matches(*argv, "dev") == 0) { } else if (matches(*argv, "dev") == 0) {
NEXT_ARG(); NEXT_ARG();
link = if_nametoindex(*argv); link = if_nametoindex(*argv);
@ -306,7 +301,7 @@ get_failed:
} else if (strcmp(*argv, "encap-remcsum") == 0) { } else if (strcmp(*argv, "encap-remcsum") == 0) {
encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM;
} else if (strcmp(*argv, "noencap-remcsum") == 0) { } else if (strcmp(*argv, "noencap-remcsum") == 0) {
encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM; encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM;
} else if (strcmp(*argv, "external") == 0) { } else if (strcmp(*argv, "external") == 0) {
metadata = 1; metadata = 1;
} else } else

View File

@ -83,7 +83,7 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
.i.ifi_family = preferred_family, .i.ifi_family = preferred_family,
.i.ifi_index = ifi->ifi_index, .i.ifi_index = ifi->ifi_index,
}; };
struct nlmsghdr *answer = NULL; struct nlmsghdr *answer;
struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1]; struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1];
@ -112,7 +112,6 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
get_failed: get_failed:
fprintf(stderr, fprintf(stderr,
"Failed to get existing tunnel info.\n"); "Failed to get existing tunnel info.\n");
free(answer);
return -1; return -1;
} }
@ -195,16 +194,10 @@ get_failed:
while (argc > 0) { while (argc > 0) {
if (strcmp(*argv, "remote") == 0) { if (strcmp(*argv, "remote") == 0) {
NEXT_ARG(); NEXT_ARG();
if (strcmp(*argv, "any")) raddr = get_addr32(*argv);
raddr = get_addr32(*argv);
else
raddr = 0;
} else if (strcmp(*argv, "local") == 0) { } else if (strcmp(*argv, "local") == 0) {
NEXT_ARG(); NEXT_ARG();
if (strcmp(*argv, "any")) laddr = get_addr32(*argv);
laddr = get_addr32(*argv);
else
laddr = 0;
} else if (matches(*argv, "dev") == 0) { } else if (matches(*argv, "dev") == 0) {
NEXT_ARG(); NEXT_ARG();
link = if_nametoindex(*argv); link = if_nametoindex(*argv);
@ -237,11 +230,11 @@ get_failed:
} else if (strcmp(lu->id, "sit") == 0 && } else if (strcmp(lu->id, "sit") == 0 &&
strcmp(*argv, "isatap") == 0) { strcmp(*argv, "isatap") == 0) {
iflags |= SIT_ISATAP; iflags |= SIT_ISATAP;
} else if (strcmp(lu->id, "sit") == 0 && } else if (strcmp(*argv, "mode") == 0) {
strcmp(*argv, "mode") == 0) {
NEXT_ARG(); NEXT_ARG();
if (strcmp(*argv, "ipv6/ipv4") == 0 || if (strcmp(lu->id, "sit") == 0 &&
strcmp(*argv, "ip6ip") == 0) (strcmp(*argv, "ipv6/ipv4") == 0 ||
strcmp(*argv, "ip6ip") == 0))
proto = IPPROTO_IPV6; proto = IPPROTO_IPV6;
else if (strcmp(*argv, "ipv4/ipv4") == 0 || else if (strcmp(*argv, "ipv4/ipv4") == 0 ||
strcmp(*argv, "ipip") == 0 || strcmp(*argv, "ipip") == 0 ||
@ -255,21 +248,6 @@ get_failed:
proto = 0; proto = 0;
else else
invarg("Cannot guess tunnel mode.", *argv); invarg("Cannot guess tunnel mode.", *argv);
} else if (strcmp(lu->id, "ipip") == 0 &&
strcmp(*argv, "mode") == 0) {
NEXT_ARG();
if (strcmp(*argv, "ipv4/ipv4") == 0 ||
strcmp(*argv, "ipip") == 0 ||
strcmp(*argv, "ip4ip4") == 0)
proto = IPPROTO_IPIP;
else if (strcmp(*argv, "mpls/ipv4") == 0 ||
strcmp(*argv, "mplsip") == 0)
proto = IPPROTO_MPLS;
else if (strcmp(*argv, "any/ipv4") == 0 ||
strcmp(*argv, "any") == 0)
proto = 0;
else
invarg("Cannot guess tunnel mode.", *argv);
} else if (strcmp(*argv, "noencap") == 0) { } else if (strcmp(*argv, "noencap") == 0) {
encaptype = TUNNEL_ENCAP_NONE; encaptype = TUNNEL_ENCAP_NONE;
} else if (strcmp(*argv, "encap") == 0) { } else if (strcmp(*argv, "encap") == 0) {
@ -344,6 +322,7 @@ get_failed:
exit(-1); exit(-1);
} }
addattr8(n, 1024, IFLA_IPTUN_PROTO, proto);
if (metadata) { if (metadata) {
addattr_l(n, 1024, IFLA_IPTUN_COLLECT_METADATA, NULL, 0); addattr_l(n, 1024, IFLA_IPTUN_COLLECT_METADATA, NULL, 0);
return 0; return 0;
@ -362,9 +341,6 @@ get_failed:
addattr16(n, 1024, IFLA_IPTUN_ENCAP_SPORT, htons(encapsport)); addattr16(n, 1024, IFLA_IPTUN_ENCAP_SPORT, htons(encapsport));
addattr16(n, 1024, IFLA_IPTUN_ENCAP_DPORT, htons(encapdport)); addattr16(n, 1024, IFLA_IPTUN_ENCAP_DPORT, htons(encapdport));
if (strcmp(lu->id, "ipip") == 0 || strcmp(lu->id, "sit") == 0)
addattr8(n, 1024, IFLA_IPTUN_PROTO, proto);
if (strcmp(lu->id, "sit") == 0) { if (strcmp(lu->id, "sit") == 0) {
addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags); addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags);
if (ip6rdprefixlen) { if (ip6rdprefixlen) {
@ -396,6 +372,23 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[
if (tb[IFLA_IPTUN_COLLECT_METADATA]) if (tb[IFLA_IPTUN_COLLECT_METADATA])
print_bool(PRINT_ANY, "external", "external ", true); print_bool(PRINT_ANY, "external", "external ", true);
if (tb[IFLA_IPTUN_PROTO]) {
switch (rta_getattr_u8(tb[IFLA_IPTUN_PROTO])) {
case IPPROTO_IPIP:
print_string(PRINT_ANY, "proto", "%s ", "ipip");
break;
case IPPROTO_IPV6:
print_string(PRINT_ANY, "proto", "%s ", "ip6ip");
break;
case IPPROTO_MPLS:
print_string(PRINT_ANY, "proto", "%s ", "mplsip");
break;
case 0:
print_string(PRINT_ANY, "proto", "%s ", "any");
break;
}
}
if (tb[IFLA_IPTUN_REMOTE]) { if (tb[IFLA_IPTUN_REMOTE]) {
unsigned int addr = rta_getattr_u32(tb[IFLA_IPTUN_REMOTE]); unsigned int addr = rta_getattr_u32(tb[IFLA_IPTUN_REMOTE]);
@ -505,6 +498,7 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[
__u16 sport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_SPORT]); __u16 sport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_SPORT]);
__u16 dport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_DPORT]); __u16 dport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_DPORT]);
open_json_object("encap");
print_string(PRINT_FP, NULL, "encap ", NULL); print_string(PRINT_FP, NULL, "encap ", NULL);
switch (type) { switch (type) {
case TUNNEL_ENCAP_FOU: case TUNNEL_ENCAP_FOU:

View File

@ -36,7 +36,7 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
char *link = NULL; char *link = NULL;
char *type = NULL; char *type = NULL;
int index = 0; int index = 0;
int err, len; int err;
struct rtattr *data; struct rtattr *data;
int group; int group;
struct ifinfomsg *ifm, *peer_ifm; struct ifinfomsg *ifm, *peer_ifm;
@ -63,11 +63,12 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
if (err < 0) if (err < 0)
return err; return err;
if (type)
duparg("type", argv[err]);
if (name) { if (name) {
len = strlen(name) + 1; addattr_l(hdr, 1024,
if (len > IFNAMSIZ) IFLA_IFNAME, name, strlen(name) + 1);
invarg("\"name\" too long\n", *argv);
addattr_l(hdr, 1024, IFLA_IFNAME, name, len);
} }
peer_ifm = RTA_DATA(data); peer_ifm = RTA_DATA(data);

View File

@ -60,12 +60,12 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
.i.ifi_family = preferred_family, .i.ifi_family = preferred_family,
.i.ifi_index = ifi->ifi_index, .i.ifi_index = ifi->ifi_index,
}; };
struct nlmsghdr *answer = NULL; struct nlmsghdr *answer;
struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
unsigned int ikey = 0; __be32 ikey = 0;
unsigned int okey = 0; __be32 okey = 0;
unsigned int saddr = 0; unsigned int saddr = 0;
unsigned int daddr = 0; unsigned int daddr = 0;
unsigned int link = 0; unsigned int link = 0;
@ -77,7 +77,6 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
get_failed: get_failed:
fprintf(stderr, fprintf(stderr,
"Failed to get existing tunnel info.\n"); "Failed to get existing tunnel info.\n");
free(answer);
return -1; return -1;
} }
@ -122,65 +121,20 @@ get_failed:
while (argc > 0) { while (argc > 0) {
if (!matches(*argv, "key")) { if (!matches(*argv, "key")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
if (strchr(*argv, '.')) ikey = okey = tnl_parse_key("key", *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;
} else if (!matches(*argv, "ikey")) { } else if (!matches(*argv, "ikey")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
if (strchr(*argv, '.')) ikey = tnl_parse_key("ikey", *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;
} else if (!matches(*argv, "okey")) { } else if (!matches(*argv, "okey")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
if (strchr(*argv, '.')) okey = tnl_parse_key("okey", *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;
} else if (!matches(*argv, "remote")) { } else if (!matches(*argv, "remote")) {
NEXT_ARG(); NEXT_ARG();
if (!strcmp(*argv, "any")) { daddr = get_addr32(*argv);
fprintf(stderr, "invalid value for \"remote\": \"%s\"\n", *argv);
exit(-1);
} else {
daddr = get_addr32(*argv);
}
} else if (!matches(*argv, "local")) { } else if (!matches(*argv, "local")) {
NEXT_ARG(); NEXT_ARG();
if (!strcmp(*argv, "any")) { saddr = get_addr32(*argv);
fprintf(stderr, "invalid value for \"local\": \"%s\"\n", *argv);
exit(-1);
} else {
saddr = get_addr32(*argv);
}
} else if (!matches(*argv, "dev")) { } else if (!matches(*argv, "dev")) {
NEXT_ARG(); NEXT_ARG();
link = if_nametoindex(*argv); link = if_nametoindex(*argv);

View File

@ -55,14 +55,14 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
.i.ifi_family = preferred_family, .i.ifi_family = preferred_family,
.i.ifi_index = ifi->ifi_index, .i.ifi_index = ifi->ifi_index,
}; };
struct nlmsghdr *answer = NULL; struct nlmsghdr *answer;
struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1];
struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; struct rtattr *vtiinfo[IFLA_VTI_MAX + 1];
struct in6_addr saddr = IN6ADDR_ANY_INIT; struct in6_addr saddr = IN6ADDR_ANY_INIT;
struct in6_addr daddr = IN6ADDR_ANY_INIT; struct in6_addr daddr = IN6ADDR_ANY_INIT;
unsigned int ikey = 0; __be32 ikey = 0;
unsigned int okey = 0; __be32 okey = 0;
unsigned int link = 0; unsigned int link = 0;
__u32 fwmark = 0; __u32 fwmark = 0;
int len; int len;
@ -72,7 +72,6 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
get_failed: get_failed:
fprintf(stderr, fprintf(stderr,
"Failed to get existing tunnel info.\n"); "Failed to get existing tunnel info.\n");
free(answer);
return -1; return -1;
} }
@ -117,71 +116,26 @@ get_failed:
while (argc > 0) { while (argc > 0) {
if (!matches(*argv, "key")) { if (!matches(*argv, "key")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
if (strchr(*argv, '.')) ikey = okey = tnl_parse_key("key", *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;
} else if (!matches(*argv, "ikey")) { } else if (!matches(*argv, "ikey")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
if (strchr(*argv, '.')) ikey = tnl_parse_key("ikey", *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;
} else if (!matches(*argv, "okey")) { } else if (!matches(*argv, "okey")) {
unsigned int uval;
NEXT_ARG(); NEXT_ARG();
if (strchr(*argv, '.')) okey = tnl_parse_key("okey", *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;
} else if (!matches(*argv, "remote")) { } else if (!matches(*argv, "remote")) {
NEXT_ARG(); inet_prefix addr;
if (!strcmp(*argv, "any")) {
fprintf(stderr, "invalid value for \"remote\": \"%s\"\n", *argv);
exit(-1);
} else {
inet_prefix addr;
get_prefix(&addr, *argv, AF_INET6); NEXT_ARG();
memcpy(&daddr, addr.data, addr.bytelen); get_addr(&addr, *argv, AF_INET6);
} memcpy(&daddr, addr.data, sizeof(daddr));
} else if (!matches(*argv, "local")) { } else if (!matches(*argv, "local")) {
NEXT_ARG(); inet_prefix addr;
if (!strcmp(*argv, "any")) {
fprintf(stderr, "invalid value for \"local\": \"%s\"\n", *argv);
exit(-1);
} else {
inet_prefix addr;
get_prefix(&addr, *argv, AF_INET6); NEXT_ARG();
memcpy(&saddr, addr.data, addr.bytelen); get_addr(&addr, *argv, AF_INET6);
} memcpy(&saddr, addr.data, sizeof(saddr));
} else if (!matches(*argv, "dev")) { } else if (!matches(*argv, "dev")) {
NEXT_ARG(); NEXT_ARG();
link = if_nametoindex(*argv); link = if_nametoindex(*argv);
@ -199,10 +153,8 @@ get_failed:
addattr32(n, 1024, IFLA_VTI_IKEY, ikey); addattr32(n, 1024, IFLA_VTI_IKEY, ikey);
addattr32(n, 1024, IFLA_VTI_OKEY, okey); addattr32(n, 1024, IFLA_VTI_OKEY, okey);
if (memcmp(&saddr, &in6addr_any, sizeof(in6addr_any))) addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr));
addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr)); addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr));
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); addattr32(n, 1024, IFLA_VTI_FWMARK, fwmark);
if (link) if (link)
addattr32(n, 1024, IFLA_VTI_LINK, link); addattr32(n, 1024, IFLA_VTI_LINK, link);

View File

@ -192,8 +192,9 @@ __be32 tnl_parse_key(const char *name, const char *key)
return get_addr32(key); return get_addr32(key);
if (get_unsigned(&uval, key, 0) < 0) { if (get_unsigned(&uval, key, 0) < 0) {
fprintf(stderr, "invalid value for \"%s\": \"%s\";", name, key); fprintf(stderr,
fprintf(stderr, " it should be an unsigned integer\n"); "invalid value for \"%s\": \"%s\"; it should be an unsigned integer\n",
name, key);
exit(-1); exit(-1);
} }
return htonl(uval); return htonl(uval);

View File

@ -36,7 +36,8 @@ const char *ll_addr_n2a(const unsigned char *addr, int alen, int type, char *buf
(type == ARPHRD_TUNNEL || type == ARPHRD_SIT || type == ARPHRD_IPGRE)) { (type == ARPHRD_TUNNEL || type == ARPHRD_SIT || type == ARPHRD_IPGRE)) {
return inet_ntop(AF_INET, addr, buf, blen); return inet_ntop(AF_INET, addr, buf, blen);
} }
if (alen == 16 && type == ARPHRD_TUNNEL6) { if (alen == 16 &&
(type == ARPHRD_TUNNEL6 || type == ARPHRD_IP6GRE)) {
return inet_ntop(AF_INET6, addr, buf, blen); return inet_ntop(AF_INET6, addr, buf, blen);
} }
snprintf(buf, blen, "%02x", addr[0]); snprintf(buf, blen, "%02x", addr[0]);

View File

@ -658,6 +658,7 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family)
dst->family = family; dst->family = family;
dst->bytelen = 0; dst->bytelen = 0;
dst->bitlen = 0; dst->bitlen = 0;
dst->flags |= PREFIXLEN_SPECIFIED;
return 0; return 0;
} }
@ -1206,10 +1207,16 @@ ssize_t getcmdline(char **linep, size_t *lenp, FILE *in)
int makeargs(char *line, char *argv[], int maxargs) int makeargs(char *line, char *argv[], int maxargs)
{ {
static const char ws[] = " \t\r\n"; static const char ws[] = " \t\r\n";
char *cp; char *cp = line;
int argc = 0; int argc = 0;
for (cp = line + strspn(line, ws); *cp; cp += strspn(cp, ws)) { while (*cp) {
/* skip leading whitespace */
cp += strspn(cp, ws);
if (*cp == '\0')
break;
if (argc >= (maxargs - 1)) { if (argc >= (maxargs - 1)) {
fprintf(stderr, "Too many arguments to command\n"); fprintf(stderr, "Too many arguments to command\n");
exit(1); exit(1);
@ -1226,13 +1233,16 @@ int makeargs(char *line, char *argv[], int maxargs)
fprintf(stderr, "Unterminated quoted string\n"); fprintf(stderr, "Unterminated quoted string\n");
exit(1); exit(1);
} }
*cp++ = 0; } else {
continue; argv[argc++] = cp;
/* find end of word */
cp += strcspn(cp, ws);
if (*cp == '\0')
break;
} }
argv[argc++] = cp; /* seperate words */
/* find end of word */
cp += strcspn(cp, ws);
*cp++ = 0; *cp++ = 0;
} }
argv[argc] = NULL; argv[argc] = NULL;

View File

@ -227,7 +227,7 @@ This command is used to browse shared buffer occupancy values. Values are showed
current_value/max_value current_value/max_value
.in -16 .in -16
Note that before showing values, one has to issue Note that before showing values, one has to issue
.b occupancy snapshot .B occupancy snapshot
command first. command first.
.PP .PP

View File

@ -190,6 +190,7 @@ Each address may be tagged with a label string.
In order to preserve compatibility with Linux-2.0 net aliases, In order to preserve compatibility with Linux-2.0 net aliases,
this string must coincide with the name of the device or must be prefixed this string must coincide with the name of the device or must be prefixed
with the device name followed by colon. with the device name followed by colon.
The maximum allowed total length of label is 15 characters.
.TP .TP
.BI scope " SCOPE_VALUE" .BI scope " SCOPE_VALUE"

View File

@ -199,6 +199,7 @@ ip-link \- network device configuration
.BR macvlan " | " .BR macvlan " | "
.BR macvtap " | " .BR macvtap " | "
.BR vcan " | " .BR vcan " | "
.BR vxcan " | "
.BR veth " | " .BR veth " | "
.BR vlan " | " .BR vlan " | "
.BR vxlan " |" .BR vxlan " |"
@ -258,9 +259,6 @@ Link types:
.B bond .B bond
- Bonding device - Bonding device
.sp .sp
.B can
- Controller Area Network interface
.sp
.B dummy .B dummy
- Dummy network interface - Dummy network interface
.sp .sp
@ -282,6 +280,9 @@ Link types:
.B vcan .B vcan
- Virtual Controller Area Network interface - Virtual Controller Area Network interface
.sp .sp
.B vxcan
- Virtual Controller Area Network tunnel interface
.sp
.B veth .B veth
- Virtual ethernet interface - Virtual ethernet interface
.sp .sp
@ -668,6 +669,29 @@ keyword.
.in -8 .in -8
.TP
VETH, VXCAN Type Support
For a link of types
.I VETH/VXCAN
the following additional arguments are supported:
.BI "ip link add " DEVICE
.BR type " { " veth " | " vxcan " }"
[
.BR peer
.BI "name " NAME
]
.in +8
.sp
.BR peer
.BI "name " NAME
- specifies the virtual pair device name of the
.I VETH/VXCAN
tunnel.
.in -8
.TP .TP
GRE, IPIP, SIT Type Support GRE, IPIP, SIT Type Support
For a link of types For a link of types
@ -689,6 +713,8 @@ the following additional arguments are supported:
.I " [no]encap-remcsum " .I " [no]encap-remcsum "
] [ ] [
.I " mode " { ip6ip | ipip | mplsip | any } " .I " mode " { ip6ip | ipip | mplsip | any } "
] [
.BR external
] ]
.in +8 .in +8
@ -733,6 +759,11 @@ MPLS-Over-IPv4, "any" indicates IPv6, IPv4 or MPLS Over IPv4. Supported for
SIT where the default is "ip6ip" and IPIP where the default is "ipip". SIT where the default is "ip6ip" and IPIP where the default is "ipip".
IPv6-Over-IPv4 is not supported for IPIP. IPv6-Over-IPv4 is not supported for IPIP.
.sp
.BR external
- make this tunnel externally controlled
.RB "(e.g. " "ip route encap" ).
.in -8 .in -8
.TP .TP
@ -1339,7 +1370,7 @@ or disable
arptables hooks on the bridge. arptables hooks on the bridge.
.in-8 .in -8
.TP .TP
MACsec Type Support MACsec Type Support

View File

@ -1,6 +1,6 @@
.TH IP 8 "20 Dec 2011" "iproute2" "Linux" .TH IP 8 "20 Dec 2011" "iproute2" "Linux"
.SH NAME .SH NAME
ip \- show / manipulate routing, devices, policy routing and tunnels ip \- show / manipulate routing, network devices, interfaces and tunnels
.SH SYNOPSIS .SH SYNOPSIS
.ad l .ad l

View File

@ -254,8 +254,7 @@ Number of hash table list traversals for output traffic. Deprecated since IP
route cache removal, therefore always zero. route cache removal, therefore always zero.
.SH SEE ALSO .SH SEE ALSO
.BR ip (8), .BR ip (8)
and /usr/share/doc/iproute-doc/README.lnstat (package iproute-doc on Debian)
.br .br
.SH AUTHOR .SH AUTHOR
lnstat was written by Harald Welte <laforge@gnumonks.org>. lnstat was written by Harald Welte <laforge@gnumonks.org>.

View File

@ -17,11 +17,6 @@ The routel script will list routes in a format that some might consider easier t
.br .br
The routef script does not take any arguments and will simply flush the routing table down the drain. Beware! This means deleting all routes which will make your network unusable! The routef script does not take any arguments and will simply flush the routing table down the drain. Beware! This means deleting all routes which will make your network unusable!
.SH "FILES"
.LP
\fI/usr/bin/routef\fP
.br
\fI/usr/bin/routel\fP
.SH "AUTHORS" .SH "AUTHORS"
.LP .LP
The routel script was written by Stephen R. van den Berg <srb@cuci.nl>, 1999/04/18 and donated to the public domain. The routel script was written by Stephen R. van den Berg <srb@cuci.nl>, 1999/04/18 and donated to the public domain.

View File

@ -184,6 +184,10 @@ max segment size
congestion window size congestion window size
.P .P
.TP .TP
.B pmtu:<pmtu>
path MTU value
.P
.TP
.B ssthresh:<ssthresh> .B ssthresh:<ssthresh>
tcp congestion window slow start threshold tcp congestion window slow start threshold
.P .P
@ -323,7 +327,7 @@ Read filter information from FILE.
Each line of FILE is interpreted like single command line option. If FILE is - stdin is used. Each line of FILE is interpreted like single command line option. If FILE is - stdin is used.
.TP .TP
.B FILTER := [ state STATE-FILTER ] [ EXPRESSION ] .B FILTER := [ state STATE-FILTER ] [ EXPRESSION ]
Please take a look at the official documentation (Debian package iproute-doc) for details regarding filters. Please take a look at the official documentation for details regarding filters.
.SH STATE-FILTER .SH STATE-FILTER
@ -378,7 +382,6 @@ Find all local processes connected to X server.
List all the tcp sockets in state FIN-WAIT-1 for our apache to network 193.233.7/24 and look at their timers. List all the tcp sockets in state FIN-WAIT-1 for our apache to network 193.233.7/24 and look at their timers.
.SH SEE ALSO .SH SEE ALSO
.BR ip (8), .BR ip (8),
.BR /usr/share/doc/iproute-doc/ss.html " (package iproute­doc)",
.br .br
.BR RFC " 793 " .BR RFC " 793 "
- https://tools.ietf.org/rfc/rfc793.txt (TCP states) - https://tools.ietf.org/rfc/rfc793.txt (TCP states)

View File

@ -29,10 +29,8 @@ u32 \- universal 32bit traffic control filter
.IR HANDLE " ] [ " .IR HANDLE " ] [ "
.B indev .B indev
.IR ifname " ] [ " .IR ifname " ] [ "
.B skip_hw .BR skip_hw " | "
.R "|" .BR skip_sw " ] [ "
.B skip_sw
.R " ] [ "
.BR help " ]" .BR help " ]"
.ti -8 .ti -8

View File

@ -790,6 +790,7 @@ struct tcpstat {
int mss; int mss;
int rcv_mss; int rcv_mss;
int advmss; int advmss;
unsigned int pmtu;
unsigned int cwnd; unsigned int cwnd;
unsigned int lastsnd; unsigned int lastsnd;
unsigned int lastrcv; unsigned int lastrcv;
@ -2360,6 +2361,8 @@ static void tcp_stats_print(struct tcpstat *s)
if (s->mss) if (s->mss)
out(" mss:%d", s->mss); out(" mss:%d", s->mss);
if (s->pmtu)
out(" pmtu:%u", s->pmtu);
if (s->rcv_mss) if (s->rcv_mss)
out(" rcvmss:%d", s->rcv_mss); out(" rcvmss:%d", s->rcv_mss);
if (s->advmss) if (s->advmss)
@ -2707,6 +2710,7 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
s.reordering = info->tcpi_reordering; s.reordering = info->tcpi_reordering;
s.rcv_ssthresh = info->tcpi_rcv_ssthresh; s.rcv_ssthresh = info->tcpi_rcv_ssthresh;
s.cwnd = info->tcpi_snd_cwnd; s.cwnd = info->tcpi_snd_cwnd;
s.pmtu = info->tcpi_pmtu;
if (info->tcpi_snd_ssthresh < 0xFFFF) if (info->tcpi_snd_ssthresh < 0xFFFF)
s.ssthresh = info->tcpi_snd_ssthresh; s.ssthresh = info->tcpi_snd_ssthresh;

View File

@ -202,15 +202,23 @@ int yylex(void)
argc++; argc++;
} else if (yy_fp) { } else if (yy_fp) {
while (tokptr == NULL) { while (tokptr == NULL) {
if (fgets(argbuf, sizeof(argbuf)-1, yy_fp) == NULL) size_t len;
if (fgets(argbuf, sizeof(argbuf), yy_fp) == NULL)
return 0; return 0;
argbuf[sizeof(argbuf)-1] = 0;
if (strlen(argbuf) == sizeof(argbuf) - 1) { len = strnlen(argbuf, sizeof(argbuf));
fprintf(stderr, "Too long line in filter"); if (len == 0) {
fprintf(stderr, "Invalid line\n");
exit(-1); exit(-1);
} }
if (argbuf[strlen(argbuf)-1] == '\n')
argbuf[strlen(argbuf)-1] = 0; if (len >= sizeof(argbuf) - 1) {
fprintf(stderr, "Too long line in filter\n");
exit(-1);
}
if (argbuf[len - 1] == '\n')
argbuf[len-1] = 0;
if (argbuf[0] == '#' || argbuf[0] == '0') if (argbuf[0] == '#' || argbuf[0] == '0')
continue; continue;
tokptr = argbuf; tokptr = argbuf;

View File

@ -1,11 +1,13 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
include ../config.mk include ../config.mk
TARGETS :=
ifeq ($(HAVE_MNL),y) ifeq ($(HAVE_MNL),y)
RDMA_OBJ = rdma.o utils.o dev.o link.o RDMA_OBJ = rdma.o utils.o dev.o link.o
TARGETS=rdma TARGETS += rdma
endif endif
all: $(TARGETS) $(LIBS) all: $(TARGETS) $(LIBS)

View File

@ -266,6 +266,10 @@ int print_qdisc(const struct sockaddr_nl *who,
if (t->tcm_info != 1) if (t->tcm_info != 1)
print_uint(PRINT_ANY, "refcnt", "refcnt %u ", t->tcm_info); print_uint(PRINT_ANY, "refcnt", "refcnt %u ", t->tcm_info);
if (tb[TCA_HW_OFFLOAD] &&
(rta_getattr_u8(tb[TCA_HW_OFFLOAD])))
print_bool(PRINT_ANY, "offloaded", "offloaded ", true);
/* pfifo_fast is generic enough to warrant the hardcoding --JHS */ /* pfifo_fast is generic enough to warrant the hardcoding --JHS */
if (strcmp("pfifo_fast", RTA_DATA(tb[TCA_KIND])) == 0) if (strcmp("pfifo_fast", RTA_DATA(tb[TCA_KIND])) == 0)
q = get_qdisc_kind("prio"); q = get_qdisc_kind("prio");

View File

@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
include ../config.mk include ../config.mk
TARGETS :=
ifeq ($(HAVE_MNL),y) ifeq ($(HAVE_MNL),y)
TIPCOBJ=bearer.o \ TIPCOBJ=bearer.o \
@ -10,7 +12,7 @@ TIPCOBJ=bearer.o \
node.o socket.o \ node.o socket.o \
peer.o tipc.o peer.o tipc.o
TARGETS=tipc TARGETS += tipc
endif endif