Networking · Link Layer

MAC Learning and How a Bridge Builds Its Forwarding Table

A transparent bridge learns source addresses, forwards unknown destinations out every port, and ages entries out; the failure modes of each step.

A switch is a device that receives frames on one port and transmits them on another, with no modification to the frame. There is no header a switch adds, no acknowledgement it sends, and no negotiation with the end stations. The entire mechanism is a table, populated by watching the traffic that passes, and a rule for what to do when the table has no answer. That simplicity is why bridges are cheap and why their failure modes are subtle: everything a switch knows, it inferred.

Learning from the source address

When a frame arrives on a port, the bridge records a mapping from the frame’s source address to that port. The reasoning is that the station which sent the frame is reachable through the port it arrived on, and any future frame addressed to it should go out that port.

The record carries an age. A station that goes silent stops refreshing its entry, and after the aging time expires the entry is removed. The default aging time in 802.1D is 300 seconds, five minutes, a number chosen to be long enough that a quiet but present station does not lose its entry and short enough that a station which moved does not leave a stale mapping pointing at its old port for long.

Learning happens on every received frame that carries an individual source address, including frames the bridge forwards and frames it drops. That is not an incidental optimisation; it is what keeps the table current for stations that never receive traffic. A host that only transmits still gets an entry.

A frame with a source address that is a group address is not learned. Group addresses do not identify a station, so a mapping from a group address to a port would be meaningless and would poison the table. Bridges are required to discard such frames or ignore them for learning purposes.

Forwarding, filtering, and flooding

With an entry present, the bridge forwards the frame out the recorded port if that port is not the one it arrived on, and drops it if it is. The drop case is called filtering, and it is what keeps traffic between two stations on the same port from consuming bandwidth on other ports. This is the main efficiency gain of a bridge over a repeater: a repeater copies every frame to every port, a bridge copies only the frames that need to cross.

With no entry, the bridge floods: it transmits the frame out every port in the same broadcast domain except the one it arrived on. Flooding is also used for group addresses, which are never learned, and for the broadcast address. Every station in the domain therefore sees unknown-unicast traffic addressed to some other station, which is a privacy consideration as much as a bandwidth one.

The result of flooding is that the destination station replies, the bridge learns its address from the reply’s source field, and subsequent frames are forwarded rather than flooded. This is why the first frame of a conversation is more expensive than the rest, and why a table that has just been cleared produces a burst of flooding until it refills.

ConditionAction
Destination learned, port equals ingressFilter (drop)
Destination learned, port differsForward to that port
Destination unlearnedFlood to all ports except ingress
Destination is broadcast or groupFlood to all ports except ingress
Source is a group addressDo not learn

The table as a hash, and its capacity

The forwarding table is a hash table keyed by the 48-bit address, sized by the switch’s memory rather than by any protocol requirement. Entry counts range from a few thousand on small devices to hundreds of thousands on chassis switches. When the table is full, the bridge must either evict an entry or fail to learn the new one; both behaviours exist, and both produce the same visible symptom: frames for the evicted address get flooded until they are relearned.

This is a real boundary condition and not a theoretical one. A segment with more distinct source addresses than the table holds, which happens when a bridge sits in front of a virtualised host whose hypervisor assigns a fresh address per guest, causes continuous relearning and continuous flooding. The symptom is bandwidth consumed by traffic that should have been filtered, and it appears only under load, which makes it hard to attribute.

The lookup itself is done in hardware in the forwarding ASIC, typically as a hash of the address into a bucket with a small number of ways, or as a content-addressable memory lookup. The cost is typically a single memory access per frame, which is why store-and-forward switching can keep up with wire rate at every port simultaneously. The precise structure is vendor-specific; the property that matters is that lookup cost does not grow with table size.

Loops, and why learning alone does not fix them

Two bridges connected by two links form a loop. A broadcast frame entering the loop is flooded in both directions, each copy is flooded again when it arrives at the other bridge, and the copies multiply. There is no TTL in an Ethernet frame to stop this, and the frame is not modified as it circulates, so the loop sustains itself until a link is removed.

Learning makes the situation worse in a specific way. As copies circulate, the same source address arrives on alternating ports, so the table entry for that station flips back and forth. Every flip changes which port the bridge considers correct, so frames for that station are sent out the wrong port, and the loop carries them around again. The table never converges, and the visible symptom is a network that forwards nothing reliably while every link is saturated.

The remedy is not in the learning algorithm. It is a separate protocol that disables ports so that the active topology is a tree, which is covered in spanning tree and its port state machine. Learning assumes an acyclic topology; the protocol exists to provide one.

Learning assumes that the path from A to B is the path from B to A. On a link where one direction fails, the assumption breaks. If a bridge’s port can receive but not transmit, it learns entries from frames arriving on that port while being unable to forward to them, so traffic sent toward stations on that side disappears. The reverse case, transmit-only, leaves the port able to send but unable to learn: the bridge floods toward that side, and traffic from those stations never arrives.

The standard’s answer is the bridge’s own liveness protocol: bridges exchange BPDUs, and a port that stops receiving them eventually ages out the information it learned from them, forcing a recomputation of the tree. That mechanism is part of the spanning tree protocol rather than of learning, which is why a bridge with learning disabled but BPDUs enabled still reacts to a dead link; a unidirectional link can nevertheless produce a loop, because the end that continues to transmit believes the link is healthy.

Interaction with the receive filter

A bridge port must receive frames addressed to stations other than itself, since forwarding depends on destinations the bridge does not own. This requires the NIC behind the port to accept frames not addressed to it, which in practice means promiscuous mode. That is also why a software bridge costs more CPU than a hardware one: every frame crosses into host memory, the bridge looks up the destination, and the frame is transmitted out another interface. The receive filter modes available for this are described in MAC address structure and group addressing.

A software bridge can also be selective about what it accepts. Linux’s bridge implementation, for instance, has per-port options controlling whether group traffic is flooded and whether the port learns, which is how a port facing an untrusted segment is configured to avoid filling the table with addresses that will never be destinations. The defaults follow 802.1D; the options exist because the default behaviour is not always what an operator wants at an edge.

What the table does not record

The forwarding table holds addresses and ports. It does not hold a path, a cost, or a preference between two ports that both claim the same address. When a station moves, the bridge does not remove the old entry first; it overwrites it, because the source address arrived on a new port and the newest observation wins. The station’s traffic is disrupted only for the interval between the move and the first frame it sends from the new location.

There is also no authentication of the source address. Any station can send a frame with another station’s source address, and the bridge will update its table to point at the impostor’s port. This is address spoofing, and it redirects traffic for the victim to the attacker until the victim transmits again and the table flips back. The defence is a port security feature that limits which source addresses a port may use, or authentication at a higher layer; neither is part of the learning algorithm.

The table’s aging behaviour also interacts with topology changes. A spanning tree reconfiguration can move a whole subtree from one port to another, and the entries learned through the old port remain valid-looking until they age out, so traffic is black-holed for up to the aging time. The standard’s fix is to flush the table on a topology change rather than wait for aging, which is why a spanning tree event produces a brief burst of flooding. The states that trigger such a flush are described in spanning tree port states, and the way tagged frames are kept in separate tables is the subject of 802.1Q VLAN tagging.

References

  1. IEEE 802.1D: MAC Bridges — IEEE
  2. IEEE 802.1Q: Bridges and Bridged Networks — IEEE
  3. Linux kernel documentation — netdev and bridge — Linux kernel documentation