Mastering the `ip` Command: The Modern Replacement for `ifconfig` (and Why You Should Use It)
If you’ve worked with Linux networking for any length of time, you’ve probably used ifconfig (from the net-tools package) to configure interfaces, set IP addresses, or check network status. But here’s a hard truth: net-tools is deprecated. The Linux community has moved on to iproute2—a powerful suite of tools that includes the ip command—for all network configuration tasks.
Why does this matter? The ip command is:
- More feature-rich: Supports modern networking technologies (IPv6, VLANs, tunnels, namespaces) that
ifconfigstruggles with. - More efficient: Uses the netlink protocol (instead of legacy
ioctl) to communicate with the kernel, enabling asynchronous updates and better performance. - Actively maintained: Net-tools hasn’t been updated in years, while iproute2 receives regular improvements.
This blog will teach you everything you need to know about ip—from basic interface management to advanced topics like namespaces and policy routing. By the end, you’ll be able to replace ifconfig with confidence and leverage ip’s full potential.
Table of Contents#
- Why
ipReplacesifconfig(and Net-Tools) - Core Concepts: Iproute2 and Netlink
- Diving into
ipSubcommands - Common Workflows with
ip - Best Practices for Using
ip - Migrating from
ifconfigtoip: Cheat Sheet - Conclusion
- References
1. Why ip Replaces ifconfig (and Net-Tools)#
Net-tools (which includes ifconfig, netstat, and arp) relies on ioctl—a legacy system call for device control. Ioctl is:
- Synchronous: The kernel can’t notify user-space of changes (e.g., a link going down) without polling.
- Limited: Doesn’t support modern features like multiple IP addresses per interface, IPv6 autoconfiguration, or network namespaces.
Iproute2 (and ip) uses netlink—a modern, socket-based protocol that:
- Supports asynchronous messages: The kernel can push updates to user-space (e.g., "interface eth0 is now DOWN").
- Is object-oriented: You operate on network objects (links, addresses, routes) instead of raw device settings.
- Scales: Works with thousands of interfaces (critical for cloud/container environments).
Most modern Linux distributions (Ubuntu 20.04+, RHEL 8+, Fedora 30+) ship with iproute2 preinstalled. Net-tools is often an optional package—and may not be available at all in minimal installations.
2. Core Concepts: Iproute2 and Netlink#
Before diving into ip, let’s clarify key terms:
What is Iproute2?#
Iproute2 is a suite of tools for Linux networking. The most important ones are:
ip: Configure interfaces, addresses, routes, and namespaces.tc: Traffic control (QoS, bandwidth shaping).ss: Monitor sockets (replacesnetstat).nstat: Network statistics (replacesnetstat -s).
What is Netlink?#
Netlink is a communication protocol between user-space (your terminal) and kernel-space (the Linux network stack). It’s used by iproute2 to:
- Send configuration commands to the kernel (e.g., "add IP 192.168.1.10 to eth0").
- Receive notifications from the kernel (e.g., "eth0 lost carrier").
Netlink is the backbone of modern Linux networking—without it, tools like Docker or Kubernetes couldn’t exist.
3. Diving into ip Subcommands#
The ip command follows a simple syntax:
ip [ OPTIONS ] OBJECT { COMMAND | help }Where:
OBJECT: The network resource you want to modify (e.g.,link,addr,route).COMMAND: The action to take (e.g.,show,add,delete).
Let’s explore the most common objects.
3.1 Link Management: ip link#
A link is a physical or virtual network interface (e.g., eth0, wlan0, veth0). The ip link command manages these interfaces.
Common Use Cases#
| Task | Command |
|---|---|
| Show all links | ip link show |
| Show details for a specific link | ip link show dev eth0 |
| Bring a link up | sudo ip link set eth0 up |
| Bring a link down | sudo ip link set eth0 down |
| Change MTU (e.g., jumbo frames) | sudo ip link set eth0 mtu 9000 |
| Rename a link | sudo ip link set eth0 name lan0 |
| Change MAC address (spoofing) | sudo ip link set eth0 address 00:11:22:33:44:55 |
Key Output Fields#
When you run ip link show eth0, you’ll see:
- State:
UP(active) orDOWN(inactive). - MAC address:
link/ether 00:11:22:33:44:55. - MTU: Maximum packet size (default: 1500 for Ethernet).
- qdisc: Queueing discipline (e.g.,
mqfor multi-queue).
Example: Check Link Status#
$ ip link show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ffThe <UP,LOWER_UP> flags mean the interface is active and has carrier (connected to a switch).
3.2 Address Management: ip addr#
The ip addr command manages IP addresses assigned to links. Unlike ifconfig, ip supports:
- Multiple IP addresses per interface.
- IPv6 link-local addresses (e.g.,
fe80::/10). - CIDR notation (e.g.,
/24instead of255.255.255.0).
Common Use Cases#
| Task | Command |
|---|---|
| Show all addresses | ip addr show |
| Show addresses for a link | ip addr show dev eth0 |
| Add an IPv4 address | sudo ip addr add 192.168.1.10/24 dev eth0 |
| Add an IPv6 address | sudo ip addr add 2001:db8::1/64 dev eth0 |
| Delete an address | sudo ip addr del 192.168.1.10/24 dev eth0 |
| Replace an existing address | sudo ip addr replace 192.168.1.11/24 dev eth0 |
| Flush all addresses from a link | sudo ip addr flush dev eth0 |
Key Concepts#
- CIDR Notation: Use
/prefix(e.g.,/24) instead of netmasks. It’s more concise and widely adopted. - Scope: Defines where the address is valid:
global: Accessible from anywhere (public IPv4/IPv6).link: Only valid on the local link (e.g., IPv6 link-local).host: Only valid for the local system (loopback).
- Label: A nickname for multiple addresses on the same interface (e.g.,
eth0:1). Uselabelto avoid conflicts:sudo ip addr add 192.168.1.10/24 dev eth0 label eth0:office
Example: Add Multiple Addresses#
# Add IPv4 and IPv6 addresses to eth0
sudo ip addr add 192.168.1.10/24 dev eth0
sudo ip addr add 2001:db8::1/64 dev eth0
# Verify
ip addr show dev eth03.3 Routing: ip route#
The ip route command manages the routing table—a list of rules that tell the kernel how to forward traffic to remote networks.
Common Use Cases#
| Task | Command |
|---|---|
| Show the main routing table | ip route show |
| Add a default route (IPv4) | sudo ip route add default via 192.168.1.1 dev eth0 |
| Add a static route (remote network) | sudo ip route add 10.0.0.0/24 via 192.168.1.254 dev eth0 |
| Delete a route | sudo ip route del 10.0.0.0/24 |
| Flush all routes | sudo ip route flush all |
| Check which route is used for a target | ip route get 8.8.8.8 |
Key Concepts#
- Default Route: The "catch-all" route for traffic not matching any other rule (usually your router’s IP).
- Gateway: The next-hop IP address for remote traffic.
- Dev: The exit interface for the route (e.g.,
eth0). - Metric: A priority value (lower = higher priority). Use this for load balancing or failover:
# Add two default routes with different metrics sudo ip route add default via 192.168.1.1 dev eth0 metric 100 sudo ip route add default via 192.168.1.2 dev eth0 metric 200
Example: Verify Routing#
$ ip route show
default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.10 metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10proto dhcp: The route was added by DHCP.scope link: The route is valid only on the local link.
3.4 Neighbor (ARP/NDP) Management: ip neigh#
The ip neigh command manages the neighbor table—a mapping of IP addresses to MAC addresses. For IPv4, this is the ARP table; for IPv6, it’s NDP (Neighbor Discovery Protocol).
Common Use Cases#
| Task | Command |
|---|---|
| Show the neighbor table | ip neigh show |
| Add a static ARP entry | sudo ip neigh add 192.168.1.5 lladdr 00:11:22:33:44:55 dev eth0 |
| Delete an entry | sudo ip neigh del 192.168.1.5 dev eth0 |
| Flush the table | sudo ip neigh flush all |
Key States#
- REACHABLE: The entry is valid (recently used).
- STALE: The entry hasn’t been used in a while (will be refreshed on next use).
- PERMANENT: A static entry (won’t expire).
- FAILED: The ARP request timed out (indicates a connectivity issue).
Example: Check ARP Entries#
$ ip neigh show
192.168.1.1 dev eth0 lladdr 00:aa:bb:cc:dd:ee STALE
192.168.1.5 dev eth0 lladdr 00:11:22:33:44:55 PERMANENT3.5 Tunnels: ip tunnel#
Tunnels let you encapsulate one network protocol within another (e.g., IPv6 over IPv4, GRE for VPNs). The ip tunnel command creates and manages tunnel interfaces.
Common Use Cases#
| Task | Command |
|---|---|
| Show all tunnels | ip tunnel show |
| Create a GRE tunnel | sudo ip tunnel add gre0 mode gre remote 198.51.100.1 local 203.0.113.1 ttl 255 |
| Bring up a tunnel | sudo ip link set gre0 up |
| Add an IP address to a tunnel | sudo ip addr add 10.1.1.1/24 dev gre0 |
| Delete a tunnel | sudo ip tunnel del gre0 |
Example: GRE Tunnel Setup#
Suppose you have two servers:
- Local:
203.0.113.1(public IP) - Remote:
198.51.100.1(public IP)
Create a tunnel between them:
# On local server
sudo ip tunnel add gre0 mode gre remote 198.51.100.1 local 203.0.113.1 ttl 255
sudo ip link set gre0 up
sudo ip addr add 10.1.1.1/24 dev gre0
# On remote server
sudo ip tunnel add gre0 mode gre remote 203.0.113.1 local 198.51.100.1 ttl 255
sudo ip link set gre0 up
sudo ip addr add 10.1.1.2/24 dev gre0
# Test connectivity
ping 10.1.1.2 # From local server3.6 VLANs and Virtual Interfaces#
VLANs (Virtual Local Area Networks) segment a physical network into logical subnets. The ip link command creates VLAN interfaces using the type vlan parameter.
Create a VLAN Interface#
# Create VLAN 10 on eth0 (interface name: eth0.10)
sudo ip link add link eth0 name eth0.10 type vlan id 10
# Bring it up and assign an IP
sudo ip link set eth0.10 up
sudo ip addr add 192.168.10.10/24 dev eth0.10Virtual Ethernet (veth) Pairs#
Veth pairs are "virtual cables" that connect two network namespaces (e.g., a container and the host). Use type veth to create them:
# Create a veth pair (veth0 and veth1)
sudo ip link add veth0 type veth peer name veth13.7 Namespaces: ip netns#
Network namespaces are isolated network environments—processes in a namespace can’t see interfaces, routes, or neighbors from other namespaces. This is how containers (Docker, Kubernetes) achieve network isolation.
Common Use Cases#
| Task | Command |
|---|---|
| Create a namespace | sudo ip netns add ns1 |
| List namespaces | ip netns list |
| Run a command in a namespace | sudo ip netns exec ns1 ping 8.8.8.8 |
| Delete a namespace | sudo ip netns del ns1 |
Example: Isolated Namespace Setup#
Let’s create a namespace (ns1) and connect it to the host using a veth pair:
-
Create a veth pair:
sudo ip link add veth0 type veth peer name veth1 -
Move one end to the namespace:
sudo ip link set veth1 netns ns1 -
Configure the host side:
sudo ip link set veth0 up sudo ip addr add 10.0.0.1/24 dev veth0 -
Configure the namespace:
# Enter the namespace sudo ip netns exec ns1 bash # Bring up veth1 and set IP ip link set lo up # Enable loopback (required for some tools) ip link set veth1 up ip addr add 10.0.0.2/24 dev veth1 # Test connectivity to the host ping 10.0.0.1 -
Exit the namespace:
exit
This setup lets you test network configurations without affecting the host.
4. Common Workflows with ip#
Let’s walk through real-world scenarios where ip shines.
4.1 Basic Network Setup#
Suppose you want to configure eth0 with a static IP:
# 1. Bring up the interface
sudo ip link set eth0 up
# 2. Add an IPv4 address
sudo ip addr add 192.168.1.10/24 dev eth0
# 3. Add a default route
sudo ip route add default via 192.168.1.1 dev eth0
# 4. Verify
ip addr show dev eth0
ip route showCompare this to ifconfig:
# Legacy ifconfig command (don’t use this!)
sudo ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up
sudo route add default gw 192.168.1.1 eth0The ip version is more explicit and supports modern features.
4.2 Troubleshooting Connectivity#
If you can’t reach a remote server (e.g., 8.8.8.8), use these steps:
-
Check if the interface is up:
ip link show eth0 # Look for <UP,LOWER_UP> -
Verify the interface has an IP:
ip addr show dev eth0 -
Check the default route:
ip route show | grep default -
Ping the gateway:
ping 192.168.1.1 # Replace with your gateway IP -
Check ARP entries for the gateway:
ip neigh show dev eth0 | grep 192.168.1.1 -
Check if the remote IP is reachable:
ip route get 8.8.8.8 # Shows which route is used ping 8.8.8.8
If the ping fails at step 5, the gateway’s MAC address is missing—check the physical connection!
4.3 Isolated Testing with Namespaces#
Suppose you want to test a new firewall rule without breaking the host network. Use a namespace:
-
Create a namespace:
sudo ip netns add test-ns -
Create a veth pair and connect it to the namespace:
sudo ip link add veth0 type veth peer name veth1 sudo ip link set veth1 netns test-ns -
Configure the host and namespace:
# Host side sudo ip link set veth0 up sudo ip addr add 10.0.0.1/24 dev veth0 # Namespace side sudo ip netns exec test-ns ip link set lo up sudo ip netns exec test-ns ip link set veth1 up sudo ip netns exec test-ns ip addr add 10.0.0.2/24 dev veth1 -
Test connectivity:
# From the host ping 10.0.0.2 # From the namespace sudo ip netns exec test-ns ping 10.0.0.1
This setup lets you test firewall rules (e.g., iptables) in isolation.
5. Best Practices for Using ip#
Follow these rules to avoid mistakes and write maintainable scripts:
1. Use Explicit Commands in Scripts#
Avoid shortcuts (e.g., ip a for ip addr)—they’re harder to read in scripts. Use full commands:
# Good
sudo ip link set eth0 up
# Bad (don’t do this!)
sudo ip l set eth0 up2. Back Up Before Making Changes#
Always save your routing table or addresses before modifying them:
# Backup routing table
ip route show > route_backup.txt
# Backup addresses for eth0
ip addr show dev eth0 > eth0_addr_backup.txt3. Use CIDR Notation#
CIDR (/24) is more concise and less error-prone than netmasks (255.255.255.0).
4. Prefer replace Over add in Scripts#
Use replace to overwrite existing addresses/routes (avoids "address already exists" errors):
# Add or replace an IP address
sudo ip addr replace 192.168.1.10/24 dev eth05. Use Namespaces for Testing#
Never test network changes on a production host. Use namespaces to isolate experiments.
6. Use ss Instead of netstat#
The ss command (from iproute2) is faster and more feature-rich than netstat. Use it to check open ports:
# Show all TCP ports (listen state)
ss -tuln6. Migrating from ifconfig to ip: Cheat Sheet#
Use this table to translate legacy ifconfig commands to ip:
Legacy ifconfig Command | Equivalent ip Command |
|---|---|
ifconfig eth0 up | ip link set eth0 up |
ifconfig eth0 down | ip link set eth0 down |
ifconfig eth0 192.168.1.10/24 | ip addr add 192.168.1.10/24 dev eth0 |
ifconfig eth0 netmask 255.255.255.0 | ip addr add 192.168.1.10/24 dev eth0 |
ifconfig eth0 hw ether 00:11:22:33:44:55 | ip link set eth0 address 00:11:22:33:44:55 |
ifconfig -a | ip link show |
route add default gw 192.168.1.1 | ip route add default via 192.168.1.1 dev eth0 |
arp -a | ip neigh show |
netstat -nr | ip route show |
netstat -tuln | ss -tuln |
7. Conclusion#
The ip command is the future of Linux networking. It’s more powerful, more efficient, and better supported than ifconfig. By learning ip, you’ll:
- Master modern networking features (VLANs, tunnels, namespaces).
- Write scripts that work on all modern Linux distributions.
- Troubleshoot complex issues faster (thanks to netlink’s asynchronous updates).
If you’re still using ifconfig, now is the time to switch. Start with basic tasks (setting an IP, checking routes) and work your way up to advanced topics like namespaces. The investment will pay off—especially in cloud or container environments where ip is the only game in town.
8. References#
- Iproute2 Official Wiki: https://wiki.linuxfoundation.org/networking/iproute2
ipMan Page: https://man7.org/linux/man-pages/man8/ip.8.html- Linux Kernel Netlink Documentation: https://www.kernel.org/doc/html/latest/networking/netlink.html
- Red Hat Ip Command Guide: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/using-the-ip-command_configuring-and-managing-networking
- Ubuntu Network Configuration: https://ubuntu.com/server/docs/network-configuration
Let me know if you have questions—happy to help!