Page MenuHomeFreeBSD

D50504.diff
No OneTemporary

D50504.diff

diff --git a/share/man/man4/bridge.4 b/share/man/man4/bridge.4
--- a/share/man/man4/bridge.4
+++ b/share/man/man4/bridge.4
@@ -281,6 +281,11 @@
Incoming frames with an 802.1Q tag will be assigned to the appropriate
VLAN.
.Pp
+Traffic sent to or from the host is not assigned to a VLAN by default.
+To allow the host to communicate on a VLAN, configure a
+.Xr vlan 4
+interface on the bridge and (if necessary) assign IP addresses there.
+.Pp
By default no access control is enabled, so any interface may
participate in any VLAN.
.Pp
@@ -581,6 +586,7 @@
.Xr ipfw 4 ,
.Xr netmap 4 ,
.Xr pf 4 ,
+.Xr vlan 4 ,
.Xr ifconfig 8
.Sh HISTORY
The
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -847,6 +847,7 @@
ifp->if_softc = sc;
if_initname(ifp, bridge_name, ifd->unit);
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_capabilities = ifp->if_capenable = IFCAP_VLAN_HWTAGGING;
ifp->if_ioctl = bridge_ioctl;
#ifdef ALTQ
ifp->if_start = bridge_altq_start;
@@ -2484,16 +2485,17 @@
struct ether_header *eh;
struct ifnet *dst_if;
int error = 0;
+ ether_vlanid_t vlan;
sc = ifp->if_softc;
ETHER_BPF_MTAP(ifp, m);
eh = mtod(m, struct ether_header *);
+ vlan = VLANTAGOF(m);
if (((m->m_flags & (M_BCAST|M_MCAST)) == 0) &&
- (dst_if = bridge_rtlookup(sc, eh->ether_dhost, DOT1Q_VID_NULL)) !=
- NULL) {
+ (dst_if = bridge_rtlookup(sc, eh->ether_dhost, vlan)) != NULL) {
error = bridge_enqueue(sc, dst_if, m, NULL);
} else
bridge_broadcast(sc, ifp, m, 0);
@@ -2894,6 +2896,15 @@
} \
if ((iface) != bifp) \
ETHER_BPF_MTAP(iface, m); \
+ /* Pass tagged packets to if_vlan, if it's loaded */ \
+ if (VLANTAGOF(m) != 0) { \
+ if (bifp->if_vlantrunk == NULL) { \
+ m_freem(m); \
+ return (NULL); \
+ } \
+ (*vlan_input_p)(bifp, m); \
+ return (NULL); \
+ } \
return (m); \
} \
\
@@ -2950,6 +2961,30 @@
{
struct bridge_softc *sc;
+ if (ifp->if_type == IFT_L2VLAN) {
+ /*
+ * vlan(4) gives us the vlan ifnet, so we need to get the
+ * bridge softc to get a pointer to ether_input to send the
+ * packet to.
+ */
+ struct ifnet *bifp = NULL;
+
+ if (vlan_trunkdev_p == NULL) {
+ m_freem(m);
+ return;
+ }
+
+ bifp = vlan_trunkdev_p(ifp);
+ if (bifp == NULL) {
+ m_freem(m);
+ return;
+ }
+
+ sc = if_getsoftc(bifp);
+ sc->sc_if_input(ifp, m);
+ return;
+ }
+
KASSERT((if_getcapenable(ifp) & IFCAP_NETMAP) != 0,
("%s: iface %s is not running in netmap mode",
__func__, if_name(ifp)));
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1673,6 +1673,7 @@
*/
if (p->if_type != IFT_ETHER &&
p->if_type != IFT_L2VLAN &&
+ p->if_type != IFT_BRIDGE &&
(p->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
return (EPROTONOSUPPORT);
if ((p->if_flags & VLAN_IFFLAGS) != VLAN_IFFLAGS)
diff --git a/tests/sys/net/if_bridge_test.sh b/tests/sys/net/if_bridge_test.sh
--- a/tests/sys/net/if_bridge_test.sh
+++ b/tests/sys/net/if_bridge_test.sh
@@ -1124,6 +1124,46 @@
vnet_cleanup
}
+#
+# Test a vlan(4) "SVI" interface on top of a bridge.
+#
+atf_test_case "vlan_svi" "cleanup"
+vlan_svi_head()
+{
+ atf_set descr 'vlan bridge with an SVI'
+ atf_set require.user root
+}
+
+vlan_svi_body()
+{
+ vnet_init
+ vnet_init_bridge
+
+ epone=$(vnet_mkepair)
+
+ vnet_mkjail one ${epone}b
+
+ jexec one ifconfig ${epone}b up
+ jexec one ifconfig ${epone}b.20 create 192.0.2.1/24 up
+
+ bridge=$(vnet_mkbridge)
+
+ ifconfig ${bridge} up
+ ifconfig ${epone}a up
+ ifconfig ${bridge} addm ${epone}a tagged ${epone}a 20
+
+ svi=$(vnet_mkvlan)
+ ifconfig ${svi} vlan 20 vlandev ${bridge}
+ ifconfig ${svi} inet 192.0.2.2/24 up
+
+ atf_check -s exit:0 -o ignore ping -c 3 -t 1 192.0.2.1
+}
+
+vlan_svi_cleanup()
+{
+ vnet_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "bridge_transmit_ipv4_unicast"
@@ -1148,4 +1188,5 @@
atf_add_test_case "vlan_pvid_tagged"
atf_add_test_case "vlan_filtering"
atf_add_test_case "vlan_ifconfig_tagged"
+ atf_add_test_case "vlan_svi"
}

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 19, 8:47 AM (9 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25614221
Default Alt Text
D50504.diff (4 KB)

Event Timeline