Skip to content

Commit

Permalink
net: bridge: mcast: prepare is-router function for mcast router split
Browse files Browse the repository at this point in the history
In preparation for the upcoming split of multicast router state into
their IPv4 and IPv6 variants make br_multicast_is_router() protocol
family aware.

Note that for now br_ip6_multicast_is_router() uses the currently still
common ip4_mc_router_timer for now. It will be renamed to
ip6_mc_router_timer later when the split is performed.

While at it also renames the "1" and "2" constants in
br_multicast_is_router() to the MDB_RTR_TYPE_TEMP_QUERY and
MDB_RTR_TYPE_PERM enums.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Linus Lüssing authored and David S. Miller committed May 13, 2021
1 parent b19232e commit 1a3065a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
2 changes: 1 addition & 1 deletion net/bridge/br_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
br_multicast_querier_exists(br, eth_hdr(skb), mdst)) {
if ((mdst && mdst->host_joined) ||
br_multicast_is_router(br)) {
br_multicast_is_router(br, skb)) {
local_rcv = true;
br->dev->stats.multicast++;
}
Expand Down
5 changes: 3 additions & 2 deletions net/bridge/br_multicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,8 @@ static void br_multicast_local_router_expired(struct timer_list *t)
spin_lock(&br->multicast_lock);
if (br->multicast_router == MDB_RTR_TYPE_DISABLED ||
br->multicast_router == MDB_RTR_TYPE_PERM ||
timer_pending(&br->ip4_mc_router_timer))
br_ip4_multicast_is_router(br) ||
br_ip6_multicast_is_router(br))
goto out;

br_mc_router_state_change(br, false);
Expand Down Expand Up @@ -3622,7 +3623,7 @@ bool br_multicast_router(const struct net_device *dev)
bool is_router;

spin_lock_bh(&br->multicast_lock);
is_router = br_multicast_is_router(br);
is_router = br_multicast_is_router(br, NULL);
spin_unlock_bh(&br->multicast_lock);
return is_router;
}
Expand Down
37 changes: 33 additions & 4 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -874,11 +874,40 @@ br_multicast_rport_from_node_skb(struct hlist_node *rp, struct sk_buff *skb) {
return hlist_entry_safe(rp, struct net_bridge_port, ip4_rlist);
}

static inline bool br_multicast_is_router(struct net_bridge *br)
static inline bool br_ip4_multicast_is_router(struct net_bridge *br)
{
return br->multicast_router == 2 ||
(br->multicast_router == 1 &&
timer_pending(&br->ip4_mc_router_timer));
return timer_pending(&br->ip4_mc_router_timer);
}

static inline bool br_ip6_multicast_is_router(struct net_bridge *br)
{
#if IS_ENABLED(CONFIG_IPV6)
return timer_pending(&br->ip4_mc_router_timer);
#else
return false;
#endif
}

static inline bool
br_multicast_is_router(struct net_bridge *br, struct sk_buff *skb)
{
switch (br->multicast_router) {
case MDB_RTR_TYPE_PERM:
return true;
case MDB_RTR_TYPE_TEMP_QUERY:
if (skb) {
if (skb->protocol == htons(ETH_P_IP))
return br_ip4_multicast_is_router(br);
else if (skb->protocol == htons(ETH_P_IPV6))
return br_ip6_multicast_is_router(br);
} else {
return br_ip4_multicast_is_router(br) ||
br_ip6_multicast_is_router(br);
}
fallthrough;
default:
return false;
}
}

static inline bool
Expand Down

0 comments on commit 1a3065a

Please sign in to comment.