↓ Skip to main content

One link at a time: frames, ARP, switches and the data center

Networking foundations - This article is part of a series.
Part 6: This Article

The worker 10.1.4.21 sends an IPv4 packet to db-b1 at 10.3.2.6: through sw-a1 to gw-a1 10.1.4.1, then over a second link to core-a1. The IP destination does not change on the way; the TTL does, and the checksum that depends on it (Part 4). Yet each link delivers only to a hardware address, a MAC such as 00:00:5e:00:53:01: how does the packet cross one link?

Intent: IP picks the next router; the link moves the packet there inside a frame addressed by MAC. ARP finds that MAC, and a switch learns which port leads to it. A data center connects many such links so that every pair of racks has several equal paths.

Link one: the worker sends a frame through sw-a1 to gw-a1, to 00:00:5e:00:53:01 from 00:00:5e:00:53:21. Link two: gw-a1 builds a new frame from :11 to core-a1 at :12. Then more links, new frames, to db-b1 at 10.3.2.6. A panel holds each link’s frame: destination and source MAC, type 0800 (IPv4), the packet 10.1.4.21 to 10.3.2.6 with TTL 64 then 63, and the frame check. The MAC fields and the TTL change; the IP addresses do not.
Each link, a new frame: the MAC addresses change at every router, the IP destination does not.

A frame carries the packet over one link#

A frame is the envelope one link puts around a packet, addressed to the next device only. Here a link is everything a frame crosses without a router: the cable of the worker 10.1.4.21, sw-a1, and the cable of gw-a1 10.1.4.1. The frame ends with a check value, so the card at the end of a cable can tell when the cable damaged it.

Phase intact: segment 6 from the worker crosses sw-a1, passes gw-a1’s check and goes on to db-b1 at 10.3.2.6. Phase damaged: segment 7; a bit flips on the cable between sw-a1 and gw-a1, the check fails, gw-a1 drops the frame and sends nothing, and the crc count in the panel inside gw-a1 rises by one. Phase resend: no ACK came, so the worker sends segment 7 again; it reaches db-b1, which answers with an ACK.
A damaged frame is dropped, and nobody is told: TCP notices the gap and sends again.

What a frame holds
#

The anchor figure showed the idea: one frame per link. gw-a1 throws away the worker’s frame and builds a new one from its core side, 00:00:5e:00:53:11, to core-a1 at 00:00:5e:00:53:12. The packet inside keeps its addresses.

FieldBytesHoldsOn the worker’s frame
destination MAC6the next device on this linkgw-a1, 00:00:5e:00:53:01
source MAC6the sender on this linkthe worker, 00:00:5e:00:53:21
type2what the payload is: 0800 IPv4, 86DD IPv6, 0806 ARP, 8100 a VLAN tag follows0800
payload46 to 1,500the IP packet; a shorter one is padded to 46the packet for 10.3.2.6
frame check4a CRC (cyclic redundancy check) computed over the framechecked by gw-a1 on arrival

The 1,500-byte limit on the payload is the MTU of Part 4. A type value of 05DC (1,500) or less is read as a length instead, from an older way of framing the same field.

An everyday picture: a frame is a courier’s label for one leg of a trip. Each depot puts on a new label, and the address on the parcel stays. The picture breaks here: a label names a depot, but a MAC address names a card, not a place.

MAC addresses
#

A MAC address is 48 bits, written as six bytes: 00:00:5e:00:53:21. In a globally unique address, the first 24 bits or more name the owner of the block: the OUI (organizationally unique identifier). The owner numbers the rest.

ff:ff:ff:ff:ff:ff, all ones, is the broadcast address: every device on the link accepts that frame. The addresses in this part come from a block kept for documentation (RFC 9542), so they match no real card.

A MAC address is flat. An IP prefix says which network a host is in; a MAC address says nothing about where the card is plugged in. That is why a switch has to learn it (below).

A damaged frame is dropped, silently
#

The sender’s card computes the frame check as it sends, and the receiving card computes it again and compares. The link uses a CRC because a card computes it in hardware. It also catches more errors than the software checksum of TCP and UDP.

In the figure, segment 6 for db-b1 arrives whole, and gw-a1 sends it on (Phase intact). Segment 7 is hit on the cable between sw-a1 and gw-a1. gw-a1’s card, at the end of the damaged cable, finds a mismatch and throws the frame away without telling the sender (Phase damaged).

The link itself does not repair the loss.

The worker’s TCP gets no acknowledgement (ACK) for segment 7. It sends the segment again after its timer (Part 3; Phase resend in the figure above). UDP data is simply lost.

On Linux, ip -s -s link counts these drops per interface: the crc column under RX errors. The panel inside gw-a1 shows that counter rising by one.

In a VPC
#

The MTU depends on the provider and the settings, and it is not always 1,500. The table shows two providers.

ProviderMTU inside the VPCLeaving the VPC
Google Clouddefault 1,460; you may set 1,300 to 8,896; a Linux VM on a public image learns it through DHCP option 26the internet generally uses 1,500, so packets of 1,500 or less avoid most MTU trouble
AWSevery instance type supports 1,500; current types support 9,001, called jumbo frames1,500 through an internet gateway or a VPN; 8,500 over peering between Regions

So a 9,001-byte packet that works between two AWS instances will not pass the internet gateway as it is. It is split, or dropped if its DF flag is set. Keep traffic that leaves the VPC at 1,500 or below (When it breaks).

ARP: whose MAC is 10.1.4.1?
#

The worker learned gw-a1’s IP address, 10.1.4.1, from DHCP (Part 4). To build the frame it also needs gw-a1’s MAC, and nobody told it. On a plain Ethernet LAN like this one, it asks the whole link with ARP (Address Resolution Protocol).

Phase request: the worker asks everyone on the link who has 10.1.4.1, giving 10.1.4.21 and 00:00:5e:00:53:21; sw-a1 floods it to worker-2 and gw-a1, and worker-2 sends no reply. Phase reply: gw-a1 answers that 10.1.4.1 is at 00:00:5e:00:53:01, to the worker alone. Phase cache: the panel inside the worker gains the row 10.1.4.1 REACHABLE, beside the states STALE and DELAY, and the waiting packet leaves. A footer says ARP asks only for the next hop.
Ask everyone, hear back from one: the answer is kept, so the next packet leaves at once.

Request and reply
#

The request goes in a broadcast frame, and sw-a1 floods it to every port (Phase request). worker-2, 10.1.4.22, sees an address that is not its own and sends no reply. Only gw-a1, which owns 10.1.4.1, answers, and its reply goes to the worker’s MAC alone (Phase reply).

ARP field, as RFC 826 names itIn the requestIn the reply
opcoderequestreply
hardware address of sender00:00:5e:00:53:21, the worker00:00:5e:00:53:01, gw-a1
protocol address of sender10.1.4.2110.1.4.1
hardware address of targetnot known yet, so not set00:00:5e:00:53:21
protocol address of target10.1.4.1, the address asked about10.1.4.21
frame sent toff:ff:ff:ff:ff:ff, everyone00:00:5e:00:53:21, the worker only

While it waits, the worker holds the packet for gw-a1. RFC 1122 says a host should hold at least the latest one; Linux keeps up to 3. When the reply arrives, the pair goes into the cache, and the packet leaves (Phase cache).

Only on your own subnet
#

The worker asks for gw-a1’s MAC, never for the MAC of 10.3.2.6. A host on another subnet is reached through the gateway (Part 4), so the frame goes to gw-a1, and gw-a1 builds the next frame.

A request for an address on another subnet normally gets no answer (a router doing proxy ARP is the exception). ARP has a request and a reply, and no error message.

How long the answer is kept
#

Linux treats a confirmed entry as valid for at least 15 to 45 seconds, a random value around a base of 30. TCP replies that keep arriving count as proof and extend it.

After that the entry is stale. The next packet still goes out, and if no reply confirms the address within about 5 seconds, Linux asks again, first by unicast.

ip neigh shows the cache and the state of each entry:

$ ip neigh
10.1.4.1 dev eth0 lladdr 00:00:5e:00:53:01 REACHABLE
StateMeans
REACHABLEconfirmed recently; used as it is
STALEstill valid but not trusted; the next packet starts a check
DELAYwaiting a few seconds for proof before asking
FAILEDthe checks got no answer

Other systems use other times. The host requirements standard (RFC 1122) speaks of cache timeouts of about a minute or less.

IPv6
#

IPv6 does the same job with Neighbor Discovery. The question goes to a multicast address built from the target’s address, not to everyone on the link.

In a VPC
#

In a VPC, broadcast is not supported: Google Cloud says so, and AWS says it does not support broadcast in a VPC. A VM still sends an ARP request for its gateway, but no other VM sees it. In Google Cloud the VPC network answers: “the instance kernel issues ARP requests and the VPC network issues ARP replies”.

A Linux VM there gets a /32 netmask by default. So even traffic to a VM in the same subnet goes to the gateway’s MAC address. The AWS pages used here do not say which device answers.

A switch learns where everyone is
#

sw-a1 joins the worker 10.1.4.21, worker-2 10.1.4.22 and gw-a1 10.1.4.1 on ports 1, 2 and 3. It forwards frames by MAC address; it does not route. Nobody types its table: it fills the table from the frames it sees.

sw-a1: the worker on port 1, worker-2 on port 2, gw-a1 on port 3, and a panel with its MAC table. Phase flood: the worker’s ARP request to ff:ff:ff:ff:ff:ff meets an empty table; sw-a1 writes 00:00:5e:00:53:21 on port 1 and floods ports 2 and 3. Phase learn: gw-a1’s reply adds 00:00:5e:00:53:01 on port 3, out of port 1 only. Phase forward: the first data frame goes port 1 to port 3 alone. Phase age: after 300 s of silence that row is removed, and the next frame floods again.
A switch learns from source addresses: unknown destinations go out every port, known ones out of one.

Learn, then forward, flood or filter
#

For every frame, sw-a1 first learns from the source, then decides from the destination.

A frame arrives withsw-a1 does
any source MACwrites it with the port the frame came in on, and resets its age (learn)
a destination in the table, on another portsends the frame out of that port only (forward)
a destination not in the table, or ff:ff:ff:ff:ff:ffsends it out of every other port (flood)
a destination on the port the frame came in ondrops it, because the receiver already has it (filter)

The figure replays the ARP exchange from sw-a1’s side. In Phase flood the table is empty: sw-a1 writes 00:00:5e:00:53:21 on port 1 and floods the request to ports 2 and 3. gw-a1’s reply teaches sw-a1 00:00:5e:00:53:01 on port 3, and goes out of port 1 only (Phase learn).

The worker’s first data frame for gw-a1 then goes from port 1 to port 3 alone (Phase forward). When a switch floods a frame meant for one host, the others get it too. Their cards normally drop a frame whose destination MAC is not their own.

A switch is invisible to hosts. The worker addresses its frame to gw-a1, never to sw-a1. sw-a1 sends no message to hosts about its learning; it shows only in its table.

An everyday picture: a receptionist learns which office each person works in by watching where their visitors come from. For a stranger, the receptionist calls on every floor. The picture breaks here: a receptionist could ask, and a switch never asks; it only watches the frames.

Rows age out
#

A row that no frame from its address refreshes is removed once it is too old. A host that moves to another port is learned again on the new one as soon as it sends a frame.

On a Linux bridge, the software switch inside a host, bridge fdb show lists the table. The bridge setting ageing_time is the age limit, in seconds. On one Linux host checked on 2026-10-16 it was 300 seconds, the value in Phase age of the figure.

Switch or router
#

SwitchRouter
address it readsthe destination MACthe destination IP
table built byitself, learning from framesrouting protocols or the operator (Parts 4, 5)
setupnone for a plain switch: plug in, and it learnsan address and routes on every interface
loopsmust not exist: a frame has no TTL, so it would circle foreversurvive: the TTL ends a looping packet (Part 4)
reachone broadcast domainbetween subnets

A broadcast domain is the set of devices that one broadcast frame reaches. A router ends it; a switch does not.

Loops and spanning tree
#

Two switches joined by two cables form a loop. A flooded frame then goes round and round, copied at each switch. That is a broadcast storm: copies of one frame fill every link until the network stops.

The classic fix is spanning tree. The switches agree on one active path between any two of them and keep the extra cables on standby.

VLANs: one switch, separate networks
#

ops-a1, 10.1.5.10, plugs into port 4 of sw-a1 but belongs to another subnet, 10.1.5.0/24. Without more, the worker’s broadcasts would reach it. A VLAN (virtual LAN) splits one switch into separate networks, and a trunk carries several VLANs to a second switch, sw-a2, where ops-a2 sits.

Two islands: VLAN 10 holds the worker and worker-2; VLAN 20 holds ops-a1 on sw-a1 and ops-a2 on sw-a2. gw-a1 on port 3 carries both VLANs, tagged, with 10.1.5.1 in VLAN 20. Phase over the trunk: ops-a1’s frame carries the tag VLAN 20 on the trunk; sw-a2 removes it. Phase between VLANs: the worker’s packet for ops-a1 goes up to gw-a1 and back down. Phase broadcast in VLAN 10: the ARP request reaches ports 2 and 3 and the trunk; VLAN 20 ports are marked not sent.
A VLAN is a separate network on shared switches: only a router crosses from one to another.

Ports in groups
#

The operator puts each port of a switch in a VLAN. A port that carries one VLAN, without tags, leads to a host; it is called an access port. Each VLAN is its own broadcast domain.

Port of sw-a1DeviceVLANSubnet
1the worker, 10.1.4.211010.1.4.0/24
2worker-2, 10.1.4.221010.1.4.0/24
3gw-a1, 10.1.4.1 in VLAN 10 and 10.1.5.1 in VLAN 2010 and 20, taggedboth
4ops-a1, 10.1.5.102010.1.5.0/24
trunksw-a2, which holds ops-a2, 10.1.5.1110 and 20, taggedboth

In Phase broadcast in VLAN 10, the worker’s ARP request reaches ports 2 and 3 and the trunk. It never reaches port 4, although ops-a1 is plugged into the same switch.

Between VLANs only a router passes
#

The worker cannot reach ops-a1 through the switch alone. Its packet for 10.1.5.10 goes to gw-a1, its gateway, which routes it into VLAN 20 and sends it back down (Phase between VLANs).

So gw-a1 needs an interface in each VLAN. Here its one port carries both VLANs, tagged, and its address in VLAN 20 is 10.1.5.1.

A trunk carries its VLANs, tagged
#

Between sw-a1 and sw-a2, one cable carries both VLANs. Each frame on it carries a 4-byte 802.1Q tag that names its VLAN. sw-a1 adds the tag as the frame enters the trunk, and sw-a2 removes it before ops-a2 (Phase over the trunk).

Part of the tagBitsHolds
tag type168100: a VLAN tag follows; it sits after the source MAC
priority3the frame’s class, 0 to 7
one flag1a bit this part skips
VLAN ID12the VLAN, 10 or 20 here

The frame’s own type field, 0800 for IPv4, follows the tag. A trunk may also carry one VLAN without a tag, the native VLAN; both ends must then agree on which one.

Twelve bits give 4,096 values, of which 4,094 can be used as VLAN IDs. That is too few for a cloud provider with many customers (RFC 7348).

Overlays
#

A VPC spans many hosts and racks, and a provider runs many customers’ networks at once. Instead of a VLAN tag, an overlay such as VXLAN wraps each frame in a UDP packet. The provider’s own IP network carries it.

VXLAN (RFC 7348) gives each segment a 24-bit ID, which allows up to 16 million segments. The outer packet goes to UDP port 4789 by default.

The Google Cloud and AWS pages used here do not say how their VPCs keep one customer’s traffic apart from another’s. Read VXLAN as an example of the idea, not as what they use.

The data center: many equal paths
#

In a data center, each rack has a top-of-rack switch (ToR), here tor-1 and tor-2. Every ToR connects to every spine switch, spine-1 and spine-2. server-1 under tor-1 has two equal paths to server-2 under tor-2: which one does each packet take?

Rack 1 holds server-1 under tor-1, rack 2 holds server-2 under tor-2; each leaf connects to spine-1 and spine-2. Phase flow 1: server-1 sends packets of flow 1, port 41001 to 443; the panel inside tor-1 shows the header fields it hashes and picks spine-1. Phase flow 2: flow 2, port 41002 to 443, hashes to spine-2. Phase spine down: spine-1 fails, the panel drops it from the set, and flow 1’s next packet goes through spine-2.
One flow, one path: a hash of the flow’s header picks the spine, so its packets stay in order.

Leaf and spine
#

The older design was a tree of ever bigger switches. It reaches its limit: the top switches cannot get enough ports, and traffic between racks must share their few links.

Many large data centers use leaf and spine, a design that repeats one kind of switch in two layers. Every leaf, here the ToR, connects to every spine (RFC 7938); larger sites add a tier.

TreeLeaf and spine
paths between two racksa few, all through the top switchesone per spine
to growreplace the top switches with bigger onesadd leaves, and spines up to the number of leaf uplinks

In the design of RFC 7938 these switches also route. BGP (Part 5) runs between them and fills their tables. In 2014 Facebook (now Meta) described its fabric the same way: routed from the ToR uplinks to the edge, with BGP alone.

ECMP: one flow, one path
#

Between two racks there are as many equal paths as there are spines. ECMP (equal-cost multipath) spreads traffic over them per flow, not per packet. tor-1 hashes the header fields that name a flow: the addresses, the protocol (TCP here) and the ports; the result picks one spine.

So every packet of flow 1, port 41001 to 443, takes spine-1 and usually arrives in order (Phase flow 1). Flow 2, port 41002, hashes to spine-2 (Phase flow 2). If one flow’s packets took both spines, some would arrive early, and early segments make the receiver send duplicate ACKs (Part 3).

When spine-1 fails, its links go dead. Data center links are mostly point-to-point fiber, so a dead link is often noticed in milliseconds.

Many BGP routers then close the session over that link at once. tor-1 drops spine-1 from its set, and flow 1 moves to spine-2 (Phase spine down).

Speeds, with their dates
#

DateSourceSays
2022-08-24Google, on its Jupiter data center networkservers and storage moving from 40 to 100, 200 and now 400 Gb/s; more than 6 Pb/s of data center bandwidth; no spine layer: optical circuit switches join groups of racks in a direct mesh
2026-10-15the IEEE 802.3 Ethernet working groupa task force still at work on 200 Gb/s, 400 Gb/s, 800 Gb/s and 1.6 Tb/s Ethernet
2026the Ethernet Alliance roadmap100G to 800G links, with 1.6 Tb/s emerging

In a cloud
#

Google Cloud places resources in zones, deployment areas inside a region. Putting VMs in different zones lowers the risk that one infrastructure outage hits them all.

Google names Compute Engine among the services that run on Jupiter. So a VM’s packets cross a data center fabric that the provider builds and runs.

One request through the whole stack
#

The worker boots in network A, subnet 10.1.4.0/24, and calls https://api.acme.example in network B, 10.3.0.0/16. A plain HTTPS request over TCP takes six exchanges before the first byte of the reply, each taught in a part of this series. Every one that leaves the subnet goes to gw-a1’s MAC first.

Six phases between the worker, sw-a1 and gw-a1 in network A, the resolver at 10.1.0.53 and the api at 10.3.2.5 in network B. DHCP: gw-a1 gives the worker 10.1.4.21. ARP: gw-a1 answers 00:00:5e:00:53:01. DNS: the resolver answers 10.3.2.5 for api.acme.example. TCP: SYN, SYN-ACK and ACK on port 443. TLS: the handshake. HTTP: the request and the response. A panel keeps one row per phase: the IP destination and the MAC on the first link, gw-a1’s from DNS on.
Six exchanges before the first byte: every one that leaves the subnet goes to gw-a1’s MAC first.
PhaseWhat the worker sendsIP destinationMAC destination on the first linkTaught in
DHCPdiscover and request; gw-a1 offers and confirms 10.1.4.21255.255.255.255, from 0.0.0.0ff:ff:ff:ff:ff:ffPart 4
ARPwho has 10.1.4.1?none: ARP is not carried in IPff:ff:ff:ff:ff:ffthis part
DNSthe A record for api.acme.example, UDP port 53the resolver, 10.1.0.53gw-a1, 00:00:5e:00:53:01Part 2
TCPSYN from port 51514 to port 443; the api answers SYN-ACK, the worker ACKthe api, 10.3.2.5gw-a1, 00:00:5e:00:53:01Part 3
TLSthe handshake10.3.2.5gw-a1Part 8
HTTPthe request10.3.2.5gw-a1Part 2

After the DHCP ACK the worker also checks its new address with an ARP probe, one more broadcast (RFC 2131, RFC 5227). The resolver sits on another subnet, 10.1.0.53, so even the DNS query goes to gw-a1’s MAC.

sw-a1 passes that frame on to gw-a1; the frame says gw-a1, and the packet inside says the resolver. Only the DHCP and ARP phases use broadcast. After them the worker needs no more ARP while its entry for gw-a1 is fresh.

At every router on the way, the frame is rebuilt and the packet keeps its addresses.

When it breaks
#

CaseDescriptionCheck withWhyFix
two hosts, one addressconnections to 10.1.4.21 work, fail, then work again; the MAC behind the address keeps changing in gw-a1’s ARP cachearping -D 10.1.4.21 from a host on the link: any reply means a card already holds the addresstwo hosts were given the same address, for example one typed by hand inside the DHCP rangegive one host another address; RFC 5227 has a host probe an address with ARP before it uses it
a failover that keeps the old MACan address moves to a standby host, yet clients keep sending to the old one for a whileip neigh on a client: the old MAC is still listed for the addressthe clients’ ARP caches hold the old pair until it is checked againthe new owner announces the pair: arping -U sends an unsolicited ARP that updates neighbors’ caches
a packet bigger than the linksmall requests work, big ones hang; often a jumbo-frame VPC talking to the internetip link shows each interface’s MTU; ping -M do -s 1472 (Part 5)a link on the way takes smaller packets than the sender sends (Part 4), and the message that says so is lost or blocked (Part 5)the same MTU on every interface of a link; 1,500 for traffic that leaves the VPC; let ICMP 3/4 through
a link with damaged framestransfers slow down and TCP resends more; UDP data goes missingip -s -s link: the crc count under RX errors keeps growinga bad cable, port or card flips bits, and each damaged frame is droppedreplace the cable or move to another port; read the counters at both ends
a loop between switchesthe whole network slows to a stop, and every link is fullthe switches’ port counters: the same broadcast frames at a huge rate on every porttwo paths between switches and no spanning tree; a frame has no TTL, so a broadcast circles foreverturn spanning tree on, or remove the extra cable

Remember
#

  • Each link carries the packet in a new frame: the MAC addresses change at every router, the IP destination does not.
  • A damaged frame is dropped and nobody is told: TCP sends again, UDP loses it.
  • ARP asks everyone and hears back from one; for another subnet, the frame goes to the gateway’s MAC.
  • A switch learns from source addresses and floods what it does not know; a broadcast stops only at a VLAN’s edge or a router.
  • Leaf and spine give two racks one path per spine, and ECMP keeps each flow on one of them.

Sources
#

Checked 2026-10-16.

Networking foundations - This article is part of a series.
Part 6: This Article