diff --git a/devlink/Makefile b/devlink/Makefile index 3afda65e..ace34c7b 100644 --- a/devlink/Makefile +++ b/devlink/Makefile @@ -1,10 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 include ../config.mk +TARGETS := + ifeq ($(HAVE_MNL),y) DEVLINKOBJ = devlink.o mnlg.o -TARGETS=devlink +TARGETS += devlink CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags) LDLIBS += $(shell $(PKG_CONFIG) libmnl --libs) diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c index 4563e1e0..b8db49c9 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/iplink.c b/ip/iplink.c index 8768b93f..0ea5547f 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -285,11 +285,13 @@ static void iplink_parse_vf_vlan_info(int vf, int *argcp, char ***argvp, { int argc = *argcp; char **argv = *argvp; + unsigned int vci; NEXT_ARG(); - if (get_unsigned(&ivvip->vlan, *argv, 0)) + if (get_unsigned(&vci, *argv, 0) || vci > 4095) invarg("Invalid \"vlan\" value\n", *argv); + ivvip->vlan = vci; ivvip->vf = vf; ivvip->qos = 0; ivvip->vlan_proto = htons(ETH_P_8021Q); @@ -593,8 +595,10 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, *name = *argv; } else if (strcmp(*argv, "index") == 0) { NEXT_ARG(); + if (*index) + duparg("index", *argv); *index = atoi(*argv); - if (*index < 0) + if (*index <= 0) invarg("Invalid \"index\" value", *argv); } else if (matches(*argv, "link") == 0) { NEXT_ARG(); @@ -775,11 +779,12 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, argc--; argv++; break; } else if (matches(*argv, "alias") == 0) { + len = strlen(*argv); + if (len >= IFALIASZ) + invarg("alias too long\n", *argv); NEXT_ARG(); addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, - *argv, strlen(*argv)); - argc--; argv++; - break; + *argv, len); } else if (strcmp(*argv, "group") == 0) { NEXT_ARG(); if (*group != -1) @@ -913,7 +918,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) char *name = NULL; char *link = NULL; char *type = NULL; - int index = -1; + int index = 0; int group; struct link_util *lu = NULL; struct iplink_req req = { @@ -949,7 +954,6 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) return -1; } - req.i.ifi_index = 0; addattr32(&req.n, sizeof(req), IFLA_GROUP, group); if (rtnl_talk(&rth, &req.n, NULL) < 0) 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"); exit(-1); } - if (cmd == RTM_NEWLINK && index != -1) { + if (cmd == RTM_NEWLINK && index) { fprintf(stderr, "index can be used only when creating devices.\n"); 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); } - if (index == -1) - req.i.ifi_index = 0; - else - req.i.ifi_index = index; + req.i.ifi_index = index; } if (name) { diff --git a/ip/iplink_vxcan.c b/ip/iplink_vxcan.c index 680f640f..ed0ad8b9 100644 --- a/ip/iplink_vxcan.c +++ b/ip/iplink_vxcan.c @@ -38,7 +38,7 @@ static int vxcan_parse_opt(struct link_util *lu, int argc, char **argv, char *link = NULL; char *type = NULL; int index = 0; - int err, len; + int err; struct rtattr *data; int group; 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) return err; + if (type) + duparg("type", argv[err]); + if (name) { - len = strlen(name) + 1; - if (len > IFNAMSIZ) - invarg("\"name\" too long\n", *argv); - addattr_l(hdr, 1024, IFLA_IFNAME, name, len); + addattr_l(hdr, 1024, + IFLA_IFNAME, name, strlen(name) + 1); } peer_ifm = RTA_DATA(data); diff --git a/ip/iproute.c b/ip/iproute.c index 16eadab1..bf886fda 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -126,6 +126,7 @@ static struct int oif, oifmask; int mark, markmask; int realm, realmmask; + __u32 metric, metricmask; inet_prefix rprefsrc; inet_prefix rvia; inet_prefix rdst; @@ -190,20 +191,42 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) return 0; if ((filter.tos^r->rtm_tos)&filter.tosmask) return 0; - if (filter.rdst.family && - (r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len)) - return 0; - if (filter.mdst.family && - (r->rtm_family != filter.mdst.family || - (filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len))) - return 0; - if (filter.rsrc.family && - (r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len)) - return 0; - if (filter.msrc.family && - (r->rtm_family != filter.msrc.family || - (filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len))) - return 0; + if (filter.rdst.family) { + if (r->rtm_family != filter.rdst.family || + filter.rdst.bitlen > r->rtm_dst_len) + return 0; + } else if (filter.rdst.flags & PREFIXLEN_SPECIFIED) { + if (filter.rdst.bitlen > r->rtm_dst_len) + return 0; + } + if (filter.mdst.family) { + if (r->rtm_family != filter.mdst.family || + (filter.mdst.bitlen >= 0 && + filter.mdst.bitlen < r->rtm_dst_len)) + 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) { 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]) 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]) 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); } - 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; - 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)) 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; - 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)) 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) 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 && r->rtm_family == AF_INET6 && 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 ", 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])); if (r->rtm_flags & RTNH_F_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)) invarg("invalid mark value", *argv); 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) { int family; diff --git a/ip/iptunnel.c b/ip/iptunnel.c index 208a1f06..ce610f84 100644 --- a/ip/iptunnel.c +++ b/ip/iptunnel.c @@ -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); } else if (strcmp(*argv, "remote") == 0) { NEXT_ARG(); - if (strcmp(*argv, "any")) - p->iph.daddr = get_addr32(*argv); - else - p->iph.daddr = htonl(INADDR_ANY); + p->iph.daddr = get_addr32(*argv); } else if (strcmp(*argv, "local") == 0) { NEXT_ARG(); - if (strcmp(*argv, "any")) - p->iph.saddr = get_addr32(*argv); - else - p->iph.saddr = htonl(INADDR_ANY); + p->iph.saddr = get_addr32(*argv); } else if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); medium = *argv; diff --git a/ip/link_gre.c b/ip/link_gre.c index 65ad8bad..52c581d2 100644 --- a/ip/link_gre.c +++ b/ip/link_gre.c @@ -43,6 +43,7 @@ static void print_usage(FILE *f) " [ [no]encap-csum ]\n" " [ [no]encap-csum6 ]\n" " [ [no]encap-remcsum ]\n" + " [ external ]\n" " [ fwmark MARK ]\n" " [ erspan_ver version ]\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_index = ifi->ifi_index, }; - struct nlmsghdr *answer = NULL; + struct nlmsghdr *answer; struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *greinfo[IFLA_GRE_MAX + 1]; __u16 iflags = 0; __u16 oflags = 0; - unsigned int ikey = 0; - unsigned int okey = 0; + __be32 ikey = 0; + __be32 okey = 0; unsigned int saddr = 0; unsigned int daddr = 0; unsigned int link = 0; @@ -111,7 +112,6 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); - free(answer); return -1; } @@ -162,7 +162,7 @@ get_failed: tos = rta_getattr_u8(greinfo[IFLA_GRE_TOS]); 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]) encaptype = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_TYPE]); @@ -200,53 +200,18 @@ get_failed: while (argc > 0) { if (!matches(*argv, "key")) { - unsigned int uval; - NEXT_ARG(); iflags |= GRE_KEY; oflags |= GRE_KEY; - if (strchr(*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; + ikey = okey = tnl_parse_key("key", *argv); } else if (!matches(*argv, "ikey")) { - unsigned int uval; - NEXT_ARG(); iflags |= GRE_KEY; - if (strchr(*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; + ikey = tnl_parse_key("ikey", *argv); } else if (!matches(*argv, "okey")) { - unsigned int uval; - NEXT_ARG(); oflags |= GRE_KEY; - if (strchr(*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; + okey = tnl_parse_key("okey", *argv); } else if (!matches(*argv, "seq")) { iflags |= GRE_SEQ; oflags |= GRE_SEQ; @@ -267,12 +232,10 @@ get_failed: pmtudisc = 1; } else if (!matches(*argv, "remote")) { NEXT_ARG(); - if (strcmp(*argv, "any")) - daddr = get_addr32(*argv); + daddr = get_addr32(*argv); } else if (!matches(*argv, "local")) { NEXT_ARG(); - if (strcmp(*argv, "any")) - saddr = get_addr32(*argv); + saddr = get_addr32(*argv); } else if (!matches(*argv, "dev")) { NEXT_ARG(); link = if_nametoindex(*argv); @@ -335,11 +298,11 @@ get_failed: } else if (strcmp(*argv, "encap-udp6-csum") == 0) { encapflags |= TUNNEL_ENCAP_FLAG_CSUM6; } 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) { encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; } else if (strcmp(*argv, "noencap-remcsum") == 0) { - encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM; + encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM; } else if (strcmp(*argv, "external") == 0) { metadata = 1; } else if (strcmp(*argv, "ignore-df") == 0) { diff --git a/ip/link_gre6.c b/ip/link_gre6.c index cb621806..bc33026c 100644 --- a/ip/link_gre6.c +++ b/ip/link_gre6.c @@ -90,14 +90,14 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, .i.ifi_family = preferred_family, .i.ifi_index = ifi->ifi_index, }; - struct nlmsghdr *answer = NULL; + struct nlmsghdr *answer; struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *greinfo[IFLA_GRE_MAX + 1]; __u16 iflags = 0; __u16 oflags = 0; - unsigned int ikey = 0; - unsigned int okey = 0; + __be32 ikey = 0; + __be32 okey = 0; struct in6_addr raddr = IN6ADDR_ANY_INIT; struct in6_addr laddr = IN6ADDR_ANY_INIT; unsigned int link = 0; @@ -122,7 +122,6 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); - free(answer); return -1; } @@ -212,53 +211,18 @@ get_failed: while (argc > 0) { if (!matches(*argv, "key")) { - unsigned int uval; - NEXT_ARG(); iflags |= GRE_KEY; oflags |= GRE_KEY; - if (strchr(*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; + ikey = okey = tnl_parse_key("key", *argv); } else if (!matches(*argv, "ikey")) { - unsigned int uval; - NEXT_ARG(); iflags |= GRE_KEY; - if (strchr(*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; + ikey = tnl_parse_key("ikey", *argv); } else if (!matches(*argv, "okey")) { - unsigned int uval; - NEXT_ARG(); oflags |= GRE_KEY; - if (strchr(*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; + okey = tnl_parse_key("okey", *argv); } else if (!matches(*argv, "seq")) { iflags |= GRE_SEQ; oflags |= GRE_SEQ; @@ -277,17 +241,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(); @@ -311,12 +271,12 @@ get_failed: __u8 uval; NEXT_ARG(); + flowinfo &= ~IP6_FLOWINFO_TCLASS; if (strcmp(*argv, "inherit") == 0) flags |= IP6_TNL_F_USE_ORIG_TCLASS; else { if (get_u8(&uval, *argv, 16)) invarg("invalid TClass", *argv); - flowinfo &= ~IP6_FLOWINFO_TCLASS; flowinfo |= htonl((__u32)uval << 20) & IP6_FLOWINFO_TCLASS; flags &= ~IP6_TNL_F_USE_ORIG_TCLASS; } @@ -325,6 +285,7 @@ get_failed: __u32 uval; NEXT_ARG(); + flowinfo &= ~IP6_FLOWINFO_FLOWLABEL; if (strcmp(*argv, "inherit") == 0) flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL; else { @@ -332,7 +293,6 @@ get_failed: invarg("invalid Flowlabel", *argv); if (uval > 0xFFFFF) invarg("invalid Flowlabel", *argv); - flowinfo &= ~IP6_FLOWINFO_FLOWLABEL; flowinfo |= htonl(uval) & IP6_FLOWINFO_FLOWLABEL; flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL; } diff --git a/ip/link_ip6tnl.c b/ip/link_ip6tnl.c index af796c30..84205b12 100644 --- a/ip/link_ip6tnl.c +++ b/ip/link_ip6tnl.c @@ -83,13 +83,13 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv, .i.ifi_family = preferred_family, .i.ifi_index = ifi->ifi_index, }; - struct nlmsghdr *answer = NULL; + struct nlmsghdr *answer; struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *iptuninfo[IFLA_IPTUN_MAX + 1]; int len; - struct in6_addr laddr = {}; - struct in6_addr raddr = {}; + struct in6_addr laddr = IN6ADDR_ANY_INIT; + struct in6_addr raddr = IN6ADDR_ANY_INIT; __u8 hop_limit = DEFAULT_TNL_HOP_LIMIT; __u8 encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT; __u32 flowinfo = 0; @@ -108,7 +108,6 @@ static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); - free(answer); return -1; } @@ -184,18 +183,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); @@ -306,7 +301,7 @@ get_failed: } else if (strcmp(*argv, "encap-remcsum") == 0) { encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; } else if (strcmp(*argv, "noencap-remcsum") == 0) { - encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM; + encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM; } else if (strcmp(*argv, "external") == 0) { metadata = 1; } else diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c index 2804b8f4..24a0f0cd 100644 --- a/ip/link_iptnl.c +++ b/ip/link_iptnl.c @@ -83,7 +83,7 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv, .i.ifi_family = preferred_family, .i.ifi_index = ifi->ifi_index, }; - struct nlmsghdr *answer = NULL; + struct nlmsghdr *answer; struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_INFO_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: fprintf(stderr, "Failed to get existing tunnel info.\n"); - free(answer); return -1; } @@ -195,16 +194,10 @@ get_failed: while (argc > 0) { if (strcmp(*argv, "remote") == 0) { NEXT_ARG(); - if (strcmp(*argv, "any")) - raddr = get_addr32(*argv); - else - raddr = 0; + raddr = get_addr32(*argv); } else if (strcmp(*argv, "local") == 0) { NEXT_ARG(); - if (strcmp(*argv, "any")) - laddr = get_addr32(*argv); - else - laddr = 0; + laddr = get_addr32(*argv); } else if (matches(*argv, "dev") == 0) { NEXT_ARG(); link = if_nametoindex(*argv); @@ -237,11 +230,11 @@ get_failed: } else if (strcmp(lu->id, "sit") == 0 && strcmp(*argv, "isatap") == 0) { iflags |= SIT_ISATAP; - } else if (strcmp(lu->id, "sit") == 0 && - strcmp(*argv, "mode") == 0) { + } else if (strcmp(*argv, "mode") == 0) { NEXT_ARG(); - if (strcmp(*argv, "ipv6/ipv4") == 0 || - strcmp(*argv, "ip6ip") == 0) + if (strcmp(lu->id, "sit") == 0 && + (strcmp(*argv, "ipv6/ipv4") == 0 || + strcmp(*argv, "ip6ip") == 0)) proto = IPPROTO_IPV6; else if (strcmp(*argv, "ipv4/ipv4") == 0 || strcmp(*argv, "ipip") == 0 || @@ -255,21 +248,6 @@ get_failed: proto = 0; else 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) { encaptype = TUNNEL_ENCAP_NONE; } else if (strcmp(*argv, "encap") == 0) { @@ -344,6 +322,7 @@ get_failed: exit(-1); } + addattr8(n, 1024, IFLA_IPTUN_PROTO, proto); if (metadata) { addattr_l(n, 1024, IFLA_IPTUN_COLLECT_METADATA, NULL, 0); return 0; @@ -362,9 +341,6 @@ get_failed: addattr16(n, 1024, IFLA_IPTUN_ENCAP_SPORT, htons(encapsport)); 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) { addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags); 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]) 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]) { 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 dport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_DPORT]); + open_json_object("encap"); print_string(PRINT_FP, NULL, "encap ", NULL); switch (type) { case TUNNEL_ENCAP_FOU: diff --git a/ip/link_veth.c b/ip/link_veth.c index a3688274..fddb7ac3 100644 --- a/ip/link_veth.c +++ b/ip/link_veth.c @@ -36,7 +36,7 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv, char *link = NULL; char *type = NULL; int index = 0; - int err, len; + int err; struct rtattr *data; int group; 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) return err; + if (type) + duparg("type", argv[err]); + if (name) { - len = strlen(name) + 1; - if (len > IFNAMSIZ) - invarg("\"name\" too long\n", *argv); - addattr_l(hdr, 1024, IFLA_IFNAME, name, len); + addattr_l(hdr, 1024, + IFLA_IFNAME, name, strlen(name) + 1); } peer_ifm = RTA_DATA(data); diff --git a/ip/link_vti.c b/ip/link_vti.c index 07ac94e7..2b0fab27 100644 --- a/ip/link_vti.c +++ b/ip/link_vti.c @@ -60,12 +60,12 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv, .i.ifi_family = preferred_family, .i.ifi_index = ifi->ifi_index, }; - struct nlmsghdr *answer = NULL; + struct nlmsghdr *answer; struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_INFO_MAX+1]; struct rtattr *vtiinfo[IFLA_VTI_MAX + 1]; - unsigned int ikey = 0; - unsigned int okey = 0; + __be32 ikey = 0; + __be32 okey = 0; unsigned int saddr = 0; unsigned int daddr = 0; unsigned int link = 0; @@ -77,7 +77,6 @@ static int vti_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); - free(answer); return -1; } @@ -122,65 +121,20 @@ get_failed: while (argc > 0) { if (!matches(*argv, "key")) { - unsigned int uval; - NEXT_ARG(); - if (strchr(*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; + ikey = okey = tnl_parse_key("key", *argv); } else if (!matches(*argv, "ikey")) { - unsigned int uval; - NEXT_ARG(); - if (strchr(*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; + ikey = tnl_parse_key("ikey", *argv); } else if (!matches(*argv, "okey")) { - unsigned int uval; - NEXT_ARG(); - if (strchr(*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; + okey = tnl_parse_key("okey", *argv); } else if (!matches(*argv, "remote")) { NEXT_ARG(); - if (!strcmp(*argv, "any")) { - fprintf(stderr, "invalid value for \"remote\": \"%s\"\n", *argv); - exit(-1); - } else { - daddr = get_addr32(*argv); - } + daddr = get_addr32(*argv); } else if (!matches(*argv, "local")) { NEXT_ARG(); - if (!strcmp(*argv, "any")) { - fprintf(stderr, "invalid value for \"local\": \"%s\"\n", *argv); - exit(-1); - } else { - saddr = get_addr32(*argv); - } + saddr = get_addr32(*argv); } else if (!matches(*argv, "dev")) { NEXT_ARG(); link = if_nametoindex(*argv); diff --git a/ip/link_vti6.c b/ip/link_vti6.c index 6d08bfe0..74c246d3 100644 --- a/ip/link_vti6.c +++ b/ip/link_vti6.c @@ -55,14 +55,14 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, .i.ifi_family = preferred_family, .i.ifi_index = ifi->ifi_index, }; - struct nlmsghdr *answer = NULL; + struct nlmsghdr *answer; 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; - unsigned int ikey = 0; - unsigned int okey = 0; + __be32 ikey = 0; + __be32 okey = 0; unsigned int link = 0; __u32 fwmark = 0; int len; @@ -72,7 +72,6 @@ static int vti6_parse_opt(struct link_util *lu, int argc, char **argv, get_failed: fprintf(stderr, "Failed to get existing tunnel info.\n"); - free(answer); return -1; } @@ -117,71 +116,26 @@ get_failed: while (argc > 0) { if (!matches(*argv, "key")) { - unsigned int uval; - NEXT_ARG(); - if (strchr(*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; + ikey = okey = tnl_parse_key("key", *argv); } else if (!matches(*argv, "ikey")) { - unsigned int uval; - NEXT_ARG(); - if (strchr(*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; + ikey = tnl_parse_key("ikey", *argv); } else if (!matches(*argv, "okey")) { - unsigned int uval; - NEXT_ARG(); - if (strchr(*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; + okey = tnl_parse_key("okey", *argv); } else if (!matches(*argv, "remote")) { - NEXT_ARG(); - if (!strcmp(*argv, "any")) { - fprintf(stderr, "invalid value for \"remote\": \"%s\"\n", *argv); - exit(-1); - } else { - inet_prefix addr; + inet_prefix addr; - get_prefix(&addr, *argv, AF_INET6); - memcpy(&daddr, addr.data, addr.bytelen); - } + NEXT_ARG(); + get_addr(&addr, *argv, AF_INET6); + memcpy(&daddr, addr.data, sizeof(daddr)); } else if (!matches(*argv, "local")) { - NEXT_ARG(); - if (!strcmp(*argv, "any")) { - fprintf(stderr, "invalid value for \"local\": \"%s\"\n", *argv); - exit(-1); - } else { - inet_prefix addr; + inet_prefix addr; - get_prefix(&addr, *argv, AF_INET6); - memcpy(&saddr, addr.data, addr.bytelen); - } + NEXT_ARG(); + get_addr(&addr, *argv, AF_INET6); + memcpy(&saddr, addr.data, sizeof(saddr)); } else if (!matches(*argv, "dev")) { NEXT_ARG(); link = if_nametoindex(*argv); @@ -199,10 +153,8 @@ get_failed: addattr32(n, 1024, IFLA_VTI_IKEY, ikey); 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)); - if (memcmp(&daddr, &in6addr_any, sizeof(in6addr_any))) - addattr_l(n, 1024, IFLA_VTI_REMOTE, &daddr, sizeof(daddr)); + addattr_l(n, 1024, IFLA_VTI_LOCAL, &saddr, sizeof(saddr)); + 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); diff --git a/ip/tunnel.c b/ip/tunnel.c index d359eb95..f8601038 100644 --- a/ip/tunnel.c +++ b/ip/tunnel.c @@ -192,8 +192,9 @@ __be32 tnl_parse_key(const char *name, const char *key) return get_addr32(key); if (get_unsigned(&uval, key, 0) < 0) { - fprintf(stderr, "invalid value for \"%s\": \"%s\";", name, key); - fprintf(stderr, " it should be an unsigned integer\n"); + fprintf(stderr, + "invalid value for \"%s\": \"%s\"; it should be an unsigned integer\n", + name, key); exit(-1); } return htonl(uval); diff --git a/lib/ll_addr.c b/lib/ll_addr.c index c03523d5..84de64e2 100644 --- a/lib/ll_addr.c +++ b/lib/ll_addr.c @@ -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)) { 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); } snprintf(buf, blen, "%02x", addr[0]); diff --git a/lib/utils.c b/lib/utils.c index 7ced8c06..9fa52204 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -658,6 +658,7 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family) dst->family = family; dst->bytelen = 0; dst->bitlen = 0; + dst->flags |= PREFIXLEN_SPECIFIED; return 0; } @@ -1206,10 +1207,16 @@ ssize_t getcmdline(char **linep, size_t *lenp, FILE *in) int makeargs(char *line, char *argv[], int maxargs) { static const char ws[] = " \t\r\n"; - char *cp; + char *cp = line; 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)) { fprintf(stderr, "Too many arguments to command\n"); exit(1); @@ -1226,13 +1233,16 @@ int makeargs(char *line, char *argv[], int maxargs) fprintf(stderr, "Unterminated quoted string\n"); exit(1); } - *cp++ = 0; - continue; + } else { + argv[argc++] = cp; + + /* find end of word */ + cp += strcspn(cp, ws); + if (*cp == '\0') + break; } - argv[argc++] = cp; - /* find end of word */ - cp += strcspn(cp, ws); + /* seperate words */ *cp++ = 0; } argv[argc] = NULL; diff --git a/man/man8/devlink-sb.8 b/man/man8/devlink-sb.8 index ffb5553e..1882833a 100644 --- a/man/man8/devlink-sb.8 +++ b/man/man8/devlink-sb.8 @@ -227,7 +227,7 @@ This command is used to browse shared buffer occupancy values. Values are showed current_value/max_value .in -16 Note that before showing values, one has to issue -.b occupancy snapshot +.B occupancy snapshot command first. .PP diff --git a/man/man8/ip-address.8.in b/man/man8/ip-address.8.in index eaa179c6..7ebf0bc9 100644 --- a/man/man8/ip-address.8.in +++ b/man/man8/ip-address.8.in @@ -190,6 +190,7 @@ Each address may be tagged with a label string. 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 with the device name followed by colon. +The maximum allowed total length of label is 15 characters. .TP .BI scope " SCOPE_VALUE" diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index fc6694c0..1d1f0363 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -199,6 +199,7 @@ ip-link \- network device configuration .BR macvlan " | " .BR macvtap " | " .BR vcan " | " +.BR vxcan " | " .BR veth " | " .BR vlan " | " .BR vxlan " |" @@ -258,9 +259,6 @@ Link types: .B bond - Bonding device .sp -.B can -- Controller Area Network interface -.sp .B dummy - Dummy network interface .sp @@ -282,6 +280,9 @@ Link types: .B vcan - Virtual Controller Area Network interface .sp +.B vxcan +- Virtual Controller Area Network tunnel interface +.sp .B veth - Virtual ethernet interface .sp @@ -668,6 +669,29 @@ keyword. .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 GRE, IPIP, SIT Type Support For a link of types @@ -689,6 +713,8 @@ the following additional arguments are supported: .I " [no]encap-remcsum " ] [ .I " mode " { ip6ip | ipip | mplsip | any } " +] [ +.BR external ] .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". IPv6-Over-IPv4 is not supported for IPIP. +.sp +.BR external +- make this tunnel externally controlled +.RB "(e.g. " "ip route encap" ). + .in -8 .TP @@ -1339,7 +1370,7 @@ or disable arptables hooks on the bridge. -.in-8 +.in -8 .TP MACsec Type Support diff --git a/man/man8/ip.8 b/man/man8/ip.8 index ae018fdf..7f26582d 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -1,6 +1,6 @@ .TH IP 8 "20 Dec 2011" "iproute2" "Linux" .SH NAME -ip \- show / manipulate routing, devices, policy routing and tunnels +ip \- show / manipulate routing, network devices, interfaces and tunnels .SH SYNOPSIS .ad l diff --git a/man/man8/lnstat.8 b/man/man8/lnstat.8 index acd5f4a2..b98241bf 100644 --- a/man/man8/lnstat.8 +++ b/man/man8/lnstat.8 @@ -254,8 +254,7 @@ Number of hash table list traversals for output traffic. Deprecated since IP route cache removal, therefore always zero. .SH SEE ALSO -.BR ip (8), -and /usr/share/doc/iproute-doc/README.lnstat (package iproute-doc on Debian) +.BR ip (8) .br .SH AUTHOR lnstat was written by Harald Welte . diff --git a/man/man8/routel.8 b/man/man8/routel.8 index 82d580fb..2270eacb 100644 --- a/man/man8/routel.8 +++ b/man/man8/routel.8 @@ -17,11 +17,6 @@ The routel script will list routes in a format that some might consider easier t .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! -.SH "FILES" -.LP -\fI/usr/bin/routef\fP -.br -\fI/usr/bin/routel\fP .SH "AUTHORS" .LP The routel script was written by Stephen R. van den Berg , 1999/04/18 and donated to the public domain. diff --git a/man/man8/ss.8 b/man/man8/ss.8 index 6d06383b..973afbe0 100644 --- a/man/man8/ss.8 +++ b/man/man8/ss.8 @@ -184,6 +184,10 @@ max segment size congestion window size .P .TP +.B pmtu: +path MTU value +.P +.TP .B ssthresh: tcp congestion window slow start threshold .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. .TP .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 @@ -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. .SH SEE ALSO .BR ip (8), -.BR /usr/share/doc/iproute-doc/ss.html " (package iproute­doc)", .br .BR RFC " 793 " - https://tools.ietf.org/rfc/rfc793.txt (TCP states) diff --git a/man/man8/tc-u32.8 b/man/man8/tc-u32.8 index e9475a93..2bf2e3e9 100644 --- a/man/man8/tc-u32.8 +++ b/man/man8/tc-u32.8 @@ -29,10 +29,8 @@ u32 \- universal 32bit traffic control filter .IR HANDLE " ] [ " .B indev .IR ifname " ] [ " -.B skip_hw -.R "|" -.B skip_sw -.R " ] [ " +.BR skip_hw " | " +.BR skip_sw " ] [ " .BR help " ]" .ti -8 diff --git a/misc/ss.c b/misc/ss.c index 9d21ed7a..1abf43d0 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -790,6 +790,7 @@ struct tcpstat { int mss; int rcv_mss; int advmss; + unsigned int pmtu; unsigned int cwnd; unsigned int lastsnd; unsigned int lastrcv; @@ -2360,6 +2361,8 @@ static void tcp_stats_print(struct tcpstat *s) if (s->mss) out(" mss:%d", s->mss); + if (s->pmtu) + out(" pmtu:%u", s->pmtu); if (s->rcv_mss) out(" rcvmss:%d", s->rcv_mss); 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.rcv_ssthresh = info->tcpi_rcv_ssthresh; s.cwnd = info->tcpi_snd_cwnd; + s.pmtu = info->tcpi_pmtu; if (info->tcpi_snd_ssthresh < 0xFFFF) s.ssthresh = info->tcpi_snd_ssthresh; diff --git a/misc/ssfilter.y b/misc/ssfilter.y index ba82b65f..4db3c95f 100644 --- a/misc/ssfilter.y +++ b/misc/ssfilter.y @@ -202,15 +202,23 @@ int yylex(void) argc++; } else if (yy_fp) { 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; - argbuf[sizeof(argbuf)-1] = 0; - if (strlen(argbuf) == sizeof(argbuf) - 1) { - fprintf(stderr, "Too long line in filter"); + + len = strnlen(argbuf, sizeof(argbuf)); + if (len == 0) { + fprintf(stderr, "Invalid line\n"); 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') continue; tokptr = argbuf; diff --git a/rdma/Makefile b/rdma/Makefile index c8966bfd..454f25f8 100644 --- a/rdma/Makefile +++ b/rdma/Makefile @@ -1,11 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 include ../config.mk +TARGETS := + ifeq ($(HAVE_MNL),y) RDMA_OBJ = rdma.o utils.o dev.o link.o -TARGETS=rdma +TARGETS += rdma endif all: $(TARGETS) $(LIBS) diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c index 4431d5fd..70279b9d 100644 --- a/tc/tc_qdisc.c +++ b/tc/tc_qdisc.c @@ -266,6 +266,10 @@ int print_qdisc(const struct sockaddr_nl *who, if (t->tcm_info != 1) 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 */ if (strcmp("pfifo_fast", RTA_DATA(tb[TCA_KIND])) == 0) q = get_qdisc_kind("prio"); diff --git a/tipc/Makefile b/tipc/Makefile index abd33ab0..fdb18d39 100644 --- a/tipc/Makefile +++ b/tipc/Makefile @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 include ../config.mk +TARGETS := + ifeq ($(HAVE_MNL),y) TIPCOBJ=bearer.o \ @@ -10,7 +12,7 @@ TIPCOBJ=bearer.o \ node.o socket.o \ peer.o tipc.o -TARGETS=tipc +TARGETS += tipc endif