cheat sheet
ip
Modern replacement for ifconfig, route, and arp. Inspect and configure interfaces, addresses, routes, neighbour tables, and network namespaces with the iproute2 ip command.
ip — iproute2 Networking
What it is
ip is the unified Linux networking utility from the iproute2 suite, written by Alexey Kuznetsov to replace the legacy ifconfig, route, arp, and iwconfig commands with a single tool that exposes the full kernel networking API. It speaks to the kernel through netlink — the same channel iproute2's sister tool ss uses — so it sees every interface, address, route, and neighbour entry, including features the legacy tools never learned about (IPv6 properly, VRF, network namespaces, MPLS, eBPF hooks). Reach for ip whenever you need to inspect or configure Linux networking; on modern distributions the legacy tools may not even be installed, and where they are they often hide critical state. On macOS and BSD, ip is not available — use ifconfig and netstat -nr instead.
iproute2 tracks the kernel release cadence — major versions ship roughly every two months. As of 2026, recent releases (6.10 → 6.15) added support for the NO_COLOR environment variable, improved dark-background color output, and continued expanding netlink coverage for new kernel features (multi-path TCP, MPLS extensions, VRF refinements). The user-visible command surface is stable — anything in this page works on every iproute2 from the past several years.
Install
iproute2 is part of every modern Linux base install; if it's missing, install the iproute2 (Debian/Ubuntu) or iproute (RHEL) package.
# Debian/Ubuntu
sudo apt install iproute2
# Fedora/RHEL
sudo dnf install iproute
# Alpine
sudo apk add iproute2
# macOS — not available; use ifconfig + netstat -nr
Output: (none — exits 0 on success)
Syntax
ip uses a noun-verb command structure: ip OBJECT COMMAND [ARGS], where OBJECT is what you're inspecting (link, addr, route, neigh, netns, …) and COMMAND is the action (show, add, del, set, flush). Object names accept short forms — ip a is ip addr show, ip l is ip link show, ip r is ip route show — which is what most experienced users actually type.
ip [OPTIONS] OBJECT { COMMAND | help }
Output: (none — exits 0 on success)
Essential options
| Option | Meaning |
|---|---|
-4 / -6 | Restrict to IPv4 or IPv6 |
-s | Show statistics |
-d | Detailed output |
-br | Brief one-line-per-entry table |
-c / -color | Colorize output |
-j | JSON output |
-p | Pretty-print (combine with -j) |
-n NETNS | Operate inside a network namespace |
-r | Show numeric DNS hostnames |
-h | Human-readable byte counts (with -s) |
Configuration
ip itself has no traditional config file — every mutation is volatile and lives in the kernel until the next reboot. What does live on disk is a handful of name-to-number tables under /etc/iproute2/, used by ip to translate human-readable strings into the small integers the kernel actually uses.
| File | What it maps | Used by |
|---|---|---|
/etc/iproute2/rt_tables | Routing-table ID ↔ name (e.g. 100 vpn) | ip rule, ip route ... table NAME |
/etc/iproute2/rt_protos | Route protocol ID ↔ name (e.g. boot, dhcp, kernel) | ip route ... proto NAME |
/etc/iproute2/rt_realms | Realm ID ↔ name | ip route ... realm NAME |
/etc/iproute2/rt_scopes | Scope ID ↔ name (global, link, host) | ip addr ... scope NAME |
/etc/iproute2/rt_dsfield | DiffServ / TOS values | ip rule ... tos NAME |
/etc/iproute2/group | Interface-group ID ↔ name | ip link ... group NAME |
Distributions ship sensible defaults. The one you'll edit most often is rt_tables — add a line like 200 vpn so you can refer to a custom routing table by name instead of number.
# Append a named table for use with policy routing
echo "200 vpn" | sudo tee -a /etc/iproute2/rt_tables
# Override per-user without root (since iproute2 5.x)
mkdir -p ~/.config/iproute2
echo "201 lab" >> ~/.config/iproute2/rt_tables
Output (after both edits, ip rule add table vpn ... and ip rule add table lab ... then ip rule):
0: from all lookup local
32764: from all lookup vpn
32765: from all lookup lab
32766: from all lookup main
32767: from all lookup default
For persistence of actual interface, address, and route state — none of which ip itself remembers across reboots — see Modern alternatives below.
Objects at a glance
| Object | Replaces | What it manages |
|---|---|---|
ip link | ifconfig (link layer), mii-tool | Interfaces themselves: MAC, MTU, up/down |
ip addr | ifconfig (L3) | IPv4/IPv6 addresses assigned to interfaces |
ip route | route | Routing table(s) |
ip neigh | arp | ARP / IPv6 neighbour cache |
ip rule | — | Policy routing rules |
ip netns | — | Network namespaces |
ip tunnel / ip xfrm | — | Tunnels, IPsec |
ip mroute | — | Multicast routing |
ip link — interfaces
ip link manages link-layer state: which interfaces exist, their MAC addresses, MTU, up/down status, and master/slave bonding relationships. It is the right tool for "is the cable plugged in?" and "rename / bond / change MAC" tasks.
ip link # list all interfaces
ip -br link # one line each
ip link show eth0 # specific interface
ip -s link show eth0 # with TX/RX stats
ip -d link show eth0 # detailed (driver, queue, etc.)
Output (ip -br link):
lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
eth0 UP 52:54:00:ab:cd:ef <BROADCAST,MULTICAST,UP,LOWER_UP>
wlan0 DOWN a8:6d:aa:11:22:33 <BROADCAST,MULTICAST>
docker0 DOWN 02:42:1c:5b:7c:88 <NO-CARRIER,BROADCAST,MULTICAST,UP>
The <...> flags decode like this — read them as a checklist of "is this interface usable?":
| Flag | Meaning |
|---|---|
UP | Administratively up (ip link set ... up) |
LOWER_UP | Carrier present (cable plugged, Wi-Fi associated) |
BROADCAST | Supports broadcast |
MULTICAST | Supports multicast |
LOOPBACK | Loopback device |
POINTOPOINT | Point-to-point link (PPP, tun) |
NO-CARRIER | UP but no link (cable unplugged) |
Bringing interfaces up/down
The most common link-layer mutation, equivalent to ifconfig eth0 up/down.
sudo ip link set eth0 up
sudo ip link set eth0 down
sudo ip link set eth0 mtu 9000 # jumbo frames
sudo ip link set eth0 address 02:42:11:22:33:44 # change MAC
sudo ip link set eth0 name lan0 # rename (must be down first)
sudo ip link set eth0 promisc on # promiscuous mode
Output: (none — exits 0 on success)
Creating virtual interfaces
ip link add creates virtual interface types — bridges, VLANs, dummies, veth pairs (used by Docker, Kubernetes, and network namespaces), and more.
# VLAN 100 on eth0
sudo ip link add link eth0 name eth0.100 type vlan id 100
# Linux bridge
sudo ip link add name br0 type bridge
sudo ip link set eth0 master br0
# veth pair (back-to-back virtual cable)
sudo ip link add veth0 type veth peer name veth1
# Dummy interface (for testing)
sudo ip link add dummy0 type dummy
Output: (none — exits 0 on success)
ip addr — IP addresses
ip addr manages IPv4 and IPv6 addresses on interfaces. Unlike ifconfig, which only ever shows one address per interface, ip addr correctly displays the multiple addresses an interface usually has — typically at least one IPv4 plus one link-local + one global IPv6.
ip addr # all interfaces, all addresses
ip a # same, short form
ip -br addr # brief table
ip addr show eth0 # specific interface
ip -4 addr # only IPv4
ip -6 addr # only IPv6
ip -j addr | jq # JSON
Output (ip -br addr):
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 10.0.0.10/24 fe80::5054:ff:feab:cdef/64
docker0 DOWN 172.17.0.1/16
Adding and removing addresses
ip addr add puts a new address on an interface; multiple addresses on one interface are fully supported (the alias-IP use case).
sudo ip addr add 10.0.0.50/24 dev eth0
sudo ip addr add 10.0.0.50/24 dev eth0 label eth0:1 # legacy alias name
sudo ip addr add 2001:db8::42/64 dev eth0
sudo ip addr del 10.0.0.50/24 dev eth0
sudo ip addr flush dev eth0 # remove all
sudo ip -4 addr flush dev eth0 # only IPv4
Output (ip -br addr show eth0):
eth0 UP 10.0.0.10/24 10.0.0.50/24 2001:db8::42/64 fe80::5054:ff:feab:cdef/64
Address scopes
Each address has a scope describing how far it can reach. The most common are global (routable across the internet), link (link-local, e.g. fe80::/10), and host (loopback). Setting scope explicitly is rarely needed but useful when adding addresses for special purposes.
sudo ip addr add 169.254.1.1/16 dev eth0 scope link
sudo ip addr add 127.0.0.42/8 dev lo scope host
Output: (none — exits 0 on success)
ip route — routing table
ip route reads and writes the kernel routing table. The default route is what packets use when no more specific route matches — usually pointing at your gateway — and you'll inspect it in every "why can't this host reach the internet?" investigation.
ip route # main routing table
ip r # short form
ip -br route # brief one-line table (newer iproute2)
ip route show default # just the default route
ip -6 route # IPv6 routes
ip route show table all # every routing table
ip route get 8.8.8.8 # which route would be used?
Output (ip route):
default via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.10 metric 100
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.10
169.254.0.0/16 dev eth0 scope link metric 1000
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
Output (ip route get 8.8.8.8):
8.8.8.8 via 10.0.0.1 dev eth0 src 10.0.0.10 uid 1000
cache
Adding and removing routes
ip route add adds a static route; ip route replace is the idempotent variant — replaces an existing entry or adds a new one.
# Static route to a remote subnet via a specific gateway
sudo ip route add 192.168.10.0/24 via 10.0.0.254
# Route via an interface (no gateway, for point-to-point links)
sudo ip route add 192.168.10.0/24 dev tun0
# Default route
sudo ip route add default via 10.0.0.1 dev eth0
# Replace (won't fail if exists)
sudo ip route replace 192.168.10.0/24 via 10.0.0.254
# Delete
sudo ip route del 192.168.10.0/24
# Blackhole — drop traffic to a network silently
sudo ip route add blackhole 198.51.100.0/24
# Unreachable — return ICMP "destination unreachable"
sudo ip route add unreachable 198.51.100.0/24
Output: (none — exits 0 on success)
Route metrics and source addresses
When multiple routes match the same destination, the kernel picks the one with the lowest metric. src pins the source address used for outgoing packets — useful on multi-homed hosts to control which IP shows up at the remote end.
sudo ip route add default via 10.0.0.1 dev eth0 metric 100
sudo ip route add default via 10.0.0.2 dev eth1 metric 200 # backup
sudo ip route add 192.168.10.0/24 via 10.0.0.254 src 10.0.0.50
Output: (none — exits 0 on success)
ip neigh — ARP / neighbour cache
ip neigh shows the kernel's ARP table (IPv4) and IPv6 neighbour cache — the MAC ↔ IP mappings the kernel learned by sending ARP/NDISC requests. Stale entries during a router failover or after MAC changes are diagnosable here.
ip neigh # all entries
ip n # short form
ip -br neigh # brief
ip neigh show dev eth0 # only on one interface
ip neigh show 10.0.0.1 # specific neighbour
Output (ip neigh):
10.0.0.1 dev eth0 lladdr 00:1a:2b:3c:4d:5e REACHABLE
10.0.0.5 dev eth0 lladdr aa:bb:cc:11:22:33 STALE
fe80::1 dev eth0 lladdr 00:1a:2b:3c:4d:5e router REACHABLE
| State | Meaning |
|---|---|
REACHABLE | Recently confirmed reachable |
STALE | Old entry — kernel may probe before use |
DELAY | Probe scheduled |
PROBE | Probe in flight |
FAILED | No response — entry is bad |
INCOMPLETE | First lookup pending |
PERMANENT | Manually configured, never expires |
Managing the cache
Static ARP entries are occasionally useful for embedded targets that don't answer ARP, or to defeat ARP poisoning on a trusted LAN.
sudo ip neigh add 10.0.0.42 lladdr 02:42:11:22:33:44 dev eth0
sudo ip neigh replace 10.0.0.42 lladdr 02:42:99:88:77:66 dev eth0
sudo ip neigh del 10.0.0.42 dev eth0
sudo ip neigh flush dev eth0 # clear all entries on eth0
sudo ip neigh flush all # clear everything
Output: (none — exits 0 on success)
ip rule — policy routing
Policy routing lets the kernel pick between multiple routing tables based on source address, mark, or interface — the foundation of VPN split-tunnels, multi-WAN setups, and Linux VRFs. ip rule lists and edits the matching rules; the tables themselves live in /etc/iproute2/rt_tables.
ip rule # list rules
ip rule show
sudo ip rule add from 10.0.0.50 table 100 # source-based
sudo ip rule add fwmark 1 table 100 # mark-based
sudo ip rule del from 10.0.0.50
sudo ip route add default via 10.0.0.254 table 100
ip route show table 100
Output (ip rule):
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
ip netns — network namespaces
Network namespaces are isolated Linux networking stacks — each has its own interfaces, routing tables, and firewall rules. They're the kernel feature that makes containers possible, and you can use them directly without Docker or any container runtime. ip netns is the user-space management tool.
sudo ip netns add red # create namespace "red"
ip netns list # show namespaces
sudo ip netns exec red ip addr # run a command inside
sudo ip netns exec red ip link set lo up # bring up loopback inside
sudo ip netns del red # delete namespace
Output (ip netns list):
red
Connect two namespaces with veth
The veth pair is a "back-to-back virtual cable" — one end in one namespace, the other end in the other. This is how containers reach the outside world.
# Create namespaces and veth pair
sudo ip netns add red
sudo ip netns add blue
sudo ip link add veth-red type veth peer name veth-blue
# Move each end into its namespace
sudo ip link set veth-red netns red
sudo ip link set veth-blue netns blue
# Configure addresses inside each namespace
sudo ip -n red addr add 10.10.0.1/24 dev veth-red
sudo ip -n blue addr add 10.10.0.2/24 dev veth-blue
sudo ip -n red link set veth-red up
sudo ip -n blue link set veth-blue up
sudo ip -n red link set lo up
sudo ip -n blue link set lo up
# Test
sudo ip netns exec red ping -c 2 10.10.0.2
Output:
PING 10.10.0.2 (10.10.0.2) 56(84) bytes of data.
64 bytes from 10.10.0.2: icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from 10.10.0.2: icmp_seq=2 ttl=64 time=0.038 ms
ip -n NAME OBJECT ...is shorthand forip netns exec NAME ip OBJECT ...— saves typing inside scripts that touch many namespaces.
JSON and brief output
The -j (JSON) and -br (brief) flags transform any ip query into pipeline-friendly output. -j is the right choice when feeding state to a tool; -br is best for human dashboards.
ip -j -p addr | jq '.[] | {name: .ifname, addrs: [.addr_info[].local]}'
ip -j route | jq '.[] | select(.dst == "default") | .gateway'
Output (ip -j route | jq):
"10.0.0.1"
Statistics
-s adds packet and byte counters; -s -s adds detailed error counters; -h makes the numbers human-readable.
ip -s link show eth0
ip -s -s link show eth0 # extended error counters
ip -h -s link show eth0 # human-readable bytes
Output (ip -h -s link show eth0):
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
link/ether 52:54:00:ab:cd:ef
RX: bytes packets errors dropped overrun mcast
12.4M 98.2K 0 0 0 0
TX: bytes packets errors dropped carrier collsns
45.1M 72.8K 0 0 0 0
Monitoring changes
ip monitor watches kernel networking events in real time — interface up/down, address changes, route changes — useful for debugging DHCP or VPN clients that mutate state silently.
ip monitor # everything
ip monitor link # link state only
ip monitor route # route changes
ip monitor neigh # neighbour cache changes
ip monitor address # address changes
Output: (none — exits 0 on success)
ip vs the legacy tools
| Old | New | Notes |
|---|---|---|
ifconfig | ip addr, ip link | ip shows multiple IPs per interface, full IPv6 |
ifconfig eth0 up | ip link set eth0 up | |
ifconfig eth0 10.0.0.10/24 | ip addr add 10.0.0.10/24 dev eth0 | |
route -n | ip route | |
route add default gw 10.0.0.1 | ip route add default via 10.0.0.1 | |
arp -n | ip neigh | |
arp -s 10.0.0.42 ... | ip neigh add ... | |
iptunnel | ip tunnel | absorbed into iproute2 |
Modern alternatives
ip is the low-level imperative tool — every change is volatile and dies at reboot. On real systems you usually pair it with one of three higher-level declarative network managers, each of which still ultimately drives the same netlink API. Knowing which one your distro uses is the difference between a change that sticks and a change that gets clobbered five minutes later by a reconciliation loop.
| Tool | Where you find it | Persistence | When to reach for it |
|---|---|---|---|
ip (iproute2) | Everywhere | None — kernel-only until reboot | Diagnostics, scripts, container setup, one-off testing |
nmcli (NetworkManager) | Fedora, RHEL, Arch, desktop Ubuntu | /etc/NetworkManager/system-connections/ | Laptops, Wi-Fi, VPN, GUI integration, frequent network swaps |
networkctl (systemd-networkd) | Server Ubuntu, Debian, embedded, containers | /etc/systemd/network/*.network, *.netdev, *.link | Servers, containers, minimal/headless systems |
netplan | Ubuntu 18.04+ (default) | /etc/netplan/*.yaml → renderer | Ubuntu — writes config that NetworkManager or systemd-networkd then enacts |
nmcli — NetworkManager CLI
nmcli creates, modifies, activates, and deletes named connection profiles — persistent recipes for "this interface, this IP, this DNS, this VPN". It is fully scriptable, the default on Fedora/RHEL/Arch desktops, and the right answer whenever you need persistence on those distros.
nmcli device status # interface status
nmcli connection show # list saved profiles
nmcli connection show "Wired connection 1" # full detail
nmcli device wifi list # scan Wi-Fi
sudo nmcli device wifi connect MyAP password 'sekret'
# Persistent static address on eth0
sudo nmcli connection modify "Wired connection 1" \
ipv4.method manual ipv4.addresses 10.0.0.10/24 \
ipv4.gateway 10.0.0.1 ipv4.dns 1.1.1.1
sudo nmcli connection up "Wired connection 1"
Output (nmcli device status):
DEVICE TYPE STATE CONNECTION
eth0 ethernet connected Wired connection 1
wlan0 wifi connected MyAP
lo loopback unmanaged --
networkctl — systemd-networkd CLI
networkctl is the inspection-and-control front end for systemd-networkd. Configuration is purely file-based — drop *.network / *.netdev / *.link files in /etc/systemd/network/, then use networkctl reload and networkctl reconfigure IFACE to apply. Common on server installs, containers, and anywhere systemd is already running but a full NetworkManager stack is overkill.
networkctl # list managed interfaces
networkctl status # overall daemon state
networkctl status eth0 # per-interface detail
networkctl lldp # show LLDP neighbours
sudo networkctl reload # re-read config files
sudo networkctl reconfigure eth0 # apply config to one interface
sudo networkctl renew eth0 # renew DHCP lease
sudo networkctl up eth0 # bring link up
networkctl monitor # watch state changes in real time
Output (networkctl):
IDX LINK TYPE OPERATIONAL SETUP
1 lo loopback carrier unmanaged
2 eth0 ether routable configured
3 wlan0 wlan no-carrier unmanaged
The two state columns are the most useful diagnostic: OPERATIONAL is the kernel's view (carrier, addresses, routes), SETUP is systemd-networkd's view (did it find a matching .network file?). When something isn't working, the combination of networkctl status IFACE and journalctl -u systemd-networkd tells you everything.
A minimal /etc/systemd/network/10-eth0.network:
[Match]
Name=eth0
[Network]
Address=10.0.0.10/24
Gateway=10.0.0.1
DNS=1.1.1.1
Which to use
If you ran nmcli device status and it returned interfaces, you're on NetworkManager — make changes there. If networkctl returned configured interfaces, you're on systemd-networkd — drop .network files. If you're on Ubuntu and /etc/netplan/ has YAML, edit that and run sudo netplan apply (netplan generates the underlying NM or networkd config for you). Never mix tools: writing ip addr add while NetworkManager owns the interface buys you about 30 seconds before NM erases your change.
Common pitfalls
- Changes aren't persistent —
ipmutations live only until the next reboot or interface restart. Use NetworkManager, systemd-networkd,/etc/netplan/, or distribution-specific configs to make them stick. ifconfigshows different state thanip— only when both are installed.ifconfigonly displays the first IPv4 alias and the first IPv6 address;ipshows everything. Always trustip.- Missing
sudo— read commands (ip addr,ip route) work as any user; write commands (ip ... add/del/set) require root and fail withRTNETLINK answers: Operation not permittedotherwise. - Flushing
lo—ip addr flush dev lowill break127.0.0.1. Don't do that, and re-add127.0.0.1/8if you did. linkdownin routes — when an interface is down, routes via it still appear inip routebut are markedlinkdownand aren't used. The fix is usuallyip link set IFACE up, not editing routes.- MAC address change requires DOWN —
ip link set eth0 address ...only works when the interface is administratively down.ip link set eth0 downfirst. - Namespaces are kernel-only — opening a file or socket inside a namespace doesn't escape it; this is the foundation of container isolation.
nsenter -t PID -nis the way to drop into another process's namespace. ip route getis not a ping — it shows the route the kernel would use but doesn't actually send traffic. Combine withping -c 1 -I IFACEto confirm reachability.- macOS / BSD have no
ip— scripts that need to be portable should detect the OS and fall back toifconfig+netstat -nr.
Real-world recipes
Add an alias IP to eth0
The classic "I need a second IP for testing" scenario. The address sticks until reboot; for permanence, edit your distro's network config.
sudo ip addr add 10.0.0.50/24 dev eth0 label eth0:1
ip -br addr show eth0
Output:
eth0 UP 10.0.0.10/24 10.0.0.50/24 fe80::5054:ff:feab:cdef/64
Find your default gateway
Useful in scripts that need to know where outbound traffic is heading.
ip route show default | awk '/default/ {print $3}'
Output:
10.0.0.1
Find the interface used for a specific destination
ip route get walks the routing table the way the kernel will, including policy-routing rules — the canonical "which NIC will this packet leave?" answer.
ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++) if($i=="dev") print $(i+1)}'
Output:
eth0
Reset a stuck NIC
The 90 % cure for "the network is acting weird" — down, flush, up. Equivalent to ifdown eth0 && ifup eth0 on legacy systems.
sudo ip link set eth0 down
sudo ip addr flush dev eth0
sudo ip link set eth0 up
sudo dhclient -r eth0 && sudo dhclient eth0 # re-acquire DHCP lease
Output: (none — exits 0 on success)
Two default gateways with metrics
A common multi-WAN setup: primary link with lower metric is preferred, secondary takes over when primary goes down. The kernel automatically promotes the lower-metric route only if its interface is up.
sudo ip route add default via 10.0.0.1 dev eth0 metric 100
sudo ip route add default via 10.0.1.1 dev eth1 metric 200
ip route show default
Output:
default via 10.0.0.1 dev eth0 metric 100
default via 10.0.1.1 dev eth1 metric 200
Source-based policy routing
Route traffic from a specific source address through a different gateway — the building block of VPN split-tunnels.
# 1. Create a custom routing table (or just use an integer)
echo "200 vpn" | sudo tee -a /etc/iproute2/rt_tables
# 2. Send traffic from 10.0.0.50 through the VPN gateway
sudo ip route add default via 192.168.99.1 table vpn
sudo ip rule add from 10.0.0.50 table vpn
# 3. Verify
ip rule
ip route show table vpn
Output (ip rule):
0: from all lookup local
32765: from 10.0.0.50 lookup vpn
32766: from all lookup main
32767: from all lookup default
Trace a packet path on a multi-homed box
ip route get repeated for several destinations is the quickest way to confirm policy routing is doing what you think.
for dst in 8.8.8.8 192.168.1.1 10.0.0.5; do
echo -n "$dst -> "; ip route get $dst | awk '{print $3, $4, $5}'
done
Output:
8.8.8.8 -> via 10.0.0.1 dev eth0
192.168.1.1 -> via 10.0.1.1 dev eth1
10.0.0.5 -> dev eth0 src
Clear a stale ARP entry
After a router swap or DHCP lease move, the old MAC can sit in the cache long enough to break connectivity. Force a refresh.
sudo ip neigh flush 10.0.0.1
ping -c 1 10.0.0.1 # triggers re-ARP
ip neigh show 10.0.0.1
Output:
10.0.0.1 dev eth0 lladdr 00:1a:2b:99:88:77 REACHABLE
Dump everything for a bug report
When asking for help, paste this. It's enough state to debug 99 % of Linux networking questions.
{ ip -br link; echo; ip -br addr; echo; ip route; echo; ip -6 route; echo; ip neigh; } | tee net-state.txt
Output:
lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
eth0 UP 52:54:00:ab:cd:ef <BROADCAST,MULTICAST,UP,LOWER_UP>
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 10.0.0.10/24 fe80::5054:ff:feab:cdef/64
default via 10.0.0.1 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.10
10.0.0.1 dev eth0 lladdr 00:1a:2b:3c:4d:5e REACHABLE
Tips
The
-br(brief) and-c(color) flags makeipoutput dramatically more readable. Addalias ip='ip -c'to your shell rc to always get color in interactive use.
ipandssare siblings from the iproute2 suite — they both speak netlink and they both replace older/proc-scraping tools (ifconfig,netstat). If you have one, you have the other. Pairip route get DESTwithss -tn dst DESTto see both the routing decision and the actual active connections in two commands.
Network namespace experiments are completely safe — they can't affect your host's main network. Use
ip netns add scratchandip netns exec scratch bashto drop into an isolated networking sandbox and play with any of these commands without risk.
Sources
- iproute2 releases — GitHub — official upstream tags and tarballs (6.10 → 6.15+, 2024–2026).
- iproute2 Debian package tracker — version history, distro-specific patches, and changelog entries.
- networkctl(1) — freedesktop.org — authoritative reference for systemd-networkd's CLI.
- systemd-networkd — ArchWiki —
.network/.netdev/.linkfile syntax and recipes. - Netplan vs NetworkManager vs systemd-networkd vs ip — howtouselinux — decision guide across the four tools.
- Task-centered iproute2 user guide — baturin.org — long-form recipe collection by an iproute2 contributor.