iproute2: Life after ifconfig

The standard network tools ifconfig, netstat and route will be familiar to anyone with more than a passing interest in UNIX or any of its derivations. Linux is no exception, and if you hop on to your nearest Linux machine, you’ll find these installed. However, for the past few years ifconfig and its ilk (often collectively referred to as net-tools) have been deprecated in favour of the iproute2 suite.

iproute2 is a suite of tools developed to unify the functions provided by the traditional tools in one place under the ip command. Interface configuration, routing and tunnelling can now all be configured and managed using the ip command.

Interface configuration

Historically, interfaces are managed using the ifconfig command, and to get an overview of the interfaces you’d type ifconfig -a. With iproute2, interfaces addressing is managed through the address subcommand – which, like the rest of the subcommands for iproute2 can be shortened Cisco IOS-style, as long as it’s unique. In theory this means you can use ip a, but the manual page refers to it as ip addr, which I’ll use here for clarity. So, the equivalent of ifconfig -a is the self-explanatory ip addr show, which if we’re not specifying a specific interface can be shortened to simply ip addr:-

[root@example ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc
      pfifo_fast state DOWN qlen 1000
    link/ether 00:d0:b7:2d:ce:cf brd ff:ff:ff:ff:ff:ff
    inet brd scope global eth0

Most of this should be self-explanatory, and everything you would see with ifconfig -a you’ll see with ip addr.

Bringing up eth0 on a Linux box would usually consist of doing the following:-

[root@example ~]# ifconfig eth0 up
[root@example ~]# ifconfig eth0 netmask

With iproute2, control of interfaces themselves – both physical and logical – is through the link subcommand. Bringing up eth0 can be done with:-

[root@example ~]# ip link set eth0 up

Managing the addresses on an interface is through the aforementioned addr subcommand, so using our example again, we’d do something like this to add an IP to eth0:-

[root@example ~]# ip addr add dev eth0

I’ve used CIDR notation in this example, but you can use the normal dotted quad format for the netmask if you wish.

This also makes adding multiple IP addresses to interfaces really easy. To add to our example eth0 interface, you’d just do:-

[root@example ~]# ip addr add dev eth0

Showing the addresses on our eth0 interface only will show that both the addresses are now there:-

[root@example ~]# ip addr show dev eth0
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc
      pfifo_fast state DOWN qlen 1000
    link/ether 00:d0:b7:2d:ce:cf brd ff:ff:ff:ff:ff:ff
    inet brd scope global eth1
    inet scope global secondary eth1

Removing an IP from an interface is also straightforward:-

[root@example ~#] ip addr del dev eth0

Querying the interface again shows that is no longer assigned to eth0:-

[root@example ~]# ip addr show dev eth0
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc
      pfifo_fast state DOWN qlen 1000
    link/ether 00:d0:b7:2d:ce:cf brd ff:ff:ff:ff:ff:ff
    inet brd scope global eth1


Using netstat -rn is pretty much burned into the brains of most UNIX engineers, but luckily the iproute2 method is just as snappy. Routing management is handled with the route subcommand, and in line with addr and link, it can be shortened – ip r will work, but I usually settle for ip ro. The full command for showing the routing table is ip route show, but as with ip addr you can drop the show if you want to show the entire routing table:-

[root@example ~]# ip ro dev eth0  proto kernel  scope link  src
default via dev eth0

Adding and removing routes is accomplished with ip ro add and ip ro del respectively:-

[root@example ~]# ip ro add via
[root@example ~]# ip ro del via

One useful feature of ip route is the get function, which we can use to query the routing table for a particular network or address. In our example, querying for an address not on our local network shows that the route to it goes via our default gateway:-

[root@example ~]# ip ro get via dev eth0  src
    cache  mtu 1500 advmss 1460 hoplimit 64


arp -na is the traditional way you’d query the ARP table on a UNIX machine. You can accomplish this with iproute2 using ip neighbor (or ip neighbour for us not from the US), with ip n being the shortened extreme:-

[root@example ~]# ip neigh dev eth0 lladdr 00:02:a5:1f:cb:2d REACHABLE dev eth0 lladdr 00:09:43:bc:aa:80 REACHABLE

I’ll skip the example for this, but needless to say you can add and remove entries with ip neigh add and ip neigh del respectively.

A little helping hand

If you’re stuck, then the help argument can come in handy. If you specify help as an argument to ip itself, or to one of the subcommands, it’ll give you a quick overview of the options available. For example, for ip neighbor:-

[root@example ~]# ip neigh help
Usage: ip neigh { add | del | change | replace } { ADDR [ lladdr
          LLADDR ] [ nud { permanent | noarp | stale |
          reachable } ] | proxy ADDR } [ dev DEV ]
       ip neigh {show|flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]

Not forgetting IPv6…

I’ve purposely neglected to show any configuration of IPv6 addresses in this post, not because iproute2 can’t handle it, but for the exact opposite reason – the iproute2 suite will handle IPv6 addresses in exactly the same way as IPv4 addresses. All the commands used above can be used for both IPv4 and IPv6 configuration without any issues.

If there’s a reason you want to force the behaviour one way or the other, you can use the -4 and -6 switches. This isn’t needed normally, because when adding or removing an address, for example, iproute2 will happily recognise an IPv6 address instead of an IPv4 one. Where it does come in useful is if you want to limit the data returned in a query to just IPv6, or just IPv4. A real-world example of this is on one of my Linux machines, where ip -6 ro shows:-

[root@daedalus ~]# ip -6 ro
2001:470:XXXX:1::/64 dev eth0  proto kernel  metric 256  mtu 1500
  advmss 1440 hoplimit 0
fe80::/64 dev eth0  proto kernel  metric 256  mtu 1500 advmss 1440
  hoplimit 0
default via 2001:470:XXXX:1::1 dev eth0  metric 1  mtu 1500 advmss
  1440 hoplimit 0

…which comes in handy if you’re only interested in the IPv6 routing table.

What next?

This post only really scratches the surface of iproute2 – I’ve just covered the iproute2 equivalents of the most-used commands. It’s capable of much, much more, such as setting up tunnels, managing multiple routing tables and configuring interfaces for multicast to name a few. I’ll be covering some of these in more depth in future posts.

Further reading

6 comments to iproute2: Life after ifconfig

Leave a Reply




You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>