# ip: Network Setup and Diagnostics in CLI

LLMS index: [llms.txt](/en/llms.txt)

---

When ifconfig returns nothing and configuring a route requires a separate command, that's not a system bug. It's iproute2 — the package that replaced net-tools in modern Linux distributions. The `ip` utility from iproute2 is the standard interface for managing the Linux network stack. It covers interfaces, addresses, routes, ARP cache, routing policies, and namespace isolation.

## Why iproute2 replaced net-tools

net-tools (ifconfig, route, arp, netstat, nameif) originated in BSD and migrated to Linux in the 1990s. By the 2000s it became clear: they cannot handle VLAN, IPsec, QoS, multicast routing, or Policy Routing. Each task required a separate command with unrelated syntax.

iproute2 consolidated everything into one `ip` utility with subcommands. The Linux kernel communicates with the network subsystem via netlink sockets — `ip` talks to them directly, while ifconfig parses /proc/net/. In systemd-based distributions (RHEL 7+, Ubuntu 16.04+, Debian 9+) `ip` is installed by default. net-tools remains in repositories for compatibility, but kernel developers haven't added new functionality since 2001.

Install if needed: `apt install iproute2` or `yum install iproute`.

## ip link: interface state and management

ip link operates at L2 — listing and controlling interface state.

```bash
ip link show
ip link show eth0
ip link show type bridge
```

Output shows index, name, MAC address, MTU, state (UP/DOWN), and error/packet counters.

Bring an interface up or down:

```bash
ip link set eth0 up
ip link set eth0 down
```

> [!WARNING]
> Taking down an interface severs connectivity. When working remotely, wrap in a script with a timeout and auto-recovery.

Set MTU, change MAC, or rename:

```bash
ip link set eth0 mtu 9000
ip link set eth0 address 02:42:ac:11:00:02
ip link set eth0 name enp0s3
```

Create virtual interfaces (VETH pair for namespace or bridge):

```bash
ip link add veth0 type veth peer name veth1
ip link add br0 type bridge
ip link set veth0 master br0
```

Delete an interface:

```bash
ip link del veth0
```

| Flag | Purpose |
|------|---------|
| show | display interfaces (shorthand: ip l) |
| set | modify interface parameters |
| add / del | create or delete virtual interface |
| master | attach interface to a bridge |

## ip addr: address binding and diagnostics

ip addr manages IP addresses (L3).

```bash
ip addr show
ip addr show eth0
```

Add an address:

```bash
ip addr add 192.168.1.10/24 dev eth0
```

Add a secondary address (alias) on the same interface:

```bash
ip addr add 192.168.1.11/24 dev eth0
```

> [!NOTE]
> Secondary addresses in Linux are not aliases in the ifconfig sense — they are part of a single address entity. The command `ifconfig eth0:0` created a pseudodevice with a separate name; `ip` works differently.

Remove an address:

```bash
ip addr del 192.168.1.10/24 dev eth0
```

Flush all addresses from an interface:

```bash
ip addr flush dev eth0
```

Useful during reconfiguration: clear old addresses and assign new ones without restarting the service.

Specify scope and label:

```bash
ip addr add 10.0.0.5/8 dev eth0 scope host label eth0:internal
```

scope host — address only for local sockets; scope global — routable.

| Subcommand | Action |
|------------|--------|
| add | assign address |
| del | remove address |
| show | display addresses |
| flush | clear interface addresses |

## ip route: default and static routes

ip route works with the routing table.

```bash
ip route show
```

Add a default route (gateway):

```bash
ip route add default via 192.168.1.1 dev eth0
```

Add a specific route:

```bash
ip route add 10.20.0.0/16 via 192.168.1.254 dev eth0
```

Route to a host via direct ARP (no route, L2 only):

```bash
ip route add 192.168.1.50/32 dev eth0
```

Remove a route:

```bash
ip route del default via 192.168.1.1
```

Replace a route (updates if exists, creates if not):

```bash
ip route replace default via 10.0.0.1 dev eth0
```

Get the route the kernel will choose for an address:

```bash
ip route get 8.8.8.8
```

Add a route to a different table (default is table 254):

```bash
ip route add default via 10.0.0.1 dev eth0 table 100
```

| Subcommand | Purpose |
|------------|---------|
| show / list | display routing table |
| add | add a route |
| del | remove a route |
| replace | modify or create a route |
| get | show route to an address |
| flush | clear route cache |

## ip neigh: ARP/NDP cache

ip neigh manages the neighbour table — ARP for IPv4, NDP for IPv6.

```bash
ip neigh show
ip neigh show dev eth0
```

Add a static ARP entry:

```bash
ip neigh add 192.168.1.1 lladdr 00:11:22:33:44:55 dev eth0 nud permanent
```

nud (Neighbour Unreachability Detection) defines the state:

- permanent — entry never expires
- noarp — managed by protocol but not removed
- reachable / stale / delay / probe — automatic states

Remove an entry:

```bash
ip neigh del 192.168.1.1 dev eth0
```

Flush all neighbours on an interface:

```bash
ip neigh flush dev eth0
```

> [!TIP]
> After changing a gateway MAC address, flushing the ARP cache speeds up connectivity recovery: `ip neigh flush dev eth0`.

## ip rule: routing policies

ip rule determines which routing table is used for a packet.

```bash
ip rule show
```

Standard output:

```
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
```

Add a rule for source IP:

```bash
ip rule add from 10.0.0.5 table 100
```

Rule for incoming interface:

```bash
ip rule add iif eth0 table 100
```

Remove a rule:

```bash
ip rule del from 10.0.0.5 table 100
```

> [!NOTE]
> Rules are checked in order (priority). Low number means high priority. Add rules with priority between existing ones if ordering matters.

| Action | Purpose |
|--------|---------|
| from | source IP or CIDR |
| to | destination IP or CIDR |
| iif | incoming interface |
| lookup | routing table |
| prio | numeric priority |

## ip maddr: multicast addresses

ip maddr displays and manages multicast groups on an interface.

```bash
ip maddr show eth0
```

Add an interface to a multicast group:

```bash
ip maddr add 239.0.0.1 dev eth0
```

Remove:

```bash
ip maddr del 239.0.0.1 dev eth0
```

Unlike unicast, multicast addressing is used in broadcast domains, routing protocols (OSPF, RIP), discovery services, and streaming. In most tasks this command is unnecessary, but when configuring clusters or monitoring via specific protocols — it will be required.

## ip netns: network stack isolation

ip netns creates isolated network namespaces. Each namespace has its own interfaces, addresses, routes, ARP table, and rules.

Create a namespace:

```bash
ip netns add testns
```

Run a command inside a namespace:

```bash
ip netns exec testns ip link show
```

Bring up an interface in a namespace:

```bash
ip netns exec testns ip link set lo up
ip netns exec testns ip addr add 127.0.0.1/8 dev lo
```

Move a VETH interface into a namespace:

```bash
ip link set veth1 netns testns
```

Delete a namespace:

```bash
ip netns del testns
```

List namespaces:

```bash
ip netns list
```

> [!TIP]
> Containers (docker, podman, LXC) use netns underneath. If a container has no network — check the host namespace: `ip netns exec <container_pid> ip addr`.

## ifconfig, arp, route — legacy compatibility

net-tools is formally available in all major distribution repositories. The source code is unmaintained, but packages persist for compatibility.

| Legacy command | Equivalent ip | Status |
|----------------|---------------|--------|
| ifconfig | ip addr, ip link | deprecated |
| route -n | ip route | deprecated |
| arp -a | ip neigh | deprecated |
| netstat -tulpn | ss -tulpn | deprecated |
| nameif | ip link name | deprecated |

ss from iproute2 replaces netstat — faster and provides more socket information.

> [!WARNING]
> Network initialization scripts in old distributions may rely on ifconfig. On modern systems, systemd-networkd, NetworkManager, and cloud-init use `ip` directly or through their own abstractions.

If ifconfig is missing in a fresh distribution — that's expected. Configuration via `ip` covers all current scenarios: from address assignment to complex routing policies and service isolation via namespaces.
