Network Fundamentals — Hands-on in a Linux VM
See ARP as Frames
This lab runs on a VM
You create two network namespaces and use them as two hosts. One veth pair is the cable connecting them. Everything is inside a single VM, but from the kernel's point of view they are two real machines.
Goal
Capture ARP, which turns an IP address into a MAC address, frame by frame; read the neighbor table; and put in a static entry to confirm how a wrong MAC kills communication.
Why it matters
Communication inside the same subnet goes by MAC, not by IP. The IP says "to whom", and the actual frame is delivered by looking at the MAC. ARP links the two, and its result is the neighbor table (the ARP cache). So when the IP settings are all correct but communication fails, you look at the neighbor table first — stale entries, duplicate IPs, and wrong static entries are there. Even if clouds and Kubernetes hide ARP, the foundation is the same.
Steps
- Create the namespaces
aliceandbob. - Create a veth pair
va·vband putvainaliceandvbinbob. - Attach
10.10.0.1/24tovainaliceand10.10.0.2/24tovbinbob, bringloUP as well, and make ping work fromalicetobob. - After the ping, save the neighbor table of
alice(ip -n alice neigh) to/root/arp/neigh.txt.bob's MAC must be visible. - Flush the neighbor table of
alice, capture ARP onvawithtcpdumpwhile sendingarping, and save the request and reply frames to/root/arp/capture.txt. - Put
bob's MAC intoaliceas a static (permanent) neighbor entry. - Change the static entry to a wrong MAC, record the dead ping in
/root/arp/broken.txt, and then restore the static entry with the correct MAC. - In
/root/arp/report.md, write one linebob_mac=together with an explanation of why an ARP request is a broadcast and why a wrong static entry is not visible at the IP layer.
Notes
- Run a command inside a namespace with
ip netns exec alice <명령>(replace the placeholder with the command), orip -n alice ...if it is just an ip command. ip link add va type veth peer name vbcreates a pair of cable ends. Move one withip link set va netns alice.- Neighbor table:
ip -n alice neigh. Flush it:ip -n alice neigh flush all. Static entry:ip -n alice neigh replace 10.10.0.2 lladdr <MAC> dev va nud permanent. - For the capture, start it in the background like
ip netns exec alice timeout 6 tcpdump -i va -nn -l arp > 파일 2>&1 &(replace the file placeholder with the output file name), send the arping, and then wait. - A common mistake: forgetting to bring
loup. The lo in a namespace is DOWN by default.
Two hosts
Create the namespaces alice and bob.
Create one like ip netns add alice. Check with ip netns list. One namespace is one independent network stack — interfaces, addresses, routing, and neighbor table.
Connecting the cable
Create a veth pair va·vb and put va in alice and vb in bob.
Create the pair with ip link add va type veth peer name vb, then move each end with ip link set va netns alice and ip link set vb netns bob. Once moved, they are no longer visible in the root namespace.
Attach addresses and ping
Attach 10.10.0.1/24 to va in alice and 10.10.0.2/24 to vb in bob, bring lo UP as well, and make ping work from alice to bob.
ip -n alice addr add 10.10.0.1/24 dev va, ip -n alice link set va up, ip -n alice link set lo up — do the same for bob. Then ip netns exec alice ping -c 2 10.10.0.2.
Reading the neighbor table
After the ping, save the neighbor table of alice (ip -n alice neigh) to /root/arp/neigh.txt. bob's MAC must be visible.
Once a ping has gone back and forth, the kernel puts the ARP result in the neighbor table. In ip -n alice neigh, what follows lladdr is the MAC and the last field is the state (REACHABLE, STALE, and so on). Cross-check bob's MAC with ip -n bob link show vb.
ARP as frames
Flush the neighbor table of alice, capture ARP on va with tcpdump while sending arping, and save the request and reply frames to /root/arp/capture.txt.
Start the capture in the background first: ip netns exec alice timeout 6 tcpdump -i va -nn -l arp > /root/arp/capture.txt 2>&1 &. Then run ip -n alice neigh flush all and ip netns exec alice arping -I va -c 1 10.10.0.2. The file must contain two lines, Request who-has and Reply … is-at.
Static neighbor entry
Put bob's MAC into alice as a static (permanent) neighbor entry.
ip -n alice neigh replace 10.10.0.2 lladdr <bob의 MAC> dev va nud permanent (replace the placeholder with bob's MAC). It must show as PERMANENT in ip -n alice neigh. A static entry does not disappear over time, and no ARP is sent for it.
With a wrong MAC
Change the static entry to a wrong MAC, record the neighbor entry at that moment together with the dead ping in /root/arp/broken.txt, and then restore the static entry with the correct MAC.
After running neigh replace … nud permanent with a fake MAC such as lladdr 02:00:00:00:00:01, save the results of ip -n alice neigh show 10.10.0.2 and ping -c 1 -W 1 (100% packet loss) in one file. The ping statistics alone cannot be told apart from an unplugged cable, so which MAC you pinned must be included too. When you are done, replace it again with the real MAC, as in step 6 — the grader also checks that you restored it.
What you learned
In /root/arp/report.md, write one line bob_mac= together with an explanation of why an ARP request is a broadcast and why a wrong static entry is not visible at the IP layer.
bob_mac is the value from ip -n bob link show vb. It is a broadcast because the sender is asking without knowing the peer's MAC, and it is invisible at the IP layer because the place where the frame is dropped is the peer's NIC, so no error comes back.