Saturday, March 26, 2011

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 127.0.0.1/8 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 192.0.2.1/24 brd 192.0.2.255 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 192.0.2.1 netmask 255.255.255.0
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 192.0.2.1/24 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 192.0.2.2 to our example eth0 interface, you’d just do:-
[root@example ~]# ip addr add 192.0.2.2/24 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 192.0.2.1/24 brd 192.0.2.255 scope global eth1
    inet 192.0.2.2/24 scope global secondary eth1
Removing an IP from an interface is also straightforward:-
[root@example ~#] ip addr del 192.0.2.2/24 dev eth0
Querying the interface again shows that 192.0.2.2 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 192.0.2.1/24 brd 192.0.2.255 scope global eth1

Routing

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
192.0.2.0/24 dev eth0  proto kernel  scope link  src 192.0.2.1
default via 192.0.2.254 dev eth0
Adding and removing routes is accomplished with ip ro add and ip ro del respectively:-
[root@example ~]# ip ro add 10.0.0.0/16 via 192.0.2.253
[root@example ~]# ip ro del 10.0.0.0/16 via 192.0.2.253
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 1.2.3.4
1.2.3.4 via 192.0.2.254 dev eth0  src 192.0.2.1
    cache  mtu 1500 advmss 1460 hoplimit 64

Neighbours

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
192.0.2.3 dev eth0 lladdr 00:02:a5:1f:cb:2d REACHABLE
192.0.2.254 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

Courtesy : http://andys.org.uk/bits/2010/02/24/iproute2-life-after-ifconfig/