1/*
2 * net/tipc/bearer.c: TIPC bearer code
3 *
4 * Copyright (c) 1996-2006, 2013-2014, Ericsson AB
5 * Copyright (c) 2004-2006, 2010-2013, Wind River Systems
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its
17 *    contributors may be used to endorse or promote products derived from
18 *    this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include <net/sock.h>
38#include "core.h"
39#include "bearer.h"
40#include "link.h"
41#include "discover.h"
42#include "bcast.h"
43
44#define MAX_ADDR_STR 60
45
46static struct tipc_media * const media_info_array[] = {
47	&eth_media_info,
48#ifdef CONFIG_TIPC_MEDIA_IB
49	&ib_media_info,
50#endif
51#ifdef CONFIG_TIPC_MEDIA_UDP
52	&udp_media_info,
53#endif
54	NULL
55};
56
57static const struct nla_policy
58tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1]	= {
59	[TIPC_NLA_BEARER_UNSPEC]		= { .type = NLA_UNSPEC },
60	[TIPC_NLA_BEARER_NAME] = {
61		.type = NLA_STRING,
62		.len = TIPC_MAX_BEARER_NAME
63	},
64	[TIPC_NLA_BEARER_PROP]			= { .type = NLA_NESTED },
65	[TIPC_NLA_BEARER_DOMAIN]		= { .type = NLA_U32 }
66};
67
68static const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = {
69	[TIPC_NLA_MEDIA_UNSPEC]		= { .type = NLA_UNSPEC },
70	[TIPC_NLA_MEDIA_NAME]		= { .type = NLA_STRING },
71	[TIPC_NLA_MEDIA_PROP]		= { .type = NLA_NESTED }
72};
73
74static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr,
75			   bool shutting_down);
76
77/**
78 * tipc_media_find - locates specified media object by name
79 */
80struct tipc_media *tipc_media_find(const char *name)
81{
82	u32 i;
83
84	for (i = 0; media_info_array[i] != NULL; i++) {
85		if (!strcmp(media_info_array[i]->name, name))
86			break;
87	}
88	return media_info_array[i];
89}
90
91/**
92 * media_find_id - locates specified media object by type identifier
93 */
94static struct tipc_media *media_find_id(u8 type)
95{
96	u32 i;
97
98	for (i = 0; media_info_array[i] != NULL; i++) {
99		if (media_info_array[i]->type_id == type)
100			break;
101	}
102	return media_info_array[i];
103}
104
105/**
106 * tipc_media_addr_printf - record media address in print buffer
107 */
108void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a)
109{
110	char addr_str[MAX_ADDR_STR];
111	struct tipc_media *m_ptr;
112	int ret;
113
114	m_ptr = media_find_id(a->media_id);
115
116	if (m_ptr && !m_ptr->addr2str(a, addr_str, sizeof(addr_str)))
117		ret = scnprintf(buf, len, "%s(%s)", m_ptr->name, addr_str);
118	else {
119		u32 i;
120
121		ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id);
122		for (i = 0; i < sizeof(a->value); i++)
123			ret += scnprintf(buf - ret, len + ret,
124					    "-%02x", a->value[i]);
125	}
126}
127
128/**
129 * bearer_name_validate - validate & (optionally) deconstruct bearer name
130 * @name: ptr to bearer name string
131 * @name_parts: ptr to area for bearer name components (or NULL if not needed)
132 *
133 * Returns 1 if bearer name is valid, otherwise 0.
134 */
135static int bearer_name_validate(const char *name,
136				struct tipc_bearer_names *name_parts)
137{
138	char name_copy[TIPC_MAX_BEARER_NAME];
139	char *media_name;
140	char *if_name;
141	u32 media_len;
142	u32 if_len;
143
144	/* copy bearer name & ensure length is OK */
145	name_copy[TIPC_MAX_BEARER_NAME - 1] = 0;
146	/* need above in case non-Posix strncpy() doesn't pad with nulls */
147	strncpy(name_copy, name, TIPC_MAX_BEARER_NAME);
148	if (name_copy[TIPC_MAX_BEARER_NAME - 1] != 0)
149		return 0;
150
151	/* ensure all component parts of bearer name are present */
152	media_name = name_copy;
153	if_name = strchr(media_name, ':');
154	if (if_name == NULL)
155		return 0;
156	*(if_name++) = 0;
157	media_len = if_name - media_name;
158	if_len = strlen(if_name) + 1;
159
160	/* validate component parts of bearer name */
161	if ((media_len <= 1) || (media_len > TIPC_MAX_MEDIA_NAME) ||
162	    (if_len <= 1) || (if_len > TIPC_MAX_IF_NAME))
163		return 0;
164
165	/* return bearer name components, if necessary */
166	if (name_parts) {
167		strcpy(name_parts->media_name, media_name);
168		strcpy(name_parts->if_name, if_name);
169	}
170	return 1;
171}
172
173/**
174 * tipc_bearer_find - locates bearer object with matching bearer name
175 */
176struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name)
177{
178	struct tipc_net *tn = net_generic(net, tipc_net_id);
179	struct tipc_bearer *b_ptr;
180	u32 i;
181
182	for (i = 0; i < MAX_BEARERS; i++) {
183		b_ptr = rtnl_dereference(tn->bearer_list[i]);
184		if (b_ptr && (!strcmp(b_ptr->name, name)))
185			return b_ptr;
186	}
187	return NULL;
188}
189
190void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest)
191{
192	struct tipc_net *tn = net_generic(net, tipc_net_id);
193	struct tipc_bearer *b_ptr;
194
195	rcu_read_lock();
196	b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
197	if (b_ptr) {
198		tipc_bcbearer_sort(net, &b_ptr->nodes, dest, true);
199		tipc_disc_add_dest(b_ptr->link_req);
200	}
201	rcu_read_unlock();
202}
203
204void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
205{
206	struct tipc_net *tn = net_generic(net, tipc_net_id);
207	struct tipc_bearer *b_ptr;
208
209	rcu_read_lock();
210	b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
211	if (b_ptr) {
212		tipc_bcbearer_sort(net, &b_ptr->nodes, dest, false);
213		tipc_disc_remove_dest(b_ptr->link_req);
214	}
215	rcu_read_unlock();
216}
217
218/**
219 * tipc_enable_bearer - enable bearer with the given name
220 */
221static int tipc_enable_bearer(struct net *net, const char *name,
222			      u32 disc_domain, u32 priority,
223			      struct nlattr *attr[])
224{
225	struct tipc_net *tn = net_generic(net, tipc_net_id);
226	struct tipc_bearer *b_ptr;
227	struct tipc_media *m_ptr;
228	struct tipc_bearer_names b_names;
229	char addr_string[16];
230	u32 bearer_id;
231	u32 with_this_prio;
232	u32 i;
233	int res = -EINVAL;
234
235	if (!tn->own_addr) {
236		pr_warn("Bearer <%s> rejected, not supported in standalone mode\n",
237			name);
238		return -ENOPROTOOPT;
239	}
240	if (!bearer_name_validate(name, &b_names)) {
241		pr_warn("Bearer <%s> rejected, illegal name\n", name);
242		return -EINVAL;
243	}
244	if (tipc_addr_domain_valid(disc_domain) &&
245	    (disc_domain != tn->own_addr)) {
246		if (tipc_in_scope(disc_domain, tn->own_addr)) {
247			disc_domain = tn->own_addr & TIPC_CLUSTER_MASK;
248			res = 0;   /* accept any node in own cluster */
249		} else if (in_own_cluster_exact(net, disc_domain))
250			res = 0;   /* accept specified node in own cluster */
251	}
252	if (res) {
253		pr_warn("Bearer <%s> rejected, illegal discovery domain\n",
254			name);
255		return -EINVAL;
256	}
257	if ((priority > TIPC_MAX_LINK_PRI) &&
258	    (priority != TIPC_MEDIA_LINK_PRI)) {
259		pr_warn("Bearer <%s> rejected, illegal priority\n", name);
260		return -EINVAL;
261	}
262
263	m_ptr = tipc_media_find(b_names.media_name);
264	if (!m_ptr) {
265		pr_warn("Bearer <%s> rejected, media <%s> not registered\n",
266			name, b_names.media_name);
267		return -EINVAL;
268	}
269
270	if (priority == TIPC_MEDIA_LINK_PRI)
271		priority = m_ptr->priority;
272
273restart:
274	bearer_id = MAX_BEARERS;
275	with_this_prio = 1;
276	for (i = MAX_BEARERS; i-- != 0; ) {
277		b_ptr = rtnl_dereference(tn->bearer_list[i]);
278		if (!b_ptr) {
279			bearer_id = i;
280			continue;
281		}
282		if (!strcmp(name, b_ptr->name)) {
283			pr_warn("Bearer <%s> rejected, already enabled\n",
284				name);
285			return -EINVAL;
286		}
287		if ((b_ptr->priority == priority) &&
288		    (++with_this_prio > 2)) {
289			if (priority-- == 0) {
290				pr_warn("Bearer <%s> rejected, duplicate priority\n",
291					name);
292				return -EINVAL;
293			}
294			pr_warn("Bearer <%s> priority adjustment required %u->%u\n",
295				name, priority + 1, priority);
296			goto restart;
297		}
298	}
299	if (bearer_id >= MAX_BEARERS) {
300		pr_warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
301			name, MAX_BEARERS);
302		return -EINVAL;
303	}
304
305	b_ptr = kzalloc(sizeof(*b_ptr), GFP_ATOMIC);
306	if (!b_ptr)
307		return -ENOMEM;
308
309	strcpy(b_ptr->name, name);
310	b_ptr->media = m_ptr;
311	res = m_ptr->enable_media(net, b_ptr, attr);
312	if (res) {
313		pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
314			name, -res);
315		return -EINVAL;
316	}
317
318	b_ptr->identity = bearer_id;
319	b_ptr->tolerance = m_ptr->tolerance;
320	b_ptr->window = m_ptr->window;
321	b_ptr->domain = disc_domain;
322	b_ptr->net_plane = bearer_id + 'A';
323	b_ptr->priority = priority;
324
325	res = tipc_disc_create(net, b_ptr, &b_ptr->bcast_addr);
326	if (res) {
327		bearer_disable(net, b_ptr, false);
328		pr_warn("Bearer <%s> rejected, discovery object creation failed\n",
329			name);
330		return -EINVAL;
331	}
332
333	rcu_assign_pointer(tn->bearer_list[bearer_id], b_ptr);
334
335	pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
336		name,
337		tipc_addr_string_fill(addr_string, disc_domain), priority);
338	return res;
339}
340
341/**
342 * tipc_reset_bearer - Reset all links established over this bearer
343 */
344static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b_ptr)
345{
346	pr_info("Resetting bearer <%s>\n", b_ptr->name);
347	tipc_link_reset_list(net, b_ptr->identity);
348	tipc_disc_reset(net, b_ptr);
349	return 0;
350}
351
352/**
353 * bearer_disable
354 *
355 * Note: This routine assumes caller holds RTNL lock.
356 */
357static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr,
358			   bool shutting_down)
359{
360	struct tipc_net *tn = net_generic(net, tipc_net_id);
361	u32 i;
362
363	pr_info("Disabling bearer <%s>\n", b_ptr->name);
364	b_ptr->media->disable_media(b_ptr);
365
366	tipc_link_delete_list(net, b_ptr->identity, shutting_down);
367	if (b_ptr->link_req)
368		tipc_disc_delete(b_ptr->link_req);
369
370	for (i = 0; i < MAX_BEARERS; i++) {
371		if (b_ptr == rtnl_dereference(tn->bearer_list[i])) {
372			RCU_INIT_POINTER(tn->bearer_list[i], NULL);
373			break;
374		}
375	}
376	kfree_rcu(b_ptr, rcu);
377}
378
379int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
380			 struct nlattr *attr[])
381{
382	struct net_device *dev;
383	char *driver_name = strchr((const char *)b->name, ':') + 1;
384
385	/* Find device with specified name */
386	dev = dev_get_by_name(net, driver_name);
387	if (!dev)
388		return -ENODEV;
389
390	/* Associate TIPC bearer with L2 bearer */
391	rcu_assign_pointer(b->media_ptr, dev);
392	memset(&b->bcast_addr, 0, sizeof(b->bcast_addr));
393	memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len);
394	b->bcast_addr.media_id = b->media->type_id;
395	b->bcast_addr.broadcast = 1;
396	b->mtu = dev->mtu;
397	b->media->raw2addr(b, &b->addr, (char *)dev->dev_addr);
398	rcu_assign_pointer(dev->tipc_ptr, b);
399	return 0;
400}
401
402/* tipc_disable_l2_media - detach TIPC bearer from an L2 interface
403 *
404 * Mark L2 bearer as inactive so that incoming buffers are thrown away,
405 * then get worker thread to complete bearer cleanup.  (Can't do cleanup
406 * here because cleanup code needs to sleep and caller holds spinlocks.)
407 */
408void tipc_disable_l2_media(struct tipc_bearer *b)
409{
410	struct net_device *dev;
411
412	dev = (struct net_device *)rtnl_dereference(b->media_ptr);
413	RCU_INIT_POINTER(b->media_ptr, NULL);
414	RCU_INIT_POINTER(dev->tipc_ptr, NULL);
415	synchronize_net();
416	dev_put(dev);
417}
418
419/**
420 * tipc_l2_send_msg - send a TIPC packet out over an L2 interface
421 * @buf: the packet to be sent
422 * @b_ptr: the bearer through which the packet is to be sent
423 * @dest: peer destination address
424 */
425int tipc_l2_send_msg(struct net *net, struct sk_buff *buf,
426		     struct tipc_bearer *b, struct tipc_media_addr *dest)
427{
428	struct sk_buff *clone;
429	struct net_device *dev;
430	int delta;
431
432	dev = (struct net_device *)rcu_dereference_rtnl(b->media_ptr);
433	if (!dev)
434		return 0;
435
436	clone = skb_clone(buf, GFP_ATOMIC);
437	if (!clone)
438		return 0;
439
440	delta = dev->hard_header_len - skb_headroom(buf);
441	if ((delta > 0) &&
442	    pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
443		kfree_skb(clone);
444		return 0;
445	}
446
447	skb_reset_network_header(clone);
448	clone->dev = dev;
449	clone->protocol = htons(ETH_P_TIPC);
450	dev_hard_header(clone, dev, ETH_P_TIPC, dest->value,
451			dev->dev_addr, clone->len);
452	dev_queue_xmit(clone);
453	return 0;
454}
455
456/* tipc_bearer_send- sends buffer to destination over bearer
457 *
458 * IMPORTANT:
459 * The media send routine must not alter the buffer being passed in
460 * as it may be needed for later retransmission!
461 */
462void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf,
463		      struct tipc_media_addr *dest)
464{
465	struct tipc_net *tn = net_generic(net, tipc_net_id);
466	struct tipc_bearer *b_ptr;
467
468	rcu_read_lock();
469	b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
470	if (likely(b_ptr))
471		b_ptr->media->send_msg(net, buf, b_ptr, dest);
472	rcu_read_unlock();
473}
474
475/**
476 * tipc_l2_rcv_msg - handle incoming TIPC message from an interface
477 * @buf: the received packet
478 * @dev: the net device that the packet was received on
479 * @pt: the packet_type structure which was used to register this handler
480 * @orig_dev: the original receive net device in case the device is a bond
481 *
482 * Accept only packets explicitly sent to this node, or broadcast packets;
483 * ignores packets sent using interface multicast, and traffic sent to other
484 * nodes (which can happen if interface is running in promiscuous mode).
485 */
486static int tipc_l2_rcv_msg(struct sk_buff *buf, struct net_device *dev,
487			   struct packet_type *pt, struct net_device *orig_dev)
488{
489	struct tipc_bearer *b_ptr;
490
491	rcu_read_lock();
492	b_ptr = rcu_dereference_rtnl(dev->tipc_ptr);
493	if (likely(b_ptr)) {
494		if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
495			buf->next = NULL;
496			tipc_rcv(dev_net(dev), buf, b_ptr);
497			rcu_read_unlock();
498			return NET_RX_SUCCESS;
499		}
500	}
501	rcu_read_unlock();
502
503	kfree_skb(buf);
504	return NET_RX_DROP;
505}
506
507/**
508 * tipc_l2_device_event - handle device events from network device
509 * @nb: the context of the notification
510 * @evt: the type of event
511 * @ptr: the net device that the event was on
512 *
513 * This function is called by the Ethernet driver in case of link
514 * change event.
515 */
516static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
517				void *ptr)
518{
519	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
520	struct net *net = dev_net(dev);
521	struct tipc_bearer *b_ptr;
522
523	b_ptr = rtnl_dereference(dev->tipc_ptr);
524	if (!b_ptr)
525		return NOTIFY_DONE;
526
527	b_ptr->mtu = dev->mtu;
528
529	switch (evt) {
530	case NETDEV_CHANGE:
531		if (netif_carrier_ok(dev))
532			break;
533	case NETDEV_DOWN:
534	case NETDEV_CHANGEMTU:
535		tipc_reset_bearer(net, b_ptr);
536		break;
537	case NETDEV_CHANGEADDR:
538		b_ptr->media->raw2addr(b_ptr, &b_ptr->addr,
539				       (char *)dev->dev_addr);
540		tipc_reset_bearer(net, b_ptr);
541		break;
542	case NETDEV_UNREGISTER:
543	case NETDEV_CHANGENAME:
544		bearer_disable(dev_net(dev), b_ptr, false);
545		break;
546	}
547	return NOTIFY_OK;
548}
549
550static struct packet_type tipc_packet_type __read_mostly = {
551	.type = htons(ETH_P_TIPC),
552	.func = tipc_l2_rcv_msg,
553};
554
555static struct notifier_block notifier = {
556	.notifier_call  = tipc_l2_device_event,
557	.priority	= 0,
558};
559
560int tipc_bearer_setup(void)
561{
562	int err;
563
564	err = register_netdevice_notifier(&notifier);
565	if (err)
566		return err;
567	dev_add_pack(&tipc_packet_type);
568	return 0;
569}
570
571void tipc_bearer_cleanup(void)
572{
573	unregister_netdevice_notifier(&notifier);
574	dev_remove_pack(&tipc_packet_type);
575}
576
577void tipc_bearer_stop(struct net *net)
578{
579	struct tipc_net *tn = net_generic(net, tipc_net_id);
580	struct tipc_bearer *b_ptr;
581	u32 i;
582
583	for (i = 0; i < MAX_BEARERS; i++) {
584		b_ptr = rtnl_dereference(tn->bearer_list[i]);
585		if (b_ptr) {
586			bearer_disable(net, b_ptr, true);
587			tn->bearer_list[i] = NULL;
588		}
589	}
590}
591
592/* Caller should hold rtnl_lock to protect the bearer */
593static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg,
594				struct tipc_bearer *bearer, int nlflags)
595{
596	void *hdr;
597	struct nlattr *attrs;
598	struct nlattr *prop;
599
600	hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
601			  nlflags, TIPC_NL_BEARER_GET);
602	if (!hdr)
603		return -EMSGSIZE;
604
605	attrs = nla_nest_start(msg->skb, TIPC_NLA_BEARER);
606	if (!attrs)
607		goto msg_full;
608
609	if (nla_put_string(msg->skb, TIPC_NLA_BEARER_NAME, bearer->name))
610		goto attr_msg_full;
611
612	prop = nla_nest_start(msg->skb, TIPC_NLA_BEARER_PROP);
613	if (!prop)
614		goto prop_msg_full;
615	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, bearer->priority))
616		goto prop_msg_full;
617	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, bearer->tolerance))
618		goto prop_msg_full;
619	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bearer->window))
620		goto prop_msg_full;
621
622	nla_nest_end(msg->skb, prop);
623	nla_nest_end(msg->skb, attrs);
624	genlmsg_end(msg->skb, hdr);
625
626	return 0;
627
628prop_msg_full:
629	nla_nest_cancel(msg->skb, prop);
630attr_msg_full:
631	nla_nest_cancel(msg->skb, attrs);
632msg_full:
633	genlmsg_cancel(msg->skb, hdr);
634
635	return -EMSGSIZE;
636}
637
638int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb)
639{
640	int err;
641	int i = cb->args[0];
642	struct tipc_bearer *bearer;
643	struct tipc_nl_msg msg;
644	struct net *net = sock_net(skb->sk);
645	struct tipc_net *tn = net_generic(net, tipc_net_id);
646
647	if (i == MAX_BEARERS)
648		return 0;
649
650	msg.skb = skb;
651	msg.portid = NETLINK_CB(cb->skb).portid;
652	msg.seq = cb->nlh->nlmsg_seq;
653
654	rtnl_lock();
655	for (i = 0; i < MAX_BEARERS; i++) {
656		bearer = rtnl_dereference(tn->bearer_list[i]);
657		if (!bearer)
658			continue;
659
660		err = __tipc_nl_add_bearer(&msg, bearer, NLM_F_MULTI);
661		if (err)
662			break;
663	}
664	rtnl_unlock();
665
666	cb->args[0] = i;
667	return skb->len;
668}
669
670int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
671{
672	int err;
673	char *name;
674	struct sk_buff *rep;
675	struct tipc_bearer *bearer;
676	struct tipc_nl_msg msg;
677	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
678	struct net *net = genl_info_net(info);
679
680	if (!info->attrs[TIPC_NLA_BEARER])
681		return -EINVAL;
682
683	err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
684			       info->attrs[TIPC_NLA_BEARER],
685			       tipc_nl_bearer_policy);
686	if (err)
687		return err;
688
689	if (!attrs[TIPC_NLA_BEARER_NAME])
690		return -EINVAL;
691	name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
692
693	rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
694	if (!rep)
695		return -ENOMEM;
696
697	msg.skb = rep;
698	msg.portid = info->snd_portid;
699	msg.seq = info->snd_seq;
700
701	rtnl_lock();
702	bearer = tipc_bearer_find(net, name);
703	if (!bearer) {
704		err = -EINVAL;
705		goto err_out;
706	}
707
708	err = __tipc_nl_add_bearer(&msg, bearer, 0);
709	if (err)
710		goto err_out;
711	rtnl_unlock();
712
713	return genlmsg_reply(rep, info);
714err_out:
715	rtnl_unlock();
716	nlmsg_free(rep);
717
718	return err;
719}
720
721int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
722{
723	int err;
724	char *name;
725	struct tipc_bearer *bearer;
726	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
727	struct net *net = sock_net(skb->sk);
728
729	if (!info->attrs[TIPC_NLA_BEARER])
730		return -EINVAL;
731
732	err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
733			       info->attrs[TIPC_NLA_BEARER],
734			       tipc_nl_bearer_policy);
735	if (err)
736		return err;
737
738	if (!attrs[TIPC_NLA_BEARER_NAME])
739		return -EINVAL;
740
741	name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
742
743	rtnl_lock();
744	bearer = tipc_bearer_find(net, name);
745	if (!bearer) {
746		rtnl_unlock();
747		return -EINVAL;
748	}
749
750	bearer_disable(net, bearer, false);
751	rtnl_unlock();
752
753	return 0;
754}
755
756int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
757{
758	int err;
759	char *bearer;
760	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
761	struct net *net = sock_net(skb->sk);
762	struct tipc_net *tn = net_generic(net, tipc_net_id);
763	u32 domain;
764	u32 prio;
765
766	prio = TIPC_MEDIA_LINK_PRI;
767	domain = tn->own_addr & TIPC_CLUSTER_MASK;
768
769	if (!info->attrs[TIPC_NLA_BEARER])
770		return -EINVAL;
771
772	err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
773			       info->attrs[TIPC_NLA_BEARER],
774			       tipc_nl_bearer_policy);
775	if (err)
776		return err;
777
778	if (!attrs[TIPC_NLA_BEARER_NAME])
779		return -EINVAL;
780
781	bearer = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
782
783	if (attrs[TIPC_NLA_BEARER_DOMAIN])
784		domain = nla_get_u32(attrs[TIPC_NLA_BEARER_DOMAIN]);
785
786	if (attrs[TIPC_NLA_BEARER_PROP]) {
787		struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
788
789		err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP],
790					      props);
791		if (err)
792			return err;
793
794		if (props[TIPC_NLA_PROP_PRIO])
795			prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
796	}
797
798	rtnl_lock();
799	err = tipc_enable_bearer(net, bearer, domain, prio, attrs);
800	if (err) {
801		rtnl_unlock();
802		return err;
803	}
804	rtnl_unlock();
805
806	return 0;
807}
808
809int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
810{
811	int err;
812	char *name;
813	struct tipc_bearer *b;
814	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
815	struct net *net = genl_info_net(info);
816
817	if (!info->attrs[TIPC_NLA_BEARER])
818		return -EINVAL;
819
820	err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
821			       info->attrs[TIPC_NLA_BEARER],
822			       tipc_nl_bearer_policy);
823	if (err)
824		return err;
825
826	if (!attrs[TIPC_NLA_BEARER_NAME])
827		return -EINVAL;
828	name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
829
830	rtnl_lock();
831	b = tipc_bearer_find(net, name);
832	if (!b) {
833		rtnl_unlock();
834		return -EINVAL;
835	}
836
837	if (attrs[TIPC_NLA_BEARER_PROP]) {
838		struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
839
840		err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP],
841					      props);
842		if (err) {
843			rtnl_unlock();
844			return err;
845		}
846
847		if (props[TIPC_NLA_PROP_TOL])
848			b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
849		if (props[TIPC_NLA_PROP_PRIO])
850			b->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
851		if (props[TIPC_NLA_PROP_WIN])
852			b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
853	}
854	rtnl_unlock();
855
856	return 0;
857}
858
859static int __tipc_nl_add_media(struct tipc_nl_msg *msg,
860			       struct tipc_media *media, int nlflags)
861{
862	void *hdr;
863	struct nlattr *attrs;
864	struct nlattr *prop;
865
866	hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
867			  nlflags, TIPC_NL_MEDIA_GET);
868	if (!hdr)
869		return -EMSGSIZE;
870
871	attrs = nla_nest_start(msg->skb, TIPC_NLA_MEDIA);
872	if (!attrs)
873		goto msg_full;
874
875	if (nla_put_string(msg->skb, TIPC_NLA_MEDIA_NAME, media->name))
876		goto attr_msg_full;
877
878	prop = nla_nest_start(msg->skb, TIPC_NLA_MEDIA_PROP);
879	if (!prop)
880		goto prop_msg_full;
881	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, media->priority))
882		goto prop_msg_full;
883	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, media->tolerance))
884		goto prop_msg_full;
885	if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, media->window))
886		goto prop_msg_full;
887
888	nla_nest_end(msg->skb, prop);
889	nla_nest_end(msg->skb, attrs);
890	genlmsg_end(msg->skb, hdr);
891
892	return 0;
893
894prop_msg_full:
895	nla_nest_cancel(msg->skb, prop);
896attr_msg_full:
897	nla_nest_cancel(msg->skb, attrs);
898msg_full:
899	genlmsg_cancel(msg->skb, hdr);
900
901	return -EMSGSIZE;
902}
903
904int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb)
905{
906	int err;
907	int i = cb->args[0];
908	struct tipc_nl_msg msg;
909
910	if (i == MAX_MEDIA)
911		return 0;
912
913	msg.skb = skb;
914	msg.portid = NETLINK_CB(cb->skb).portid;
915	msg.seq = cb->nlh->nlmsg_seq;
916
917	rtnl_lock();
918	for (; media_info_array[i] != NULL; i++) {
919		err = __tipc_nl_add_media(&msg, media_info_array[i],
920					  NLM_F_MULTI);
921		if (err)
922			break;
923	}
924	rtnl_unlock();
925
926	cb->args[0] = i;
927	return skb->len;
928}
929
930int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info)
931{
932	int err;
933	char *name;
934	struct tipc_nl_msg msg;
935	struct tipc_media *media;
936	struct sk_buff *rep;
937	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
938
939	if (!info->attrs[TIPC_NLA_MEDIA])
940		return -EINVAL;
941
942	err = nla_parse_nested(attrs, TIPC_NLA_MEDIA_MAX,
943			       info->attrs[TIPC_NLA_MEDIA],
944			       tipc_nl_media_policy);
945	if (err)
946		return err;
947
948	if (!attrs[TIPC_NLA_MEDIA_NAME])
949		return -EINVAL;
950	name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);
951
952	rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
953	if (!rep)
954		return -ENOMEM;
955
956	msg.skb = rep;
957	msg.portid = info->snd_portid;
958	msg.seq = info->snd_seq;
959
960	rtnl_lock();
961	media = tipc_media_find(name);
962	if (!media) {
963		err = -EINVAL;
964		goto err_out;
965	}
966
967	err = __tipc_nl_add_media(&msg, media, 0);
968	if (err)
969		goto err_out;
970	rtnl_unlock();
971
972	return genlmsg_reply(rep, info);
973err_out:
974	rtnl_unlock();
975	nlmsg_free(rep);
976
977	return err;
978}
979
980int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
981{
982	int err;
983	char *name;
984	struct tipc_media *m;
985	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
986
987	if (!info->attrs[TIPC_NLA_MEDIA])
988		return -EINVAL;
989
990	err = nla_parse_nested(attrs, TIPC_NLA_MEDIA_MAX,
991			       info->attrs[TIPC_NLA_MEDIA],
992			       tipc_nl_media_policy);
993
994	if (!attrs[TIPC_NLA_MEDIA_NAME])
995		return -EINVAL;
996	name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);
997
998	rtnl_lock();
999	m = tipc_media_find(name);
1000	if (!m) {
1001		rtnl_unlock();
1002		return -EINVAL;
1003	}
1004
1005	if (attrs[TIPC_NLA_MEDIA_PROP]) {
1006		struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
1007
1008		err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_MEDIA_PROP],
1009					      props);
1010		if (err) {
1011			rtnl_unlock();
1012			return err;
1013		}
1014
1015		if (props[TIPC_NLA_PROP_TOL])
1016			m->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1017		if (props[TIPC_NLA_PROP_PRIO])
1018			m->priority = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1019		if (props[TIPC_NLA_PROP_WIN])
1020			m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
1021	}
1022	rtnl_unlock();
1023
1024	return 0;
1025}
1026