> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/ask/flat/chapter-24-advanced-networking/di-24.2-jie-wang-qiao.md).

# 24.2 Network Bridges

Sometimes it is necessary to divide a network such as Ethernet into multiple network segments without creating IP subnets or using routers to connect these segments. The device that connects two networks is called a "bridge".

A bridge learns the MAC addresses of devices on each network interface and only forwards traffic when the source and destination MAC addresses are on different network segments. In essence, **a modern Ethernet switch is a type of multi-port bridge**. A FreeBSD system with multiple network interfaces can be configured as a bridge device.

## Overview

A bridge is a network interconnection device that operates at the OSI data link layer. Its core working mechanism is to filter and forward data frames based on a MAC (physical address) address table. In terms of physical topology, a bridge can logically divide a large local area network into multiple independent collision domains, thereby effectively reducing network congestion; at the same time, it can also integrate multiple dispersed physical network segments into a unified logical local area network, ensuring that all nodes in the network can achieve transparent mutual access and resource scheduling within the same Layer 2 broadcast domain. When a bridge receives a broadcast frame or multicast frame on an interface, it forwards it to other interfaces (flooding). Flooding is a data flow transmission technique used by switches and bridges, which sends data flow received on a certain interface out through all other interfaces except the one it was received on.

In practical applications, there are mainly four types of bridges:

| Type                                | Description                                        |
| ----------------------------------- | -------------------------------------------------- |
| Transparent bridge                  | **The predecessor of modern switches**             |
| Source routing bridge               | IBM Token Ring network                             |
| Translational bridge                | Connects Ethernet with Token Ring or FDDI networks |
| Source routing-translational bridge | Mixed Ethernet and Token Ring                      |

Bridge technologies other than transparent bridging are no longer mainstream. Therefore, this section only discusses transparent bridges.

Transparent bridging is used to connect local area networks with the same physical media type, and is primarily applied in Ethernet environments. A transparent bridge typically maintains a bridge table, which records the correspondence between destination MAC addresses and interfaces. The bridge forwards based on the bridge table, which consists of two parts: MAC addresses and interfaces. When a bridge is connected to a physical network segment, it monitors all Ethernet frames on that physical network segment. Once it detects an Ethernet frame sent from a node on a certain interface, it extracts the source MAC address of that frame and adds the correspondence between that MAC address and the interface that received the frame to the bridge address table.

Bridges are particularly useful in the following scenarios:

**Connecting Networks**

The basic operation of a bridge is to interconnect two or more network segments. There are various reasons to use a host-based bridge instead of a dedicated network device, such as cable limitations or firewall issues. A bridge can also connect a wireless interface running in hostap mode to a wired network and function as an access point.

**Filtering/Traffic Shaping Firewall**

When firewall functionality is needed without involving routing or Network Address Translation (NAT), a bridge can be used.

For example, a small company connects to an ISP via fiber broadband, and the ISP assigns a /29 public IPv4 address block (6 usable addresses). The company has four servers that need to use public addresses directly to provide services externally. In this case, using a router-based firewall would encounter issues with subnet division and NAT configuration — the servers would not be able to use the original public addresses directly. A bridge-based firewall, however, operates at Layer 2, requiring no additional subnet division or address translation. The servers can continue using the original public addresses while the firewall still filters traffic.

**Network Tap**

A bridge can connect two network segments so that all Ethernet frames passing through the bridge can be inspected on the bridge interface using bpf(4) and tcpdump(1), or copies of all frames can be sent to another interface called a span port for inspection.

**Layer 2 VPN (L2 VPN)**

Two Ethernet networks can be connected over an IP link using a bridge network, employing EtherIP tunnels or tap(4)-based solutions such as OpenVPN.

**Layer 2 Redundancy**

Networks can be connected through multiple links, and the Spanning Tree Protocol (STP) can be used to block redundant paths.

This section describes how to configure a FreeBSD system as a bridge device using if\_bridge(4).

> **Note**
>
> Packet filtering can be used in conjunction with firewall software packages that interface with the pfil(9) framework. A bridge can also be used as a traffic shaper in combination with altq(4) or dummynet(4).

## Forwarding and Filtering Illustration

```sh
     Ethernet 1 (192.168.1.0/24)
======================================================================

 Host A                                      Host B
 +-------------------+                +-------------------+
 | IP : 192.168.1.2  |                | IP : 192.168.1.3  |
 | MAC: AA:AA:AA:AA  |                | MAC: BB:BB:BB:BB  |
 |      :AA:01       |                |      :BB:01       |
 +---------+---------+                +---------+---------+
           |                                    |
           +------------------+-----------------+
                              |
                          [ Interface 1 ]
                        MAC: 00:11:22:33:44:01
                       +----------------+
| Bridge |
| ------ |
                       +----------------+
                        MAC: 00:11:22:33:44:02
                          [ Interface 2 ]
                              |
           +------------------+-----------------+
           |                                    |
 +---------+---------+                +---------+---------+
 | IP : 192.168.2.2  |                | IP : 192.168.2.3  |
 | MAC: CC:CC:CC:CC  |                | MAC: DD:DD:DD:DD  |
 |      :CC:01       |                |      :DD:01       |
 +-------------------+                +-------------------+
 Host C                                      Host D
======================================================================
     Ethernet 2 (192.168.2.0/24)
```

Address table after bridge learning is complete:

| MAC Address       | Interface   |
| ----------------- | ----------- |
| AA:AA:AA:AA:AA:01 | Interface 1 |
| BB:BB:BB:BB:BB:01 | Interface 1 |
| CC:CC:CC:CC:CC:01 | Interface 2 |
| DD:DD:DD:DD:DD:01 | Interface 2 |

Case 1: Host A -> Host C (Forwarding)

```sh
Host A                                    Host C
192.168.1.2                               192.168.2.2
AA:AA:AA:AA:AA:01                         CC:CC:CC:CC:CC:01

     Ethernet Frame
+-----------------------+
| Src = AA:AA:AA:AA:01  |
| Dst = CC:CC:CC:CC:01  |
+-----------------------+

     |
     v

 [Interface 1] -> [Bridge] -> [Interface 2]

 Bridge lookup:

 CC:CC:CC:CC:CC:01 -> Interface 2

 Therefore forward to Interface 2

     |
     v

 Host C receives
```

Case 2: Host A -> Host B (Filtering)

```sh
Host A                                    Host B
192.168.1.2                               192.168.1.3
AA:AA:AA:AA:AA:01                         BB:BB:BB:BB:BB:01

     Ethernet Frame
+-----------------------+
| Src = AA:AA:AA:AA:01  |
| Dst = BB:BB:BB:BB:01  |
+-----------------------+

     |
     v

 [Interface 1] -> [Bridge]

 Bridge lookup:

 BB:BB:BB:BB:BB:01 -> Interface 1

 Destination interface = Receiving interface

 Therefore:
      x Not forwarded
      x Not sent to Interface 2

 Host B has already received the frame directly on Ethernet 1
```

Case 3: Host A -> Unknown Host (Flooding)

```sh
Host A
192.168.1.2
AA:AA:AA:AA:AA:01

     Ethernet Frame
+-----------------------+
| Src = AA:AA:AA:AA:01  |
| Dst = EE:EE:EE:EE:01  |
+-----------------------+

     |
     v

 [Interface 1] -> [Bridge]

 Lookup:

 EE:EE:EE:EE:EE:01
      |
 Not found

 Therefore flooding

                 +-----------------> Host C
                 |
 [Interface 1] -> [Bridge]
                 |
                 +-----------------> Host D
```

Case 4: Broadcast Frame

```sh
Host A

     Ethernet Frame
+---------------------------+
| Src = AA:AA:AA:AA:AA:01   |
| Dst = FF:FF:FF:FF:FF:FF   |
+---------------------------+

     |
     v

 [Interface 1] -> [Bridge]

 Broadcast address

 FF:FF:FF:FF:FF:FF

 Bridge must forward to other interfaces

                 +-----------------> Host C
                 |
 [Interface 1] -> [Bridge]
                 |
                 +-----------------> Host D
```

Address learning process:

```sh
Step 1

Host A sends frame

AA:AA:AA:AA:AA:01
        |
        v
      Interface 1

Bridge records:

AA:AA:AA:AA:AA:01 -> Interface 1


Step 2

Host B replies

BB:BB:BB:BB:BB:01
        |
        v
      Interface 1

Bridge records:

BB:BB:BB:BB:BB:01 -> Interface 1


Step 3

Host C sends frame

CC:CC:CC:CC:CC:01
        |
        v
      Interface 2

Bridge records:

CC:CC:CC:CC:CC:01 -> Interface 2


Step 4

Host D sends frame

DD:DD:DD:DD:DD:01
        |
        v
      Interface 2

Bridge records:

DD:DD:DD:DD:DD:01 -> Interface 2
```

The bridge now has complete knowledge of the Layer 2 network topology:

| MAC Address       | Corresponding Interface |
| ----------------- | ----------------------- |
| AA:AA:AA:AA:AA:01 | Interface 1             |
| BB:BB:BB:BB:BB:01 | Interface 1             |
| CC:CC:CC:CC:CC:01 | Interface 2             |
| DD:DD:DD:DD:DD:01 | Interface 2             |

IP addresses are only used for host communication; the bridge operates at the data link layer (Layer 2), and learning and forwarding are based on MAC addresses, not IP addresses.

## Enabling the Bridge

In FreeBSD, when a bridge interface is created, the system automatically loads the kernel module `if_bridge` via ifconfig(8).

A bridge must be created through interface cloning. To create a bridge interface, use the following command:

```sh
# ifconfig bridge create
bridge0
# ifconfig bridge0
bridge0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=10<VLAN_HWTAGGING>
        ether 58:9c:fc:10:12:5b
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
        root id 00:00:00:00:00:00 priority 0 ifcost 0 port 0
        bridge flags=0<>
        groups: bridge
        nd6 options=809<PERFORMNUD,IFDISABLED,STABLEADDR>
```

When a bridge interface is created, it is automatically assigned a randomly generated Ethernet address.

* The `maxaddr` parameter controls the number of MAC addresses retained in the bridge forwarding table; in the example above, it is 2000 entries;
* The `timeout` parameter controls how many seconds after the last occurrence each entry will be deleted; in the example above, it is 1200 seconds (20 minutes).
* `rstp` indicates that the RSTP protocol is used.

Other parameters control the operation of the Spanning Tree Protocol (STP).

Next, specify the network interfaces to add (`addm`, add member) to the bridge.

```sh
# ifconfig bridge0 addm em0 addm em1 up
```

Bridge forwarding of packets requires all member interfaces and the bridge interface to be enabled:

```sh
# ifconfig em0 up
# ifconfig em1 up
```

Now, the bridge can forward Ethernet frames between **em0** and **em1**.

```sh
bridge0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=10<VLAN_HWTAGGING>
        ether 58:9c:fc:10:12:5b
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        bridge flags=0<>
        member: em1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                port 3 priority 128 path cost 20000 vlan protocol 802.1q
        member: em0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                port 1 priority 128 path cost 20000 vlan protocol 802.1q
        groups: bridge
        nd6 options=809<PERFORMNUD,IFDISABLED,STABLEADDR>
```

To automatically create the bridge at boot time, add the following to the **/etc/rc.conf** file:

```sh
cloned_interfaces="bridge0"
ifconfig_bridge0="addm em0 addm em1 up"
ifconfig_em0="up"
ifconfig_em1="up"
```

If the bridge host needs an IP address, it should be configured on the bridge interface rather than on member interfaces. The address can be set using a static IP address or via DHCP. The following example sets a static IP address:

```sh
# ifconfig bridge0 inet 192.168.0.1/24
```

An IPv6 address can also be assigned to the bridge interface. To make the changes permanent, add the address information to the **/etc/rc.conf** file.

> **Note**
>
> When packet filtering is enabled, bridge packets pass through the filter on both the inbound and outbound directions of the source interface and destination interface of the bridge interface. Any stage can be disabled. When packet flow direction matters, it is advisable to configure firewall settings on member interfaces rather than the bridge interface.
>
> The bridge has multiple configurable settings for passing non-IP packets and IP packets, as well as for the Layer 2 firewall functionality of ipfw(8).

## Enabling the Spanning Tree Protocol (STP)

Proper Ethernet operation requires only one active path between any two devices. The Spanning Tree Protocol (STP) is used to detect loops and place redundant links in a blocking state. If one of the active links fails, STP calculates a new tree structure and enables one of the blocked paths to restore connectivity to all points in the network.

The Rapid Spanning Tree Protocol (RSTP or 802.1w) is compatible with traditional STP. RSTP provides faster convergence and exchanges information with neighboring switches, enabling rapid transition to forwarding mode while avoiding loops. FreeBSD supports both RSTP and STP as operating modes, with RSTP as the default mode.

STP can be enabled on member interfaces using ifconfig(8). For member interfaces **em0** and **em1**, the commands to enable STP are as follows:

```sh
# Create the bridge
# ifconfig bridge0 create

# Add two network cards to the bridge
# ifconfig bridge0 addm em0 addm em1

# Enable STP
# ifconfig bridge0 stp em0 stp em1

# Bring up the bridge
# ifconfig bridge0 up
# ifconfig em0 up
# ifconfig em1 up
```

View the bridge:

```sh
# ifconfig bridge0
bridge0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=10<VLAN_HWTAGGING>
        ether 58:9c:fc:10:12:5b
        id 00:50:56:28:c8:68 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
        root id 00:50:56:28:c8:68 priority 32768 ifcost 0 port 0
        bridge flags=0<>
        member: em1 flags=147<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 2 priority 128 path cost 20000 proto rstp
                role backup state discarding vlan protocol 802.1q
        member: em0 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 1 priority 128 path cost 20000 proto rstp
                role root state forwarding vlan protocol 802.1q
        groups: bridge
        nd6 options=809<PERFORMNUD,IFDISABLED,STABLEADDR>
```

This bridge has a spanning tree ID of `00:50:56:28:c8:68` with a priority of `32768`. Since the spanning tree ID is the same as the `root id`, this indicates that this bridge is the root bridge of the spanning tree.

Another bridge in the network with STP enabled is shown below:

```sh
# ifconfig bridge0
bridge0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=10<VLAN_HWTAGGING>
        ether 58:9c:fc:10:12:5b
        id 00:50:56:2a:53:d9 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
        root id 00:50:56:28:c8:68 priority 32768 ifcost 200000 port 1
        bridge flags=0<>
        member: em1 flags=147<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 2 priority 128 path cost 20000 proto rstp
                role backup state discarding vlan protocol 802.1q
        member: em0 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 1 priority 128 path cost 20000 proto rstp
                role designated state forwarding vlan protocol 802.1q
        groups: bridge
        nd6 options=809<PERFORMNUD,IFDISABLED,STABLEADDR>
```

In the line `root id 00:50:56:28:c8:68 priority 32768 ifcost 200000 port 1`, it shows that the root bridge ID is `00:50:56:28:c8:68`, and the path cost from this bridge to the root bridge is `200000`, with the path going through `port 1` (i.e., **em0**).

## Bridge Interface Parameters

Bridge interfaces have several dedicated `ifconfig` parameters. This section summarizes some common uses of these parameters.

**private**

A private interface does not forward any traffic to any other port designated as a private interface. All traffic is unconditionally blocked, so no Ethernet frames are forwarded, including ARP packets. If selective traffic blocking is needed, a firewall should be used instead.

**span**

A span port sends a copy of every Ethernet frame received by the bridge. Multiple span ports can be configured for a bridge, but if an interface is designated as a span port, it cannot simultaneously serve as a regular bridge port. This feature is best suited for passively monitoring the bridge network on another host through the bridge's span port. For example, to send copies of all frames to an interface named **em4**:

```sh
# ifconfig bridge0 span em4
```

**sticky**

If a bridge member interface is marked as `sticky`, dynamically learned address entries are treated as static entries and stored in the forwarding cache. Even if the address is detected on another interface, `sticky` entries are never deleted or replaced from the cache. This provides the advantage of static address entries without the need to pre-populate the forwarding table. Addresses learned by clients on one segment of the bridge cannot jump to another segment.

An example of using sticky addresses with VLANs is: isolating customer networks without wasting IP address space. Suppose `CustomerA` is on `vlan100`, `CustomerB` is on `vlan101`, and the bridge has the address **192.168.0.1**:

```sh
# ifconfig bridge0 addm vlan100 sticky vlan100 addm vlan101 sticky vlan101
# ifconfig bridge0 inet 192.168.0.1/24
```

In this example, both customers use **192.168.0.1** as the default gateway. Since the bridge cache is sticky, a host cannot spoof another customer's MAC address to intercept their traffic.

A firewall or private interfaces as shown above can be used to block any communication between VLANs:

```sh
# ifconfig bridge0 private vlan100 private vlan101
```

This way, customers are completely isolated from each other, and the entire `/24` address range can be assigned without subnetting.

The number of unique source MAC addresses behind each interface can also be limited. Once the limit is reached, packets with unknown source addresses will be dropped until existing host cache entries expire or are removed.

The following example limits the number of Ethernet devices for `CustomerA` on `vlan100` to 10:

```sh
# ifconfig bridge0 ifmaxaddr vlan100 10
```

The bridge interface also supports monitor mode, where packets are dropped after bpf(4) processing and are not further processed or forwarded. This can be used to multiplex input from two or more interfaces into a single bpf(4) stream. This feature is useful for reconstructing traffic from network Taps, especially those that output RX/TX signals through two separate interfaces. For example, to read input from four network interfaces as a single stream:

```sh
# ifconfig bridge0 addm em0 addm em1 addm em2 addm em3 monitor up
# tcpdump -i bridge0
```

## References

* H3C. Bridge Technology Introduction\[EB/OL]. \[2026-06-09]. <https://www.h3c.com/cn/d_200805/605742_30003_0.htm>. The introduction to bridges referenced here.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/ask/flat/chapter-24-advanced-networking/di-24.2-jie-wang-qiao.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
