Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

ip: manage the Linux network from the command line

By updated

Improve this page

When you need to diagnose a network problem, add an IP address or configure a route, the ip command is the modern, official tool on Linux. It replaces the historical ifconfig, route, arp and netstat commands of the net-tools package, which distributions no longer install by default. With a consistent OBJECT + COMMAND syntax, ip manages every aspect of the network from a single tool.

What you will learn

  • Display and interpret the network configuration (interfaces, IPs, routes)
  • Add, change and remove IP addresses
  • Manage static routes and the default gateway
  • Bring network interfaces up and down
  • Diagnose connectivity problems
  • Read the ARP cache (network neighbours)

The ip command in the network toolbox

ip centralises network management, but other commands remain useful for specific diagnostics:

CommandSpecialityWhen to use it
ipNetwork configuration and stateInterfaces, IPs, routes, ARP
ssSockets and connectionsListening ports, established connections
pingConnectivity testCheck that a host answers
mtrReal-time tracerouteDiagnose latency and loss
digDNS queriesTest name resolution

Mapping with the deprecated commands:

Old commandip equivalent
ifconfigip addr, ip link
ifconfig eth0 upip link set eth0 up
route -nip route show
route add default gwip route add default via
arp -aip neigh show
netstat -iip -s link

Understand the ip command in 2 minutes

Every ip command follows the same word order, which spares you learning a different syntax for each task. You first name the object you act on (an address, an interface, a route), then the action to carry out on that object. Global options go before the object and only change how the output is presented.

🧠 Mental model: ip, the modern network Swiss army knife

The ip command follows one consistent structure: you pick an OBJECT (what you want to manage) then a COMMAND (what you want to do). It reads like an instruction to a colleague: "ip, on the address OBJECT, do the show ACTION".

The ip command reads from left to right: ip, then the object (addr, link, route, neigh), then the command (show, add, del, set, flush), then the arguments, for example ip addr add 192.168.1.10/24 dev eth0.ipOBJECTaddr · link · route · neighCOMMANDshow · add · del · set · flushARGUMENTSdev eth0 · 192.168.1.10/24 · via 192.168.1.1ip addr add 192.168.1.10/24 dev eth0
Source · SVG
Esc to close, + and − to zoom, scroll to move around. 100 %

Key points

  • ip replaces ifconfig, route, arp and netstat, the net-tools commands that distributions no longer install by default
  • Everything is OBJECT + COMMAND: ip addr show, ip route add, ip link set
  • Objects have abbreviations: addr→a, link→l, route→r, neigh→n
  • Changes are temporary unless persisted in the system configuration

Golden rules

1
ip addr ≠ ip link addr manages IP addresses, link manages the physical state of the interface (up/down, MTU)
2
Always check after a change ip addr show or ip route show to confirm that the change took effect
3
Changes are volatile At reboot everything is lost unless it is configured in /etc/network/interfaces or netplan

Essential vocabulary

addr
Object that manages the IP addresses (IPv4/IPv6) of interfaces
link
Object that manages the state and properties of interfaces (up/down, MTU, MAC)
route
Object that manages the routing table (static routes, gateway)
neigh
Object that manages the ARP/NDP cache (network neighbours)
CIDR
IP/mask notation such as 192.168.1.10/24 (equivalent to netmask 255.255.255.0)
scope
Reach of the address: global (routable), link (local), host (loopback)
📚 Going further: 4 advanced options
netns
Object that manages network namespaces (network isolation for containers)
vrf
Virtual Routing and Forwarding, separate routing tables
xfrm
IPsec transformation framework (encrypted tunnels)
maddr
Multicast addresses of the interfaces

The logic of ip is simple: you choose what you want to manage (the object) then what you want to do (the command).

Complete syntax

Only the object is mandatory: ip addr is enough, because show is the implicit command when none is given.

Terminal window
ip [OPTIONS] OBJECT COMMAND [ARGUMENTS]

The 4 essential objects:

ObjectAbbreviationWhat it manages
addraIP addresses of the interfaces
linklPhysical state of the interfaces (up/down, MTU)
routerRouting table
neighnARP/NDP cache (network neighbours)

The main commands:

CommandWhat it does
show (or s)Display (the default if omitted)
addAdd
delDelete
setChange (for link)
flushEmpty everything
replaceReplace if it exists

Useful global options:

OptionDescriptionExample
-cColoured outputip -c addr
-4 / -6IPv4 or IPv6 onlyip -4 addr
-oOne line per recordip -o addr
-jJSON outputip -j addr
-sDetailed statisticsip -s link
-brBrief format (summary)ip -br addr

Fundamental examples

Read commands run without any particular privilege; as soon as a command changes the network state, it needs sudo, otherwise the kernel answers Operation not permitted.

Terminal window
# Show all IP addresses
ip addr show
ip a # Short form
# Show the routing table
ip route show
ip r # Short form
# Show the active interfaces
ip link show up
# Add an IP address
sudo ip addr add 192.168.1.100/24 dev eth0
# Bring an interface up
sudo ip link set eth0 up
# Add a default route
sudo ip route add default via 192.168.1.1

Manage IP addresses (ip addr)

The addr object manages the IPv4 and IPv6 addresses assigned to interfaces. One interface can carry several at the same time, with no practical limit: this is how a server hosts several services on distinct addresses. Every change made here lives only in memory and disappears at reboot, a point developed at the end of the guide.

Display the addresses

-br (brief) reduces each interface to one line: name, state, addresses. It is the view to favour to quickly spot the interface you care about before looking at it more closely.

Terminal window
# All interfaces
ip addr show
# One specific interface
ip addr show dev eth0
# Summary format (more readable)
ip -br addr show
# Example output:
# lo UNKNOWN 127.0.0.1/8 ::1/128
# eth0 UP 192.168.1.50/24 fe80::1/64

Interpret the output

The full output condenses four pieces of information per interface: its administrative state, its hardware address, its IP addresses and their scope. Two flags look alike but do not say the same thing: UP means you brought the interface up, LOWER_UP that the cable is actually plugged in and the link negotiated. An UP interface without LOWER_UP therefore points to a physical problem, not a configuration error.

Terminal window
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.50/24 brd 192.168.1.255 scope global eth0
inet6 fe80::5054:ff:fe12:3456/64 scope link
ElementMeaning
<UP,LOWER_UP>Interface up, physical link OK
mtu 1500Maximum packet size (Ethernet standard)
state UPOperational state
link/etherMAC address
inet 192.168.1.50/24IPv4 address with its mask
scope globalRoutable address (vs link = local)
inet6 ... scope linkIPv6 link-local address

Add and remove addresses

These commands take effect immediately, with no service restart and no confirmation. The CIDR mask given at removal must be exactly the one used when adding, otherwise the kernel does not find the address and refuses the operation.

Terminal window
# Add an address (the CIDR mask is mandatory!)
sudo ip addr add 192.168.1.100/24 dev eth0
# Add a secondary address
sudo ip addr add 192.168.1.101/24 dev eth0
# Remove an address (mask mandatory too)
sudo ip addr del 192.168.1.100/24 dev eth0
# Remove ALL addresses of an interface (Warning: danger)
sudo ip addr flush dev eth0

The link object manages the physical state of interfaces: activation, MTU, MAC address. Its distinction from addr is the most frequent source of confusion: link decides whether the interface transmits frames, addr decides which IP addresses it carries. An interface can therefore be perfectly configured in addresses and still stay silent because it remained DOWN.

Display the state of the interfaces

The output shows no IP address, and that is normal: link only knows the MAC address and the state of the link. -s adds the counters of received and sent packets.

Terminal window
# All interfaces
ip link show
# Only the UP interfaces
ip link show up
# With statistics (packets, errors)
ip -s link show eth0

Bring an interface up or down

Setting an interface down destroys every connection that uses it and removes all the routes that go through it, default route included. Setting it back up only recreates the route of the local network (proto kernel): the default route and the static routes added by hand are lost.

Terminal window
# Bring up
sudo ip link set eth0 up
# Bring down
sudo ip link set eth0 down

Change the MTU

The MTU (Maximum Transmission Unit) is the size of the largest packet the interface agrees to send in one go. Raising this value only has an effect if every piece of equipment on the path accepts it too, otherwise packets are fragmented or silently dropped.

Terminal window
# Standard MTU: 1500
# Jumbo frames: 9000 (for high-performance networks)
sudo ip link set eth0 mtu 9000
# Check
ip link show eth0 | grep mtu

Manage routing (ip route)

The route object manages the routing table: how to reach each network. For every outgoing packet, the kernel walks this table and keeps the route whose prefix matches the destination most precisely; the default route is only used when no other one matches. A machine without a default route therefore works perfectly on its local network while being unable to reach the Internet.

Display the routes

ip route get is the most useful command of this section: it does not print the table, it asks the kernel for the decision it would really take for a given destination, interface and source address included.

Terminal window
# Full routing table
ip route show
# Example output:
# default via 192.168.1.1 dev eth0
# 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.50
# Route to a specific destination (very useful for diagnosis)
ip route get 8.8.8.8
# 8.8.8.8 via 192.168.1.1 dev eth0 src 192.168.1.50

Interpret the routing table

A routing line reads in three steps: which destination it covers, where to go (via a gateway or directly dev an interface), and with which source address. Routes marked proto kernel were not typed by an administrator, the kernel created them on its own when you added an address to the interface. Deleting them breaks communication with the local network.

ElementMeaning
default via 192.168.1.1Default gateway
192.168.1.0/24 dev eth0Local network reachable directly
proto kernelRoute created automatically by the kernel
scope linkDestination on the same physical link
src 192.168.1.50Source address used for this network

Add and remove routes

The gateway given after via must be directly reachable, that is belong to a network already present on a local interface; otherwise the kernel refuses with Error: Nexthop has invalid gateway.

Terminal window
# Add the default gateway
sudo ip route add default via 192.168.1.1
# Add a route to a remote network
sudo ip route add 10.0.0.0/8 via 192.168.1.254
# Add a route through an interface (no gateway)
sudo ip route add 172.16.0.0/12 dev eth1
# Remove a route
sudo ip route del 10.0.0.0/8
# Replace an existing route (avoids the "File exists" error)
sudo ip route replace default via 192.168.1.1

Manage ARP neighbours (ip neigh)

The neigh object manages the ARP cache (IPv4) and NDP (IPv6): the mapping between IP addresses and MAC addresses. On a local network, knowing the IP address of a machine is not enough to talk to it, you need its hardware address; ARP (Address Resolution Protocol) discovers it by querying the network, and Linux keeps the result for a few minutes in this cache. This cache explains some outages after a piece of equipment is replaced: the IP address is the same, the MAC has changed, and the machine still talks to the old one.

Display the ARP cache

Only the neighbours the machine talked to recently appear; an empty cache signals no problem, just an absence of local traffic.

Terminal window
ip neigh show
# Example output:
# 192.168.1.1 dev eth0 lladdr 00:11:22:33:44:55 REACHABLE
# 192.168.1.100 dev eth0 lladdr aa:bb:cc:dd:ee:ff STALE

Possible states:

StateMeaning
REACHABLERecent communication, valid entry
STALENo recent communication, may be outdated
INCOMPLETEARP request sent, no answer yet
DELAYWaiting for confirmation
PROBESending ARP requests
FAILEDResolution failed
PERMANENTStatic entry

Manipulate the cache

Flushing the cache is harmless: entries rebuild at the next communication. A static entry, on the other hand, never expires on its own and becomes a trap if the equipment changes network card.

Terminal window
# Add a static entry
sudo ip neigh add 192.168.1.50 lladdr aa:bb:cc:dd:ee:ff dev eth0
# Remove an entry
sudo ip neigh del 192.168.1.50 dev eth0
# Flush the whole cache (forces rediscovery)
sudo ip neigh flush all

Statistics and diagnosis

The three tools of this section answer different questions. The counters tell whether the network card loses packets, hence whether the problem is hardware. The monitor mode shows state changes as they happen, which is the only way to catch an intermittent outage. The JSON output, finally, makes the same information usable by a script instead of a human eye.

Interface statistics

These counters accumulate since the interface came up: it is their evolution between two readings that makes sense, not their absolute value.

Terminal window
# Packet and error counters
ip -s link show eth0
# Output (excerpt):
# RX: bytes packets errors dropped missed mcast
# 1234567 8901 0 0 0 123
# TX: bytes packets errors dropped carrier collsns
# 7654321 4567 0 0 0 0

Indicators to watch:

CounterNormalProblem if high
errors0Physical problem (cable, driver)
dropped~0Saturation, buffer too small
missed0The card missed packets: the system cannot keep up with the rate
carrier0Physical link problem
collsns0 (full-duplex)Bad negotiation

Watch in real time

ip monitor does not give the prompt back and prints nothing while nothing moves: every line that appears matches a real kernel event, a DHCP lease obtained, a link lost, a route added.

Terminal window
# Watch network events (new IPs, route changes...)
ip monitor all
# Filter by type
ip monitor address # Address changes only
ip monitor route # Route changes only
ip monitor link # Interface changes only

JSON output for scripts

The default display format changes from one iproute2 version to the next, which breaks scripts built on awk or grep. The JSON output produced by -j has a stable structure, it is the only form to use in code meant to last.

Terminal window
# All addresses in JSON
ip -j addr show
# Parse with jq
ip -j addr show | jq '.[].ifname' # Interface names
ip -j addr show | jq '.[].addr_info[].local' # All IPs
ip -j route show | jq '.[] | select(.dst=="default")' # Default route

Common command patterns

Here are twenty ready-to-use ip patterns, grouped by object. Each one gives its general formula and a concrete example.

List all interfaces

See the state of every network interface.

Terminal window
ip addr show # formula
ip a # example (short form)

Show one interface

See the details of a single interface.

Terminal window
ip addr show dev <interface> # formula
ip addr show dev eth0 # example

List the active interfaces

Keep only the interfaces in the UP state.

Terminal window
ip link show up # formula and example

Show IPv4 only

Leave the IPv6 addresses out of the display.

Terminal window
ip -4 addr show # formula
ip -4 a # example

Add an IP address

Assign an address to an interface.

Terminal window
sudo ip addr add <ip>/<cidr> dev <interface> # formula
sudo ip addr add 192.168.1.100/24 dev eth0 # example
  • The CIDR mask (/24) is mandatory.

Remove an IP address

Take an address off an interface.

Terminal window
sudo ip addr del <ip>/<cidr> dev <interface> # formula
sudo ip addr del 192.168.1.100/24 dev eth0 # example

Flush all addresses of an interface

Remove every IP in one command.

Terminal window
sudo ip addr flush dev <interface> # formula
sudo ip addr flush dev eth0 # example: handle with care

Bring an interface up

Set an interface to the UP state.

Terminal window
sudo ip link set <interface> up # formula
sudo ip link set eth0 up # example

Bring an interface down

Set an interface to the DOWN state.

Terminal window
sudo ip link set <interface> down # formula
sudo ip link set eth0 down # example
  • Never bring down the interface that carries your SSH connection.

Change the MTU

Change the maximum packet size.

Terminal window
sudo ip link set <interface> mtu <size> # formula
sudo ip link set eth0 mtu 9000 # example (jumbo frames)

Show the routing table

See every configured route.

Terminal window
ip route show # formula
ip r # example (short form)

See the route to a destination

Find where packets to an IP go, the most useful diagnosis.

Terminal window
ip route get <destination> # formula
ip route get 8.8.8.8 # example

Add a static route

Create a route to a remote network.

Terminal window
sudo ip route add <network>/<cidr> via <gateway> # formula
sudo ip route add 10.0.0.0/8 via 192.168.1.1 # example

Set the default gateway

Configure the default route.

Terminal window
sudo ip route add default via <gateway> # formula
sudo ip route add default via 192.168.1.1 # example

Remove a route

Take a route out of the table.

Terminal window
sudo ip route del <network>/<cidr> # formula
sudo ip route del 10.0.0.0/8 # example

Show the ARP cache

See the known IP ↔ MAC mappings.

Terminal window
ip neigh show # formula
ip n # example (short form)

Add a static ARP entry

Force an IP ↔ MAC association.

Terminal window
sudo ip neigh add <ip> lladdr <mac> dev <interface> # formula
sudo ip neigh add 192.168.1.50 lladdr aa:bb:cc:dd:ee:ff dev eth0 # example

Flush the ARP cache

Force the rediscovery of network neighbours.

Terminal window
sudo ip neigh flush all # formula and example

Statistics of an interface

See the packet and error counters.

Terminal window
ip -s link show <interface> # formula
ip -s link show eth0 # example

JSON output for scripts

Get the data in a parsable format.

Terminal window
ip -j addr show # formula
ip -j addr show | jq '.[].ifname' # example: interface names
  • -j produces JSON; jq makes it usable in a script.

Traps to avoid

Eight mistakes come back constantly with ip. Some of them can cut your access to the machine.

Forgetting the CIDR mask

Terminal window
sudo ip addr add 192.168.1.100 dev eth0 # WRONG: no /CIDR

Symptom: no error, but the address is created as a /32 and the machines of the local network stay unreachable through it. Cause: without a mask, ip guesses nothing and takes the smallest possible network.

Terminal window
sudo ip addr add 192.168.1.100/24 dev eth0 # RIGHT: explicit mask

Cutting your own SSH connection

Terminal window
sudo ip link set eth0 down # WRONG: if eth0 carries your SSH session

Symptom: SSH connection lost, console access needed. Cause: bringing the interface down cuts every connection going through it.

Terminal window
ip route get <your_ip> # RIGHT: check the interface in use BEFORE acting

Non-persistent changes

Terminal window
sudo ip addr add 192.168.1.100/24 dev eth0 # Warning: lost at the next reboot

Symptom: the configuration disappears after a reboot. Cause: ip changes the state in memory only.

Terminal window
# RIGHT: persist through the distribution's tool
sudo nano /etc/netplan/01-config.yaml && sudo netplan apply
Terminal window
ip link show # WRONG: to see the IP addresses

Symptom: the IP addresses do not appear. Cause: link manages the physical state, addr manages the IP addresses.

Terminal window
ip addr show # RIGHT: addr for addresses

Default route already present

Terminal window
sudo ip route add default via 192.168.1.1 # WRONG: "RTNETLINK answers: File exists"

Symptom: File exists error. Cause: a default route already exists.

Terminal window
sudo ip route replace default via 192.168.1.1 # RIGHT: replace instead of add

Wrong mask at removal

Terminal window
sudo ip addr del 192.168.1.100/32 dev eth0 # WRONG: when it was a /24

Symptom: error Error: ipv4: Address not found. Cause: the mask must match exactly the one of the added address. Leaving the mask out is no workaround: ip then attempts a wildcard deletion and warns (Executing wildcard deletion) that this behaviour will disappear.

Terminal window
ip addr show dev eth0 # RIGHT: check the exact mask before removing

flush on the wrong interface

Terminal window
sudo ip addr flush dev eth0 # WRONG: removes ALL IPs, without confirmation

Symptom: every address removed, machine unreachable. Cause: flush asks for no confirmation.

Terminal window
# RIGHT: double-check the interface, and keep a fallback console access
ip -br addr show

Using ifconfig instead of ip

Terminal window
ifconfig eth0 192.168.1.100 # WRONG: net-tools tool, obsolete

Symptom: it works, but with no native CIDR notation, and the output of ifconfig ignores the secondary addresses set by ip. Cause: ifconfig (package net-tools) no longer follows the network state of the kernel.

Terminal window
sudo ip addr add 192.168.1.100/24 dev eth0 # RIGHT: move to ip

Hands-on

Nothing replaces practice. This lab creates an isolated network namespace: you experiment with no risk at all for the real configuration of the machine. At the end, clean up with the second script.

Prepare the ground

This script creates a lab-ip namespace linked to the host by a pair of virtual veth interfaces.

#!/bin/bash
# Create a test network namespace
sudo ip netns add lab-ip
# Create a pair of veth interfaces
sudo ip link add veth-host type veth peer name veth-lab
# Move one end into the namespace
sudo ip link set veth-lab netns lab-ip
# Configure the host-side interface
sudo ip addr add 10.0.0.1/24 dev veth-host
sudo ip link set veth-host up
# Configure the namespace-side interface
sudo ip netns exec lab-ip ip addr add 10.0.0.2/24 dev veth-lab
sudo ip netns exec lab-ip ip link set veth-lab up
sudo ip netns exec lab-ip ip link set lo up
echo "Lab ready: namespace lab-ip, host IP 10.0.0.1, lab IP 10.0.0.2"

To clean up at the end:

Terminal window
sudo ip netns del lab-ip
sudo ip link del veth-host 2>/dev/null

The eight steps

Chain these steps in order, each one builds on the result of the previous one. Every manipulation targets veth-host, the end of the virtual link left on the machine side, never your real interface: you can therefore cut it without losing access. After each command, take the time to read the output again before moving on.

  1. List the interfaces. Display every interface with its addresses.

    Terminal window
    ip addr show

    ip addr show (or ip a) displays each interface with its state and its IPv4/IPv6 addresses, veth-host included.

  2. Filter one interface. Display veth-host only.

    Terminal window
    ip addr show dev veth-host

    The dev parameter targets one precise interface, state UP, address 10.0.0.1/24.

  3. Add a secondary address. Add 10.0.0.10/24 to veth-host.

    Terminal window
    sudo ip addr add 10.0.0.10/24 dev veth-host

    One interface can carry several addresses (aliasing), useful to host several services.

  4. Check the routing table. Display the routing table.

    Terminal window
    ip route show

    When you add an IP, Linux automatically creates a route to the matching network.

  5. Test connectivity. Check that the namespace answers.

    Terminal window
    ping -c 2 10.0.0.2

    The lab-ip namespace answers: both ends of the veth link are configured.

  6. Read the ARP cache. Display the discovered network neighbours.

    Terminal window
    ip neigh show

    After the ping, Linux resolved the MAC address of 10.0.0.2 and cached it (REACHABLE).

  7. Bring an interface down. Bring veth-host down, then up again.

    Terminal window
    sudo ip link set veth-host down
    sudo ip link set veth-host up

    ip link set controls the physical state: down cuts the interface (the ping fails), up brings it back.

  8. Remove an address. Take off the secondary address 10.0.0.10/24.

    Terminal window
    sudo ip addr del 10.0.0.10/24 dev veth-host

    del is the reverse of add, the CIDR mask stays mandatory.

Progressive exercises

Ten exercises to validate your skills. Look for the answer yourself first, then unfold the solution to check.

Foundation level

These five exercises only cover reading the network state and adding an address with no consequence. They run safely on your work machine.

Exercise 1, Find the IP of an interface. Display the IP address of the eth0 interface (or its equivalent). Hint: ip addr show with the dev parameter.

See the solution
Terminal window
ip addr show dev eth0

ip addr show dev <interface> displays the details of one precise interface.

Exercise 2, Identify the default gateway. Find the address of your default gateway. Hint: the default via line of the routing table.

See the solution
Terminal window
ip route show default

The default route (0.0.0.0/0) tells where to send traffic bound for the Internet.

Exercise 3, Add a secondary IP. Add the address 192.168.100.10/24 to the lo interface. Hint: ip addr add … dev lo.

See the solution
Terminal window
sudo ip addr add 192.168.100.10/24 dev lo

You can add addresses to the loopback for tests, without touching the real interfaces.

Exercise 4, List the active interfaces. Display only the interfaces in the UP state. Hint: ip link accepts a state filter.

See the solution
Terminal window
ip link show up

The up keyword keeps the interfaces in the operational state.

Exercise 5, Diagnose a route. Find through which interface and gateway your machine reaches 1.1.1.1. Hint: ip route get queries the kernel.

See the solution
Terminal window
ip route get 1.1.1.1

This command simulates the routing of a packet and shows the chosen path.

Composition level

Here you move from the isolated command to combining it with other shell tools (awk, jq) and to changing the routing table. Exercise 7 really changes the routing of the machine, remember to remove the added route afterwards.

Exercise 6, Extract the interface names. List only the names of the interfaces, without the details. Hint: combine ip -o with awk.

See the solution
Terminal window
ip -o link show | awk -F': ' '{print $2}'

-o produces a "one line per record" output, simpler to parse; awk extracts the 2nd field. A virtual interface keeps the suffix of its peer (veth-host@veth-lab, eth0@if6635 in a container): add | cut -d@ -f1 to strip it.

Exercise 7, Create a static route. Add a route to 10.20.30.0/24 through the gateway 192.168.1.1. Hint: ip route add <network> via <gateway>.

See the solution
Terminal window
sudo ip route add 10.20.30.0/24 via 192.168.1.1

Static routes define specific paths to some networks.

Exercise 8, JSON output and parsing. Extract the IPv4 addresses of every interface through JSON and jq. Hint: ip -j addr show | jq ….

See the solution
Terminal window
ip -j addr show | jq -r '.[].addr_info[] | select(.family=="inet") | .local'

The JSON output allows precise and reliable parsing for automation.

Industrialisation level

Last step: produce a reusable tool rather than a throwaway command. The goal is to gather in a single run everything a network incident requires you to observe, and to know how to watch changes while they happen.

Exercise 9, Network diagnosis script. Write a script that displays IPs, routes, ARP neighbours and statistics of the main interface. Hint: chain several ip commands in a bash script.

See the solution
#!/bin/bash
echo "=== INTERFACES ==="
ip -c addr show
echo -e "\n=== ROUTES ==="
ip -c route show
echo -e "\n=== NEIGHBOURS ==="
ip -c neigh show
IFACE=$(ip route get 1.1.1.1 | grep -oP 'dev \K\S+')
echo -e "\n=== STATS $IFACE ==="
ip -s link show "$IFACE"

A diagnosis script gathers the useful information in case of a network incident.

Exercise 10, Watch network events. Start a real-time watch of network changes. Hint: ip monitor.

See the solution
Terminal window
ip monitor all

Useful to debug dynamic problems (DHCP, link failover, route changes).

Troubleshooting

When an ip command fails, its error message almost always gives the cause. Here is how to diagnose.

Diagnosis methods

These five commands run in this order: the configuration first, the routing decision next, then the physical layer and neighbour resolution. None of them changes anything, so they are safe on a production server.

Terminal window
# List every interface (coloured output)
ip -c addr show
# See through which interface and gateway packets go
ip route get 8.8.8.8
# Detect physical problems (errors, lost packets)
ip -s link show eth0
# Watch network events in real time
ip monitor
# Check ARP resolution
ip neigh show

Frequent errors

RTNETLINK is the interface through which the ip command talks to the kernel: a message that starts with RTNETLINK answers: or with Error: comes from the kernel itself, a message without a prefix (Cannot find device) comes from the ip command before any call. The messages below were recorded identically on Ubuntu 24.04, Debian 13 and AlmaLinux 10.

Error messageProbable causeSolution
RTNETLINK answers: Operation not permittedCommand without sudo, or restricted containerAdd sudo, check the capabilities of the container
RTNETLINK answers: File existsAddress or route already presentRemove the existing one, or use replace
Cannot find device "eth9"Wrong interface nameList the interfaces: ip link show
Error: Nexthop has invalid gateway.Gateway outside any local network, or interface downCheck the address of the interface, bring the interface up
Error: any valid prefix is expected rather than …Malformed address (300.1.1.1/24)Fix the address
Error: ipv4: Address not found.Address missing, or wrong mask at removalCheck the exact address with ip addr show

ip cheat sheet

This section gathers by object the commands seen above, for quick reference during an intervention. One rule runs through every table: the show forms run without privilege, the add, del, set and flush forms need sudo and take effect immediately, with no confirmation and no undo.

Syntax and aliases

Abbreviations actually accept any unambiguous prefix (ip ad, ip ro), but sticking to the one-letter form avoids surprises from one version to the next.

FormRoleExample
ip [object] [command]Basic structureip addr show
ip aAlias of ip addr showip a
ip rAlias of ip route showip r
ip lAlias of ip link showip l
ip nAlias of ip neigh showip n

Global options

They go before the object and only change the presentation, never the result of the command; they combine freely, as in ip -c -br addr.

OptionRoleExample
-cColoured outputip -c addr
-4 / -6IPv4 or IPv6 onlyip -4 addr
-oOne line per recordip -o addr
-jJSON outputip -j addr
-sDetailed statisticsip -s link
-brBrief format (summary)ip -br addr

Addresses (addr)

All these forms need the CIDR mask stuck to the address, removal included, and flush removes every address of the interface without asking anything.

CommandRoleExample
ip addr showShow every addressip addr show
ip addr show dev XAddresses of one interfaceip addr show dev eth0
ip addr add IP/CIDR dev XAdd an addressip addr add 10.0.0.1/24 dev eth0
ip addr del IP/CIDR dev XRemove an addressip addr del 10.0.0.1/24 dev eth0
ip addr flush dev XRemove every addressip addr flush dev eth0

The verb here is set, not add or del: you do not create a physical interface, you change the state of those the kernel detected.

CommandRoleExample
ip link showState of the interfacesip link show
ip link show upActive interfaces onlyip link show up
ip link set X upBring an interface upip link set eth0 up
ip link set X downBring an interface downip link set eth0 down
ip link set X mtu NChange the MTUip link set eth0 mtu 9000

Routing (route)

replace is the form to remember for scripts: it creates the route when it is missing and updates it when it exists, where add fails on a route already present.

CommandRoleExample
ip route showRouting tableip route show
ip route get IPRoute to a destinationip route get 8.8.8.8
ip route add NET via GWAdd a routeip route add 10.0.0.0/8 via 192.168.1.1
ip route add default via GWDefault routeip route add default via 192.168.1.1
ip route del NETRemove a routeip route del 10.0.0.0/8
ip route replace …Replace an existing routeip route replace default via 192.168.1.1

ARP neighbours (neigh)

These entries are rebuilt automatically by the kernel; only freeze one as static to work around faulty equipment, and write it down somewhere.

CommandRoleExample
ip neigh showARP / NDP cacheip neigh show
ip neigh add IP lladdr MAC dev XStatic ARP entryip neigh add 10.0.0.5 lladdr aa:bb:cc:dd:ee:ff dev eth0
ip neigh del IP dev XRemove an ARP entryip neigh del 10.0.0.5 dev eth0
ip neigh flush allFlush the ARP cacheip neigh flush all

Mastery checklist

You master ip when you can tick each of these points:

  • I can display the IP addresses of every interface
  • I can identify the default gateway
  • I can add and remove IP addresses
  • I can create and remove static routes
  • I can bring an interface up and down
  • I can diagnose a routing problem with ip route get
  • I can read the ARP cache
  • I can use the JSON output in scripts

Persist the configuration

The ip command talks directly to the kernel, which keeps this state in RAM. For a configuration to survive a reboot, you must write it into the file read by the network manager of the distribution, which will replay the same operations at the next boot. Three tools share this role depending on the distribution, and they do not coexist on the same machine: identify the active one before changing anything.

/etc/netplan/01-config.yaml
network:
version: 2
ethernets:
eth0:
addresses:
- 192.168.1.100/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
Terminal window
# Apply
sudo netplan apply

Key points

  1. Unified syntax: ip OBJECT COMMAND, consistent across the whole network
  2. 4 essential objects: addr (IP), link (interface), route (routing), neigh (ARP)
  3. Abbreviations: ip a = ip addr show, ip r = ip route show
  4. CIDR mask mandatory: 192.168.1.100/24, never without the /24
  5. Temporary changes: everything is lost at reboot without persistence
  6. ip route get: the most useful diagnosis to understand routing
  7. JSON with -j: perfect for automation and scripting
  8. Replaces everything: ifconfig, route, arp, netstat -i are obsolete, and ifconfig does not even see secondary addresses
  9. Without a mask, a silent /32: no error warns you

Knowledge check

Check that the essentials of this guide stuck. The questions cover only what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

6 questions
6 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn