Commit adc47037 authored by Nikolay Aleksandrov's avatar Nikolay Aleksandrov Committed by David S. Miller

net: bridge: multicast: use multicast contexts instead of bridge or port

Pass multicast context pointers to multicast functions instead of bridge/port.
This would make it easier later to switch these contexts to their per-vlan
versions. The patch is basically search and replace, no functional changes.
Signed-off-by: default avatarNikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d3d065c0
...@@ -28,6 +28,7 @@ EXPORT_SYMBOL_GPL(nf_br_ops); ...@@ -28,6 +28,7 @@ EXPORT_SYMBOL_GPL(nf_br_ops);
netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct net_bridge *br = netdev_priv(dev); struct net_bridge *br = netdev_priv(dev);
struct net_bridge_mcast *brmctx = &br->multicast_ctx;
struct net_bridge_fdb_entry *dst; struct net_bridge_fdb_entry *dst;
struct net_bridge_mdb_entry *mdst; struct net_bridge_mdb_entry *mdst;
const struct nf_br_ops *nf_ops; const struct nf_br_ops *nf_ops;
...@@ -82,15 +83,15 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -82,15 +83,15 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
br_flood(br, skb, BR_PKT_MULTICAST, false, true); br_flood(br, skb, BR_PKT_MULTICAST, false, true);
goto out; goto out;
} }
if (br_multicast_rcv(br, NULL, skb, vid)) { if (br_multicast_rcv(brmctx, NULL, skb, vid)) {
kfree_skb(skb); kfree_skb(skb);
goto out; goto out;
} }
mdst = br_mdb_get(br, skb, vid); mdst = br_mdb_get(brmctx, skb, vid);
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
br_multicast_querier_exists(br, eth_hdr(skb), mdst)) br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst))
br_multicast_flood(mdst, skb, false, true); br_multicast_flood(mdst, skb, brmctx, false, true);
else else
br_flood(br, skb, BR_PKT_MULTICAST, false, true); br_flood(br, skb, BR_PKT_MULTICAST, false, true);
} else if ((dst = br_fdb_find_rcu(br, dest, vid)) != NULL) { } else if ((dst = br_fdb_find_rcu(br, dest, vid)) != NULL) {
......
...@@ -267,20 +267,19 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, ...@@ -267,20 +267,19 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
/* called with rcu_read_lock */ /* called with rcu_read_lock */
void br_multicast_flood(struct net_bridge_mdb_entry *mdst, void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
struct sk_buff *skb, struct sk_buff *skb,
struct net_bridge_mcast *brmctx,
bool local_rcv, bool local_orig) bool local_rcv, bool local_orig)
{ {
struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
struct net_bridge *br = netdev_priv(dev);
struct net_bridge_port *prev = NULL; struct net_bridge_port *prev = NULL;
struct net_bridge_port_group *p; struct net_bridge_port_group *p;
bool allow_mode_include = true; bool allow_mode_include = true;
struct hlist_node *rp; struct hlist_node *rp;
rp = br_multicast_get_first_rport_node(br, skb); rp = br_multicast_get_first_rport_node(brmctx, skb);
if (mdst) { if (mdst) {
p = rcu_dereference(mdst->ports); p = rcu_dereference(mdst->ports);
if (br_multicast_should_handle_mode(br, mdst->addr.proto) && if (br_multicast_should_handle_mode(brmctx, mdst->addr.proto) &&
br_multicast_is_star_g(&mdst->addr)) br_multicast_is_star_g(&mdst->addr))
allow_mode_include = false; allow_mode_include = false;
} else { } else {
......
...@@ -69,8 +69,10 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb ...@@ -69,8 +69,10 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
struct net_bridge_port *p = br_port_get_rcu(skb->dev); struct net_bridge_port *p = br_port_get_rcu(skb->dev);
enum br_pkt_type pkt_type = BR_PKT_UNICAST; enum br_pkt_type pkt_type = BR_PKT_UNICAST;
struct net_bridge_fdb_entry *dst = NULL; struct net_bridge_fdb_entry *dst = NULL;
struct net_bridge_mcast_port *pmctx;
struct net_bridge_mdb_entry *mdst; struct net_bridge_mdb_entry *mdst;
bool local_rcv, mcast_hit = false; bool local_rcv, mcast_hit = false;
struct net_bridge_mcast *brmctx;
struct net_bridge *br; struct net_bridge *br;
u16 vid = 0; u16 vid = 0;
u8 state; u8 state;
...@@ -78,6 +80,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb ...@@ -78,6 +80,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
if (!p || p->state == BR_STATE_DISABLED) if (!p || p->state == BR_STATE_DISABLED)
goto drop; goto drop;
brmctx = &p->br->multicast_ctx;
pmctx = &p->multicast_ctx;
state = p->state; state = p->state;
if (!br_allowed_ingress(p->br, nbp_vlan_group_rcu(p), skb, &vid, if (!br_allowed_ingress(p->br, nbp_vlan_group_rcu(p), skb, &vid,
&state)) &state))
...@@ -98,7 +102,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb ...@@ -98,7 +102,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
local_rcv = true; local_rcv = true;
} else { } else {
pkt_type = BR_PKT_MULTICAST; pkt_type = BR_PKT_MULTICAST;
if (br_multicast_rcv(br, p, skb, vid)) if (br_multicast_rcv(brmctx, pmctx, skb, vid))
goto drop; goto drop;
} }
} }
...@@ -128,11 +132,11 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb ...@@ -128,11 +132,11 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
switch (pkt_type) { switch (pkt_type) {
case BR_PKT_MULTICAST: case BR_PKT_MULTICAST:
mdst = br_mdb_get(br, skb, vid); mdst = br_mdb_get(brmctx, skb, vid);
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
br_multicast_querier_exists(br, eth_hdr(skb), mdst)) { br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) {
if ((mdst && mdst->host_joined) || if ((mdst && mdst->host_joined) ||
br_multicast_is_router(br, skb)) { br_multicast_is_router(brmctx, skb)) {
local_rcv = true; local_rcv = true;
br->dev->stats.multicast++; br->dev->stats.multicast++;
} }
...@@ -162,7 +166,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb ...@@ -162,7 +166,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
if (!mcast_hit) if (!mcast_hit)
br_flood(br, skb, pkt_type, local_rcv, false); br_flood(br, skb, pkt_type, local_rcv, false);
else else
br_multicast_flood(mdst, skb, local_rcv, false); br_multicast_flood(mdst, skb, brmctx, local_rcv, false);
} }
if (local_rcv) if (local_rcv)
......
...@@ -1092,7 +1092,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, ...@@ -1092,7 +1092,7 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
* a new INCLUDE port (S,G) then all of *,G EXCLUDE ports need to be * a new INCLUDE port (S,G) then all of *,G EXCLUDE ports need to be
* added to it for proper replication * added to it for proper replication
*/ */
if (br_multicast_should_handle_mode(br, group.proto)) { if (br_multicast_should_handle_mode(&br->multicast_ctx, group.proto)) {
switch (filter_mode) { switch (filter_mode) {
case MCAST_EXCLUDE: case MCAST_EXCLUDE:
br_multicast_star_g_handle_mode(p, MCAST_EXCLUDE); br_multicast_star_g_handle_mode(p, MCAST_EXCLUDE);
......
This diff is collapsed.
This diff is collapsed.
...@@ -817,9 +817,10 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, ...@@ -817,9 +817,10 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd,
/* br_multicast.c */ /* br_multicast.c */
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, int br_multicast_rcv(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb, u16 vid); struct sk_buff *skb, u16 vid);
struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
struct sk_buff *skb, u16 vid); struct sk_buff *skb, u16 vid);
int br_multicast_add_port(struct net_bridge_port *port); int br_multicast_add_port(struct net_bridge_port *port);
void br_multicast_del_port(struct net_bridge_port *port); void br_multicast_del_port(struct net_bridge_port *port);
...@@ -831,8 +832,9 @@ void br_multicast_leave_snoopers(struct net_bridge *br); ...@@ -831,8 +832,9 @@ void br_multicast_leave_snoopers(struct net_bridge *br);
void br_multicast_open(struct net_bridge *br); void br_multicast_open(struct net_bridge *br);
void br_multicast_stop(struct net_bridge *br); void br_multicast_stop(struct net_bridge *br);
void br_multicast_dev_del(struct net_bridge *br); void br_multicast_dev_del(struct net_bridge *br);
void br_multicast_flood(struct net_bridge_mdb_entry *mdst, void br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct sk_buff *skb,
struct sk_buff *skb, bool local_rcv, bool local_orig); struct net_bridge_mcast *brmctx,
bool local_rcv, bool local_orig);
int br_multicast_set_router(struct net_bridge *br, unsigned long val); int br_multicast_set_router(struct net_bridge *br, unsigned long val);
int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val); int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val);
int br_multicast_toggle(struct net_bridge *br, unsigned long val, int br_multicast_toggle(struct net_bridge *br, unsigned long val,
...@@ -861,7 +863,8 @@ void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, ...@@ -861,7 +863,8 @@ void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port,
void br_multicast_del_pg(struct net_bridge_mdb_entry *mp, void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
struct net_bridge_port_group *pg, struct net_bridge_port_group *pg,
struct net_bridge_port_group __rcu **pp); struct net_bridge_port_group __rcu **pp);
void br_multicast_count(struct net_bridge *br, const struct net_bridge_port *p, void br_multicast_count(struct net_bridge *br,
const struct net_bridge_port *p,
const struct sk_buff *skb, u8 type, u8 dir); const struct sk_buff *skb, u8 type, u8 dir);
int br_multicast_init_stats(struct net_bridge *br); int br_multicast_init_stats(struct net_bridge *br);
void br_multicast_uninit_stats(struct net_bridge *br); void br_multicast_uninit_stats(struct net_bridge *br);
...@@ -890,10 +893,9 @@ static inline bool br_group_is_l2(const struct br_ip *group) ...@@ -890,10 +893,9 @@ static inline bool br_group_is_l2(const struct br_ip *group)
rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
static inline struct hlist_node * static inline struct hlist_node *
br_multicast_get_first_rport_node(struct net_bridge *br, struct sk_buff *skb) br_multicast_get_first_rport_node(struct net_bridge_mcast *brmctx,
struct sk_buff *skb)
{ {
struct net_bridge_mcast *brmctx = &br->multicast_ctx;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
if (skb->protocol == htons(ETH_P_IPV6)) if (skb->protocol == htons(ETH_P_IPV6))
return rcu_dereference(hlist_first_rcu(&brmctx->ip6_mc_router_list)); return rcu_dereference(hlist_first_rcu(&brmctx->ip6_mc_router_list));
...@@ -936,10 +938,8 @@ static inline bool br_ip6_multicast_is_router(struct net_bridge_mcast *brmctx) ...@@ -936,10 +938,8 @@ static inline bool br_ip6_multicast_is_router(struct net_bridge_mcast *brmctx)
} }
static inline bool static inline bool
br_multicast_is_router(struct net_bridge *br, struct sk_buff *skb) br_multicast_is_router(struct net_bridge_mcast *brmctx, struct sk_buff *skb)
{ {
struct net_bridge_mcast *brmctx = &br->multicast_ctx;
switch (brmctx->multicast_router) { switch (brmctx->multicast_router) {
case MDB_RTR_TYPE_PERM: case MDB_RTR_TYPE_PERM:
return true; return true;
...@@ -960,14 +960,14 @@ br_multicast_is_router(struct net_bridge *br, struct sk_buff *skb) ...@@ -960,14 +960,14 @@ br_multicast_is_router(struct net_bridge *br, struct sk_buff *skb)
} }
static inline bool static inline bool
__br_multicast_querier_exists(struct net_bridge *br, __br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
struct bridge_mcast_other_query *querier, struct bridge_mcast_other_query *querier,
const bool is_ipv6) const bool is_ipv6)
{ {
bool own_querier_enabled; bool own_querier_enabled;
if (br_opt_get(br, BROPT_MULTICAST_QUERIER)) { if (br_opt_get(brmctx->br, BROPT_MULTICAST_QUERIER)) {
if (is_ipv6 && !br_opt_get(br, BROPT_HAS_IPV6_ADDR)) if (is_ipv6 && !br_opt_get(brmctx->br, BROPT_HAS_IPV6_ADDR))
own_querier_enabled = false; own_querier_enabled = false;
else else
own_querier_enabled = true; own_querier_enabled = true;
...@@ -979,18 +979,18 @@ __br_multicast_querier_exists(struct net_bridge *br, ...@@ -979,18 +979,18 @@ __br_multicast_querier_exists(struct net_bridge *br,
(own_querier_enabled || timer_pending(&querier->timer)); (own_querier_enabled || timer_pending(&querier->timer));
} }
static inline bool br_multicast_querier_exists(struct net_bridge *br, static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
struct ethhdr *eth, struct ethhdr *eth,
const struct net_bridge_mdb_entry *mdb) const struct net_bridge_mdb_entry *mdb)
{ {
switch (eth->h_proto) { switch (eth->h_proto) {
case (htons(ETH_P_IP)): case (htons(ETH_P_IP)):
return __br_multicast_querier_exists(br, return __br_multicast_querier_exists(brmctx,
&br->multicast_ctx.ip4_other_query, false); &brmctx->ip4_other_query, false);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
case (htons(ETH_P_IPV6)): case (htons(ETH_P_IPV6)):
return __br_multicast_querier_exists(br, return __br_multicast_querier_exists(brmctx,
&br->multicast_ctx.ip6_other_query, true); &brmctx->ip6_other_query, true);
#endif #endif
default: default:
return !!mdb && br_group_is_l2(&mdb->addr); return !!mdb && br_group_is_l2(&mdb->addr);
...@@ -1011,15 +1011,16 @@ static inline bool br_multicast_is_star_g(const struct br_ip *ip) ...@@ -1011,15 +1011,16 @@ static inline bool br_multicast_is_star_g(const struct br_ip *ip)
} }
} }
static inline bool br_multicast_should_handle_mode(const struct net_bridge *br, static inline bool
__be16 proto) br_multicast_should_handle_mode(const struct net_bridge_mcast *brmctx,
__be16 proto)
{ {
switch (proto) { switch (proto) {
case htons(ETH_P_IP): case htons(ETH_P_IP):
return !!(br->multicast_ctx.multicast_igmp_version == 3); return !!(brmctx->multicast_igmp_version == 3);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
case htons(ETH_P_IPV6): case htons(ETH_P_IPV6):
return !!(br->multicast_ctx.multicast_mld_version == 2); return !!(brmctx->multicast_mld_version == 2);
#endif #endif
default: default:
return false; return false;
...@@ -1031,28 +1032,28 @@ static inline int br_multicast_igmp_type(const struct sk_buff *skb) ...@@ -1031,28 +1032,28 @@ static inline int br_multicast_igmp_type(const struct sk_buff *skb)
return BR_INPUT_SKB_CB(skb)->igmp; return BR_INPUT_SKB_CB(skb)->igmp;
} }
static inline unsigned long br_multicast_lmqt(const struct net_bridge *br) static inline unsigned long br_multicast_lmqt(const struct net_bridge_mcast *brmctx)
{ {
return br->multicast_ctx.multicast_last_member_interval * return brmctx->multicast_last_member_interval *
br->multicast_ctx.multicast_last_member_count; brmctx->multicast_last_member_count;
} }
static inline unsigned long br_multicast_gmi(const struct net_bridge *br) static inline unsigned long br_multicast_gmi(const struct net_bridge_mcast *brmctx)
{ {
/* use the RFC default of 2 for QRV */ /* use the RFC default of 2 for QRV */
return 2 * br->multicast_ctx.multicast_query_interval + return 2 * brmctx->multicast_query_interval +
br->multicast_ctx.multicast_query_response_interval; brmctx->multicast_query_response_interval;
} }
#else #else
static inline int br_multicast_rcv(struct net_bridge *br, static inline int br_multicast_rcv(struct net_bridge_mcast *brmctx,
struct net_bridge_port *port, struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb, struct sk_buff *skb,
u16 vid) u16 vid)
{ {
return 0; return 0;
} }
static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
struct sk_buff *skb, u16 vid) struct sk_buff *skb, u16 vid)
{ {
return NULL; return NULL;
...@@ -1101,17 +1102,18 @@ static inline void br_multicast_dev_del(struct net_bridge *br) ...@@ -1101,17 +1102,18 @@ static inline void br_multicast_dev_del(struct net_bridge *br)
static inline void br_multicast_flood(struct net_bridge_mdb_entry *mdst, static inline void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
struct sk_buff *skb, struct sk_buff *skb,
struct net_bridge_mcast *brmctx,
bool local_rcv, bool local_orig) bool local_rcv, bool local_orig)
{ {
} }
static inline bool br_multicast_is_router(struct net_bridge *br, static inline bool br_multicast_is_router(struct net_bridge_mcast *brmctx,
struct sk_buff *skb) struct sk_buff *skb)
{ {
return false; return false;
} }
static inline bool br_multicast_querier_exists(struct net_bridge *br, static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
struct ethhdr *eth, struct ethhdr *eth,
const struct net_bridge_mdb_entry *mdb) const struct net_bridge_mdb_entry *mdb)
{ {
......
...@@ -51,7 +51,8 @@ struct net_bridge_group_eht_set { ...@@ -51,7 +51,8 @@ struct net_bridge_group_eht_set {
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
void br_multicast_eht_clean_sets(struct net_bridge_port_group *pg); void br_multicast_eht_clean_sets(struct net_bridge_port_group *pg);
bool br_multicast_eht_handle(struct net_bridge_port_group *pg, bool br_multicast_eht_handle(const struct net_bridge_mcast *brmctx,
struct net_bridge_port_group *pg,
void *h_addr, void *h_addr,
void *srcs, void *srcs,
u32 nsrcs, u32 nsrcs,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment