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