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