How Switches Work — MAC Learning, CAM Table, Forward/Flood/Filter
A switch is a self-teaching frame forwarder. Nobody tells it which device sits on which port — it builds that map itself by watching the source address of every frame that passes through, and then decides where to send each frame by its destination address. Two different header fields, two completely different jobs, on the same frame. Three possible outcomes follow: forward, flood, or filter. And because one of those outcomes applies to every broadcast, a single switch is a single broadcast domain — the fact that motivates both VLANs and Spanning Tree.
Key Components
- CAM table (MAC address table, forwarding table)
- The switch's map from
MAC address → physical port, stored in Content Addressable Memory — hardware built for exact-match lookup in a single step. Every forwarding decision is one lookup in this table. It is built entirely from observed traffic, never from configuration. - MAC learning
- The act of reading the source MAC address of an arriving frame and recording "this address lives on the port this frame arrived on." Every frame a device transmits teaches the switch that device's location for free — no protocol, no handshake, just observation.
- Forward / Flood / Filter
- The three (and only three) outcomes of a lookup on the destination MAC. Forward: the address is known and on a different port — send out that one port. Flood: the address is unknown, or the frame is a broadcast/multicast — send out every port except the arrival port. Filter: the address is known and on the same port the frame arrived on — drop it, because sender and receiver already share a segment.
- Age timer
- A per-entry countdown (Cisco default ≈300 s) that resets every time that MAC is seen again and deletes the entry when it expires. This is what makes the table dynamic and self-maintaining: silent devices fall out, moved devices get re-learned on their new port.
- Broadcast domain vs collision domain
- A collision domain is the set of ports whose transmissions can interfere with each other; on a switch, each port is its own collision domain. A broadcast domain is the set of devices a broadcast frame reaches; on a switch, that is every port. Switching splits collision domains but does nothing to split broadcast domains.
Concrete Example
The table itself is unglamorous — an address, a port, and a clock:
┌───────────────────┬──────┬───────┐
│ MAC │ Port │ Age │
├───────────────────┼──────┼───────┤
│ aa:aa:aa:aa:aa:aa │ 1 │ 12 s │
│ bb:bb:bb:bb:bb:bb │ 2 │ 45 s │
└───────────────────┴──────┴───────┘
What makes it interesting is that nothing wrote those rows on purpose. Take three hosts on a switch that was powered on a second ago, with the table completely empty:
Host A ── port 1 ┐
Host B ── port 2 ┼── [ SWITCH ]
Host C ── port 3 ┘
Frame 1 — A sends to B. It arrives on port 1 carrying SRC = aa:aa:aa:aa:aa:aa and DST = bb:bb:bb:bb:bb:bb. The switch does two independent things with it:
LEARN (source field) aa:aa:aa:aa:aa:aa arrived on port 1
→ write row: aa:aa:aa:aa:aa:aa → port 1
DECIDE (dest field) lookup bb:bb:bb:bb:bb:bb → MISS
→ FLOOD out ports 2 and 3 (everything but port 1)
Table after frame 1: aa:aa:aa:aa:aa:aa → port 1
B receives the flooded copy and processes it because the destination is its own address. C also receives a copy, sees a destination that is not its address, and silently discards it. Note what did not happen: the switch learned nothing whatsoever about B from this frame. A destination address is a question, not evidence.
Frame 2 — B replies to A. Same two jobs, mirrored:
LEARN (source field) bb:bb:bb:bb:bb:bb arrived on port 2
→ write row: bb:bb:bb:bb:bb:bb → port 2
DECIDE (dest field) lookup aa:aa:aa:aa:aa:aa → HIT, port 1
→ FORWARD out port 1 only
Table after frame 2: aa:aa:aa:aa:aa:aa → port 1
bb:bb:bb:bb:bb:bb → port 2
C is not touched this time. Frame 3 — A sends to B again and the destination is now a hit on port 2, so it is forwarded out that single port. Clean unicast, with no configuration ever entered.
That is the whole pattern, and it generalises: the first frame to an unknown destination floods; the reply teaches the switch; everything afterwards is efficient unicast. Flooding is not a failure mode — it is the designed response to not knowing, and it is self-correcting, because the response it provokes carries the missing information in its source field. On a busy network the table fills within seconds and flooding becomes rare.
On real hardware the same table is visible directly:
Switch# show mac address-table
Mac Address Table
-------------------------------------------
Vlan Mac Address Type Ports
---- ----------- -------- -----
1 aaaa.aaaa.aaaa DYNAMIC Fa0/1
1 bbbb.bbbb.bbbb DYNAMIC Fa0/2
DYNAMIC means the row was learned by observation, exactly as traced above; STATIC rows are pinned by an administrator and never age out. The Vlan column is a preview of the next idea: the table is not really one table but one table per VLAN.
Visual Model
Think of the switch as a receptionist in a building with numbered doors, who has never been given a staff directory. Every time a memo comes through a door, they glance at who sent it and jot down "this person is behind door 1" — that is the only way the directory ever gets written. Then they look at who the memo is addressed to and check the directory: a match means slide it under that one door; no match means photocopy it and slide it under every other door, because asking everyone is better than dropping it. The two glances are at two different lines of the same memo, and confusing them is the single most common mistake in this topic.
Step through the trace below and watch the two halves work independently. On the left, the frame arrives and the switch picks one of its three decisions; on the right, the CAM table fills in row by row. At the bottom sits the frame itself, with its source field (green, feeding the table) and its destination field (orange, feeding the decision) highlighted separately — the same frame, two fields, two jobs.
Loading…
Notice that steps 2 and 3 describe the same frame. The switch does not choose between learning and deciding — it always does both, in that order, on every frame it receives. Learning is a side effect that costs nothing and happens even when the decision turns out to be "drop this".
Deeper — Edge Cases & Gotchas
Why this beats the thing it replaced
A hub — the Layer 1 device switches displaced — had no table and made no decisions. Every bit arriving on one port was repeated out of every other port, always. That made the entire hub one collision domain: two hosts transmitting at once corrupted each other, and every host saw every other host's traffic. A switch learns MAC addresses and forwards selectively, so each port becomes its own collision domain (and with full-duplex links, collisions stop existing at all), traffic between A and B never reaches C, and the usable aggregate bandwidth multiplies. Hubs are extinct for exactly these reasons.
One switch is one broadcast domain
Selective forwarding has a hard limit: it only applies to unicast destinations. A broadcast frame — destination ff:ff:ff:ff:ff:ff — is flooded to every port, always, by definition. A switch never filters a broadcast and there is no table entry that could make it do so.
A switch, by default, is a single broadcast domain: every broadcast reaches every device attached to it.
ARP requests, DHCP discovery, and every other discovery protocol therefore interrupt every host on the switch. On a small network that is harmless. On a large flat network it wastes bandwidth on every link and CPU on every host. Two later topics exist because of this one sentence: VLANs slice a single physical switch into several independent broadcast domains, and Spanning Tree exists because a flooded broadcast that meets a loop between redundant switches circulates forever — a broadcast storm, since Ethernet frames carry no hop counter to kill them.
Security: CAM table overflow
The CAM table is finite — a fixed number of hardware entries. A MAC flooding attack exploits that by transmitting thousands of frames with randomly generated fake source addresses, each one dutifully learned, until the table is full. Once it can no longer learn or store entries, the switch fails open: every destination lookup misses, so every frame is flooded out every port, and the switch degrades into a hub. An attacker on any port then sees all traffic. The defence is port security — capping how many distinct source MACs a single port is allowed to teach the switch, and shutting the port down or dropping frames beyond that. It is worth sitting with the irony: the mechanism that makes a switch effortless to deploy is the same one that has an exploitable capacity limit.
Aging, moves, and re-learning
Entries expire after roughly five minutes of silence. That is not a bug to engineer around — it is what lets a laptop unplugged from port 4 and re-plugged into port 9 work immediately: its first transmitted frame overwrites the stale row with the new port. A device that has been quiet longer than the age timer will trigger one flood the next time somebody addresses it, and then be known again. Occasional flooding for quiet devices is normal, healthy behaviour.
Two ways to move the bits
Store-and-forward reads the entire frame into a buffer, verifies its FCS checksum, and only then forwards it — corrupt frames die at the switch. Cut-through starts transmitting as soon as it has read the destination MAC (the first six bytes after the preamble), which cuts latency but forwards damaged frames because the checksum sits at the end and has not arrived yet. Store-and-forward is the default on modern gear; cut-through appears where latency is worth more than error containment.
WRONG: frame arrives on port 1, DST = bb:bb:bb:bb:bb:bb
→ "so bb:bb:bb:bb:bb:bb must be on port 1" ✗
RIGHT: frame arrives on port 1, SRC = aa:aa:aa:aa:aa:aa
→ "aa:aa:aa:aa:aa:aa is on port 1" ✓
DST = bb:bb:bb:bb:bb:bb → look it up, don't record it
Why it breaks: the destination address states where the frame wants to go, which is precisely the thing the switch does not yet know — that is why it is asking the table in the first place. Only the source address is evidence, because the frame demonstrably just came from that device, through that port. Learn from the source; decide by the destination. If you record destinations, the first frame to an unknown host permanently poisons the table with an entry pointing back at the sender's own port, and every reply gets filtered as "same port" — the network silently stops working.
See Also
Ethernet — Frame Format, MAC Addresses & EtherType Defines the two fields this entire entry turns on: the source and destination MAC in the frame header, plus what makes an address a broadcast. OSI 7-Layer Model — What Each Layer Does and Why the Split Exists Places the switch at Layer 2 and the router at Layer 3 — the framing that makes "switch ≠ router" structural rather than trivia. VLANs — Segmentation, Access vs Trunk Ports, 802.1Q Tagging The direct answer to "one switch is one broadcast domain": VLANs make the CAM table per-VLAN and flooding VLAN-scoped. Spanning Tree Protocol (STP/RSTP) — Loop Prevention & Root Bridge Election What happens when flooding meets a redundant loop — a broadcast storm — and the protocol that blocks links to prevent it. How the Internet Works End-to-End — A Packet's Journey Where switch forwarding sits in the full journey: the local-segment hop that happens between every pair of Layer 3 devices.Sources consulted
- IEEE 802.1D — MAC Bridges
Test Yourself
A frame arrives on port 3 carrying a destination MAC the switch has never seen. What does the switch do with it, and what — if anything — does it record?
Hosts A and B have been exchanging traffic for a while, so both are in the CAM table. A now sends a unicast frame to B, and separately sends an ARP broadcast. Which of these does host C receive?
An attacker connects to one port and transmits a continuous stream of frames, each with a different randomly generated source MAC. Trace what happens inside the switch, and explain why the result is a security problem rather than just a performance one.