Skip to content

Commit

Permalink
net: bridge: vlan: use br_rports_fill_info() to export mcast router p…
Browse files Browse the repository at this point in the history
…orts

Embed the standard multicast router port export by br_rports_fill_info()
into a new global vlan attribute BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS.
In order to have the same format for the global bridge mcast context and
the per-vlan mcast context we need a double-nesting:
 - BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS
   - MDBA_ROUTER

Currently we don't compare router lists, if any router port exists in
the bridge mcast contexts we consider their option sets as different and
export them separately.

In addition we export the router port vlan id when dumping similar to
the router port notification format.

Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nikolay Aleksandrov authored and David S. Miller committed Aug 11, 2021
1 parent e04d377 commit dc00287
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 13 deletions.
1 change: 1 addition & 0 deletions include/uapi/linux/if_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ enum {
BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
BRIDGE_VLANDB_GOPTS_MCAST_ROUTER,
BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS,
__BRIDGE_VLANDB_GOPTS_MAX
};
#define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1)
Expand Down
17 changes: 4 additions & 13 deletions net/bridge/br_mdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@

#include "br_private.h"

static bool br_rports_have_mc_router(const struct net_bridge_mcast *brmctx)
{
#if IS_ENABLED(CONFIG_IPV6)
return !hlist_empty(&brmctx->ip4_mc_router_list) ||
!hlist_empty(&brmctx->ip6_mc_router_list);
#else
return !hlist_empty(&brmctx->ip4_mc_router_list);
#endif
}

static bool
br_ip4_rports_get_timer(struct net_bridge_mcast_port *pmctx,
unsigned long *timer)
Expand All @@ -47,8 +37,8 @@ br_ip6_rports_get_timer(struct net_bridge_mcast_port *pmctx,
#endif
}

static int br_rports_fill_info(struct sk_buff *skb,
const struct net_bridge_mcast *brmctx)
int br_rports_fill_info(struct sk_buff *skb,
const struct net_bridge_mcast *brmctx)
{
u16 vid = brmctx->vlan ? brmctx->vlan->vid : 0;
bool have_ip4_mc_rtr, have_ip6_mc_rtr;
Expand Down Expand Up @@ -97,7 +87,8 @@ static int br_rports_fill_info(struct sk_buff *skb,
ip4_timer)) ||
(have_ip6_mc_rtr &&
nla_put_u32(skb, MDBA_ROUTER_PATTR_INET6_TIMER,
ip6_timer))) {
ip6_timer)) ||
(vid && nla_put_u16(skb, MDBA_ROUTER_PATTR_VID, vid))) {
nla_nest_cancel(skb, port_nest);
goto fail;
}
Expand Down
15 changes: 15 additions & 0 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,8 @@ bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, bool on);
int br_mdb_replay(struct net_device *br_dev, struct net_device *dev,
const void *ctx, bool adding, struct notifier_block *nb,
struct netlink_ext_ack *extack);
int br_rports_fill_info(struct sk_buff *skb,
const struct net_bridge_mcast *brmctx);

static inline bool br_group_is_l2(const struct br_ip *group)
{
Expand Down Expand Up @@ -1168,6 +1170,17 @@ br_multicast_port_ctx_state_stopped(const struct net_bridge_mcast_port *pmctx)
pmctx->vlan->state == BR_STATE_BLOCKING);
}

static inline bool
br_rports_have_mc_router(const struct net_bridge_mcast *brmctx)
{
#if IS_ENABLED(CONFIG_IPV6)
return !hlist_empty(&brmctx->ip4_mc_router_list) ||
!hlist_empty(&brmctx->ip6_mc_router_list);
#else
return !hlist_empty(&brmctx->ip4_mc_router_list);
#endif
}

static inline bool
br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
const struct net_bridge_mcast *brmctx2)
Expand All @@ -1192,6 +1205,8 @@ br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
brmctx2->multicast_startup_query_interval &&
brmctx1->multicast_querier == brmctx2->multicast_querier &&
brmctx1->multicast_router == brmctx2->multicast_router &&
!br_rports_have_mc_router(brmctx1) &&
!br_rports_have_mc_router(brmctx2) &&
#if IS_ENABLED(CONFIG_IPV6)
brmctx1->multicast_mld_version ==
brmctx2->multicast_mld_version &&
Expand Down
18 changes: 18 additions & 0 deletions net/bridge/br_vlan_options.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
const struct net_bridge_vlan *v_opts)
{
struct nlattr *nest2 __maybe_unused;
u64 clockval __maybe_unused;
struct nlattr *nest;

Expand Down Expand Up @@ -326,6 +327,23 @@ bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
clockval, BRIDGE_VLANDB_GOPTS_PAD))
goto out_err;

if (br_rports_have_mc_router(&v_opts->br_mcast_ctx)) {
nest2 = nla_nest_start(skb,
BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS);
if (!nest2)
goto out_err;

rcu_read_lock();
if (br_rports_fill_info(skb, &v_opts->br_mcast_ctx)) {
rcu_read_unlock();
nla_nest_cancel(skb, nest2);
goto out_err;
}
rcu_read_unlock();

nla_nest_end(skb, nest2);
}

#if IS_ENABLED(CONFIG_IPV6)
if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION,
v_opts->br_mcast_ctx.multicast_mld_version))
Expand Down

0 comments on commit dc00287

Please sign in to comment.