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