Somewhere in the last decade, the network stopped being a thing made only of routers and switches. The load balancer is a Linux box. The firewall is a Linux box. The DNS server, the VPN concentrator, the container host with four hundred virtual interfaces, the SD-WAN edge device: Linux, all of them, and increasingly the thing on the other end of your show cdp neighbors output too. An engineer who can read a routing table on IOS but not on Debian is working with one eye closed.
This guide is the map for the Linux side. It covers the command set that replaced ifconfig, how the kernel actually makes a forwarding decision, the neighbor table and its state machine, the layer below the kernel where the NIC driver lives, and how any of it survives a reboot. Every command and every block of output on this page and across the cluster was captured on a Debian 13 host wired into a Cisco Modeling Labs topology, so all of it is reproducible and none of it is transcribed from a man page. Read it top to bottom for the model, or jump to the section that matches what is currently broken.
What this toolset solves
Two problems, and they are different.
The first is translation. If your instincts were trained on Cisco, you already know what you want to see; you just do not know which command shows it. You want show ip interface brief, show ip route, show arp, show interfaces. Those all exist on Linux under different names, and most of them are better. The mapping is short enough to learn in an afternoon.
The second is that Linux exposes things a router never did. Multiple routing tables consulted in a configurable order, per-neighbor reachability states, per-queue NIC statistics, offloads that make packet captures disagree with the wire, and a strict separation between what is running now and what will be running after a reboot. None of those have an IOS equivalent, and all of them will eventually cost you an outage if you do not know they exist.
The tools split cleanly into layers, and knowing which layer owns a question is most of the diagnosis:
ethtool - speed, duplex, offloads, rings, per-queue counters
ip - addresses, links, routes, neighbors, rules, namespaces
ss, netstat -s - what is listening, what is connected, protocol counters
ping, traceroute, mtr, tracepath - does it work, and where does it stop
dig, host, nslookup, resolvectl - what the client asked and what it got back
tcpdump, tshark, ngrep - the packets themselves
nmcli, systemd-networkd, netplan - what is still true after a reboot
How it works: netlink, and why the old tools stopped being enough
The commands you may have learned first (ifconfig, route, arp, netstat) come from the net-tools package and read kernel state through /proc text files and legacy ioctls. Those interfaces still work. They also stopped being extended around 2001, so everything Linux networking gained afterward is invisible to them.
The replacement set (ip, ss, bridge, tc, all from iproute2) talks to the kernel over netlink: a structured, versioned socket protocol that new kernel features get wired into as they land. That is the whole argument for the switch, and it is not aesthetic. It is the difference between seeing your configuration and seeing part of it.
Here is the single most important consequence, stated plainly: ifconfig can report an address as absent when it is configured and working. Linux has supported multiple addresses per interface for decades. ifconfig has no model for that and only sees additional addresses carrying an alias label like eth0:1. Add an address the normal way, with ip addr add and no label, and ifconfig will not show it at all.
That is not a display quirk. It means a tool you are using to diagnose a problem can tell you a working thing is broken. Everything else in the migration argument (address lifetimes, neighbor states, policy routing, VRFs) is a matter of missing detail. This one is a matter of being actively misled, and it is why the translation from net-tools to iproute2 is worth doing properly rather than aliasing your way around.
The reference cards
These are the two you will keep scrolling back to. First, the command translation.
ip -br addrwas ifconfig, is show ip interface brief
ip -s link showwas netstat -i, is show interfaces
ip route showwas route -n or netstat -rn, is show ip route
ip route get x.x.x.xno legacy equivalent, is show ip route x.x.x.x
ip neigh showwas arp -n, is show ip arp
ss -tulpnwas netstat -tulpn, is show control-plane host open-ports
ethtool eth0no legacy equivalent, is the speed/duplex half of show interfaces
ip rule showno legacy equivalent, is PBR and show ip policy
Second, the lab every capture in this cluster came from, so you can rebuild it and follow along.
ens192, DHCP, NetworkManager-managed
ens224, 10.77.0.100/24, configured with iproute2, bridged into CML
10.77.0.1, IOS XE 17.18.2
10.77.12.0/24, R2 to R3 10.77.23.0/24, OSPF area 0
10.77.2.10 (nginx), two hops in
10.77.3.10, three hops in
The one idea that matters most
If you take a single thing from this guide, take this: on Linux, running state and saved configuration are two different things, and no command touches both.
Every command in this cluster that changes something (ip addr add, ip route add, ip link set, ethtool -G, ethtool -K, sysctl -w) writes to the running kernel and nowhere else. There is no configuration file behind any of them. Reboot the host and every one of those changes is gone, replaced by whatever the interface manager thinks the world should look like.
Coming from IOS, where copy running-config startup-config is an explicit, memorable step, this is the trap. There is no write mem on Linux, and there is nothing to remind you. A change you made at 2am and verified working is simply absent after the next maintenance window, and the outage looks like it came from nowhere.
The upside, once you internalize it, is real. A reboot is a guaranteed rollback. You can make an aggressive change on a production host knowing that the worst case, if console access still exists, is a power cycle. That is a much better safety net than most network operating systems give you, and experienced Linux engineers lean on it deliberately.
The workflow that follows from it: use ip and ethtool to find the configuration that works, then write that exact configuration into whichever manager owns the interface, then reactivate and verify. On most modern distributions that manager is NetworkManager and the tool is nmcli. On minimal server images it may be systemd-networkd, on Ubuntu it may be netplan generating one of the two, and on older Debian it may be /etc/network/interfaces. Find out which before you need to know.
The minimum viable session
Six commands cover most of what you will do on an unfamiliar Linux host. Here they are against the lab, in the order you would actually run them.
What addresses does this box have:
j@llmbits:~$ ip -br addr show
lo UNKNOWN 127.0.0.1/8 ::1/128
ens192 UP 192.168.88.156/24 fd64:f725:df42:4f01:8498:4c62:15f0:8139/64 fd64:f725:df42:4f01:20c:29ff:feb1:cc3d/64 fe80::20c:29ff:feb1:cc3d/64
ens224 UP 10.77.0.100/24Where does it send traffic:
j@llmbits:~$ ip route show
default via 192.168.88.1 dev ens192 proto dhcp src 192.168.88.156 metric 101
10.77.0.0/24 dev ens224 proto kernel scope link src 10.77.0.100
10.77.0.0/16 via 10.77.0.1 dev ens224
192.168.88.0/24 dev ens192 proto kernel scope link src 192.168.88.156 metric 101Where would it send traffic to one specific destination, which is a different and better question:
j@llmbits:~$ ip route get 10.77.3.10
10.77.3.10 via 10.77.0.1 dev ens224 src 10.77.0.100 uid 1000
cacheHas it resolved its next hop:
j@llmbits:~$ ip neigh show dev ens224
10.77.0.1 lladdr aa:bb:cc:00:04:00 REACHABLEDoes the path work, and where does it go:
j@llmbits:~$ traceroute -n 10.77.3.10
traceroute to 10.77.3.10 (10.77.3.10), 30 hops max, 60 byte packets
1 10.77.0.1 4.452 ms 4.379 ms 4.437 ms
2 10.77.12.2 4.686 ms 6.932 ms 6.960 ms
3 10.77.23.3 7.029 ms 7.022 ms 8.543 ms
4 10.77.3.10 8.506 ms 10.428 ms 10.354 msDoes the service on the far end actually answer:
j@llmbits:~$ curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' http://10.77.2.10/
200 0.009585sSix commands, and you now know the host's addressing, its forwarding decisions, its layer 2 adjacency, the path across three routers and whether the application at the end responds. That is a complete first pass and it takes under a minute.
Reading both sides of the same link
The reason this cluster is built on a real router topology rather than a single host is that the interesting mistakes happen at the boundary. Here is R1's ARP table, taken at the same moment as the ip neigh output above:
R1#show ip arp
Protocol Address Age (min) Hardware Addr Type Interface
Internet 10.77.0.1 - aabb.cc00.0400 ARPA Ethernet0/0
Internet 10.77.0.100 0 000c.29b1.cc47 ARPA Ethernet0/0
Internet 10.77.12.1 - aabb.cc00.0410 ARPA Ethernet0/1
Internet 10.77.12.2 4 aabb.cc00.0300 ARPA Ethernet0/1000c.29b1.cc47 on the router is 00:0c:29:b1:cc:47 on the host. One MAC address, two vendors' formatting conventions, one adjacency. That is the entire trick to working across both worlds: the protocols on the wire are identical, only the presentation changed.
The genuine differences are in behavior rather than syntax, and there are three worth carrying in your head. IOS ages ARP entries on a fixed four hour timer and does not track per-entry reachability; Linux tracks reachability continuously and notices a dead neighbor within about thirty seconds of trying to use it. IOS compares routes across protocols using administrative distance; the Linux kernel has no such concept and compares only metric within a table, leaving protocol preference to whatever daemon is installing routes. And IOS has one routing table per VRF, while Linux has an arbitrary number of tables consulted in a configurable order, which is both more flexible and much easier to misconfigure.
The operational concern: offloads make your captures lie
This one costs people entire afternoons and it belongs on the pillar rather than buried in a subsidiary article.
Modern NICs do work the CPU used to do. TCP segmentation offload lets the kernel hand the NIC a buffer far larger than the MTU and have the NIC cut it into frames. Generic receive offload does the reverse, merging incoming frames into larger buffers before the stack sees them. Both are on by default and both are a substantial CPU saving.
They also mean the host's own view of its traffic does not match the wire. From this host's NIC statistics:
j@llmbits:~$ sudo ethtool -S ens224
Tx Queue#: 1
TSO pkts tx: 2532
TSO bytes tx: 8251296
ucast pkts tx: 3247
ucast bytes tx: 93179872532 segmentation-offload packets carrying 8,251,296 bytes, on a link with a 1500 byte MTU. That averages 3258 bytes per "packet". The switch at the other end counted several times as many frames, and neither counter is wrong.
Two practical consequences. First, comparing a host's packet count to a switch port's packet count is not a valid diagnostic while TSO is on, and people reach for it constantly. Second, tcpdump taps above the NIC, so a capture taken on the host shows those oversized pre-segmentation buffers on transmit and merged buffers on receive, plus checksums marked invalid on outbound packets because the NIC had not filled them in yet. If you need the capture to reflect what a span port would see, disable the offloads for the duration:
sudo ethtool -K ens224 tso off gso off gro off lro off
# capture
sudo ethtool -K ens224 tso on gso on gro on lro onThe full treatment, including ring buffers, coalescing and the host-side drop counters, is in ethtool: link speed, duplex, offloads and NIC stats, and it pairs directly with tcpdump for network engineers.
Hardening: what to check on a Linux box you inherited
A Linux host on your network is an attack surface with a shell on it. Four checks, none of which take long.
What is listening, and on which address. ss -tulpn is the whole answer, and the address column is the part people skip. A service bound to 127.0.0.1 is reachable only from the host; one bound to 0.0.0.0 is reachable from every network the box touches, including the management network you did not intend to expose it on. On the host in this lab, cups is bound to loopback and sshd is not, which is the correct arrangement for both.
Whether it is forwarding. sysctl net.ipv4.ip_forward tells you whether this host will route between its interfaces. On a server it should be 0. Container runtimes turn it on, sometimes without anybody noticing, and a dual-homed host that forwards is a bridge between two security zones that no firewall rule accounted for.
Whether it accepts redirects and source routing. net.ipv4.conf.all.accept_redirects and accept_source_route should both be 0 on anything that is not a router. ICMP redirect acceptance is a genuinely usable attack on a flat network.
Reverse path filtering. net.ipv4.conf.all.rp_filter drops packets arriving on an interface the host would not use to reply. Strict mode breaks legitimate asymmetric routing, which is precisely why the policy routing approach of one table and one source-based rule per interface is the correct fix for multihoming rather than turning the protection off.
Scanning the host from outside is the other half of this, and it belongs to a real attacker's toolkit rather than the host's own. The Nmap cluster covers that side against lab gear you own.
Troubleshooting order
When a Linux host cannot reach something, work up the stack rather than guessing. Each step tells you whether to continue or stop.
ip link show for LOWER_UP, or ethtool eth0 for Link detected. No carrier means stop and look at the cable or the switch port.
ip -br addr. Wrong prefix length is the classic, and it looks fine until you try to reach something just outside it.
ip neigh show. FAILED or INCOMPLETE on the gateway is a layer 2 problem: wrong VLAN, blocked port, host down.
ip route get <dest>. Not show. This runs the real lookup including policy rules and source selection.
ping then traceroute or mtr. Which hop stops answering, and whether loss is at one hop or from one hop onward.
nc -vz or curl. Reachable host with a dead service is a completely different ticket.
dig against the configured resolver, then against a known-good one. Half of "the network is down" is DNS.
tcpdump, with offloads disabled. The last resort, and the one that settles arguments.
Step 4 deserves emphasis because it is the one people substitute for. ip route show prints the table and leaves you to do longest-prefix match by eye against possibly several tables. ip route get asks the kernel what it will actually do. On any host with policy routing, a VPN, or a container bridge, those two can give you different answers and only one of them is the truth.
The Full Cluster, in Reading Order
Six articles so far, all built on the same Debian host and the same CML topology. Read in order for the model, or jump to whatever is currently on fire.
The iproute2 core
- The Linux ip command: the complete guide - the grammar, all four everyday objects, the output modifiers, and creating interfaces out of nothing. Start here if you start anywhere.
- ip route: managing the Linux routing table - every field in a route line,
getagainstshow, blackhole routes, thereplacegotcha, and policy routing with multiple tables. - ARP on Linux: ip neigh, arp and neighbor states - the six-state neighbor machine walked live, the tunables, and what "neighbour table overflow" actually means.
- ifconfig, route and netstat: legacy net-tools to iproute2 - the full command map, and the same host through both toolsets so you can see exactly what the old one hides.
Below and around the kernel
- ethtool: link speed, duplex, offloads and NIC stats - the driver layer, the offloads that make captures disagree with the wire, ring buffers and where host-side drops show up.
- nmcli and nmtui: managing connections from the CLI - devices against profiles, the activation step everybody forgets, and how to make a configuration survive a reboot.
Already covered elsewhere on PingLabz
- The ping cluster - reachability testing properly, including the Linux-specific options and MTU discovery with the DF bit.
- The iPerf cluster - throughput measurement, which is the only honest way to answer a bandwidth question on a virtual link.
- The Nmap cluster - host discovery, port and service scanning against lab gear you own.
- tcpdump for network engineers - capture filters, reading output, and getting a file into Wireshark.
- The DNS enumeration cluster - the offensive side of DNS, run from a real Kali host.
- The network automation cluster - netmiko, NAPALM, Nornir, pyATS, Scapy and Ansible, for when one host stops being enough.
Coming next in this cluster
Path testing and sockets (traceroute, mtr, tracepath, ss), DNS client tools (dig, host, nslookup, and how Linux actually resolves a name), transfer and swiss-army tools (curl, wget, netcat, socat, SSH tunneling), traffic monitoring (tshark, ngrep, the live bandwidth monitors, /proc/net), and firewalling (iptables, nftables, ufw). This page is updated as each publishes.
FAQ
Do I actually need to stop using ifconfig?
For reading a simple host, no, and it will keep working for years. For diagnosis, yes, and the reason is specific: it cannot see addresses added without an alias label, so it can report a working address as absent. It also cannot show address lifetimes, neighbor states, policy routing or VRFs. Any of those being invisible during an incident costs more than the twenty minutes it takes to learn ip.
What is the single most useful Linux networking command?
ip route get <destination>. It performs a real forwarding lookup through policy rules, longest-prefix match and source address selection, and reports the exit interface, next hop and source address the kernel will actually use. It is the command that ends arguments, and it has no net-tools equivalent.
Why do my network changes disappear after a reboot?
Because ip, ethtool and sysctl -w write to the running kernel and have no configuration file behind them. There is no write mem. Whatever manages your interfaces at boot reapplies its own view and yours is gone. Find out whether that is NetworkManager, systemd-networkd, netplan or /etc/network/interfaces, and write the change there.
How different is Linux routing from Cisco routing?
The forwarding logic is the same: longest-prefix match, then metric. The differences are that Linux has no administrative distance in the kernel (protocol preference is the routing daemon's problem), Linux can have any number of routing tables consulted in a configurable order, and the local table that recognizes the host's own addresses is a separate visible table rather than the L entries IOS shows inline.
Which tools should I install on a new server?
iproute2 is almost always already there. Add ethtool, tcpdump, dnsutils or bind-utils for dig, mtr, netcat-openbsd and curl. That set handles nearly every host-side network problem you will meet. On a minimal container image, expect none of them and plan to debug from the host namespace with nsenter instead of installing tools into the container.
Does any of this apply to containers and Kubernetes?
All of it, and more so. A container is a network namespace with veth pairs, bridges and its own routing table, all built with the same ip commands documented here. ip netns, ip link add type veth and per-namespace routing tables are the primitives every container network plugin is built on. Understanding them on one host is what makes a CNI make sense.
Key takeaways
iproute2talks netlink, which is where every kernel feature since 2001 landed.net-toolsreads an API that stopped growing, which is why it can report a working address as absent.- Six commands cover most host-side work:
ip -br addr,ip route show,ip route get,ip neigh show,ss -tulpn,ethtool. - Running state and saved configuration are separate and no command touches both. There is no
write memon Linux, and a reboot is your rollback. ip route getbeatsip route showfor any real question, because it runs the actual lookup including policy rules and source selection.- The neighbor table has states.
REACHABLEandSTALEare both healthy;FAILEDandINCOMPLETEare your layer 2 signal. - Offloads are on by default, so host packet counts and packet captures do not match the wire. Turn TSO, GSO, GRO and LRO off before you trust a capture.
- Work up the stack when troubleshooting: carrier, address, neighbor, route, path, port, name, wire. Each step tells you whether to continue.
- On a host you inherited, check
ss -tulpnfor what is listening, andip_forward,accept_redirectsandrp_filterfor what the kernel is willing to do.
Start with the Linux ip command guide if you are new to the toolset, or with the net-tools translation if you have twenty years of ifconfig in your fingers and need the map.