Skip to content

Commit f7397cd

Browse files
committed
Merge branch 'net-bridge-mcast-add-and-enforce-query-interval-minimum'
Nikolay Aleksandrov says: ==================== net: bridge: mcast: add and enforce query interval minimum This set adds and enforces 1 second minimum value for bridge multicast query and startup query intervals in order to avoid rearming the timers too often which could lock and crash the host. I doubt anyone is using such low values or anything lower than 1 second, so it seems like a good minimum. In order to be compatible if the value is lower then it is overwritten and a log message is emitted, since we can't return an error at this point. Eric, I looked for the syzbot reports in its dashboard but couldn't find them so I've added you as the reporter. I've prepared a global bridge igmp rate limiting patch but wasn't sure if it's ok for -net. It adds a static limit of 32k packets per second, I plan to send it for net-next with added drop counters for each bridge so it can be easily debugged. Original report can be seen at: https://lore.kernel.org/netdev/[email protected]/ ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents fb7bc92 + f83a112 commit f7397cd

File tree

5 files changed

+44
-6
lines changed

5 files changed

+44
-6
lines changed

net/bridge/br_multicast.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4522,6 +4522,38 @@ int br_multicast_set_mld_version(struct net_bridge_mcast *brmctx,
45224522
}
45234523
#endif
45244524

4525+
void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx,
4526+
unsigned long val)
4527+
{
4528+
unsigned long intvl_jiffies = clock_t_to_jiffies(val);
4529+
4530+
if (intvl_jiffies < BR_MULTICAST_QUERY_INTVL_MIN) {
4531+
br_info(brmctx->br,
4532+
"trying to set multicast query interval below minimum, setting to %lu (%ums)\n",
4533+
jiffies_to_clock_t(BR_MULTICAST_QUERY_INTVL_MIN),
4534+
jiffies_to_msecs(BR_MULTICAST_QUERY_INTVL_MIN));
4535+
intvl_jiffies = BR_MULTICAST_QUERY_INTVL_MIN;
4536+
}
4537+
4538+
brmctx->multicast_query_interval = intvl_jiffies;
4539+
}
4540+
4541+
void br_multicast_set_startup_query_intvl(struct net_bridge_mcast *brmctx,
4542+
unsigned long val)
4543+
{
4544+
unsigned long intvl_jiffies = clock_t_to_jiffies(val);
4545+
4546+
if (intvl_jiffies < BR_MULTICAST_STARTUP_QUERY_INTVL_MIN) {
4547+
br_info(brmctx->br,
4548+
"trying to set multicast startup query interval below minimum, setting to %lu (%ums)\n",
4549+
jiffies_to_clock_t(BR_MULTICAST_STARTUP_QUERY_INTVL_MIN),
4550+
jiffies_to_msecs(BR_MULTICAST_STARTUP_QUERY_INTVL_MIN));
4551+
intvl_jiffies = BR_MULTICAST_STARTUP_QUERY_INTVL_MIN;
4552+
}
4553+
4554+
brmctx->multicast_startup_query_interval = intvl_jiffies;
4555+
}
4556+
45254557
/**
45264558
* br_multicast_list_adjacent - Returns snooped multicast addresses
45274559
* @dev: The bridge port adjacent to which to retrieve addresses

net/bridge/br_netlink.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,7 +1357,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
13571357
if (data[IFLA_BR_MCAST_QUERY_INTVL]) {
13581358
u64 val = nla_get_u64(data[IFLA_BR_MCAST_QUERY_INTVL]);
13591359

1360-
br->multicast_ctx.multicast_query_interval = clock_t_to_jiffies(val);
1360+
br_multicast_set_query_intvl(&br->multicast_ctx, val);
13611361
}
13621362

13631363
if (data[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]) {
@@ -1369,7 +1369,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
13691369
if (data[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]) {
13701370
u64 val = nla_get_u64(data[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]);
13711371

1372-
br->multicast_ctx.multicast_startup_query_interval = clock_t_to_jiffies(val);
1372+
br_multicast_set_startup_query_intvl(&br->multicast_ctx, val);
13731373
}
13741374

13751375
if (data[IFLA_BR_MCAST_STATS_ENABLED]) {

net/bridge/br_private.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#define BR_MAX_PORTS (1<<BR_PORT_BITS)
2929

3030
#define BR_MULTICAST_DEFAULT_HASH_MAX 4096
31+
#define BR_MULTICAST_QUERY_INTVL_MIN msecs_to_jiffies(1000)
32+
#define BR_MULTICAST_STARTUP_QUERY_INTVL_MIN BR_MULTICAST_QUERY_INTVL_MIN
3133

3234
#define BR_HWDOM_MAX BITS_PER_LONG
3335

@@ -963,6 +965,10 @@ int br_multicast_dump_querier_state(struct sk_buff *skb,
963965
int nest_attr);
964966
size_t br_multicast_querier_state_size(void);
965967
size_t br_rports_size(const struct net_bridge_mcast *brmctx);
968+
void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx,
969+
unsigned long val);
970+
void br_multicast_set_startup_query_intvl(struct net_bridge_mcast *brmctx,
971+
unsigned long val);
966972

967973
static inline bool br_group_is_l2(const struct br_ip *group)
968974
{

net/bridge/br_sysfs_br.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ static ssize_t multicast_query_interval_show(struct device *d,
658658
static int set_query_interval(struct net_bridge *br, unsigned long val,
659659
struct netlink_ext_ack *extack)
660660
{
661-
br->multicast_ctx.multicast_query_interval = clock_t_to_jiffies(val);
661+
br_multicast_set_query_intvl(&br->multicast_ctx, val);
662662
return 0;
663663
}
664664

@@ -706,7 +706,7 @@ static ssize_t multicast_startup_query_interval_show(
706706
static int set_startup_query_interval(struct net_bridge *br, unsigned long val,
707707
struct netlink_ext_ack *extack)
708708
{
709-
br->multicast_ctx.multicast_startup_query_interval = clock_t_to_jiffies(val);
709+
br_multicast_set_startup_query_intvl(&br->multicast_ctx, val);
710710
return 0;
711711
}
712712

net/bridge/br_vlan_options.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ static int br_vlan_process_global_one_opts(const struct net_bridge *br,
521521
u64 val;
522522

523523
val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]);
524-
v->br_mcast_ctx.multicast_query_interval = clock_t_to_jiffies(val);
524+
br_multicast_set_query_intvl(&v->br_mcast_ctx, val);
525525
*changed = true;
526526
}
527527
if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]) {
@@ -535,7 +535,7 @@ static int br_vlan_process_global_one_opts(const struct net_bridge *br,
535535
u64 val;
536536

537537
val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]);
538-
v->br_mcast_ctx.multicast_startup_query_interval = clock_t_to_jiffies(val);
538+
br_multicast_set_startup_query_intvl(&v->br_mcast_ctx, val);
539539
*changed = true;
540540
}
541541
if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) {

0 commit comments

Comments
 (0)