Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167144750
D58729.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D58729.id.diff
View Options
diff --git a/lib/libifconfig/libifconfig.h b/lib/libifconfig/libifconfig.h
--- a/lib/libifconfig/libifconfig.h
+++ b/lib/libifconfig/libifconfig.h
@@ -73,6 +73,7 @@
uint32_t cache_lifetime; /**< address cache entry lifetime */
ifbr_flags_t flags; /**< bridge flags */
ether_vlanid_t defpvid; /**< default pvid */
+ uint16_t group_fwd_mask; /**< link-local reserved group mask */
};
struct ifconfig_capabilities {
diff --git a/lib/libifconfig/libifconfig_bridge.c b/lib/libifconfig/libifconfig_bridge.c
--- a/lib/libifconfig/libifconfig_bridge.c
+++ b/lib/libifconfig/libifconfig_bridge.c
@@ -66,6 +66,7 @@
{
struct ifbifconf members;
struct ifbrparam cache_param;
+ struct ifbrparam fwd_mask_param;
struct _ifconfig_bridge_status *bridge = NULL;
char *buf = NULL;
@@ -104,6 +105,12 @@
}
bridge->inner.defpvid = cache_param.ifbrp_defpvid;
+ if (ifconfig_bridge_ioctlwrap(h, name, BRDGGFWDMASK,
+ &fwd_mask_param, sizeof(fwd_mask_param), false) != 0) {
+ goto err;
+ }
+ bridge->inner.group_fwd_mask = fwd_mask_param.ifbrp_group_fwd_mask;
+
if (ifconfig_bridge_ioctlwrap(h, name, BRDGPARAM,
&bridge->params, sizeof(bridge->params), false) != 0) {
goto err;
diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c
--- a/sbin/ifconfig/ifbridge.c
+++ b/sbin/ifconfig/ifbridge.c
@@ -235,6 +235,7 @@
stpproto[params->ifbop_protocol],
bridge->cache_size,
bridge->cache_lifetime);
+ printf("\tgroup_fwd_mask 0x%04x\n", bridge->group_fwd_mask);
PV2ID(params->ifbop_designated_root, bprio, lladdr);
printf("\troot id %s priority %d ifcost %u port %u\n",
ether_ntoa((struct ether_addr *)lladdr),
@@ -796,6 +797,21 @@
err(1, "BRDGSTO %s", arg);
}
+static void
+setbridge_group_fwd_mask(if_ctx *ctx, const char *arg, int dummy __unused)
+{
+ struct ifbrparam param;
+ u_long val;
+
+ if (get_val(arg, &val) < 0 || (val & ~0xffff) != 0)
+ errx(1, "invalid value: %s", arg);
+
+ param.ifbrp_group_fwd_mask = val & 0xffff;
+
+ if (do_cmd(ctx, BRDGSFWDMASK, ¶m, sizeof(param), 1) < 0)
+ err(1, "BRDGSFWDMASK %s", arg);
+}
+
static void
setbridge_private(if_ctx *ctx, const char *val, int dummy __unused)
{
@@ -1028,6 +1044,7 @@
DEF_CMD_ARG2("-iftagged", delbridge_iftagged),
DEF_CMD_ARG2("ifvlanproto", setbridge_ifvlanproto),
DEF_CMD_ARG("timeout", setbridge_timeout),
+ DEF_CMD_ARG("group_fwd_mask", setbridge_group_fwd_mask),
DEF_CMD_ARG("private", setbridge_private),
DEF_CMD_ARG("-private", unsetbridge_private),
DEF_CMD("vlanfilter", (int32_t)IFBRF_VLANFILTER,
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
@@ -121,6 +121,28 @@
For unicast traffic, the bridge learns which MAC addresses are associated
with which interfaces and will forward the traffic selectively.
.Pp
+By default,
+.Nm
+does not forward destination MAC addresses in the reserved link-local range
+.Li 01:80:c2:00:00:00
+through
+.Li 01:80:c2:00:00:0f .
+The
+.Xr ifconfig 8
+command
+.Cm group_fwd_mask
+accepts a 16-bit mask that selectively enables forwarding for this range.
+Bit
+.Ar n
+controls whether frames destined to
+.Li 01:80:c2:00:00:0n
+are forwarded across bridge member ports.
+For example, a mask of
+.Li 0x4000
+allows forwarding of
+.Li 01:80:c2:00:00:0e
+frames while leaving the remaining reserved destinations filtered.
+.Pp
By default the bridge logs MAC address port flapping to
.Xr syslog 3 .
This behavior can be disabled by setting 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
@@ -286,6 +286,7 @@
LIST_ENTRY(bridge_softc) sc_list;
struct sx sc_sx;
struct mtx sc_rt_mtx;
+ uint16_t sc_group_fwd_mask; /* link-local group fwd mask */
uint32_t sc_brtmax; /* max # of addresses */
uint32_t sc_brtcnt; /* cur. # of addresses */
uint32_t sc_brttimeout; /* rt timeout in seconds */
@@ -425,6 +426,8 @@
static int bridge_ioctl_gdefpvid(struct bridge_softc *, void *);
static int bridge_ioctl_sdefpvid(struct bridge_softc *, void *);
static int bridge_ioctl_svlanproto(struct bridge_softc *, void *);
+static int bridge_ioctl_gfwdmask(struct bridge_softc *, void *);
+static int bridge_ioctl_sfwdmask(struct bridge_softc *, void *);
static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
int);
#ifdef INET
@@ -437,6 +440,8 @@
#endif /* INET6 */
static void bridge_linkstate(struct ifnet *ifp);
static void bridge_linkcheck(struct bridge_softc *sc);
+static bool bridge_rsvd_link_local_enabled(struct bridge_softc *,
+ const uint8_t *);
/*
* Use the "null" value from IEEE 802.1Q-2014 Table 9-2
@@ -659,6 +664,13 @@
{ bridge_ioctl_svlanproto, sizeof(struct ifbreq),
BC_F_COPYIN|BC_F_SUSER },
+
+ { bridge_ioctl_gfwdmask, sizeof(struct ifbrparam),
+ BC_F_COPYOUT },
+
+ { bridge_ioctl_sfwdmask, sizeof(struct ifbrparam),
+ BC_F_COPYIN|BC_F_SUSER },
+
};
static const int bridge_control_table_size = nitems(bridge_control_table);
@@ -857,6 +869,7 @@
ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
BRIDGE_LOCK_INIT(sc);
+ sc->sc_group_fwd_mask = 0;
sc->sc_brtmax = BRIDGE_RTABLE_MAX;
sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
@@ -913,6 +926,19 @@
return (0);
}
+static bool
+bridge_rsvd_link_local_enabled(struct bridge_softc *sc, const uint8_t *dst)
+{
+ uint16_t bit;
+
+ if (dst[0] != 0x01 || dst[1] != 0x80 || dst[2] != 0xc2 ||
+ dst[3] != 0x00 || dst[4] != 0x00 || dst[5] > 0x0f)
+ return (false);
+
+ bit = (uint16_t)1 << dst[5];
+ return ((sc->sc_group_fwd_mask & bit) != 0);
+}
+
static void
bridge_clone_destroy_cb(struct epoch_context *ctx)
{
@@ -2219,6 +2245,15 @@
return (0);
}
+static int
+bridge_ioctl_gfwdmask(struct bridge_softc *sc, void *arg)
+{
+ struct ifbrparam *param = arg;
+
+ param->ifbrp_group_fwd_mask = sc->sc_group_fwd_mask;
+ return (0);
+}
+
static int
bridge_ioctl_sflags(struct bridge_softc *sc, void *arg)
{
@@ -2271,6 +2306,14 @@
return (0);
}
+bridge_ioctl_sfwdmask(struct bridge_softc *sc, void *arg)
+{
+ struct ifbrparam *param = arg;
+
+ sc->sc_group_fwd_mask = param->ifbrp_group_fwd_mask;
+ return (0);
+}
+
/*
* bridge_ifdetach:
*
@@ -2761,12 +2804,12 @@
goto drop;
} else {
/*
- * Check if its a reserved multicast address, any address
- * listed in 802.1D section 7.12.6 may not be forwarded by the
- * bridge.
- * This is currently 01-80-C2-00-00-00 to 01-80-C2-00-00-0F
+ * Reserved link-local destinations in the
+ * 01-80-C2-00-00-[00,0F] range are filtered unless the
+ * corresponding bit is enabled in group_fwd_mask.
*/
- if (dst[0] == 0x01 && dst[1] == 0x80 &&
+ if (!bridge_rsvd_link_local_enabled(sc, dst) &&
+ dst[0] == 0x01 && dst[1] == 0x80 &&
dst[2] == 0xc2 && dst[3] == 0x00 &&
dst[4] == 0x00 && dst[5] <= 0x0f)
goto drop;
diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h
--- a/sys/net/if_bridgevar.h
+++ b/sys/net/if_bridgevar.h
@@ -132,6 +132,8 @@
#define BRDGGDEFPVID 36 /* get default pvid (ifbrparam) */
#define BRDGSDEFPVID 37 /* set default pvid (ifbrparam) */
#define BRDGSIFVLANPROTO 38 /* set if vlan protocol (ifbreq) */
+#define BRDGGFWDMASK 39 /* get group_fwd_mask (ifbrparam) */
+#define BRDGSFWDMASK 40 /* set group_fwd_mask (ifbrparam) */
/* BRDGSFLAGS, Bridge flags (non-interface-specific) */
typedef uint32_t ifbr_flags_t;
@@ -245,6 +247,8 @@
#define ifbrp_csize ifbrp_ifbrpu.ifbrpu_int32 /* cache size */
#define ifbrp_ctime ifbrp_ifbrpu.ifbrpu_int32 /* cache time (sec) */
#define ifbrp_prio ifbrp_ifbrpu.ifbrpu_int16 /* bridge priority */
+#define ifbrp_group_fwd_mask ifbrp_ifbrpu.ifbrpu_int16 /* reserved group
+ * fwd mask */
#define ifbrp_proto ifbrp_ifbrpu.ifbrpu_int8 /* bridge protocol */
#define ifbrp_txhc ifbrp_ifbrpu.ifbrpu_int8 /* bpdu tx holdcount */
#define ifbrp_hellotime ifbrp_ifbrpu.ifbrpu_int8 /* hello time (sec) */
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
@@ -793,6 +793,37 @@
vnet_cleanup
}
+atf_test_case "group_fwd_mask" "cleanup"
+group_fwd_mask_head()
+{
+ atf_set descr 'bridge group_fwd_mask control path'
+ atf_set require.user root
+}
+
+group_fwd_mask_body()
+{
+ vnet_init
+ vnet_init_bridge
+
+ bridge=$(vnet_mkbridge)
+
+ atf_check -s exit:0 -o match:'group_fwd_mask 0x0000' \
+ ifconfig ${bridge}
+ atf_check -s exit:0 ifconfig ${bridge} group_fwd_mask 0x4000
+ atf_check -s exit:0 -o match:'group_fwd_mask 0x4000' \
+ ifconfig ${bridge}
+ atf_check -s exit:0 ifconfig ${bridge} group_fwd_mask 0x8
+ atf_check -s exit:0 -o match:'group_fwd_mask 0x0008' \
+ ifconfig ${bridge}
+ atf_check -s exit:1 -e ignore \
+ ifconfig ${bridge} group_fwd_mask 0x10000
+}
+
+group_fwd_mask_cleanup()
+{
+ vnet_cleanup
+}
+
atf_test_case "member_ifaddrs_enabled" "cleanup"
member_ifaddrs_enabled_head()
{
@@ -1475,6 +1506,7 @@
atf_add_test_case "mtu"
atf_add_test_case "vlan"
atf_add_test_case "many_bridge_members"
+ atf_add_test_case "group_fwd_mask"
atf_add_test_case "member_ifaddrs_enabled"
atf_add_test_case "member_ifaddrs_disabled"
atf_add_test_case "member_ifaddrs_vlan"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Aug 20, 11:32 AM (4 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36945434
Default Alt Text
D58729.id.diff (9 KB)
Attached To
Mode
D58729: if_bridge: add group_fwd_mask ioctl for reserved link-local multicast
Attached
Detach File
Event Timeline
Log In to Comment