iproute2/ip/iplink.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * iplink.c             "ip link".
   4 *
   5 * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
   6 */
   7
   8#include <stdio.h>
   9#include <stdlib.h>
  10#include <unistd.h>
  11#include <fcntl.h>
  12#include <dlfcn.h>
  13#include <errno.h>
  14#include <string.h>
  15#include <strings.h>
  16#include <limits.h>
  17
  18#include <sys/socket.h>
  19#include <arpa/inet.h>
  20#include <linux/if.h>
  21#include <linux/if_ether.h>
  22
  23#include "rt_names.h"
  24#include "utils.h"
  25#include "ip_common.h"
  26#include "namespace.h"
  27
  28#ifndef GSO_MAX_SEGS
  29#define GSO_MAX_SEGS            65535
  30#endif
  31
  32
  33static void usage(void) __attribute__((noreturn));
  34
  35void iplink_types_usage(void)
  36{
  37        /* Remember to add new entry here if new type is added. */
  38        fprintf(stderr,
  39                "TYPE := { amt | bareudp | bond | bond_slave | bridge | bridge_slave |\n"
  40                "          dsa | dummy | erspan | geneve | gre | gretap | gtp | hsr |\n"
  41                "          ifb | ip6erspan | ip6gre | ip6gretap | ip6tnl |\n"
  42                "          ipip | ipoib | ipvlan | ipvtap |\n"
  43                "          macsec | macvlan | macvtap | netdevsim |\n"
  44                "          netkit | nlmon | pfcp | rmnet | sit | team | team_slave |\n"
  45                "          vcan | veth | vlan | vrf | vti | vxcan | vxlan | wwan |\n"
  46                "          xfrm | virt_wifi }\n");
  47}
  48
  49void iplink_usage(void)
  50{
  51        fprintf(stderr,
  52                "Usage: ip link add [link DEV | parentdev NAME] [ name ] NAME\n"
  53                "                   [ txqueuelen PACKETS ]\n"
  54                "                   [ address LLADDR ]\n"
  55                "                   [ broadcast LLADDR ]\n"
  56                "                   [ mtu MTU ] [index IDX ]\n"
  57                "                   [ numtxqueues QUEUE_COUNT ]\n"
  58                "                   [ numrxqueues QUEUE_COUNT ]\n"
  59                "                   [ netns { PID | NETNSNAME | NETNSFILE } ]\n"
  60                "                   type TYPE [ ARGS ]\n"
  61                "\n"
  62                "       ip link delete { DEVICE | dev DEVICE | group DEVGROUP } type TYPE [ ARGS ]\n"
  63                "\n"
  64                "       ip link { set | change } { DEVICE | dev DEVICE | group DEVGROUP }\n"
  65                "                       [ { up | down } ]\n"
  66                "                       [ type TYPE ARGS ]\n");
  67
  68        fprintf(stderr,
  69                "               [ arp { on | off } ]\n"
  70                "               [ dynamic { on | off } ]\n"
  71                "               [ multicast { on | off } ]\n"
  72                "               [ allmulticast { on | off } ]\n"
  73                "               [ promisc { on | off } ]\n"
  74                "               [ trailers { on | off } ]\n"
  75                "               [ carrier { on | off } ]\n"
  76                "               [ txqueuelen PACKETS ]\n"
  77                "               [ name NEWNAME ]\n"
  78                "               [ address LLADDR ]\n"
  79                "               [ broadcast LLADDR ]\n"
  80                "               [ mtu MTU ]\n"
  81                "               [ netns { PID | NETNSNAME | NETNSFILE } ]\n"
  82                "               [ link-netns NAME | link-netnsid ID ]\n"
  83                "               [ alias NAME ]\n"
  84                "               [ vf NUM [ mac LLADDR ]\n"
  85                "                        [ vlan VLANID [ qos VLAN-QOS ] [ proto VLAN-PROTO ] ]\n"
  86                "                        [ rate TXRATE ]\n"
  87                "                        [ max_tx_rate TXRATE ]\n"
  88                "                        [ min_tx_rate TXRATE ]\n"
  89                "                        [ spoofchk { on | off} ]\n"
  90                "                        [ query_rss { on | off} ]\n"
  91                "                        [ state { auto | enable | disable} ]\n"
  92                "                        [ trust { on | off} ]\n"
  93                "                        [ node_guid EUI64 ]\n"
  94                "                        [ port_guid EUI64 ] ]\n"
  95                "               [ { xdp | xdpgeneric | xdpdrv | xdpoffload } { off |\n"
  96#ifdef HAVE_LIBBPF
  97                "                         object FILE [ { section | program } NAME ] [ verbose ] |\n"
  98#else
  99                "                         object FILE [ section NAME ] [ verbose ] |\n"
 100#endif
 101                "                         pinned FILE } ]\n"
 102                "               [ master DEVICE ][ vrf NAME ]\n"
 103                "               [ nomaster ]\n"
 104                "               [ addrgenmode { eui64 | none | stable_secret | random } ]\n"
 105                "               [ protodown { on | off } ]\n"
 106                "               [ protodown_reason PREASON { on | off } ]\n"
 107                "               [ gso_max_size BYTES ] [ gso_ipv4_max_size BYTES ] [ gso_max_segs PACKETS ]\n"
 108                "               [ gro_max_size BYTES ] [ gro_ipv4_max_size BYTES ]\n"
 109                "\n"
 110                "       ip link show [ DEVICE | group GROUP ] [ { up | down } ] [master DEV] [vrf NAME]\n"
 111                "               [type TYPE] [nomaster] [ novf ]\n"
 112                "\n"
 113                "       ip link xstats type TYPE [ ARGS ]\n"
 114                "\n"
 115                "       ip link afstats [ dev DEVICE ]\n"
 116                "       ip link property add dev DEVICE [ altname NAME .. ]\n"
 117                "       ip link property del dev DEVICE [ altname NAME .. ]\n");
 118
 119        fprintf(stderr,
 120                "\n"
 121                "       ip link help [ TYPE ]\n"
 122                "\n");
 123        iplink_types_usage();
 124
 125        exit(-1);
 126}
 127
 128static void usage(void)
 129{
 130        iplink_usage();
 131}
 132
 133static int on_off(const char *msg, const char *realval)
 134{
 135        fprintf(stderr,
 136                "Error: argument of \"%s\" must be \"on\" or \"off\", not \"%s\"\n",
 137                msg, realval);
 138        return -1;
 139}
 140
 141static void *BODY;              /* cached dlopen(NULL) handle */
 142static struct link_util *linkutil_list;
 143
 144struct link_util *get_link_kind(const char *id)
 145{
 146        void *dlh;
 147        char buf[256];
 148        struct link_util *l;
 149
 150        for (l = linkutil_list; l; l = l->next)
 151                if (strcmp(l->id, id) == 0)
 152                        return l;
 153
 154        snprintf(buf, sizeof(buf), "%s/link_%s.so", get_ip_lib_dir(), id);
 155        dlh = dlopen(buf, RTLD_LAZY);
 156        if (dlh == NULL) {
 157                /* look in current binary, only open once */
 158                dlh = BODY;
 159                if (dlh == NULL) {
 160                        dlh = BODY = dlopen(NULL, RTLD_LAZY);
 161                        if (dlh == NULL)
 162                                return NULL;
 163                }
 164        }
 165
 166        snprintf(buf, sizeof(buf), "%s_link_util", id);
 167        l = dlsym(dlh, buf);
 168        if (l == NULL)
 169                return NULL;
 170
 171        l->next = linkutil_list;
 172        linkutil_list = l;
 173        return l;
 174}
 175
 176static int get_link_mode(const char *mode)
 177{
 178        if (strcasecmp(mode, "default") == 0)
 179                return IF_LINK_MODE_DEFAULT;
 180        if (strcasecmp(mode, "dormant") == 0)
 181                return IF_LINK_MODE_DORMANT;
 182        return -1;
 183}
 184
 185static int get_addr_gen_mode(const char *mode)
 186{
 187        if (strcasecmp(mode, "eui64") == 0)
 188                return IN6_ADDR_GEN_MODE_EUI64;
 189        if (strcasecmp(mode, "none") == 0)
 190                return IN6_ADDR_GEN_MODE_NONE;
 191        if (strcasecmp(mode, "stable_secret") == 0)
 192                return IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
 193        if (strcasecmp(mode, "random") == 0)
 194                return IN6_ADDR_GEN_MODE_RANDOM;
 195        return -1;
 196}
 197
 198static int nl_get_ll_addr_len(const char *ifname)
 199{
 200        int len;
 201        int dev_index = ll_name_to_index(ifname);
 202        struct iplink_req req = {
 203                .n = {
 204                        .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
 205                        .nlmsg_type = RTM_GETLINK,
 206                        .nlmsg_flags = NLM_F_REQUEST
 207                },
 208                .i = {
 209                        .ifi_family = preferred_family,
 210                        .ifi_index = dev_index,
 211                }
 212        };
 213        struct nlmsghdr *answer;
 214        struct rtattr *tb[IFLA_MAX+1];
 215
 216        if (dev_index == 0)
 217                return -1;
 218
 219        if (rtnl_talk(&rth, &req.n, &answer) < 0)
 220                return -1;
 221
 222        len = answer->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
 223        if (len < 0) {
 224                free(answer);
 225                return -1;
 226        }
 227
 228        parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(NLMSG_DATA(answer)),
 229                           len, NLA_F_NESTED);
 230        if (!tb[IFLA_ADDRESS]) {
 231                free(answer);
 232                return -1;
 233        }
 234
 235        len = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
 236        free(answer);
 237        return len;
 238}
 239
 240static int get_ifindex_in_netns(struct rtnl_handle *rtnl, int netnsid,
 241                                const char *ifname)
 242{
 243        struct {
 244                struct nlmsghdr         n;
 245                struct ifinfomsg        ifm;
 246                char                    buf[1024];
 247        } req = {
 248                .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
 249                .n.nlmsg_flags = NLM_F_REQUEST,
 250                .n.nlmsg_type = RTM_GETLINK,
 251        };
 252        struct nlmsghdr *answer;
 253        int ifindex;
 254
 255        addattr32(&req.n, sizeof(req), IFLA_TARGET_NETNSID, netnsid);
 256        addattr_l(&req.n, sizeof(req),
 257                  !check_ifname(ifname) ? IFLA_IFNAME : IFLA_ALT_IFNAME,
 258                  ifname, strlen(ifname) + 1);
 259
 260        if (rtnl_talk(rtnl, &req.n, &answer) < 0)
 261                return 0;
 262
 263        if (answer->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) {
 264                free(answer);
 265                return 0;
 266        }
 267        ifindex = ((struct ifinfomsg *)NLMSG_DATA(answer))->ifi_index;
 268        free(answer);
 269        return ifindex;
 270}
 271
 272static void iplink_parse_vf_vlan_info(int vf, int *argcp, char ***argvp,
 273                                      struct ifla_vf_vlan_info *ivvip)
 274{
 275        int argc = *argcp;
 276        char **argv = *argvp;
 277        unsigned int vci;
 278
 279        NEXT_ARG();
 280        if (get_unsigned(&vci, *argv, 0) || vci > 4095)
 281                invarg("Invalid \"vlan\" value\n", *argv);
 282
 283        ivvip->vlan = vci;
 284        ivvip->vf = vf;
 285        ivvip->qos = 0;
 286        ivvip->vlan_proto = htons(ETH_P_8021Q);
 287        if (NEXT_ARG_OK()) {
 288                NEXT_ARG();
 289                if (matches(*argv, "qos") == 0) {
 290                        NEXT_ARG();
 291                        if (get_unsigned(&ivvip->qos, *argv, 0))
 292                                invarg("Invalid \"qos\" value\n", *argv);
 293                } else {
 294                        /* rewind arg */
 295                        PREV_ARG();
 296                }
 297        }
 298        if (NEXT_ARG_OK()) {
 299                NEXT_ARG();
 300                if (matches(*argv, "proto") == 0) {
 301                        NEXT_ARG();
 302                        if (ll_proto_a2n(&ivvip->vlan_proto, *argv))
 303                                invarg("protocol is invalid\n", *argv);
 304                        if (ivvip->vlan_proto != htons(ETH_P_8021AD) &&
 305                            ivvip->vlan_proto != htons(ETH_P_8021Q)) {
 306                                SPRINT_BUF(b1);
 307                                SPRINT_BUF(b2);
 308                                char msg[64 + sizeof(b1) + sizeof(b2)];
 309
 310                                sprintf(msg,
 311                                        "Invalid \"vlan protocol\" value - supported %s, %s\n",
 312                                        ll_proto_n2a(htons(ETH_P_8021Q),
 313                                             b1, sizeof(b1)),
 314                                        ll_proto_n2a(htons(ETH_P_8021AD),
 315                                             b2, sizeof(b2)));
 316                                invarg(msg, *argv);
 317                        }
 318                } else {
 319                        /* rewind arg */
 320                        PREV_ARG();
 321                }
 322        }
 323
 324        *argcp = argc;
 325        *argvp = argv;
 326}
 327
 328static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
 329                           struct iplink_req *req, const char *dev)
 330{
 331        char new_rate_api = 0, count = 0, override_legacy_rate = 0;
 332        struct ifla_vf_rate tivt;
 333        int len, argc = *argcp;
 334        char **argv = *argvp;
 335        struct rtattr *vfinfo;
 336        int ret;
 337
 338        tivt.min_tx_rate = -1;
 339        tivt.max_tx_rate = -1;
 340
 341        vfinfo = addattr_nest(&req->n, sizeof(*req), IFLA_VF_INFO);
 342
 343        while (NEXT_ARG_OK()) {
 344                NEXT_ARG();
 345                count++;
 346                if (!matches(*argv, "max_tx_rate")) {
 347                        /* new API in use */
 348                        new_rate_api = 1;
 349                        /* override legacy rate */
 350                        override_legacy_rate = 1;
 351                } else if (!matches(*argv, "min_tx_rate")) {
 352                        /* new API in use */
 353                        new_rate_api = 1;
 354                }
 355        }
 356
 357        while (count--) {
 358                /* rewind arg */
 359                PREV_ARG();
 360        }
 361
 362        while (NEXT_ARG_OK()) {
 363                NEXT_ARG();
 364                if (matches(*argv, "mac") == 0) {
 365                        struct ifla_vf_mac ivm = { 0 };
 366                        int halen = nl_get_ll_addr_len(dev);
 367
 368                        NEXT_ARG();
 369                        ivm.vf = vf;
 370                        len = ll_addr_a2n((char *)ivm.mac, 32, *argv);
 371                        if (len < 0)
 372                                return -1;
 373                        if (halen > 0 && len != halen) {
 374                                fprintf(stderr,
 375                                        "Invalid address length %d - must be %d bytes\n",
 376                                        len, halen);
 377                                return -1;
 378                        }
 379                        addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC,
 380                                  &ivm, sizeof(ivm));
 381                } else if (matches(*argv, "vlan") == 0) {
 382                        struct ifla_vf_vlan_info ivvi;
 383
 384                        iplink_parse_vf_vlan_info(vf, &argc, &argv, &ivvi);
 385                        /* support the old interface in case of older kernel*/
 386                        if (ivvi.vlan_proto == htons(ETH_P_8021Q)) {
 387                                struct ifla_vf_vlan ivv;
 388
 389                                ivv.vf = ivvi.vf;
 390                                ivv.vlan = ivvi.vlan;
 391                                ivv.qos = ivvi.qos;
 392                                addattr_l(&req->n, sizeof(*req),
 393                                          IFLA_VF_VLAN, &ivv, sizeof(ivv));
 394                        } else {
 395                                struct rtattr *vfvlanlist;
 396
 397                                vfvlanlist = addattr_nest(&req->n, sizeof(*req),
 398                                                          IFLA_VF_VLAN_LIST);
 399                                addattr_l(&req->n, sizeof(*req),
 400                                          IFLA_VF_VLAN_INFO, &ivvi,
 401                                          sizeof(ivvi));
 402
 403                                while (NEXT_ARG_OK()) {
 404                                        NEXT_ARG();
 405                                        if (matches(*argv, "vlan") != 0) {
 406                                                PREV_ARG();
 407                                                break;
 408                                        }
 409                                        iplink_parse_vf_vlan_info(vf, &argc,
 410                                                                  &argv, &ivvi);
 411                                        addattr_l(&req->n, sizeof(*req),
 412                                                  IFLA_VF_VLAN_INFO, &ivvi,
 413                                                  sizeof(ivvi));
 414                                }
 415                                addattr_nest_end(&req->n, vfvlanlist);
 416                        }
 417                } else if (matches(*argv, "rate") == 0) {
 418                        struct ifla_vf_tx_rate ivt;
 419
 420                        NEXT_ARG();
 421                        if (get_unsigned(&ivt.rate, *argv, 0))
 422                                invarg("Invalid \"rate\" value\n", *argv);
 423
 424                        ivt.vf = vf;
 425                        if (!new_rate_api)
 426                                addattr_l(&req->n, sizeof(*req),
 427                                          IFLA_VF_TX_RATE, &ivt, sizeof(ivt));
 428                        else if (!override_legacy_rate)
 429                                tivt.max_tx_rate = ivt.rate;
 430
 431                } else if (matches(*argv, "max_tx_rate") == 0) {
 432                        NEXT_ARG();
 433                        if (get_unsigned(&tivt.max_tx_rate, *argv, 0))
 434                                invarg("Invalid \"max tx rate\" value\n",
 435                                       *argv);
 436                        tivt.vf = vf;
 437
 438                } else if (matches(*argv, "min_tx_rate") == 0) {
 439                        NEXT_ARG();
 440                        if (get_unsigned(&tivt.min_tx_rate, *argv, 0))
 441                                invarg("Invalid \"min tx rate\" value\n",
 442                                       *argv);
 443                        tivt.vf = vf;
 444
 445                } else if (matches(*argv, "spoofchk") == 0) {
 446                        struct ifla_vf_spoofchk ivs;
 447
 448                        NEXT_ARG();
 449                        ivs.setting = parse_on_off("spoofchk", *argv, &ret);
 450                        if (ret)
 451                                return ret;
 452                        ivs.vf = vf;
 453                        addattr_l(&req->n, sizeof(*req), IFLA_VF_SPOOFCHK,
 454                                  &ivs, sizeof(ivs));
 455
 456                } else if (matches(*argv, "query_rss") == 0) {
 457                        struct ifla_vf_rss_query_en ivs;
 458
 459                        NEXT_ARG();
 460                        ivs.setting = parse_on_off("query_rss", *argv, &ret);
 461                        if (ret)
 462                                return ret;
 463                        ivs.vf = vf;
 464                        addattr_l(&req->n, sizeof(*req), IFLA_VF_RSS_QUERY_EN,
 465                                  &ivs, sizeof(ivs));
 466
 467                } else if (matches(*argv, "trust") == 0) {
 468                        struct ifla_vf_trust ivt;
 469
 470                        NEXT_ARG();
 471                        ivt.setting = parse_on_off("trust", *argv, &ret);
 472                        if (ret)
 473                                return ret;
 474                        ivt.vf = vf;
 475                        addattr_l(&req->n, sizeof(*req), IFLA_VF_TRUST,
 476                                  &ivt, sizeof(ivt));
 477
 478                } else if (matches(*argv, "state") == 0) {
 479                        struct ifla_vf_link_state ivl;
 480
 481                        NEXT_ARG();
 482                        if (matches(*argv, "auto") == 0)
 483                                ivl.link_state = IFLA_VF_LINK_STATE_AUTO;
 484                        else if (matches(*argv, "enable") == 0)
 485                                ivl.link_state = IFLA_VF_LINK_STATE_ENABLE;
 486                        else if (matches(*argv, "disable") == 0)
 487                                ivl.link_state = IFLA_VF_LINK_STATE_DISABLE;
 488                        else
 489                                invarg("Invalid \"state\" value\n", *argv);
 490                        ivl.vf = vf;
 491                        addattr_l(&req->n, sizeof(*req), IFLA_VF_LINK_STATE,
 492                                  &ivl, sizeof(ivl));
 493                } else if (matches(*argv, "node_guid") == 0) {
 494                        struct ifla_vf_guid ivg;
 495
 496                        NEXT_ARG();
 497                        ivg.vf = vf;
 498                        if (get_guid(&ivg.guid, *argv)) {
 499                                invarg("Invalid GUID format\n", *argv);
 500                                return -1;
 501                        }
 502                        addattr_l(&req->n, sizeof(*req), IFLA_VF_IB_NODE_GUID,
 503                                  &ivg, sizeof(ivg));
 504                } else if (matches(*argv, "port_guid") == 0) {
 505                        struct ifla_vf_guid ivg;
 506
 507                        NEXT_ARG();
 508                        ivg.vf = vf;
 509                        if (get_guid(&ivg.guid, *argv)) {
 510                                invarg("Invalid GUID format\n", *argv);
 511                                return -1;
 512                        }
 513                        addattr_l(&req->n, sizeof(*req), IFLA_VF_IB_PORT_GUID,
 514                                  &ivg, sizeof(ivg));
 515                } else {
 516                        /* rewind arg */
 517                        PREV_ARG();
 518                        break;
 519                }
 520        }
 521
 522        if (new_rate_api) {
 523                int tmin, tmax;
 524
 525                if (tivt.min_tx_rate == -1 || tivt.max_tx_rate == -1) {
 526                        ipaddr_get_vf_rate(tivt.vf, &tmin, &tmax, dev);
 527                        if (tivt.min_tx_rate == -1)
 528                                tivt.min_tx_rate = tmin;
 529                        if (tivt.max_tx_rate == -1)
 530                                tivt.max_tx_rate = tmax;
 531                }
 532
 533                if (tivt.max_tx_rate && tivt.min_tx_rate > tivt.max_tx_rate) {
 534                        fprintf(stderr,
 535                                "Invalid min_tx_rate %d - must be <= max_tx_rate %d\n",
 536                                tivt.min_tx_rate, tivt.max_tx_rate);
 537                        return -1;
 538                }
 539
 540                addattr_l(&req->n, sizeof(*req), IFLA_VF_RATE, &tivt,
 541                          sizeof(tivt));
 542        }
 543
 544        if (argc == *argcp)
 545                incomplete_command();
 546
 547        addattr_nest_end(&req->n, vfinfo);
 548
 549        *argcp = argc;
 550        *argvp = argv;
 551        return 0;
 552}
 553
 554int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
 555{
 556        bool move_netns = false;
 557        char *name = NULL;
 558        char *dev = NULL;
 559        char *link = NULL;
 560        int ret, len;
 561        char abuf[32];
 562        int qlen = -1;
 563        int mtu = -1;
 564        int netns = -1;
 565        int vf = -1;
 566        int numtxqueues = -1;
 567        int numrxqueues = -1;
 568        char *link_netns = NULL;
 569        int link_netnsid = -1;
 570        struct rtnl_handle netns_rtnl;
 571        struct rtnl_handle *rtnl = &rth;
 572        int index = 0;
 573        int group = -1;
 574        int addr_len = 0;
 575        int err;
 576
 577        ret = argc;
 578
 579        while (argc > 0) {
 580                if (strcmp(*argv, "up") == 0) {
 581                        req->i.ifi_change |= IFF_UP;
 582                        req->i.ifi_flags |= IFF_UP;
 583                } else if (strcmp(*argv, "down") == 0) {
 584                        req->i.ifi_change |= IFF_UP;
 585                        req->i.ifi_flags &= ~IFF_UP;
 586                } else if (strcmp(*argv, "name") == 0) {
 587                        NEXT_ARG();
 588                        if (name)
 589                                duparg("name", *argv);
 590                        if (check_ifname(*argv))
 591                                invarg("\"name\" not a valid ifname", *argv);
 592                        name = *argv;
 593                        if (!dev)
 594                                dev = name;
 595                } else if (strcmp(*argv, "index") == 0) {
 596                        NEXT_ARG();
 597                        if (index)
 598                                duparg("index", *argv);
 599                        index = atoi(*argv);
 600                        if (index <= 0)
 601                                invarg("Invalid \"index\" value", *argv);
 602                } else if (matches(*argv, "link") == 0) {
 603                        NEXT_ARG();
 604                        link = *argv;
 605                } else if (matches(*argv, "address") == 0) {
 606                        NEXT_ARG();
 607                        addr_len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
 608                        if (addr_len < 0)
 609                                return -1;
 610                        addattr_l(&req->n, sizeof(*req),
 611                                  IFLA_ADDRESS, abuf, addr_len);
 612                } else if (matches(*argv, "broadcast") == 0 ||
 613                           strcmp(*argv, "brd") == 0) {
 614                        NEXT_ARG();
 615                        len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
 616                        if (len < 0)
 617                                return -1;
 618                        addattr_l(&req->n, sizeof(*req),
 619                                  IFLA_BROADCAST, abuf, len);
 620                } else if (matches(*argv, "txqueuelen") == 0 ||
 621                           strcmp(*argv, "qlen") == 0 ||
 622                           matches(*argv, "txqlen") == 0) {
 623                        NEXT_ARG();
 624                        if (qlen != -1)
 625                                duparg("txqueuelen", *argv);
 626                        if (get_integer(&qlen,  *argv, 0))
 627                                invarg("Invalid \"txqueuelen\" value\n", *argv);
 628                        addattr_l(&req->n, sizeof(*req),
 629                                  IFLA_TXQLEN, &qlen, 4);
 630                } else if (strcmp(*argv, "mtu") == 0) {
 631                        NEXT_ARG();
 632                        if (mtu != -1)
 633                                duparg("mtu", *argv);
 634                        if (get_integer(&mtu, *argv, 0))
 635                                invarg("Invalid \"mtu\" value\n", *argv);
 636                        addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
 637                } else if (strcmp(*argv, "xdpgeneric") == 0 ||
 638                           strcmp(*argv, "xdpdrv") == 0 ||
 639                           strcmp(*argv, "xdpoffload") == 0 ||
 640                           strcmp(*argv, "xdp") == 0) {
 641                        bool generic = strcmp(*argv, "xdpgeneric") == 0;
 642                        bool drv = strcmp(*argv, "xdpdrv") == 0;
 643                        bool offload = strcmp(*argv, "xdpoffload") == 0;
 644
 645                        NEXT_ARG();
 646                        if (xdp_parse(&argc, &argv, req, dev,
 647                                      generic, drv, offload))
 648                                exit(-1);
 649
 650                        if (offload && name == dev)
 651                                dev = NULL;
 652                } else if (strcmp(*argv, "netns") == 0) {
 653                        int pid;
 654
 655                        NEXT_ARG();
 656                        if (netns != -1)
 657                                duparg("netns", *argv);
 658                        netns = netns_get_fd(*argv);
 659                        if (netns < 0 && get_integer(&pid, *argv, 0) == 0) {
 660                                char path[PATH_MAX];
 661
 662                                snprintf(path, sizeof(path), "/proc/%d/ns/net",
 663                                         pid);
 664                                netns = open(path, O_RDONLY);
 665                        }
 666                        if (netns < 0)
 667                                invarg("Invalid \"netns\" value\n", *argv);
 668
 669                        open_fds_add(netns);
 670                        addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD,
 671                                  &netns, 4);
 672                        move_netns = true;
 673                } else if (strcmp(*argv, "multicast") == 0) {
 674                        NEXT_ARG();
 675                        req->i.ifi_change |= IFF_MULTICAST;
 676
 677                        if (strcmp(*argv, "on") == 0)
 678                                req->i.ifi_flags |= IFF_MULTICAST;
 679                        else if (strcmp(*argv, "off") == 0)
 680                                req->i.ifi_flags &= ~IFF_MULTICAST;
 681                        else
 682                                return on_off("multicast", *argv);
 683                } else if (strcmp(*argv, "allmulticast") == 0) {
 684                        NEXT_ARG();
 685                        req->i.ifi_change |= IFF_ALLMULTI;
 686
 687                        if (strcmp(*argv, "on") == 0)
 688                                req->i.ifi_flags |= IFF_ALLMULTI;
 689                        else if (strcmp(*argv, "off") == 0)
 690                                req->i.ifi_flags &= ~IFF_ALLMULTI;
 691                        else
 692                                return on_off("allmulticast", *argv);
 693                } else if (strcmp(*argv, "promisc") == 0) {
 694                        NEXT_ARG();
 695                        req->i.ifi_change |= IFF_PROMISC;
 696
 697                        if (strcmp(*argv, "on") == 0)
 698                                req->i.ifi_flags |= IFF_PROMISC;
 699                        else if (strcmp(*argv, "off") == 0)
 700                                req->i.ifi_flags &= ~IFF_PROMISC;
 701                        else
 702                                return on_off("promisc", *argv);
 703                } else if (strcmp(*argv, "trailers") == 0) {
 704                        NEXT_ARG();
 705                        req->i.ifi_change |= IFF_NOTRAILERS;
 706
 707                        if (strcmp(*argv, "off") == 0)
 708                                req->i.ifi_flags |= IFF_NOTRAILERS;
 709                        else if (strcmp(*argv, "on") == 0)
 710                                req->i.ifi_flags &= ~IFF_NOTRAILERS;
 711                        else
 712                                return on_off("trailers", *argv);
 713                } else if (strcmp(*argv, "arp") == 0) {
 714                        NEXT_ARG();
 715                        req->i.ifi_change |= IFF_NOARP;
 716
 717                        if (strcmp(*argv, "on") == 0)
 718                                req->i.ifi_flags &= ~IFF_NOARP;
 719                        else if (strcmp(*argv, "off") == 0)
 720                                req->i.ifi_flags |= IFF_NOARP;
 721                        else
 722                                return on_off("arp", *argv);
 723                } else if (strcmp(*argv, "carrier") == 0) {
 724                        int carrier;
 725
 726                        NEXT_ARG();
 727                        carrier = parse_on_off("carrier", *argv, &err);
 728                        if (err)
 729                                return err;
 730
 731                        addattr8(&req->n, sizeof(*req), IFLA_CARRIER, carrier);
 732                } else if (strcmp(*argv, "vf") == 0) {
 733                        struct rtattr *vflist;
 734
 735                        NEXT_ARG();
 736                        if (get_integer(&vf,  *argv, 0))
 737                                invarg("Invalid \"vf\" value\n", *argv);
 738
 739                        vflist = addattr_nest(&req->n, sizeof(*req),
 740                                              IFLA_VFINFO_LIST);
 741                        if (!dev)
 742                                missarg("dev");
 743
 744                        len = iplink_parse_vf(vf, &argc, &argv, req, dev);
 745                        if (len < 0)
 746                                return -1;
 747                        addattr_nest_end(&req->n, vflist);
 748
 749                        if (name == dev)
 750                                dev = NULL;
 751                } else if (matches(*argv, "master") == 0) {
 752                        int ifindex;
 753
 754                        NEXT_ARG();
 755                        ifindex = ll_name_to_index(*argv);
 756                        if (!ifindex)
 757                                invarg("Device does not exist\n", *argv);
 758                        addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
 759                                  &ifindex, 4);
 760                } else if (strcmp(*argv, "vrf") == 0) {
 761                        int ifindex;
 762
 763                        NEXT_ARG();
 764                        ifindex = ll_name_to_index(*argv);
 765                        if (!ifindex)
 766                                invarg("Not a valid VRF name\n", *argv);
 767                        if (!name_is_vrf(*argv))
 768                                invarg("Not a valid VRF name\n", *argv);
 769                        addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
 770                                  &ifindex, sizeof(ifindex));
 771                } else if (matches(*argv, "nomaster") == 0) {
 772                        int ifindex = 0;
 773
 774                        addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
 775                                  &ifindex, 4);
 776                } else if (matches(*argv, "dynamic") == 0) {
 777                        NEXT_ARG();
 778                        req->i.ifi_change |= IFF_DYNAMIC;
 779
 780                        if (strcmp(*argv, "on") == 0)
 781                                req->i.ifi_flags |= IFF_DYNAMIC;
 782                        else if (strcmp(*argv, "off") == 0)
 783                                req->i.ifi_flags &= ~IFF_DYNAMIC;
 784                        else
 785                                return on_off("dynamic", *argv);
 786                } else if (matches(*argv, "type") == 0) {
 787                        NEXT_ARG();
 788                        *type = *argv;
 789                        argc--; argv++;
 790                        break;
 791                } else if (matches(*argv, "alias") == 0) {
 792                        NEXT_ARG();
 793                        len = strlen(*argv);
 794                        if (len >= IFALIASZ)
 795                                invarg("alias too long\n", *argv);
 796                        addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS,
 797                                  *argv, len);
 798                } else if (strcmp(*argv, "group") == 0) {
 799                        NEXT_ARG();
 800                        if (group != -1)
 801                                duparg("group", *argv);
 802                        if (rtnl_group_a2n(&group, *argv))
 803                                invarg("Invalid \"group\" value\n", *argv);
 804                        addattr32(&req->n, sizeof(*req), IFLA_GROUP, group);
 805                } else if (strcmp(*argv, "mode") == 0) {
 806                        int mode;
 807
 808                        NEXT_ARG();
 809                        mode = get_link_mode(*argv);
 810                        if (mode < 0)
 811                                invarg("Invalid link mode\n", *argv);
 812                        addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
 813                } else if (strcmp(*argv, "state") == 0) {
 814                        int state;
 815
 816                        NEXT_ARG();
 817                        state = get_operstate(*argv);
 818                        if (state < 0)
 819                                invarg("Invalid operstate\n", *argv);
 820
 821                        addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);
 822                } else if (matches(*argv, "numtxqueues") == 0) {
 823                        NEXT_ARG();
 824                        if (numtxqueues != -1)
 825                                duparg("numtxqueues", *argv);
 826                        if (get_integer(&numtxqueues, *argv, 0))
 827                                invarg("Invalid \"numtxqueues\" value\n",
 828                                       *argv);
 829                        addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES,
 830                                  &numtxqueues, 4);
 831                } else if (matches(*argv, "numrxqueues") == 0) {
 832                        NEXT_ARG();
 833                        if (numrxqueues != -1)
 834                                duparg("numrxqueues", *argv);
 835                        if (get_integer(&numrxqueues, *argv, 0))
 836                                invarg("Invalid \"numrxqueues\" value\n",
 837                                       *argv);
 838                        addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES,
 839                                  &numrxqueues, 4);
 840                } else if (matches(*argv, "addrgenmode") == 0) {
 841                        struct rtattr *afs, *afs6;
 842                        int mode;
 843
 844                        NEXT_ARG();
 845                        mode = get_addr_gen_mode(*argv);
 846                        if (mode < 0)
 847                                invarg("Invalid address generation mode\n",
 848                                       *argv);
 849                        afs = addattr_nest(&req->n, sizeof(*req), IFLA_AF_SPEC);
 850                        afs6 = addattr_nest(&req->n, sizeof(*req), AF_INET6);
 851                        addattr8(&req->n, sizeof(*req),
 852                                 IFLA_INET6_ADDR_GEN_MODE, mode);
 853                        addattr_nest_end(&req->n, afs6);
 854                        addattr_nest_end(&req->n, afs);
 855                } else if (matches(*argv, "link-netns") == 0) {
 856                        NEXT_ARG();
 857                        if (link_netnsid != -1 || link_netns)
 858                                duparg("link-netns/link-netnsid", *argv);
 859                        link_netns = *argv;
 860                } else if (matches(*argv, "link-netnsid") == 0) {
 861                        NEXT_ARG();
 862                        if (link_netnsid != -1 || link_netns)
 863                                duparg("link-netns/link-netnsid", *argv);
 864                        if (get_integer(&link_netnsid, *argv, 0))
 865                                invarg("Invalid \"link-netnsid\" value\n",
 866                                       *argv);
 867                        addattr32(&req->n, sizeof(*req), IFLA_LINK_NETNSID,
 868                                  link_netnsid);
 869                } else if (strcmp(*argv, "protodown") == 0) {
 870                        unsigned int proto_down;
 871
 872                        NEXT_ARG();
 873                        proto_down = parse_on_off("protodown", *argv, &err);
 874                        if (err)
 875                                return err;
 876                        addattr8(&req->n, sizeof(*req), IFLA_PROTO_DOWN,
 877                                 proto_down);
 878                } else if (strcmp(*argv, "protodown_reason") == 0) {
 879                        struct rtattr *pr;
 880                        __u32 preason = 0, prvalue = 0, prmask = 0;
 881
 882                        NEXT_ARG();
 883                        if (protodown_reason_a2n(&preason, *argv))
 884                                invarg("invalid protodown reason\n", *argv);
 885                        NEXT_ARG();
 886                        prmask = 1 << preason;
 887                        if (matches(*argv, "on") == 0)
 888                                prvalue |= prmask;
 889                        else if (matches(*argv, "off") == 0)
 890                                prvalue &= ~prmask;
 891                        else
 892                                return on_off("protodown_reason", *argv);
 893                        pr = addattr_nest(&req->n, sizeof(*req),
 894                                          IFLA_PROTO_DOWN_REASON | NLA_F_NESTED);
 895                        addattr32(&req->n, sizeof(*req),
 896                                  IFLA_PROTO_DOWN_REASON_MASK, prmask);
 897                        addattr32(&req->n, sizeof(*req),
 898                                  IFLA_PROTO_DOWN_REASON_VALUE, prvalue);
 899                        addattr_nest_end(&req->n, pr);
 900                } else if (strcmp(*argv, "gso_max_size") == 0) {
 901                        unsigned int max_size;
 902
 903                        NEXT_ARG();
 904                        if (get_unsigned(&max_size, *argv, 0))
 905                                invarg("Invalid \"gso_max_size\" value\n",
 906                                       *argv);
 907                        addattr32(&req->n, sizeof(*req),
 908                                  IFLA_GSO_MAX_SIZE, max_size);
 909                } else if (strcmp(*argv, "gso_max_segs") == 0) {
 910                        unsigned int max_segs;
 911
 912                        NEXT_ARG();
 913                        if (get_unsigned(&max_segs, *argv, 0) ||
 914                            max_segs > GSO_MAX_SEGS)
 915                                invarg("Invalid \"gso_max_segs\" value\n",
 916                                       *argv);
 917                        addattr32(&req->n, sizeof(*req),
 918                                  IFLA_GSO_MAX_SEGS, max_segs);
 919                }  else if (strcmp(*argv, "gro_max_size") == 0) {
 920                        unsigned int max_size;
 921
 922                        NEXT_ARG();
 923                        if (get_unsigned(&max_size, *argv, 0))
 924                                invarg("Invalid \"gro_max_size\" value\n",
 925                                       *argv);
 926                        addattr32(&req->n, sizeof(*req),
 927                                  IFLA_GRO_MAX_SIZE, max_size);
 928                } else if (strcmp(*argv, "gso_ipv4_max_size") == 0) {
 929                        unsigned int max_size;
 930
 931                        NEXT_ARG();
 932                        if (get_unsigned(&max_size, *argv, 0))
 933                                invarg("Invalid \"gso_ipv4_max_size\" value\n",
 934                                       *argv);
 935                        addattr32(&req->n, sizeof(*req),
 936                                  IFLA_GSO_IPV4_MAX_SIZE, max_size);
 937                }  else if (strcmp(*argv, "gro_ipv4_max_size") == 0) {
 938                        unsigned int max_size;
 939
 940                        NEXT_ARG();
 941                        if (get_unsigned(&max_size, *argv, 0))
 942                                invarg("Invalid \"gro_ipv4_max_size\" value\n",
 943                                       *argv);
 944                        addattr32(&req->n, sizeof(*req),
 945                                  IFLA_GRO_IPV4_MAX_SIZE, max_size);
 946                } else if (strcmp(*argv, "parentdev") == 0) {
 947                        NEXT_ARG();
 948                        addattr_l(&req->n, sizeof(*req), IFLA_PARENT_DEV_NAME,
 949                                  *argv, strlen(*argv) + 1);
 950                } else {
 951                        if (matches(*argv, "help") == 0)
 952                                usage();
 953
 954                        if (strcmp(*argv, "dev") == 0)
 955                                NEXT_ARG();
 956                        if (dev != name)
 957                                duparg2("dev", *argv);
 958                        if (check_altifname(*argv))
 959                                invarg("\"dev\" not a valid ifname", *argv);
 960                        dev = *argv;
 961                }
 962                argc--; argv++;
 963        }
 964
 965        ret -= argc;
 966
 967        /* Allow "ip link add dev" and "ip link add name" */
 968        if (!name)
 969                name = dev;
 970        else if (!dev)
 971                dev = name;
 972        else if (!strcmp(name, dev))
 973                name = dev;
 974
 975        if (dev && addr_len &&
 976            !(req->n.nlmsg_flags & NLM_F_CREATE)) {
 977                int halen = nl_get_ll_addr_len(dev);
 978
 979                if (halen >= 0 && halen != addr_len) {
 980                        fprintf(stderr,
 981                                "Invalid address length %d - must be %d bytes\n",
 982                                addr_len, halen);
 983                        return -1;
 984                }
 985        }
 986
 987        if (index &&
 988            (!(req->n.nlmsg_flags & NLM_F_CREATE) &&
 989             !move_netns)) {
 990                fprintf(stderr,
 991                        "index can be used only when creating devices or when moving device to another netns.\n");
 992                exit(-1);
 993        }
 994
 995        if (group != -1) {
 996                if (!dev) {
 997                        if (argc) {
 998                                fprintf(stderr,
 999                                        "Garbage instead of arguments \"%s ...\". Try \"ip link help\".\n",
1000                                        *argv);
1001                                exit(-1);
1002                        }
1003                        if (req->n.nlmsg_flags & NLM_F_CREATE) {
1004                                fprintf(stderr,
1005                                        "group cannot be used when creating devices.\n");
1006                                exit(-1);
1007                        }
1008
1009                        *type = NULL;
1010                        return ret;
1011                }
1012        }
1013
1014        if (netns != -1 && (link_netnsid != -1 || link_netns)) {
1015                int orig_netns;
1016
1017                /*
1018                 * When both link-netns and netns are set, open an RTNL in
1019                 * target netns, to
1020                 *   1) get link-netns id from the view of target netns, and
1021                 *   2) get link ifindex from link-netns.
1022                 */
1023                orig_netns = open("/proc/self/ns/net", O_RDONLY);
1024                if (orig_netns == -1) {
1025                        fprintf(stderr, "Cannot open namespace: %s\n",
1026                                strerror(errno));
1027                        exit(-1);
1028                }
1029                if (setns(netns, CLONE_NEWNET) < 0) {
1030                        fprintf(stderr, "Cannot set namespace: %s\n",
1031                                strerror(errno));
1032                        exit(-1);
1033                }
1034                if (rtnl_open(&netns_rtnl, 0) < 0) {
1035                        fprintf(stderr, "Cannot open rtnetlink\n");
1036                        exit(-1);
1037                }
1038                if (setns(orig_netns, CLONE_NEWNET) < 0) {
1039                        fprintf(stderr, "Cannot set namespace: %s\n",
1040                                strerror(errno));
1041                        exit(-1);
1042                }
1043                close(orig_netns);
1044                rtnl = &netns_rtnl;
1045        }
1046
1047        if (link_netns) {
1048                link_netnsid = netns_id_from_name(rtnl, link_netns);
1049                /* No nsid? Try to assign one. */
1050                if (link_netnsid < 0) {
1051                        set_netns_id_from_name(rtnl, link_netns, -1);
1052                        link_netnsid = netns_id_from_name(rtnl, link_netns);
1053                }
1054                if (link_netnsid < 0)
1055                        invarg("Invalid \"link-netns\" value\n",
1056                               *argv);
1057                addattr32(&req->n, sizeof(*req), IFLA_LINK_NETNSID,
1058                          link_netnsid);
1059        }
1060
1061        if (!(req->n.nlmsg_flags & NLM_F_CREATE)) {
1062                if (!dev) {
1063                        fprintf(stderr,
1064                                "Not enough information: \"dev\" argument is required.\n");
1065                        exit(-1);
1066                }
1067
1068                req->i.ifi_index = ll_name_to_index(dev);
1069                if (!req->i.ifi_index) {
1070                        ret = nodev(dev);
1071                        goto out;
1072                }
1073
1074                /* Not renaming to the same name */
1075                if (name == dev)
1076                        name = NULL;
1077
1078                if (index)
1079                        addattr32(&req->n, sizeof(*req), IFLA_NEW_IFINDEX, index);
1080        } else {
1081                if (name != dev) {
1082                        fprintf(stderr,
1083                                "both \"name\" and \"dev\" cannot be used when creating devices.\n");
1084                        exit(-1);
1085                }
1086
1087                if (link) {
1088                        int ifindex;
1089
1090                        if (link_netnsid == -1)
1091                                ifindex = ll_name_to_index(link);
1092                        else
1093                                ifindex = get_ifindex_in_netns(rtnl,
1094                                                               link_netnsid,
1095                                                               link);
1096
1097                        if (!ifindex) {
1098                                ret = nodev(link);
1099                                goto out;
1100                        }
1101                        addattr32(&req->n, sizeof(*req), IFLA_LINK, ifindex);
1102                }
1103
1104                req->i.ifi_index = index;
1105        }
1106
1107        if (name) {
1108                addattr_l(&req->n, sizeof(*req),
1109                          IFLA_IFNAME, name, strlen(name) + 1);
1110        }
1111
1112out:
1113        if (rtnl == &netns_rtnl)
1114                rtnl_close(rtnl);
1115
1116        return ret;
1117}
1118
1119static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
1120{
1121        char *type = NULL;
1122        struct iplink_req req = {
1123                .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
1124                .n.nlmsg_flags = NLM_F_REQUEST | flags,
1125                .n.nlmsg_type = cmd,
1126                .i.ifi_family = preferred_family,
1127        };
1128        int ret;
1129
1130        ret = iplink_parse(argc, argv, &req, &type);
1131        if (ret < 0)
1132                return ret;
1133
1134        if (type) {
1135                struct link_util *lu;
1136                struct rtattr *linkinfo;
1137                char *ulinep = strchr(type, '_');
1138                int iflatype;
1139
1140                linkinfo = addattr_nest(&req.n, sizeof(req), IFLA_LINKINFO);
1141                addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type,
1142                         strlen(type));
1143
1144                lu = get_link_kind(type);
1145                if (ulinep && !strcmp(ulinep, "_slave"))
1146                        iflatype = IFLA_INFO_SLAVE_DATA;
1147                else
1148                        iflatype = IFLA_INFO_DATA;
1149
1150                argc -= ret;
1151                argv += ret;
1152
1153                if (lu && lu->parse_opt && argc) {
1154                        struct rtattr *data;
1155
1156                        data = addattr_nest(&req.n, sizeof(req), iflatype);
1157
1158                        if (lu->parse_opt(lu, argc, argv, &req.n))
1159                                return -1;
1160
1161                        addattr_nest_end(&req.n, data);
1162                } else if (argc) {
1163                        if (matches(*argv, "help") == 0)
1164                                usage();
1165                        fprintf(stderr,
1166                                "Garbage instead of arguments \"%s ...\". Try \"ip link help\".\n",
1167                                *argv);
1168                        return -1;
1169                }
1170                addattr_nest_end(&req.n, linkinfo);
1171        } else if (flags & NLM_F_CREATE) {
1172                fprintf(stderr,
1173                        "Not enough information: \"type\" argument is required\n");
1174                return -1;
1175        }
1176
1177        if (echo_request)
1178                ret = rtnl_echo_talk(&rth, &req.n, json, print_linkinfo);
1179        else
1180                ret = rtnl_talk(&rth, &req.n, NULL);
1181
1182        open_fds_close();
1183
1184        if (ret)
1185                return -2;
1186
1187        /* remove device from cache; next use can refresh with new data */
1188        ll_drop_by_index(req.i.ifi_index);
1189
1190        return 0;
1191}
1192
1193int iplink_get(char *name, __u32 filt_mask)
1194{
1195        struct iplink_req req = {
1196                .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
1197                .n.nlmsg_flags = NLM_F_REQUEST,
1198                .n.nlmsg_type = RTM_GETLINK,
1199                .i.ifi_family = preferred_family,
1200        };
1201        struct nlmsghdr *answer;
1202
1203        if (name) {
1204                addattr_l(&req.n, sizeof(req),
1205                          !check_ifname(name) ? IFLA_IFNAME : IFLA_ALT_IFNAME,
1206                          name, strlen(name) + 1);
1207        }
1208
1209        if (!show_stats)
1210                filt_mask |= RTEXT_FILTER_SKIP_STATS;
1211        addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
1212
1213        if (rtnl_talk(&rth, &req.n, &answer) < 0)
1214                return -2;
1215
1216        open_json_object(NULL);
1217        print_linkinfo(answer, stdout);
1218        close_json_object();
1219
1220        free(answer);
1221        return 0;
1222}
1223
1224
1225void print_mpls_link_stats(FILE *fp, const struct mpls_link_stats *stats,
1226                           const char *indent)
1227{
1228        unsigned int cols[] = {
1229                strlen("*X: bytes"),
1230                strlen("packets"),
1231                strlen("errors"),
1232                strlen("dropped"),
1233                strlen("noroute"),
1234        };
1235
1236        if (is_json_context()) {
1237                /* RX stats */
1238                open_json_object("rx");
1239                print_u64(PRINT_JSON, "bytes", NULL, stats->rx_bytes);
1240                print_u64(PRINT_JSON, "packets", NULL, stats->rx_packets);
1241                print_u64(PRINT_JSON, "errors", NULL, stats->rx_errors);
1242                print_u64(PRINT_JSON, "dropped", NULL, stats->rx_dropped);
1243                print_u64(PRINT_JSON, "noroute", NULL, stats->rx_noroute);
1244                close_json_object();
1245
1246                /* TX stats */
1247                open_json_object("tx");
1248                print_u64(PRINT_JSON, "bytes", NULL, stats->tx_bytes);
1249                print_u64(PRINT_JSON, "packets", NULL, stats->tx_packets);
1250                print_u64(PRINT_JSON, "errors", NULL, stats->tx_errors);
1251                print_u64(PRINT_JSON, "dropped", NULL, stats->tx_dropped);
1252                close_json_object();
1253        } else {
1254                size_columns(cols, ARRAY_SIZE(cols), stats->rx_bytes,
1255                             stats->rx_packets, stats->rx_errors,
1256                             stats->rx_dropped, stats->rx_noroute);
1257                size_columns(cols, ARRAY_SIZE(cols), stats->tx_bytes,
1258                             stats->tx_packets, stats->tx_errors,
1259                             stats->tx_dropped, 0);
1260
1261                fprintf(fp, "%sRX: %*s %*s %*s %*s %*s%s", indent,
1262                        cols[0] - 4, "bytes", cols[1], "packets",
1263                        cols[2], "errors", cols[3], "dropped",
1264                        cols[4], "noroute", _SL_);
1265                fprintf(fp, "%s", indent);
1266                print_num(fp, cols[0], stats->rx_bytes);
1267                print_num(fp, cols[1], stats->rx_packets);
1268                print_num(fp, cols[2], stats->rx_errors);
1269                print_num(fp, cols[3], stats->rx_dropped);
1270                print_num(fp, cols[4], stats->rx_noroute);
1271                print_nl();
1272
1273                fprintf(fp, "%sTX: %*s %*s %*s %*s%s", indent,
1274                        cols[0] - 4, "bytes", cols[1], "packets",
1275                        cols[2], "errors", cols[3], "dropped", _SL_);
1276                fprintf(fp, "%s", indent);
1277                print_num(fp, cols[0], stats->tx_bytes);
1278                print_num(fp, cols[1], stats->tx_packets);
1279                print_num(fp, cols[2], stats->tx_errors);
1280                print_num(fp, cols[3], stats->tx_dropped);
1281        }
1282}
1283
1284static void print_mpls_stats(FILE *fp, struct rtattr *attr)
1285{
1286        struct rtattr *mrtb[MPLS_STATS_MAX+1];
1287        struct mpls_link_stats *stats;
1288
1289        parse_rtattr(mrtb, MPLS_STATS_MAX, RTA_DATA(attr),
1290                     RTA_PAYLOAD(attr));
1291        if (!mrtb[MPLS_STATS_LINK])
1292                return;
1293
1294        stats = RTA_DATA(mrtb[MPLS_STATS_LINK]);
1295        print_string(PRINT_FP, NULL, "    mpls:", NULL);
1296        print_nl();
1297        print_mpls_link_stats(fp, stats, "        ");
1298        print_string(PRINT_FP, NULL, "%s", "\n");
1299        fflush(fp);
1300}
1301
1302static void print_af_stats_attr(FILE *fp, int ifindex, struct rtattr *attr)
1303{
1304        bool if_printed = false;
1305        struct rtattr *i;
1306        int rem;
1307
1308        rem = RTA_PAYLOAD(attr);
1309        for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
1310                if (preferred_family != AF_UNSPEC &&
1311                    i->rta_type != preferred_family)
1312                        continue;
1313
1314                if (!if_printed) {
1315                        print_uint(PRINT_ANY, "ifindex",
1316                                   "%u:", ifindex);
1317                        print_color_string(PRINT_ANY, COLOR_IFNAME,
1318                                           "ifname", "%s",
1319                                           ll_index_to_name(ifindex));
1320                        print_nl();
1321                        if_printed = true;
1322                }
1323
1324                switch (i->rta_type) {
1325                case AF_MPLS:
1326                        print_mpls_stats(fp, i);
1327                        break;
1328                default:
1329                        fprintf(stderr, "    unknown af(%d)\n", i->rta_type);
1330                        break;
1331                }
1332        }
1333}
1334
1335struct af_stats_ctx {
1336        FILE *fp;
1337        int ifindex;
1338};
1339
1340static int print_af_stats(struct nlmsghdr *n, void *arg)
1341{
1342        struct if_stats_msg *ifsm = NLMSG_DATA(n);
1343        struct rtattr *tb[IFLA_STATS_MAX+1];
1344        int len = n->nlmsg_len;
1345        struct af_stats_ctx *ctx = arg;
1346        FILE *fp = ctx->fp;
1347
1348        len -= NLMSG_LENGTH(sizeof(*ifsm));
1349        if (len < 0) {
1350                fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
1351                return -1;
1352        }
1353
1354        if (ctx->ifindex && ifsm->ifindex != ctx->ifindex)
1355                return 0;
1356
1357        parse_rtattr(tb, IFLA_STATS_MAX, IFLA_STATS_RTA(ifsm), len);
1358
1359        if (tb[IFLA_STATS_AF_SPEC])
1360                print_af_stats_attr(fp, ifsm->ifindex, tb[IFLA_STATS_AF_SPEC]);
1361
1362        fflush(fp);
1363        return 0;
1364}
1365
1366static int iplink_afstats(int argc, char **argv)
1367{
1368        __u32 filt_mask = IFLA_STATS_FILTER_BIT(IFLA_STATS_AF_SPEC);
1369        const char *filter_dev = NULL;
1370        struct af_stats_ctx ctx = {
1371                .fp = stdout,
1372                .ifindex = 0,
1373        };
1374
1375        while (argc > 0) {
1376                if (strcmp(*argv, "dev") == 0) {
1377                        NEXT_ARG();
1378                        if (filter_dev)
1379                                duparg2("dev", *argv);
1380                        filter_dev = *argv;
1381                } else if (matches(*argv, "help") == 0) {
1382                        usage();
1383                } else {
1384                        fprintf(stderr,
1385                                "Command \"%s\" is unknown, try \"ip link help\".\n",
1386                                *argv);
1387                        exit(-1);
1388                }
1389
1390                argv++; argc--;
1391        }
1392
1393        if (filter_dev) {
1394                ctx.ifindex = ll_name_to_index(filter_dev);
1395                if (ctx.ifindex <= 0) {
1396                        fprintf(stderr,
1397                                "Device \"%s\" does not exist.\n",
1398                                filter_dev);
1399                        return -1;
1400                }
1401        }
1402
1403        new_json_obj(json);
1404
1405        if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask,
1406                                      NULL, NULL) < 0) {
1407                perror("Cannot send dump request");
1408                delete_json_obj();
1409                return 1;
1410        }
1411
1412        if (rtnl_dump_filter(&rth, print_af_stats, &ctx) < 0) {
1413                fprintf(stderr, "Dump terminated\n");
1414                delete_json_obj();
1415                return 1;
1416        }
1417
1418        delete_json_obj();
1419        return 0;
1420}
1421
1422static int iplink_prop_mod(int argc, char **argv, struct iplink_req *req)
1423{
1424        struct rtattr *proplist;
1425        char *dev = NULL;
1426        char *name;
1427
1428        proplist = addattr_nest(&req->n, sizeof(*req),
1429                                IFLA_PROP_LIST | NLA_F_NESTED);
1430
1431        while (argc > 0) {
1432                if (matches(*argv, "altname") == 0) {
1433                        NEXT_ARG();
1434                        if (check_altifname(*argv))
1435                                invarg("not a valid altname", *argv);
1436                        name = *argv;
1437                        addattr_l(&req->n, sizeof(*req), IFLA_ALT_IFNAME,
1438                                  name, strlen(name) + 1);
1439                } else if (matches(*argv, "help") == 0) {
1440                        usage();
1441                } else {
1442                        if (strcmp(*argv, "dev") == 0)
1443                                NEXT_ARG();
1444                        if (dev)
1445                                duparg2("dev", *argv);
1446                        if (check_altifname(*argv))
1447                                invarg("\"dev\" not a valid ifname", *argv);
1448                        dev = *argv;
1449                }
1450                argv++; argc--;
1451        }
1452        addattr_nest_end(&req->n, proplist);
1453
1454        if (!dev) {
1455                fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n");
1456                exit(-1);
1457        }
1458
1459        req->i.ifi_index = ll_name_to_index(dev);
1460        if (!req->i.ifi_index)
1461                return nodev(dev);
1462
1463        if (rtnl_talk(&rth, &req->n, NULL) < 0)
1464                return -2;
1465
1466        return 0;
1467}
1468
1469static int iplink_prop(int argc, char **argv)
1470{
1471        struct iplink_req req = {
1472                .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
1473                .n.nlmsg_flags = NLM_F_REQUEST,
1474                .i.ifi_family = preferred_family,
1475        };
1476
1477        if (argc <= 0) {
1478                usage();
1479                exit(-1);
1480        }
1481
1482        if (matches(*argv, "add") == 0) {
1483                req.n.nlmsg_flags |= NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND;
1484                req.n.nlmsg_type = RTM_NEWLINKPROP;
1485        } else if (matches(*argv, "del") == 0) {
1486                req.n.nlmsg_type = RTM_DELLINKPROP;
1487        } else if (matches(*argv, "help") == 0) {
1488                usage();
1489        } else {
1490                fprintf(stderr, "Operator required\n");
1491                exit(-1);
1492        }
1493        return iplink_prop_mod(argc - 1, argv + 1, &req);
1494}
1495
1496static void do_help(int argc, char **argv)
1497{
1498        struct link_util *lu = NULL;
1499
1500        if (argc <= 0) {
1501                usage();
1502                return;
1503        }
1504
1505        lu = get_link_kind(*argv);
1506        if (lu && lu->print_help)
1507                lu->print_help(lu, argc-1, argv+1, stdout);
1508        else
1509                usage();
1510}
1511
1512int do_iplink(int argc, char **argv)
1513{
1514        if (argc < 1)
1515                return ipaddr_list_link(0, NULL);
1516
1517        if (matches(*argv, "add") == 0)
1518                return iplink_modify(RTM_NEWLINK,
1519                                     NLM_F_CREATE|NLM_F_EXCL,
1520                                     argc-1, argv+1);
1521        if (matches(*argv, "set") == 0 ||
1522            matches(*argv, "change") == 0)
1523                return iplink_modify(RTM_NEWLINK, 0,
1524                                     argc-1, argv+1);
1525        if (matches(*argv, "replace") == 0)
1526                return iplink_modify(RTM_NEWLINK,
1527                                     NLM_F_CREATE|NLM_F_REPLACE,
1528                                     argc-1, argv+1);
1529        if (matches(*argv, "delete") == 0)
1530                return iplink_modify(RTM_DELLINK, 0,
1531                                     argc-1, argv+1);
1532        if (matches(*argv, "show") == 0 ||
1533            matches(*argv, "lst") == 0 ||
1534            matches(*argv, "list") == 0)
1535                return ipaddr_list_link(argc-1, argv+1);
1536
1537        if (matches(*argv, "xstats") == 0)
1538                return iplink_ifla_xstats(argc-1, argv+1);
1539
1540        if (matches(*argv, "afstats") == 0) {
1541                iplink_afstats(argc-1, argv+1);
1542                return 0;
1543        }
1544
1545        if (matches(*argv, "property") == 0)
1546                return iplink_prop(argc-1, argv+1);
1547
1548        if (matches(*argv, "help") == 0) {
1549                do_help(argc-1, argv+1);
1550                return 0;
1551        }
1552
1553        fprintf(stderr, "Command \"%s\" is unknown, try \"ip link help\".\n",
1554                *argv);
1555        exit(-1);
1556}
1557