Skip to content

TCP/IP Networking and the ip Command Suite

The ifconfig/route/arp tools you'll find in old tutorials are deprecated and, on many modern distributions, not installed by default at all. Everything they did is now done through one command: ip, part of the iproute2 package.

How it works

Interfaces and addresses

$ ip -br addr show
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.0.2.10/24 fe80::21a:4aff:fe9a:1b2c/64
eth1             UP             10.0.0.5/24 fe80::21a:4aff:fe9a:1b2d/64
docker0          DOWN           172.17.0.1/16

-br ("brief") gives a one-line-per-interface summary: name, operational state (UP/DOWN/ UNKNOWN — UNKNOWN is normal for loopback, it just means the kernel doesn't track carrier state for it), and assigned addresses (IPv4 and IPv6 together).

Adding/removing an address manually (useful for troubleshooting — this does not persist across reboots, you'd configure it in netplan/NetworkManager//etc/network/interfaces for that):

sudo ip addr add 192.0.2.20/24 dev eth0
sudo ip addr del 192.0.2.20/24 dev eth0

Routing

$ ip route show
default via 192.0.2.1 dev eth0 proto dhcp src 192.0.2.10 metric 100
10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.5
192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.10

Read bottom-up conceptually: the kernel matches the most specific route first (longest prefix match), falling back to default only if nothing more specific matches the destination. A host with two interfaces (like this example — one on 192.0.2.0/24, one on 10.0.0.0/24) routes traffic for each subnet out its own interface automatically, and anything else goes out the default route.

metric matters when multiple default routes exist (common on multi-homed hosts, or hosts with both a wired and a VPN connection): the lower metric wins as the preferred route.

sudo ip route add 203.0.113.0/24 via 192.0.2.1 dev eth0
sudo ip route del 203.0.113.0/24
sudo ip route add default via 192.0.2.1 dev eth0 metric 50   # make this the preferred default

Checking connectivity layer by layer

When "the network is broken," work up the stack instead of guessing:

ip link show eth0                 # 1. Is the interface even up, physically?
ip addr show eth0                 # 2. Does it have the address you expect?
ip route get 8.8.8.8              # 3. What route/interface would be used to reach a target?
ping -c 3 192.0.2.1                # 4. Can you reach the default gateway at all?
ping -c 3 8.8.8.8                  # 5. Can you reach the internet by IP (rules out DNS)?
curl -v https://example.com        # 6. Does a full TCP+TLS+HTTP exchange succeed?

ip route get <ip> is underused and very useful — it doesn't send any traffic, it just asks the kernel's routing table which interface/gateway/source address would be used, which is often enough to spot a misconfigured route without generating any actual packets.

Watching live connections

ss -tulnp

-t TCP, -u UDP, -l listening sockets only, -n numeric (skip slow DNS/service-name lookups), -p show the owning process (needs root for other users' processes). This is the modern replacement for netstat -tulnp, which is deprecated the same way ifconfig is.

Ubuntu/Debian vs. RHEL-family differences

ip itself is identical. The persistent configuration layer differs:

Ubuntu/Debian RHEL-family
Config tool netplan (YAML) generating systemd-networkd or NetworkManager config NetworkManager (nmcli, /etc/sysconfig/network-scripts/ on older releases, keyfiles on newer)
Apply config sudo netplan apply sudo nmcli connection reload / nmcli con up <name>

Practical exercise

  1. Run ip -br addr show and identify which interface has your default route (cross-reference with ip route show).
  2. Run ip route get 1.1.1.1 and confirm the interface it reports matches the default route.
  3. Temporarily add a second address to a non-critical interface, confirm it with ip -br addr show, then remove it again with ip addr del.

How to verify you did it correctly

  • After adding the address, ip -br addr show <iface> should list both the original and the new address on the same line.
  • After ip addr del, it should be gone, with zero effect on the original address or route table.

Common mistakes

  • Forgetting ip addr add/route add changes don't survive reboot. They're runtime-only; persistent config always goes through the distribution's config system (netplan, NetworkManager, /etc/network/interfaces).
  • Troubleshooting DNS issues with ping <hostname> without first checking ping <ip> — if the IP-based ping also fails, the problem isn't DNS at all, it's routing/connectivity, and chasing DNS config first wastes time. See the companion DNS article.
  • Assuming UP in ip link show means "working." It means the administrative state is up — carrier (cable plugged in, link negotiated) is a separate LOWER_UP flag you can see in the full (non--br) ip link show output.

⚠ Dangerous commands

  • ip addr flush dev <iface> removes every address from an interface instantly, including the one you're currently SSH'd in over — doing this on a remote box's only reachable interface locks you out immediately, with no local console. If you must flush addresses on a remote host, have an out-of-band access path (console/IPMI) ready first.
  • ip route del default on a remote session over that same default route cuts your own connection before the command even finishes returning.

Review questions

  1. What does the metric value on a route control, and when does it matter?
  2. Why is ip route get <ip> safe to run on a production system, even though it's described as a "routing" command?
  3. What's the practical difference between an interface being administratively UP and having LOWER_UP (carrier)?
  4. Why should you check ping <ip> before ping <hostname> when diagnosing "the internet is down"?