Linux iproute2 : ip and ip link overview - ebiken/doc-network GitHub Wiki

Index

ip command overview

ip command is part of iproute2 tools group, whoes syntax is
ip [ OPTIONS ] OBJECT { COMMAND | help }.

As described in man ip, COMMAND specifies the action to perform on the object. The set of possible actions depends on the object type.
Instead of man ip, use ip OBJECT help command to list available commands and argument syntax conventions.

An example for OBJECT=link:

$ ip link help
Usage: ip link add [link DEV] [ name ] NAME
                   [ txqueuelen PACKETS ]
                   [ address LLADDR ]
                   [ broadcast LLADDR ]
                   [ mtu MTU ] [index IDX ]
                   [ numtxqueues QUEUE_COUNT ]
                   [ numrxqueues QUEUE_COUNT ]
                   type TYPE [ ARGS ]
       ip link delete DEV type TYPE [ ARGS ]

       ip link set { dev DEVICE | group DEVGROUP } [ { up | down } ]
                          [ arp { on | off } ]
                          [ dynamic { on | off } ]
                          [ multicast { on | off } ]
                          [ allmulticast { on | off } ]
                          [ promisc { on | off } ]
                          [ trailers { on | off } ]
                          [ txqueuelen PACKETS ]
                          [ name NEWNAME ]
                          [ address LLADDR ]
                          [ broadcast LLADDR ]
                          [ mtu MTU ]
                          [ netns PID ]
                          [ netns NAME ]
                         [ link-netnsid ID ]
                          [ alias NAME ]
                          [ vf NUM [ mac LLADDR ]
                                   [ vlan VLANID [ qos VLAN-QOS ] ]
                                   [ rate TXRATE ] ]
                                   [ spoofchk { on | off} ] ]
                                   [ state { auto | enable | disable} ] ]
                          [ master DEVICE ]
                          [ nomaster ]
                          [ addrgenmode { eui64 | none } ]
       ip link show [ DEVICE | group GROUP ] [up] [master DEV] [type TYPE]
       ip link help [ TYPE ]

TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
          bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
          gre | gretap | ip6gre | ip6gretap | vti | nlmon |
          bond_slave | ipvlan }

Function called for each OBJECT are defined in static const struct cmd {}. (ip.c)
do_cmd() will be called when ip command is executed, and dp_link is called for ip link command where OBJECT is "link".

Note that rtnl_open() is called before do_cmd() to set struct rtnl_handle rth { .fd } (&rth ~ global scope) will be set to be used when calling sendmsg(rtnl->fd, &msg, 0);.

(iproute2/ip/ip.c)
161 int main(int argc, char **argv)
162 {
...
287
288         if (rtnl_open(&rth, 0) < 0)
289                 exit(1);
290
291         if (strlen(basename) > 2)
292                 return do_cmd(basename+2, argc, argv);
293
294         if (argc > 1)
295                 return do_cmd(argv[1], argc-1, argv+1);
296
297         rtnl_close(&rth);
298         usage();
299 }
(iproute2/ip/ip.c)
static int do_cmd(const char *argv0, int argc, char **argv)
{
        const struct cmd *c;

        for (c = cmds; c->cmd; ++c) {
                if (matches(argv0, c->cmd) == 0) {
                        return -(c->func(argc-1, argv+1));
static const struct cmd {
        const char *cmd;
        int (*func)(int argc, char **argv);
} cmds[] = {
...
        { "link",       do_iplink },
};

ip link : do_iplink()

do_iplink(int argc, char **argv) is defined in (iproue2/iplink.c).

If there are one or more COMMAND specified (argc > 0) and if iplink_have_newlink() is true, it will call iplink_modify() with arguments dependent to each COMMAND, "add / set / replace / delete".

int do_iplink(int argc, char **argv)
{
        if (argc > 0) {
                if (iplink_have_newlink()) {
                        if (matches(*argv, "add") == 0)
                                return iplink_modify(RTM_NEWLINK,
                                                     NLM_F_CREATE|NLM_F_EXCL,
                                                     argc-1, argv+1);
                        if (matches(*argv, "set") == 0 ||
                            matches(*argv, "change") == 0)
                                return iplink_modify(RTM_NEWLINK, 0,
                                                     argc-1, argv+1);
                        if (matches(*argv, "replace") == 0)
                                return iplink_modify(RTM_NEWLINK,
                                                     NLM_F_CREATE|NLM_F_REPLACE,
                                                     argc-1, argv+1);
                        if (matches(*argv, "delete") == 0)
                                return iplink_modify(RTM_DELLINK, 0,
                                                     argc-1, argv+1);
                } else {

If iplink_have_newlink() was not true and IPLINK_IOCTL_COMPAT was defined, do_set(argc-1, argv+1) will be called for COMMAND, "set".
If IPLINK_IOCTL_COMPAT was not defined, it would do nothing and move to next line.

#if IPLINK_IOCTL_COMPAT
                        if (matches(*argv, "set") == 0)
                                return do_set(argc-1, argv+1);
#endif
                }

If COMMAND was "show / lst / list", or if no COMMAND was specified (i.e. ip link), ipaddr_list_link(argc-1, argv+1) will be called and list of link will be displayed.

Example of ip link which result is exactly same as ip link show / lst / list.

$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000

If COMMAND was "help", then do_help(argc-1, argv+1) will be called to show available commands and argument syntax conventions. (See ip link help above for output example.)

                }
                if (matches(*argv, "show") == 0 ||
                    matches(*argv, "lst") == 0 ||
                    matches(*argv, "list") == 0)
                        return ipaddr_list_link(argc-1, argv+1);
                if (matches(*argv, "help") == 0) {
                        do_help(argc-1, argv+1);
                        return 0;
                }
        } else
                return ipaddr_list_link(0, NULL);

        fprintf(stderr, "Command \"%s\" is unknown, try \"ip link help\".\n", *argv);
        exit(-1);
}

[ Next: Linux iproute2 : ip link bridge operations ]