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