]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
Merge branch 'master' into net-next
authorDavid Ahern <dsahern@gmail.com>
Mon, 8 Jan 2018 18:10:45 +0000 (10:10 -0800)
committerDavid Ahern <dsahern@gmail.com>
Mon, 8 Jan 2018 18:10:45 +0000 (10:10 -0800)
 Conflicts:
man/man8/ip-link.8.in

Signed-off-by: David Ahern <dsahern@gmail.com>
29 files changed:
devlink/Makefile
ip/ip6tunnel.c
ip/iplink.c
ip/iplink_vxcan.c
ip/iproute.c
ip/iptunnel.c
ip/link_gre.c
ip/link_gre6.c
ip/link_ip6tnl.c
ip/link_iptnl.c
ip/link_veth.c
ip/link_vti.c
ip/link_vti6.c
ip/tunnel.c
lib/ll_addr.c
lib/utils.c
man/man8/devlink-sb.8
man/man8/ip-address.8.in
man/man8/ip-link.8.in
man/man8/ip.8
man/man8/lnstat.8
man/man8/routel.8
man/man8/ss.8
man/man8/tc-u32.8
misc/ss.c
misc/ssfilter.y
rdma/Makefile
tc/tc_qdisc.c
tipc/Makefile

index 3afda65e6635dbf9b53d3f24e2933f9efdc298a9..ace34c7b0d600a520f65d59a696283019e25fef8 100644 (file)
@@ -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)
index 4563e1e0f73b1ed4bd1766dcbfbac96b5b2f1b70..b8db49c979abc8ed9f9277a40ba87ff2589b163f 100644 (file)
@@ -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();
index 8768b93f8f74973124f82de465bd95b084086347..0ea5547f48c58071022fb1bf39f0e2a63c57346d 100644 (file)
@@ -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) {
index 680f640f4ed83175796290703d65cea3aa6b47ab..ed0ad8b98ce87d1b0f8635c0909db02662634b67 100644 (file)
@@ -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);
index 16eadab131a7e981c3040d6e97bd562f920f466b..bf886fda9d761cbb86fe740aadf0d08106854dd5 100644 (file)
@@ -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;
 
index 208a1f06ab12f06c56bc2db8cd7a85b4f607b851..ce610f8494dae6318c7f28fe9b870398ba04d435 100644 (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);
                } 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;
index 65ad8bad4b825642706cf5d58c601cece81ecc41..52c581d224ac582ae7231340bd09af5a85d52324 100644 (file)
@@ -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) {
index cb621806261c7dd7f7b9f69f397a7ce0f4f30c4c..bc33026c31d0d12f75314ab041061ad125b3a65b 100644 (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_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;
                        }
index af796c308f13023faa3e30c3fcf5abd283babe4a..84205b1204ccbfd15a7d7e85aa58f923f00a4166 100644 (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_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
index 2804b8f4625914b6ebe1ab43a0e8f8b03a16da2f..24a0f0cd3841a1124c07874c94916e3a0a711cec 100644 (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_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:
index a36882744ec7ca5966dd553548e54422ba63a0cd..fddb7ac3c6a5cbd62a462cb6ab57247a62dec7c4 100644 (file)
@@ -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);
index 07ac94e7dc6669b95c9e2c8f99174c6f51b99467..2b0fab27dbf46b037b3a162684ddeaee2397c23a 100644 (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_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);
index 6d08bfe0f7990f74bb466770e3b38c152de60544..74c246d3ed86bb2ef55f679d21980fe3dd24c879 100644 (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_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);
-                       }
-               } 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;
+                       get_addr(&addr, *argv, AF_INET6);
+                       memcpy(&daddr, addr.data, sizeof(daddr));
+               } else if (!matches(*argv, "local")) {
+                       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);
index d359eb958a6c6796b530eec47e4dda74c7a0baac..f860103873f7ba7b254407d38e13e9256fdaf9f9 100644 (file)
@@ -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);
index c03523d567ab0edd9b5db12541cae4ae2b5f53a1..84de64e2e05373feb9265ae243282885b3e19e8a 100644 (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)) {
                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]);
index 7ced8c061cb092474b2ba46b8298cb44c883c985..9fa522047fdcabbf3166b16bf4053534c228deb4 100644 (file)
@@ -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;
index ffb5553e3147c49be1e9af3dee8a7a0285f71c18..1882833a3fa7dfae62ddf580cafb5a327d786f2b 100644 (file)
@@ -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
index eaa179c6de9133383eca89152bad6ed094cb7d5d..7ebf0bc98dcd77b46b3037cb70117ed7707de362 100644 (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,
 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"
index fc6694c0c72d340dc96c2bace9b2df9b07a64077..1d1f0363f4908cd23ff38bdc3e1140717d9cc7b8 100644 (file)
@@ -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
index ae018fdf11ac94ea166a20b5451e72cc041d0f07..7f26582db7956faec7cee77277ec39f0d7818c98 100644 (file)
@@ -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
index acd5f4a20522abd018f951fbbc76dde01bd9ca0a..b98241bf56f5c3d3bca5fd563e3184519f74d84b 100644 (file)
@@ -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 <laforge@gnumonks.org>.
index 82d580fb3c2607623fdab7e6648fa0210c9bb30a..2270eacb51fb0567e1edc88ec0b4f3934a85636b 100644 (file)
@@ -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 <srb@cuci.nl>, 1999/04/18 and donated to the public domain.
index 6d06383bfc945e0170fae44ad8b5e1335c10beb7..973afbe0b386b8506424ea1a83f7310d8927b317 100644 (file)
@@ -184,6 +184,10 @@ max segment size
 congestion window size
 .P
 .TP
+.B pmtu:<pmtu>
+path MTU value
+.P
+.TP
 .B ssthresh:<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)
index e9475a93b7422910239ea6d42482345e4b5d838b..2bf2e3e9738300722e3b4996212ee042bca24c38 100644 (file)
@@ -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
index 9d21ed7a07057584d56c92b421d6dae8b731c183..1abf43d08091a9fd1f42e4b186105747a384a2f3 100644 (file)
--- 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;
index ba82b65f712bdfa9b0efdefb4a4457de666925a0..4db3c95faa3ccfb7e1757abc87abcee01962e2f7 100644 (file)
@@ -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 (len >= sizeof(argbuf) - 1) {
+                                               fprintf(stderr, "Too long line in filter\n");
                                                exit(-1);
                                        }
-                                       if (argbuf[strlen(argbuf)-1] == '\n')
-                                               argbuf[strlen(argbuf)-1] = 0;
+                                       if (argbuf[len - 1] == '\n')
+                                               argbuf[len-1] = 0;
                                        if (argbuf[0] == '#' || argbuf[0] == '0')
                                                continue;
                                        tokptr = argbuf;
index c8966bfda9f864577cb4e8529596b9cd7e227742..454f25f867b6ec3d2d2f453881c94bf05d0b6f21 100644 (file)
@@ -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)
index 4431d5fde3240124608cd8d38a74a8b770a73bb9..70279b9dc8767390b880f8c83e6fa84a5d769aed 100644 (file)
@@ -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");
index abd33ab073e8905b80653ec611b2bf0440a692aa..fdb18d39b67d5ba3bd1346b83534ebc1d29e7ab4 100644 (file)
@@ -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