Skip to content
Tech News
← Back to articles

Task-centered iproute2 user guide

read original more articles
Why This Matters

The iproute2 toolkit is a crucial upgrade from legacy Linux networking tools, offering advanced features and unified command management for network configuration. Its comprehensive, task-centered documentation enhances usability for both developers and system administrators, promoting more efficient network management. As Linux continues to evolve, mastering iproute2 is essential for leveraging modern networking capabilities and maintaining robust, scalable systems.

Key Takeaways

Task-centered iproute2 user guide

# Overview of iproute2 iproute2 is the Linux networking toolkit that replaced legacy tools ( ifconfig , vconfig , brctl , route , arp etc.). Those tools are only kept for compatibility with old scripts and do not provide access to a lot of newer networking features of the Linux kernel. It originally written by Alex Kuznetsov and is now maintained by Stephen Hemminger. Most of the networking functionality is unified in the ip command. There’s also tc for managing traffic policies (QoS), bridge for managing software bridge interfaces, and ss (a netstat replacement). Those commands are usually shipped in a package called iproute2 or iproute . Most Linux distributions install it by default these days. The ip command is sometimes installed in /sbin and thus may not be in the $PATH of unprivileged users by default.

# About this document Historically, documentation has been a weak side of iproute2. The official man pages list available options but don’t give almost any usage examples. That need has been addressed by third-party documentation. This document aims to provide a comprehensive but easy to use guide to the ip and bridge commands, and some information about ss . Documenting tc in this style would be a separate big project. The document is task-centered: it tells you how to do different tasks using iproute2 commands instead of listing available subcommands.

# Contributing This document is maintained by Daniil Baturin and distributed under CC-BY-SA 4.0 — a strong copyleft, free culture license. Contributions are always welcome; you can find the source files at github.com/dmbaturin/iproute2-cheatsheet. git clone https://github.com/dmbaturin/iproute2-cheatsheet.git You can also show your support by buying the maintainer a metaphorical coffee. This document is provided “as is”, without any warranty. The authors are not liable for any damage related to using it. As usual, think before you type, and think twice before hitting the Enter key.

# Typographic conventions Metasyntactic variables are written in a shell-like syntax, ${something} . Optional command parts are in square brackets. Mandatory arguments are in angle brackets.

# General notes All commands that change any settings require root privileges. Commands that just display information generally do not require special privileges. There are configuration files in /etc/iproute2 , mainly for assigning symbolic names to network stack entities such as routing tables. Those files are re-read every time you run the ip command, so you don’t need to do anything to apply the changes.

# Abbreviating commands Any ip command can be abbreviated. For example, ip address add 192.0.2.1/24 dev eth0 can be written ip addr a 192.0.2.1/24 dev eth0 or even ip a a 192.0.2.1/24 dev eth0 . In some cases, you can even omit words. For example, show and list words are always fine to omit: ip address is equivalent to ip address show and ip address list . Note that the abbreviation system is not always consistent. The dev keyword in ip a a 192.0.2.1/24 dev eth0 cannot be abbreviated, even though every other word can be. This document intentionally gives all commands in their fullest form for better readability. It’s also a good idea to use full forms in scripts because readers may not be familiar with abbreviations, and code is read much more often than it’s written.

# Scripting considerations A common complaint about distributions removing ifconfig is that it forces people to rewrite scripts. However, iproute2 is better for scripting since it supports machine-readable output. It provides the following output options: -o ( --oneline ) Replaces every line break with a backslash. Supported since the earliest versions. -br ( --brief ) Produces a terse, machine-oriented output. Perfect for dissecting with awk/cut. Supported since at least 4.11. -j ( --json ) Produces JSON output, perfect for non-shell scripts. Supports --pretty and --brief options. Supported since at least 4.13. Here is a comparison of outputs ( --json --pretty and --json --brief are omitted to save space): $ ip --oneline address show lo 1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever 1: lo inet6 ::1/128 scope host \ valid_lft forever preferred_lft forever $ ip --brief address show lo lo UNKNOWN 127.0.0.1/8 ::1/128 $ ip --json --brief address show lo [{"ifname": "lo", "operstate": "UNKNOWN", "addr_info": [{"local": "127.0.0.1", "prefixlen": 8},{"local": "::1", "prefixlen": 128}]}, {}, {}]

# IPv4 and IPv6 addresses iproute2 accepts both dotted decimal masks and prefix length values. That is, both 192.0.2.10/24 and 192.0.2.10/255.255.255.0 are acceptable formats. # Show all addresses ip address show All show commands can be used with -4 or -6 options to show only IPv4 or IPv6 addresses. # Show addresses for a single interface ip address show ${interface name} Examples: ip address show eth0 # Show addresses only for running interfaces ip address show up # Show only static or dynamic IPv6 addresses Show only statically configured addresses: ip address show [dev ${interface}] permanent Show only addresses learnt via autoconfiguration: ip address show [dev ${interface}] dynamic # Add an address to an interface ip address add ${address}/${mask} dev ${interface name} Examples: ip address add 192.0.2.10/27 dev eth0 ip address add 2001:db8:1::/48 dev tun10 You can add as many addresses as you want. If you add more than one address, your machine will accept packets for all of them. The first address you add becomes a “primary address”. The primary address of an interface it’s used as the source address for outgoing packets by default. All additional addresses you set will become secondary addresses. # Add an address with a human-readable description ip address add ${address}/${mask} dev ${interface name} label ${interface name}:${description} Examples: ip address add 192.0.2.1/24 dev eth0 label eth0:WANaddress The label must start with the interface name followed by a colon due to some backward compatibility issues, otherwise you’ll get an error. Keep the label shorter than sixteen characters, or else you’ll get this error: RTNETLINK answers: Numerical result out of range . Notes For IPv6 addresses, this command has no effect. It will add the address correctly but will ignore the label. # Delete an address from an interface ip address delete ${address}/${prefix} dev ${interface name} Examples: ip address delete 192.0.2.1/24 dev eth0 ip address delete 2001:db8::1/64 dev tun1 An interface name is required—the kernel will not try to automatically guess which interface you want to remove that address from. Such a guess would not always be unambiguous: Linux does allow the same address to be configured on multiple interfaces, and it has valid use cases (in the Cisco world, this is known as “unnumbered interfaces”). # Remove all addresses from an interface ip address flush dev ${interface name} Examples: ip address flush dev eth1 By default, this command removes both IPv4 and IPv6 addresses. If you want to remove only IPv4 or IPv6 addresses, use ip -4 address flush or ip -6 address flush . # Change the primary address There is no way to swap primary and secondary IPv4 addresses or explicitly set a new primary IPv4 address. Try to always set the primary address first. If the sysctl variable net.ipv4.conf.${interface}.promote_secondaries is set to 1, when you delete a primary address, the first secondary address becomes primary. You can enable this behaviour globally with net.ipv4.conf.default.promote_secondaries=1 . Note that when promote_secondaries is set to 0, removing a primary address will also remove all secondary addresses from its interface. This setting varies between Linux distributions, so be careful to check it before attempting to change a primary address. Secondary IPv6 addresses are always promoted to primary if a primary address is deleted.

# Neighbor (ARP and NDP) tables This command supports both American ( ip neighbor ) and British ( ip neighbour ) spelling variants. # View neighbor tables ip neighbor show All “show” commands support -4 and -6 options to view only IPv4 (ARP) or IPv6 (NDP) neighbors. By default, all neighbors are displayed. # View neighbors for a specific interface ip neighbor show dev ${interface name} Examples: ip neighbor show dev eth0 # Flush table for an interface ip neighbor flush dev ${interface name} Examples: ip neighbor flush dev eth1 # Add a neighbor table entry ip neighbor add ${network address} lladdr ${link layer address} dev ${interface name} Examples: ip neighbor add 192.0.2.1 lladdr 22:ce:e0:99:63:6f dev eth0 One use case for it is a form of data link layer security. You can disable ARP on an interface completely and add MAC addresses of authorized devices by hand. # Delete a neighbor table entry ip neighbor delete ${network address} lladdr ${link layer address} dev ${interface name} Examples: ip neighbor delete 192.0.2.1 lladdr 22:ce:e0:99:63:6f dev eth0 Allows you to delete a static entry or get rid of an automatically learnt entry without flushing the table.

... continue reading