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