Network configuration on Linux — exercises with the workstation’s ID card, ifconfig commands translated and a generated ifcfg (and the /32 that left the card all alone)

In the networks practical exam we had to configure the workstation by copying the commands from the notes. I typed ip addr add 10.110.7.4 dev enp2s0, brought the card up, pinged the gateway… Network is unreachable. I checked the IP ten times: it was right. What was missing was three characters: /24. The lesson: in networking, what you don’t type counts too; without a mask, the card thinks it’s alone in the world.

These exercises close the topic after the theory and the practice. They’re done in the same isolated lab (workstation, gateway 10.110.7.1 and router 10.110.1.1), as root except where stated.

How to use this article

  1. Read the task and the expected output.
  2. Solve it on a practice or virtual machine (never on your laptop) without looking at the solution. If you get stuck, open the hint.
  3. Before the solutions, do the three “What’s wrong here?” snippets: predict the error.
  4. Compare with my commands. What counts is that the output matches and that you can explain every line.

Level 1: the workstation’s ID card

The workstation is already configured. With four commands that only look, get its MAC, its IP with prefix, its default gateway and the first DNS server.

Expected output (the MAC and the number after @if will differ on your machine):

# ip -br link show enp2s0
enp2s0@if21      UP             08:00:27:a1:07:04 <BROADCAST,MULTICAST,UP,LOWER_UP> 
# ip -br addr show enp2s0
enp2s0@if21      UP             10.110.7.4/24 
# ip route show default
default via 10.110.7.1 dev enp2s0 
# head -1 /etc/resolv.conf
nameserver 193.145.147.22

-br also works with link, and both ip addr and ip link accept show <card>. For the DNS, the first line of a file in /etc.

Level 2: from ifconfig to ip

Some old notes have these commands to configure the workstation with the IP 10.110.7.5:

ifconfig enp2s0 up
ifconfig enp2s0 10.110.7.5 netmask 255.255.255.0 broadcast 10.110.7.255
route add default gw 10.110.7.1

Translate them to ip (broadcast address included), apply them to the freshly booted workstation and check the result with ip addr show enp2s0, with the old route -n and with a 2-packet ping to the router.

Expected output:

# ip link set enp2s0 up
# ip addr add 10.110.7.5/24 brd + dev enp2s0
# ip route add default via 10.110.7.1
# ip addr show enp2s0
26: enp2s0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 08:00:27:a1:07:04 brd ff:ff:ff:ff:ff:ff link-netns gateway
    inet 10.110.7.5/24 brd 10.110.7.255 scope global enp2s0
       valid_lft forever preferred_lft forever
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.110.7.1      0.0.0.0         UG    0      0        0 enp2s0
10.110.7.0      0.0.0.0         255.255.255.0   U     0      0        0 enp2s0
# ping -c 2 10.110.1.1
PING 10.110.1.1 (10.110.1.1) 56(84) bytes of data.
64 bytes from 10.110.1.1: icmp_seq=1 ttl=63 time=0.233 ms
64 bytes from 10.110.1.1: icmp_seq=2 ttl=63 time=0.068 ms

--- 10.110.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1004ms
rtt min/avg/max/mdev = 0.068/0.150/0.233/0.082 ms

/24 replaces netmask 255.255.255.0, and brd + asks ip to work out the broadcast for you.

Level 3: generate the ifcfg of what’s there

You’ve configured a workstation by hand with ip and it works. Before a reboot wipes it all, write a script ifcfg-from-live.sh that, given the card’s name, prints the ifcfg that would reproduce the current configuration (DEVICE, BOOTPROTO=none, ONBOOT=yes, IPADDR, NETMASK with the mask written in full, and GATEWAY only if there’s a default route).

Expected output, with the workstation configured:

# ./ifcfg-from-live.sh enp2s0 > ifcfg-generated
# cat -n ifcfg-generated
     1	DEVICE=enp2s0
     2	BOOTPROTO=none
     3	ONBOOT=yes
     4	IPADDR=10.110.7.4
     5	NETMASK=255.255.255.0
     6	GATEWAY=10.110.7.1

ip -br -4 addr show dev enp2s0 gives a line whose third column is 10.110.7.4/24. ${cidr%/*} and ${cidr#*/} split it at the slash. To go from 24 to 255.255.255.0, walk through the four bytes subtracting 8 bits each time.

What’s wrong here?

Three snippets on the freshly booted workstation. Before reading the explanation, predict what will come out.

Snippet 1: the IP without a mask

ip link set enp2s0 up
ip addr add 10.110.7.4 dev enp2s0        # no /24
ip -br addr
ip route
ping -c 1 10.110.7.1

Predict: does the gateway reply?

# ip link set enp2s0 up
# ip addr add 10.110.7.4 dev enp2s0
# ip -br addr
lo               UNKNOWN        127.0.0.1/8 
enp2s0@if9       UP             10.110.7.4/32 
# ip route
# ping -c 1 10.110.7.1
ping: connect: Network is unreachable
# ip addr del 10.110.7.4/32 dev enp2s0
# ip addr add 10.110.7.4/24 dev enp2s0
# ping -c 1 10.110.7.1
PING 10.110.7.1 (10.110.7.1) 56(84) bytes of data.
64 bytes from 10.110.7.1: icmp_seq=1 ttl=64 time=0.822 ms

--- 10.110.7.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.822/0.822/0.822/0.000 ms

Network is unreachable, and ip route is empty. ip -br addr gives it away: 10.110.7.4/32. Without a prefix, ip uses /32, a network of a single address: the workstation itself. As there’s no other address in “its network”, the kernel doesn’t create the 10.110.7.0/24 route, and the gateway .1 is off every known path.

What an IP covers with /32 and with /24With /32 the network is a single address, 10.110.7.4, and the gateway 10.110.7.1 falls outside. With /24 the network spans 10.110.7.0 to 10.110.7.255 and includes the gateway.10.110.7.4/32 (no mask)my network: just me.1 gateway.4 me.255the gateway .1 is OUTSIDE → no route → Network is unreachable10.110.7.4/24my network: 256 addresses.1 gateway.4 me.255the gateway .1 is INSIDE → route 10.110.7.0/24 → it replies
Without /24, ip addr add uses /32: the card thinks it's alone in the world.

Copying ip addr add 192.168.2.2 dev enp2s0 from a cheat sheet. It works without an error… and leaves the card at /32. Always write the prefix.

The fix is in the last three commands of the session: remove the IP with its /32 (that’s its name now) and set it with /24. The ping replies.

Snippet 2: the card nobody brought up

ip addr add 10.110.7.4/24 dev enp2s0     # IP set correctly…
ping -c 1 10.110.7.1                     # …but what about the card?

Predict: the IP is set correctly, with its /24. Does the gateway reply?

# ip addr add 10.110.7.4/24 dev enp2s0
# ping -c 1 10.110.7.1
ping: connect: Network is unreachable
# ip -br addr
lo               UNKNOWN        127.0.0.1/8 
enp2s0@if13      DOWN           10.110.7.4/24 
# ip route
# ip link set enp2s0 up
# ping -c 1 10.110.7.1
PING 10.110.7.1 (10.110.7.1) 56(84) bytes of data.
64 bytes from 10.110.7.1: icmp_seq=1 ttl=64 time=0.681 ms

--- 10.110.7.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.681/0.681/0.681/0.000 ms

No again: Network is unreachable. ip -br addr shows the correct IP next to DOWN, and ip route is empty. A card that’s down has no routes, however well its IP is set. As soon as it’s brought up with ip link set enp2s0 up, the kernel creates the route and the gateway replies.

Faced with Network is unreachable, look at ip -br addr and check two things: UP and the prefix. These are the two most common slips in the lab.

Snippet 3: the router as default gateway

ip link set enp2s0 up
ip addr add 10.110.7.4/24 dev enp2s0
ip route add default via 10.110.1.1      # the router's IP as the default gateway

Predict: the router 10.110.1.1 is what gives access to the rest of the lab. Will it do as the default gateway?

# ip link set enp2s0 up
# ip addr add 10.110.7.4/24 dev enp2s0
# ip route add default via 10.110.1.1
Error: Nexthop has invalid gateway.
# ip route add default via 10.110.7.1
# ping -c 1 10.110.1.1
PING 10.110.1.1 (10.110.1.1) 56(84) bytes of data.
64 bytes from 10.110.1.1: icmp_seq=1 ttl=63 time=0.377 ms

--- 10.110.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.377/0.377/0.377/0.000 ms

Error: Nexthop has invalid gateway. The default gateway is the first hop and must be on your network, reachable without help. The router is on 10.110.1.0/24, behind the gateway, so the workstation can’t hand it anything directly. With via 10.110.7.1 (the gateway) the route is accepted and the router replies with ttl=63: there was one hop in between.

Why the router can't be the workstation's default gatewayFrom the workstation, with 10.110.7.4/24, only the 10.110.7.0/24 network is directly reachable. The gateway 10.110.7.1 is on it; the router 10.110.1.1 isn't, which is why ip rejects the route.The default gateway must be on YOUR networkWorkstation 10.110.7.4/2410.110.7.1 (gateway): directly reachable  10.110.1.1 (router): it's behind the gateway  Error: Nexthop has invalid gateway.
The default gateway is the first hop: if you already need another gateway to reach it, it won't do.

Before adding a default gateway, run ip route get <gateway IP>: if the answer has via, that IP isn’t on your network and won’t do.

Solutions

Solution to Level 1

# @lab conf
ip -br link show enp2s0                  # the MAC
ip -br addr show enp2s0                  # the IP and the prefix
ip route show default                    # the default gateway
head -1 /etc/resolv.conf                 # the first DNS server

Output:

# ip -br link show enp2s0
enp2s0@if21      UP             08:00:27:a1:07:04 <BROADCAST,MULTICAST,UP,LOWER_UP> 
# ip -br addr show enp2s0
enp2s0@if21      UP             10.110.7.4/24 
# ip route show default
default via 10.110.7.1 dev enp2s0 
# head -1 /etc/resolv.conf
nameserver 193.145.147.22

Why it’s done this way:

  • ip -br link show enp2s0 gives the MAC in the third column (08:00:27:a1:07:04), without the extra lines of ip link.
  • ip -br addr show enp2s0 gives the IP with prefix on one line: 10.110.7.4/24.
  • ip route show default filters just the default route: the third word is the default gateway.
  • head -1 /etc/resolv.conf takes the first line: the DNS server asked first. If the file started with a comment, grep -m1 nameserver /etc/resolv.conf would be safer.

Solution to Level 2

# @lab base
ip link set enp2s0 up                            # ifconfig enp2s0 up
ip addr add 10.110.7.5/24 brd + dev enp2s0       # ifconfig enp2s0 10.110.7.5 netmask 255.255.255.0 broadcast 10.110.7.255
ip route add default via 10.110.7.1              # route add default gw 10.110.7.1
ip addr show enp2s0
route -n                                         # check with the old command
ping -c 2 10.110.1.1

Output:

# ip link set enp2s0 up
# ip addr add 10.110.7.5/24 brd + dev enp2s0
# ip route add default via 10.110.7.1
# ip addr show enp2s0
26: enp2s0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 08:00:27:a1:07:04 brd ff:ff:ff:ff:ff:ff link-netns gateway
    inet 10.110.7.5/24 brd 10.110.7.255 scope global enp2s0
       valid_lft forever preferred_lft forever
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.110.7.1      0.0.0.0         UG    0      0        0 enp2s0
10.110.7.0      0.0.0.0         255.255.255.0   U     0      0        0 enp2s0
# ping -c 2 10.110.1.1
PING 10.110.1.1 (10.110.1.1) 56(84) bytes of data.
64 bytes from 10.110.1.1: icmp_seq=1 ttl=63 time=0.233 ms
64 bytes from 10.110.1.1: icmp_seq=2 ttl=63 time=0.068 ms

--- 10.110.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1004ms
rtt min/avg/max/mdev = 0.068/0.150/0.233/0.082 ms

Why it’s done this way:

  • ip link set enp2s0 up is the good old ifconfig enp2s0 up.
  • IP, mask and broadcast go in one command: 10.110.7.5/24 and brd +. Now the inet line does have brd 10.110.7.255: the last address of the network (.0 to .255, the last is .255).
  • route add default gw becomes ip route add default via.
  • route -n works as a cross-check: the table has the default route (0.0.0.0 towards 10.110.7.1, flags UG: up and via a gateway) and the network route (10.110.7.0, mask 255.255.255.0, flag U). Both tools read the same kernel table.
  • The ping to the router replies 2 of 2 with ttl=63.

Solution to Level 3

#!/bin/bash
# ifcfg-from-live.sh: writes the ifcfg that would reproduce the configuration the card has NOW
# Usage: ./ifcfg-from-live.sh enp2s0 > ifcfg-generated
dev=$1
cidr=$(ip -br -4 addr show dev "$dev" | awk '{print $3}')   # third column: 10.110.7.4/24
ip=${cidr%/*}                                               # what comes before the slash
p=${cidr#*/}                                                # what comes after the slash
gw=$(ip route show default | awk '{print $3}')              # "default via 10.110.7.1 dev …": third word

mask() {                             # 24 -> 255.255.255.0: four bytes, each with up to 8 bits set
    local p=$1 m="" i b
    for i in 1 2 3 4; do
        if [ "$p" -ge 8 ]; then b=255; p=$((p - 8))   # full byte
        else b=$((256 - 2 ** (8 - p))); p=0           # partial byte (or 0 if no bits are left)
        fi
        m="$m$b"; [ $i -lt 4 ] && m="$m."
    done
    echo "$m"
}

echo "DEVICE=$dev"
echo "BOOTPROTO=none"
echo "ONBOOT=yes"
echo "IPADDR=$ip"
echo "NETMASK=$(mask "$p")"
[ -n "$gw" ] && echo "GATEWAY=$gw"   # with no default route, the line isn't written

The session:

# @lab conf
./ifcfg-from-live.sh enp2s0 > ifcfg-generated
cat -n ifcfg-generated

Output:

# ./ifcfg-from-live.sh enp2s0 > ifcfg-generated
# cat -n ifcfg-generated
     1	DEVICE=enp2s0
     2	BOOTPROTO=none
     3	ONBOOT=yes
     4	IPADDR=10.110.7.4
     5	NETMASK=255.255.255.0
     6	GATEWAY=10.110.7.1

Why it’s done this way:

  • -4 limits the output to IPv4 and -br keeps it on one line: enp2s0@if… UP 10.110.7.4/24. awk '{print $3}' takes the third column. That way the script doesn’t depend on how many spaces ip puts between columns.
  • ${cidr%/*} removes from the last slash to the end (leaving the IP) and ${cidr#*/} removes up to the first slash (leaving the prefix).
  • ip route show default gives default via 10.110.7.1 dev enp2s0: the third word is the default gateway. If there’s no default route, gw stays empty and the last line doesn’t write GATEWAY.
  • The script prints; the > ifcfg-generated redirection decides where it’s saved. That way you can review the result before copying it to /etc/sysconfig/network-scripts/.

The mask function is the inverse of the practice’s prefix. Trace with p=24:

mask() {                          # 24 -> 255.255.255.0: four bytes, each with up to 8 bits set
    local p=$1 m="" i b
    for i in 1 2 3 4; do
        if [ "$p" -ge 8 ]; then b=255; p=$((p - 8))   # full byte
        else b=$((256 - 2 ** (8 - p))); p=0           # partial byte (or 0 if no bits are left)
        fi
        m="$m$b"; [ $i -lt 4 ] && m="$m."
    done
    echo "$m"
}
Loop ip on entryp ≥ 8?bp on exitm
124yes25516255.
216yes2558255.255.
38yes2550255.255.255.
40no256 − 2⁸ = 00255.255.255.0

With a prefix like 26, the fourth loop would give 256 − 2^(8−2) = 256 − 64 = 192: 255.255.255.192. The [ $i -lt 4 ] check avoids a dot after the last byte.

Try it in your terminal

ip route get is the best way to understand routes: you give it a destination and it tells you what the kernel would do, without sending anything. It doesn’t need root. As a normal user on the workstation:

# @lab conf
# @sergio
ip route get 10.110.7.1                  # on my network: direct
ip route get 10.110.1.1                  # off my network: via the gateway
ip route get 127.0.0.1                   # myself

The real session:

$ ip route get 10.110.7.1
10.110.7.1 dev enp2s0 src 10.110.7.4 uid 1001 
    cache 
$ ip route get 10.110.1.1
10.110.1.1 via 10.110.7.1 dev enp2s0 src 10.110.7.4 uid 1001 
    cache 
$ ip route get 127.0.0.1
local 127.0.0.1 dev lo src 127.0.0.1 uid 1001 
    cache <local> 

What to watch for:

  1. For 10.110.7.1 (the gateway) there’s no via: it’s on my network and is delivered directly through enp2s0.
  2. For 10.110.1.1, via 10.110.7.1 appears: it isn’t on my network, so it goes to the default gateway.
  3. src 10.110.7.4 is the IP the packet would leave with: the chosen card’s.
  4. 127.0.0.1 goes through lo and is local: it never leaves the machine.
  5. On your computer, try ip route get 8.8.8.8: you’ll see your default gateway and which card you use to reach the internet (wlp… if you’re on wifi).

Cheat sheet: network configuration

The essentials in 30 seconds

Getting a network takes three things: the card up, an IP with a prefix (/24 = 255.255.255.0) and a default gateway inside your network. With ip you configure it on the spot (and it’s lost on reboot); with the ifcfg and ONBOOT=yes it sticks. DNS servers go in /etc/resolv.conf.

Looking

I want to…CommandResult
summary of cards and IPsip -br addrenp2s0 UP 10.110.7.4/24
the MACip -br link08:00:27:a1:07:04
the routing tableip route (or route -n)default via 10.110.7.1 dev enp2s0
which path a packet takesip route get 10.110.1.1via 10.110.7.1 dev enp2s0 src 10.110.7.4
learnt MACs (ARP)ip neigh10.110.7.1 … lladdr … REACHABLE
the DNS serverscat /etc/resolv.confnameserver 193.145.147.22

Configuring on the spot (as root)

I want to…CommandResult
bring the card upip link set enp2s0 upUP,LOWER_UP
set IP and broadcastip addr add 10.110.7.4/24 brd + dev enp2s010.110.7.0/24 route created automatically
default gatewayip route add default via 10.110.7.1
remove one IP / all of themip addr del 10.110.7.4/24 dev enp2s0 / ip addr flush dev enp2s0their routes go too
remove the default gatewayip route del default
testping -c 3 10.110.7.1ttl=64 on your network, 63 after one router

Permanent

FileContents
/etc/sysconfig/network-scripts/ifcfg-enp2s0DEVICE, BOOTPROTO=none, ONBOOT=yes, IPADDR, NETMASK, GATEWAY
/etc/resolv.confnameserver IP (one per line)
applysystemctl restart network (with NetworkManager stopped: systemctl stop NetworkManager)

Exercise templates

ExerciseKey commandsResult
Level 1ip -br link show X, ip -br addr show X, ip route show default, head -1 /etc/resolv.confMAC, IP/prefix, gateway, DNS
Level 2ip link set X up; ip addr add IP/24 brd + dev X; ip route add default via GWbrd 10.110.7.255, ping with ttl=63
Level 3ip -br -4 addr show dev X | awk '{print $3}', ${cidr%/*}, ${cidr#*/}, mask functiona 6-line ifcfg

Symptom / likely cause

SymptomLikely cause
connect: Network is unreachablecard DOWN, IP without prefix (/32) or default gateway missing
Destination Host Unreachablethere’s a route, but the destination or the gateway doesn’t answer on the local network (an IP from another network?)
Error: Nexthop has invalid gateway.the default gateway isn’t on your network
RTNETLINK answers: Operation not permittedyou’re not root: sudo
Error: ipv4: Address already assigned. / RTNETLINK answers: File existsthat IP / that route was already set
everything is lost on rebootyou configured it with ip; move it to the ifcfg with ONBOOT=yes

Before you hand it in, ask yourself

  1. Have I pinged something on my network and something outside it?
  2. Do all the IPs have their prefix?
  3. Is the default gateway on my network (ip route get with no via)?
  4. Is whatever must survive a reboot in the ifcfg with ONBOOT=yes?

This topic ends the practical Linux part of IC2. Next comes the theory that explains everything you’ve just configured: how networks work on the inside.

Keep goingAll Linux articles

Did this article help you? Here is how you can support SergioLearns →

Sigue aprendiendo

Leave a Reply

Your email address will not be published. Required fields are marked *