Skip to content

Commit 949f1e3

Browse files
Satish Ashokdavem330
authored andcommitted
bridge: mdb: notify on router port add and del
Send notifications on router port add and del/expire, re-use the already existing MDBA_ROUTER and send NEWMDB/DELMDB netlink notifications respectively. Signed-off-by: Satish Ashok <[email protected]> Signed-off-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 597798e commit 949f1e3

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

net/bridge/br_mdb.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,73 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
247247
__br_mdb_notify(dev, &entry, type);
248248
}
249249

250+
static int nlmsg_populate_rtr_fill(struct sk_buff *skb,
251+
struct net_device *dev,
252+
int ifindex, u32 pid,
253+
u32 seq, int type, unsigned int flags)
254+
{
255+
struct br_port_msg *bpm;
256+
struct nlmsghdr *nlh;
257+
struct nlattr *nest;
258+
259+
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), NLM_F_MULTI);
260+
if (!nlh)
261+
return -EMSGSIZE;
262+
263+
bpm = nlmsg_data(nlh);
264+
memset(bpm, 0, sizeof(*bpm));
265+
bpm->family = AF_BRIDGE;
266+
bpm->ifindex = dev->ifindex;
267+
nest = nla_nest_start(skb, MDBA_ROUTER);
268+
if (!nest)
269+
goto cancel;
270+
271+
if (nla_put_u32(skb, MDBA_ROUTER_PORT, ifindex))
272+
goto end;
273+
274+
nla_nest_end(skb, nest);
275+
nlmsg_end(skb, nlh);
276+
return 0;
277+
278+
end:
279+
nla_nest_end(skb, nest);
280+
cancel:
281+
nlmsg_cancel(skb, nlh);
282+
return -EMSGSIZE;
283+
}
284+
285+
static inline size_t rtnl_rtr_nlmsg_size(void)
286+
{
287+
return NLMSG_ALIGN(sizeof(struct br_port_msg))
288+
+ nla_total_size(sizeof(__u32));
289+
}
290+
291+
void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port,
292+
int type)
293+
{
294+
struct net *net = dev_net(dev);
295+
struct sk_buff *skb;
296+
int err = -ENOBUFS;
297+
int ifindex;
298+
299+
ifindex = port ? port->dev->ifindex : 0;
300+
skb = nlmsg_new(rtnl_rtr_nlmsg_size(), GFP_ATOMIC);
301+
if (!skb)
302+
goto errout;
303+
304+
err = nlmsg_populate_rtr_fill(skb, dev, ifindex, 0, 0, type, NTF_SELF);
305+
if (err < 0) {
306+
kfree_skb(skb);
307+
goto errout;
308+
}
309+
310+
rtnl_notify(skb, net, 0, RTNLGRP_MDB, NULL, GFP_ATOMIC);
311+
return;
312+
313+
errout:
314+
rtnl_set_sk_err(net, RTNLGRP_MDB, err);
315+
}
316+
250317
static bool is_valid_mdb_entry(struct br_mdb_entry *entry)
251318
{
252319
if (entry->ifindex == 0)

net/bridge/br_multicast.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ static void br_multicast_router_expired(unsigned long data)
766766
goto out;
767767

768768
hlist_del_init_rcu(&port->rlist);
769+
br_rtr_notify(br->dev, port, RTM_DELMDB);
769770

770771
out:
771772
spin_unlock(&br->multicast_lock);
@@ -977,8 +978,10 @@ void br_multicast_disable_port(struct net_bridge_port *port)
977978
if (pg->state == MDB_TEMPORARY)
978979
br_multicast_del_pg(br, pg);
979980

980-
if (!hlist_unhashed(&port->rlist))
981+
if (!hlist_unhashed(&port->rlist)) {
981982
hlist_del_init_rcu(&port->rlist);
983+
br_rtr_notify(br->dev, port, RTM_DELMDB);
984+
}
982985
del_timer(&port->multicast_router_timer);
983986
del_timer(&port->ip4_own_query.timer);
984987
#if IS_ENABLED(CONFIG_IPV6)
@@ -1216,6 +1219,7 @@ static void br_multicast_add_router(struct net_bridge *br,
12161219
hlist_add_behind_rcu(&port->rlist, slot);
12171220
else
12181221
hlist_add_head_rcu(&port->rlist, &br->router_list);
1222+
br_rtr_notify(br->dev, port, RTM_NEWMDB);
12191223
}
12201224

12211225
static void br_multicast_mark_router(struct net_bridge *br,
@@ -1848,8 +1852,10 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val)
18481852
p->multicast_router = val;
18491853
err = 0;
18501854

1851-
if (val < 2 && !hlist_unhashed(&p->rlist))
1855+
if (val < 2 && !hlist_unhashed(&p->rlist)) {
18521856
hlist_del_init_rcu(&p->rlist);
1857+
br_rtr_notify(br->dev, p, RTM_DELMDB);
1858+
}
18531859

18541860
if (val == 1)
18551861
break;

net/bridge/br_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ void br_mdb_init(void);
490490
void br_mdb_uninit(void);
491491
void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
492492
struct br_ip *group, int type, u8 state);
493+
void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port,
494+
int type);
493495

494496
#define mlock_dereference(X, br) \
495497
rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))

0 commit comments

Comments
 (0)