xref: /openbmc/linux/net/bridge/br_mdb.c (revision 840ef8b7cc584a23c4f9d05352f4dbaf8e56e5ab)
1 #include <linux/err.h>
2 #include <linux/igmp.h>
3 #include <linux/kernel.h>
4 #include <linux/netdevice.h>
5 #include <linux/rculist.h>
6 #include <linux/skbuff.h>
7 #include <linux/if_ether.h>
8 #include <net/ip.h>
9 #include <net/netlink.h>
10 #if IS_ENABLED(CONFIG_IPV6)
11 #include <net/ipv6.h>
12 #endif
13 
14 #include "br_private.h"
15 
16 static int br_rports_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
17 			       struct net_device *dev)
18 {
19 	struct net_bridge *br = netdev_priv(dev);
20 	struct net_bridge_port *p;
21 	struct nlattr *nest;
22 
23 	if (!br->multicast_router || hlist_empty(&br->router_list))
24 		return 0;
25 
26 	nest = nla_nest_start(skb, MDBA_ROUTER);
27 	if (nest == NULL)
28 		return -EMSGSIZE;
29 
30 	hlist_for_each_entry_rcu(p, &br->router_list, rlist) {
31 		if (p && nla_put_u32(skb, MDBA_ROUTER_PORT, p->dev->ifindex))
32 			goto fail;
33 	}
34 
35 	nla_nest_end(skb, nest);
36 	return 0;
37 fail:
38 	nla_nest_cancel(skb, nest);
39 	return -EMSGSIZE;
40 }
41 
42 static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
43 			    struct net_device *dev)
44 {
45 	struct net_bridge *br = netdev_priv(dev);
46 	struct net_bridge_mdb_htable *mdb;
47 	struct nlattr *nest, *nest2;
48 	int i, err = 0;
49 	int idx = 0, s_idx = cb->args[1];
50 
51 	if (br->multicast_disabled)
52 		return 0;
53 
54 	mdb = rcu_dereference(br->mdb);
55 	if (!mdb)
56 		return 0;
57 
58 	nest = nla_nest_start(skb, MDBA_MDB);
59 	if (nest == NULL)
60 		return -EMSGSIZE;
61 
62 	for (i = 0; i < mdb->max; i++) {
63 		struct net_bridge_mdb_entry *mp;
64 		struct net_bridge_port_group *p, **pp;
65 		struct net_bridge_port *port;
66 
67 		hlist_for_each_entry_rcu(mp, &mdb->mhash[i], hlist[mdb->ver]) {
68 			if (idx < s_idx)
69 				goto skip;
70 
71 			nest2 = nla_nest_start(skb, MDBA_MDB_ENTRY);
72 			if (nest2 == NULL) {
73 				err = -EMSGSIZE;
74 				goto out;
75 			}
76 
77 			for (pp = &mp->ports;
78 			     (p = rcu_dereference(*pp)) != NULL;
79 			      pp = &p->next) {
80 				port = p->port;
81 				if (port) {
82 					struct br_mdb_entry e;
83 					e.ifindex = port->dev->ifindex;
84 					e.state = p->state;
85 					if (p->addr.proto == htons(ETH_P_IP))
86 						e.addr.u.ip4 = p->addr.u.ip4;
87 #if IS_ENABLED(CONFIG_IPV6)
88 					if (p->addr.proto == htons(ETH_P_IPV6))
89 						e.addr.u.ip6 = p->addr.u.ip6;
90 #endif
91 					e.addr.proto = p->addr.proto;
92 					if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) {
93 						nla_nest_cancel(skb, nest2);
94 						err = -EMSGSIZE;
95 						goto out;
96 					}
97 				}
98 			}
99 			nla_nest_end(skb, nest2);
100 		skip:
101 			idx++;
102 		}
103 	}
104 
105 out:
106 	cb->args[1] = idx;
107 	nla_nest_end(skb, nest);
108 	return err;
109 }
110 
111 static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
112 {
113 	struct net_device *dev;
114 	struct net *net = sock_net(skb->sk);
115 	struct nlmsghdr *nlh = NULL;
116 	int idx = 0, s_idx;
117 
118 	s_idx = cb->args[0];
119 
120 	rcu_read_lock();
121 
122 	/* In theory this could be wrapped to 0... */
123 	cb->seq = net->dev_base_seq + br_mdb_rehash_seq;
124 
125 	for_each_netdev_rcu(net, dev) {
126 		if (dev->priv_flags & IFF_EBRIDGE) {
127 			struct br_port_msg *bpm;
128 
129 			if (idx < s_idx)
130 				goto skip;
131 
132 			nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid,
133 					cb->nlh->nlmsg_seq, RTM_GETMDB,
134 					sizeof(*bpm), NLM_F_MULTI);
135 			if (nlh == NULL)
136 				break;
137 
138 			bpm = nlmsg_data(nlh);
139 			bpm->ifindex = dev->ifindex;
140 			if (br_mdb_fill_info(skb, cb, dev) < 0)
141 				goto out;
142 			if (br_rports_fill_info(skb, cb, dev) < 0)
143 				goto out;
144 
145 			cb->args[1] = 0;
146 			nlmsg_end(skb, nlh);
147 		skip:
148 			idx++;
149 		}
150 	}
151 
152 out:
153 	if (nlh)
154 		nlmsg_end(skb, nlh);
155 	rcu_read_unlock();
156 	cb->args[0] = idx;
157 	return skb->len;
158 }
159 
160 static int nlmsg_populate_mdb_fill(struct sk_buff *skb,
161 				   struct net_device *dev,
162 				   struct br_mdb_entry *entry, u32 pid,
163 				   u32 seq, int type, unsigned int flags)
164 {
165 	struct nlmsghdr *nlh;
166 	struct br_port_msg *bpm;
167 	struct nlattr *nest, *nest2;
168 
169 	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), NLM_F_MULTI);
170 	if (!nlh)
171 		return -EMSGSIZE;
172 
173 	bpm = nlmsg_data(nlh);
174 	bpm->family  = AF_BRIDGE;
175 	bpm->ifindex = dev->ifindex;
176 	nest = nla_nest_start(skb, MDBA_MDB);
177 	if (nest == NULL)
178 		goto cancel;
179 	nest2 = nla_nest_start(skb, MDBA_MDB_ENTRY);
180 	if (nest2 == NULL)
181 		goto end;
182 
183 	if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(*entry), entry))
184 		goto end;
185 
186 	nla_nest_end(skb, nest2);
187 	nla_nest_end(skb, nest);
188 	return nlmsg_end(skb, nlh);
189 
190 end:
191 	nla_nest_end(skb, nest);
192 cancel:
193 	nlmsg_cancel(skb, nlh);
194 	return -EMSGSIZE;
195 }
196 
197 static inline size_t rtnl_mdb_nlmsg_size(void)
198 {
199 	return NLMSG_ALIGN(sizeof(struct br_port_msg))
200 		+ nla_total_size(sizeof(struct br_mdb_entry));
201 }
202 
203 static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry,
204 			    int type)
205 {
206 	struct net *net = dev_net(dev);
207 	struct sk_buff *skb;
208 	int err = -ENOBUFS;
209 
210 	skb = nlmsg_new(rtnl_mdb_nlmsg_size(), GFP_ATOMIC);
211 	if (!skb)
212 		goto errout;
213 
214 	err = nlmsg_populate_mdb_fill(skb, dev, entry, 0, 0, type, NTF_SELF);
215 	if (err < 0) {
216 		kfree_skb(skb);
217 		goto errout;
218 	}
219 
220 	rtnl_notify(skb, net, 0, RTNLGRP_MDB, NULL, GFP_ATOMIC);
221 	return;
222 errout:
223 	rtnl_set_sk_err(net, RTNLGRP_MDB, err);
224 }
225 
226 void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
227 		   struct br_ip *group, int type)
228 {
229 	struct br_mdb_entry entry;
230 
231 	entry.ifindex = port->dev->ifindex;
232 	entry.addr.proto = group->proto;
233 	entry.addr.u.ip4 = group->u.ip4;
234 #if IS_ENABLED(CONFIG_IPV6)
235 	entry.addr.u.ip6 = group->u.ip6;
236 #endif
237 	__br_mdb_notify(dev, &entry, type);
238 }
239 
240 static bool is_valid_mdb_entry(struct br_mdb_entry *entry)
241 {
242 	if (entry->ifindex == 0)
243 		return false;
244 
245 	if (entry->addr.proto == htons(ETH_P_IP)) {
246 		if (!ipv4_is_multicast(entry->addr.u.ip4))
247 			return false;
248 		if (ipv4_is_local_multicast(entry->addr.u.ip4))
249 			return false;
250 #if IS_ENABLED(CONFIG_IPV6)
251 	} else if (entry->addr.proto == htons(ETH_P_IPV6)) {
252 		if (!ipv6_is_transient_multicast(&entry->addr.u.ip6))
253 			return false;
254 #endif
255 	} else
256 		return false;
257 	if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY)
258 		return false;
259 
260 	return true;
261 }
262 
263 static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
264 			struct net_device **pdev, struct br_mdb_entry **pentry)
265 {
266 	struct net *net = sock_net(skb->sk);
267 	struct br_mdb_entry *entry;
268 	struct br_port_msg *bpm;
269 	struct nlattr *tb[MDBA_SET_ENTRY_MAX+1];
270 	struct net_device *dev;
271 	int err;
272 
273 	err = nlmsg_parse(nlh, sizeof(*bpm), tb, MDBA_SET_ENTRY, NULL);
274 	if (err < 0)
275 		return err;
276 
277 	bpm = nlmsg_data(nlh);
278 	if (bpm->ifindex == 0) {
279 		pr_info("PF_BRIDGE: br_mdb_parse() with invalid ifindex\n");
280 		return -EINVAL;
281 	}
282 
283 	dev = __dev_get_by_index(net, bpm->ifindex);
284 	if (dev == NULL) {
285 		pr_info("PF_BRIDGE: br_mdb_parse() with unknown ifindex\n");
286 		return -ENODEV;
287 	}
288 
289 	if (!(dev->priv_flags & IFF_EBRIDGE)) {
290 		pr_info("PF_BRIDGE: br_mdb_parse() with non-bridge\n");
291 		return -EOPNOTSUPP;
292 	}
293 
294 	*pdev = dev;
295 
296 	if (!tb[MDBA_SET_ENTRY] ||
297 	    nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) {
298 		pr_info("PF_BRIDGE: br_mdb_parse() with invalid attr\n");
299 		return -EINVAL;
300 	}
301 
302 	entry = nla_data(tb[MDBA_SET_ENTRY]);
303 	if (!is_valid_mdb_entry(entry)) {
304 		pr_info("PF_BRIDGE: br_mdb_parse() with invalid entry\n");
305 		return -EINVAL;
306 	}
307 
308 	*pentry = entry;
309 	return 0;
310 }
311 
312 static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
313 			    struct br_ip *group, unsigned char state)
314 {
315 	struct net_bridge_mdb_entry *mp;
316 	struct net_bridge_port_group *p;
317 	struct net_bridge_port_group __rcu **pp;
318 	struct net_bridge_mdb_htable *mdb;
319 	int err;
320 
321 	mdb = mlock_dereference(br->mdb, br);
322 	mp = br_mdb_ip_get(mdb, group);
323 	if (!mp) {
324 		mp = br_multicast_new_group(br, port, group);
325 		err = PTR_ERR(mp);
326 		if (IS_ERR(mp))
327 			return err;
328 	}
329 
330 	for (pp = &mp->ports;
331 	     (p = mlock_dereference(*pp, br)) != NULL;
332 	     pp = &p->next) {
333 		if (p->port == port)
334 			return -EEXIST;
335 		if ((unsigned long)p->port < (unsigned long)port)
336 			break;
337 	}
338 
339 	p = br_multicast_new_port_group(port, group, *pp, state);
340 	if (unlikely(!p))
341 		return -ENOMEM;
342 	rcu_assign_pointer(*pp, p);
343 
344 	br_mdb_notify(br->dev, port, group, RTM_NEWMDB);
345 	return 0;
346 }
347 
348 static int __br_mdb_add(struct net *net, struct net_bridge *br,
349 			struct br_mdb_entry *entry)
350 {
351 	struct br_ip ip;
352 	struct net_device *dev;
353 	struct net_bridge_port *p;
354 	int ret;
355 
356 	if (!netif_running(br->dev) || br->multicast_disabled)
357 		return -EINVAL;
358 
359 	dev = __dev_get_by_index(net, entry->ifindex);
360 	if (!dev)
361 		return -ENODEV;
362 
363 	p = br_port_get_rtnl(dev);
364 	if (!p || p->br != br || p->state == BR_STATE_DISABLED)
365 		return -EINVAL;
366 
367 	ip.proto = entry->addr.proto;
368 	if (ip.proto == htons(ETH_P_IP))
369 		ip.u.ip4 = entry->addr.u.ip4;
370 #if IS_ENABLED(CONFIG_IPV6)
371 	else
372 		ip.u.ip6 = entry->addr.u.ip6;
373 #endif
374 
375 	spin_lock_bh(&br->multicast_lock);
376 	ret = br_mdb_add_group(br, p, &ip, entry->state);
377 	spin_unlock_bh(&br->multicast_lock);
378 	return ret;
379 }
380 
381 static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
382 {
383 	struct net *net = sock_net(skb->sk);
384 	struct br_mdb_entry *entry;
385 	struct net_device *dev;
386 	struct net_bridge *br;
387 	int err;
388 
389 	err = br_mdb_parse(skb, nlh, &dev, &entry);
390 	if (err < 0)
391 		return err;
392 
393 	br = netdev_priv(dev);
394 
395 	err = __br_mdb_add(net, br, entry);
396 	if (!err)
397 		__br_mdb_notify(dev, entry, RTM_NEWMDB);
398 	return err;
399 }
400 
401 static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
402 {
403 	struct net_bridge_mdb_htable *mdb;
404 	struct net_bridge_mdb_entry *mp;
405 	struct net_bridge_port_group *p;
406 	struct net_bridge_port_group __rcu **pp;
407 	struct br_ip ip;
408 	int err = -EINVAL;
409 
410 	if (!netif_running(br->dev) || br->multicast_disabled)
411 		return -EINVAL;
412 
413 	if (timer_pending(&br->multicast_querier_timer))
414 		return -EBUSY;
415 
416 	ip.proto = entry->addr.proto;
417 	if (ip.proto == htons(ETH_P_IP))
418 		ip.u.ip4 = entry->addr.u.ip4;
419 #if IS_ENABLED(CONFIG_IPV6)
420 	else
421 		ip.u.ip6 = entry->addr.u.ip6;
422 #endif
423 
424 	spin_lock_bh(&br->multicast_lock);
425 	mdb = mlock_dereference(br->mdb, br);
426 
427 	mp = br_mdb_ip_get(mdb, &ip);
428 	if (!mp)
429 		goto unlock;
430 
431 	for (pp = &mp->ports;
432 	     (p = mlock_dereference(*pp, br)) != NULL;
433 	     pp = &p->next) {
434 		if (!p->port || p->port->dev->ifindex != entry->ifindex)
435 			continue;
436 
437 		if (p->port->state == BR_STATE_DISABLED)
438 			goto unlock;
439 
440 		rcu_assign_pointer(*pp, p->next);
441 		hlist_del_init(&p->mglist);
442 		del_timer(&p->timer);
443 		call_rcu_bh(&p->rcu, br_multicast_free_pg);
444 		err = 0;
445 
446 		if (!mp->ports && !mp->mglist &&
447 		    netif_running(br->dev))
448 			mod_timer(&mp->timer, jiffies);
449 		break;
450 	}
451 
452 unlock:
453 	spin_unlock_bh(&br->multicast_lock);
454 	return err;
455 }
456 
457 static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
458 {
459 	struct net_device *dev;
460 	struct br_mdb_entry *entry;
461 	struct net_bridge *br;
462 	int err;
463 
464 	err = br_mdb_parse(skb, nlh, &dev, &entry);
465 	if (err < 0)
466 		return err;
467 
468 	br = netdev_priv(dev);
469 
470 	err = __br_mdb_del(br, entry);
471 	if (!err)
472 		__br_mdb_notify(dev, entry, RTM_DELMDB);
473 	return err;
474 }
475 
476 void br_mdb_init(void)
477 {
478 	rtnl_register(PF_BRIDGE, RTM_GETMDB, NULL, br_mdb_dump, NULL);
479 	rtnl_register(PF_BRIDGE, RTM_NEWMDB, br_mdb_add, NULL, NULL);
480 	rtnl_register(PF_BRIDGE, RTM_DELMDB, br_mdb_del, NULL, NULL);
481 }
482 
483 void br_mdb_uninit(void)
484 {
485 	rtnl_unregister(PF_BRIDGE, RTM_GETMDB);
486 	rtnl_unregister(PF_BRIDGE, RTM_NEWMDB);
487 	rtnl_unregister(PF_BRIDGE, RTM_DELMDB);
488 }
489