1 /* 2 * net/tipc/bearer.c: TIPC bearer code 3 * 4 * Copyright (c) 2003-2005, Ericsson Research Canada 5 * Copyright (c) 2004-2005, Wind River Systems 6 * Copyright (c) 2005-2006, Ericsson AB 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, this 13 * list of conditions and the following disclaimer. 14 * Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * Neither the names of the copyright holders nor the names of its 18 * contributors may be used to endorse or promote products derived from this 19 * software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "core.h" 35 #include "config.h" 36 #include "dbg.h" 37 #include "bearer.h" 38 #include "link.h" 39 #include "port.h" 40 #include "discover.h" 41 #include "bcast.h" 42 43 #define MAX_ADDR_STR 32 44 45 static struct media *media_list = 0; 46 static u32 media_count = 0; 47 48 struct bearer *bearers = 0; 49 50 /** 51 * media_name_valid - validate media name 52 * 53 * Returns 1 if media name is valid, otherwise 0. 54 */ 55 56 static int media_name_valid(const char *name) 57 { 58 u32 len; 59 60 len = strlen(name); 61 if ((len + 1) > TIPC_MAX_MEDIA_NAME) 62 return 0; 63 return (strspn(name, tipc_alphabet) == len); 64 } 65 66 /** 67 * media_find - locates specified media object by name 68 */ 69 70 static struct media *media_find(const char *name) 71 { 72 struct media *m_ptr; 73 u32 i; 74 75 for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { 76 if (!strcmp(m_ptr->name, name)) 77 return m_ptr; 78 } 79 return 0; 80 } 81 82 /** 83 * tipc_register_media - register a media type 84 * 85 * Bearers for this media type must be activated separately at a later stage. 86 */ 87 88 int tipc_register_media(u32 media_type, 89 char *name, 90 int (*enable)(struct tipc_bearer *), 91 void (*disable)(struct tipc_bearer *), 92 int (*send_msg)(struct sk_buff *, 93 struct tipc_bearer *, 94 struct tipc_media_addr *), 95 char *(*addr2str)(struct tipc_media_addr *a, 96 char *str_buf, int str_size), 97 struct tipc_media_addr *bcast_addr, 98 const u32 bearer_priority, 99 const u32 link_tolerance, /* [ms] */ 100 const u32 send_window_limit) 101 { 102 struct media *m_ptr; 103 u32 media_id; 104 u32 i; 105 int res = -EINVAL; 106 107 write_lock_bh(&net_lock); 108 if (!media_list) 109 goto exit; 110 111 if (!media_name_valid(name)) { 112 warn("Media registration error: illegal name <%s>\n", name); 113 goto exit; 114 } 115 if (!bcast_addr) { 116 warn("Media registration error: no broadcast address supplied\n"); 117 goto exit; 118 } 119 if (bearer_priority >= TIPC_NUM_LINK_PRI) { 120 warn("Media registration error: priority %u\n", bearer_priority); 121 goto exit; 122 } 123 if ((link_tolerance < TIPC_MIN_LINK_TOL) || 124 (link_tolerance > TIPC_MAX_LINK_TOL)) { 125 warn("Media registration error: tolerance %u\n", link_tolerance); 126 goto exit; 127 } 128 129 media_id = media_count++; 130 if (media_id >= MAX_MEDIA) { 131 warn("Attempt to register more than %u media\n", MAX_MEDIA); 132 media_count--; 133 goto exit; 134 } 135 for (i = 0; i < media_id; i++) { 136 if (media_list[i].type_id == media_type) { 137 warn("Attempt to register second media with type %u\n", 138 media_type); 139 media_count--; 140 goto exit; 141 } 142 if (!strcmp(name, media_list[i].name)) { 143 warn("Attempt to re-register media name <%s>\n", name); 144 media_count--; 145 goto exit; 146 } 147 } 148 149 m_ptr = &media_list[media_id]; 150 m_ptr->type_id = media_type; 151 m_ptr->send_msg = send_msg; 152 m_ptr->enable_bearer = enable; 153 m_ptr->disable_bearer = disable; 154 m_ptr->addr2str = addr2str; 155 memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr)); 156 m_ptr->bcast = 1; 157 strcpy(m_ptr->name, name); 158 m_ptr->priority = bearer_priority; 159 m_ptr->tolerance = link_tolerance; 160 m_ptr->window = send_window_limit; 161 dbg("Media <%s> registered\n", name); 162 res = 0; 163 exit: 164 write_unlock_bh(&net_lock); 165 return res; 166 } 167 168 /** 169 * media_addr_printf - record media address in print buffer 170 */ 171 172 void media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) 173 { 174 struct media *m_ptr; 175 u32 media_type; 176 u32 i; 177 178 media_type = ntohl(a->type); 179 for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { 180 if (m_ptr->type_id == media_type) 181 break; 182 } 183 184 if ((i < media_count) && (m_ptr->addr2str != NULL)) { 185 char addr_str[MAX_ADDR_STR]; 186 187 tipc_printf(pb, "%s(%s) ", m_ptr->name, 188 m_ptr->addr2str(a, addr_str, sizeof(addr_str))); 189 } else { 190 unchar *addr = (unchar *)&a->dev_addr; 191 192 tipc_printf(pb, "UNKNOWN(%u):", media_type); 193 for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { 194 tipc_printf(pb, "%02x ", addr[i]); 195 } 196 } 197 } 198 199 /** 200 * media_get_names - record names of registered media in buffer 201 */ 202 203 struct sk_buff *media_get_names(void) 204 { 205 struct sk_buff *buf; 206 struct media *m_ptr; 207 int i; 208 209 buf = cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME)); 210 if (!buf) 211 return NULL; 212 213 read_lock_bh(&net_lock); 214 for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { 215 cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME, m_ptr->name, 216 strlen(m_ptr->name) + 1); 217 } 218 read_unlock_bh(&net_lock); 219 return buf; 220 } 221 222 /** 223 * bearer_name_validate - validate & (optionally) deconstruct bearer name 224 * @name - ptr to bearer name string 225 * @name_parts - ptr to area for bearer name components (or NULL if not needed) 226 * 227 * Returns 1 if bearer name is valid, otherwise 0. 228 */ 229 230 static int bearer_name_validate(const char *name, 231 struct bearer_name *name_parts) 232 { 233 char name_copy[TIPC_MAX_BEARER_NAME]; 234 char *media_name; 235 char *if_name; 236 u32 media_len; 237 u32 if_len; 238 239 /* copy bearer name & ensure length is OK */ 240 241 name_copy[TIPC_MAX_BEARER_NAME - 1] = 0; 242 /* need above in case non-Posix strncpy() doesn't pad with nulls */ 243 strncpy(name_copy, name, TIPC_MAX_BEARER_NAME); 244 if (name_copy[TIPC_MAX_BEARER_NAME - 1] != 0) 245 return 0; 246 247 /* ensure all component parts of bearer name are present */ 248 249 media_name = name_copy; 250 if ((if_name = strchr(media_name, ':')) == NULL) 251 return 0; 252 *(if_name++) = 0; 253 media_len = if_name - media_name; 254 if_len = strlen(if_name) + 1; 255 256 /* validate component parts of bearer name */ 257 258 if ((media_len <= 1) || (media_len > TIPC_MAX_MEDIA_NAME) || 259 (if_len <= 1) || (if_len > TIPC_MAX_IF_NAME) || 260 (strspn(media_name, tipc_alphabet) != (media_len - 1)) || 261 (strspn(if_name, tipc_alphabet) != (if_len - 1))) 262 return 0; 263 264 /* return bearer name components, if necessary */ 265 266 if (name_parts) { 267 strcpy(name_parts->media_name, media_name); 268 strcpy(name_parts->if_name, if_name); 269 } 270 return 1; 271 } 272 273 /** 274 * bearer_find - locates bearer object with matching bearer name 275 */ 276 277 static struct bearer *bearer_find(const char *name) 278 { 279 struct bearer *b_ptr; 280 u32 i; 281 282 for (i = 0, b_ptr = bearers; i < MAX_BEARERS; i++, b_ptr++) { 283 if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) 284 return b_ptr; 285 } 286 return 0; 287 } 288 289 /** 290 * bearer_find - locates bearer object with matching interface name 291 */ 292 293 struct bearer *bearer_find_interface(const char *if_name) 294 { 295 struct bearer *b_ptr; 296 char *b_if_name; 297 u32 i; 298 299 for (i = 0, b_ptr = bearers; i < MAX_BEARERS; i++, b_ptr++) { 300 if (!b_ptr->active) 301 continue; 302 b_if_name = strchr(b_ptr->publ.name, ':') + 1; 303 if (!strcmp(b_if_name, if_name)) 304 return b_ptr; 305 } 306 return 0; 307 } 308 309 /** 310 * bearer_get_names - record names of bearers in buffer 311 */ 312 313 struct sk_buff *bearer_get_names(void) 314 { 315 struct sk_buff *buf; 316 struct media *m_ptr; 317 struct bearer *b_ptr; 318 int i, j; 319 320 buf = cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME)); 321 if (!buf) 322 return NULL; 323 324 read_lock_bh(&net_lock); 325 for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { 326 for (j = 0; j < MAX_BEARERS; j++) { 327 b_ptr = &bearers[j]; 328 if (b_ptr->active && (b_ptr->media == m_ptr)) { 329 cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 330 b_ptr->publ.name, 331 strlen(b_ptr->publ.name) + 1); 332 } 333 } 334 } 335 read_unlock_bh(&net_lock); 336 return buf; 337 } 338 339 void bearer_add_dest(struct bearer *b_ptr, u32 dest) 340 { 341 nmap_add(&b_ptr->nodes, dest); 342 disc_update_link_req(b_ptr->link_req); 343 bcbearer_sort(); 344 } 345 346 void bearer_remove_dest(struct bearer *b_ptr, u32 dest) 347 { 348 nmap_remove(&b_ptr->nodes, dest); 349 disc_update_link_req(b_ptr->link_req); 350 bcbearer_sort(); 351 } 352 353 /* 354 * bearer_push(): Resolve bearer congestion. Force the waiting 355 * links to push out their unsent packets, one packet per link 356 * per iteration, until all packets are gone or congestion reoccurs. 357 * 'net_lock' is read_locked when this function is called 358 * bearer.lock must be taken before calling 359 * Returns binary true(1) ore false(0) 360 */ 361 static int bearer_push(struct bearer *b_ptr) 362 { 363 u32 res = TIPC_OK; 364 struct link *ln, *tln; 365 366 if (b_ptr->publ.blocked) 367 return 0; 368 369 while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) { 370 list_for_each_entry_safe(ln, tln, &b_ptr->cong_links, link_list) { 371 res = link_push_packet(ln); 372 if (res == PUSH_FAILED) 373 break; 374 if (res == PUSH_FINISHED) 375 list_move_tail(&ln->link_list, &b_ptr->links); 376 } 377 } 378 return list_empty(&b_ptr->cong_links); 379 } 380 381 void bearer_lock_push(struct bearer *b_ptr) 382 { 383 int res; 384 385 spin_lock_bh(&b_ptr->publ.lock); 386 res = bearer_push(b_ptr); 387 spin_unlock_bh(&b_ptr->publ.lock); 388 if (res) 389 bcbearer_push(); 390 } 391 392 393 /* 394 * Interrupt enabling new requests after bearer congestion or blocking: 395 * See bearer_send(). 396 */ 397 void tipc_continue(struct tipc_bearer *tb_ptr) 398 { 399 struct bearer *b_ptr = (struct bearer *)tb_ptr; 400 401 spin_lock_bh(&b_ptr->publ.lock); 402 b_ptr->continue_count++; 403 if (!list_empty(&b_ptr->cong_links)) 404 k_signal((Handler)bearer_lock_push, (unsigned long)b_ptr); 405 b_ptr->publ.blocked = 0; 406 spin_unlock_bh(&b_ptr->publ.lock); 407 } 408 409 /* 410 * Schedule link for sending of messages after the bearer 411 * has been deblocked by 'continue()'. This method is called 412 * when somebody tries to send a message via this link while 413 * the bearer is congested. 'net_lock' is in read_lock here 414 * bearer.lock is busy 415 */ 416 417 static void bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr) 418 { 419 list_move_tail(&l_ptr->link_list, &b_ptr->cong_links); 420 } 421 422 /* 423 * Schedule link for sending of messages after the bearer 424 * has been deblocked by 'continue()'. This method is called 425 * when somebody tries to send a message via this link while 426 * the bearer is congested. 'net_lock' is in read_lock here, 427 * bearer.lock is free 428 */ 429 430 void bearer_schedule(struct bearer *b_ptr, struct link *l_ptr) 431 { 432 spin_lock_bh(&b_ptr->publ.lock); 433 bearer_schedule_unlocked(b_ptr, l_ptr); 434 spin_unlock_bh(&b_ptr->publ.lock); 435 } 436 437 438 /* 439 * bearer_resolve_congestion(): Check if there is bearer congestion, 440 * and if there is, try to resolve it before returning. 441 * 'net_lock' is read_locked when this function is called 442 */ 443 int bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr) 444 { 445 int res = 1; 446 447 if (list_empty(&b_ptr->cong_links)) 448 return 1; 449 spin_lock_bh(&b_ptr->publ.lock); 450 if (!bearer_push(b_ptr)) { 451 bearer_schedule_unlocked(b_ptr, l_ptr); 452 res = 0; 453 } 454 spin_unlock_bh(&b_ptr->publ.lock); 455 return res; 456 } 457 458 459 /** 460 * tipc_enable_bearer - enable bearer with the given name 461 */ 462 463 int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority) 464 { 465 struct bearer *b_ptr; 466 struct media *m_ptr; 467 struct bearer_name b_name; 468 char addr_string[16]; 469 u32 bearer_id; 470 u32 with_this_prio; 471 u32 i; 472 int res = -EINVAL; 473 474 if (tipc_mode != TIPC_NET_MODE) 475 return -ENOPROTOOPT; 476 if (!bearer_name_validate(name, &b_name) || 477 !addr_domain_valid(bcast_scope) || 478 !in_scope(bcast_scope, tipc_own_addr) || 479 (priority > TIPC_NUM_LINK_PRI)) 480 return -EINVAL; 481 482 write_lock_bh(&net_lock); 483 if (!bearers) 484 goto failed; 485 486 m_ptr = media_find(b_name.media_name); 487 if (!m_ptr) { 488 warn("No media <%s>\n", b_name.media_name); 489 goto failed; 490 } 491 if (priority == TIPC_NUM_LINK_PRI) 492 priority = m_ptr->priority; 493 494 restart: 495 bearer_id = MAX_BEARERS; 496 with_this_prio = 1; 497 for (i = MAX_BEARERS; i-- != 0; ) { 498 if (!bearers[i].active) { 499 bearer_id = i; 500 continue; 501 } 502 if (!strcmp(name, bearers[i].publ.name)) { 503 warn("Bearer <%s> already enabled\n", name); 504 goto failed; 505 } 506 if ((bearers[i].priority == priority) && 507 (++with_this_prio > 2)) { 508 if (priority-- == 0) { 509 warn("Third bearer <%s> with priority %u, unable to lower to %u\n", 510 name, priority + 1, priority); 511 goto failed; 512 } 513 warn("Third bearer <%s> with priority %u, lowering to %u\n", 514 name, priority + 1, priority); 515 goto restart; 516 } 517 } 518 if (bearer_id >= MAX_BEARERS) { 519 warn("Attempt to enable more than %d bearers\n", MAX_BEARERS); 520 goto failed; 521 } 522 523 b_ptr = &bearers[bearer_id]; 524 memset(b_ptr, 0, sizeof(struct bearer)); 525 526 strcpy(b_ptr->publ.name, name); 527 res = m_ptr->enable_bearer(&b_ptr->publ); 528 if (res) { 529 warn("Failed to enable bearer <%s>\n", name); 530 goto failed; 531 } 532 533 b_ptr->identity = bearer_id; 534 b_ptr->media = m_ptr; 535 b_ptr->net_plane = bearer_id + 'A'; 536 b_ptr->active = 1; 537 b_ptr->detect_scope = bcast_scope; 538 b_ptr->priority = priority; 539 INIT_LIST_HEAD(&b_ptr->cong_links); 540 INIT_LIST_HEAD(&b_ptr->links); 541 if (m_ptr->bcast) { 542 b_ptr->link_req = disc_init_link_req(b_ptr, &m_ptr->bcast_addr, 543 bcast_scope, 2); 544 } 545 b_ptr->publ.lock = SPIN_LOCK_UNLOCKED; 546 write_unlock_bh(&net_lock); 547 info("Enabled bearer <%s>, discovery domain %s\n", 548 name, addr_string_fill(addr_string, bcast_scope)); 549 return 0; 550 failed: 551 write_unlock_bh(&net_lock); 552 return res; 553 } 554 555 /** 556 * tipc_block_bearer(): Block the bearer with the given name, 557 * and reset all its links 558 */ 559 560 int tipc_block_bearer(const char *name) 561 { 562 struct bearer *b_ptr = 0; 563 struct link *l_ptr; 564 struct link *temp_l_ptr; 565 566 if (tipc_mode != TIPC_NET_MODE) 567 return -ENOPROTOOPT; 568 569 read_lock_bh(&net_lock); 570 b_ptr = bearer_find(name); 571 if (!b_ptr) { 572 warn("Attempt to block unknown bearer <%s>\n", name); 573 read_unlock_bh(&net_lock); 574 return -EINVAL; 575 } 576 577 spin_lock_bh(&b_ptr->publ.lock); 578 b_ptr->publ.blocked = 1; 579 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 580 struct node *n_ptr = l_ptr->owner; 581 582 spin_lock_bh(&n_ptr->lock); 583 link_reset(l_ptr); 584 spin_unlock_bh(&n_ptr->lock); 585 } 586 spin_unlock_bh(&b_ptr->publ.lock); 587 read_unlock_bh(&net_lock); 588 info("Blocked bearer <%s>\n", name); 589 return TIPC_OK; 590 } 591 592 /** 593 * bearer_disable - 594 * 595 * Note: This routine assumes caller holds net_lock. 596 */ 597 598 static int bearer_disable(const char *name) 599 { 600 struct bearer *b_ptr; 601 struct link *l_ptr; 602 struct link *temp_l_ptr; 603 604 if (tipc_mode != TIPC_NET_MODE) 605 return -ENOPROTOOPT; 606 607 b_ptr = bearer_find(name); 608 if (!b_ptr) { 609 warn("Attempt to disable unknown bearer <%s>\n", name); 610 return -EINVAL; 611 } 612 613 disc_stop_link_req(b_ptr->link_req); 614 spin_lock_bh(&b_ptr->publ.lock); 615 b_ptr->link_req = NULL; 616 b_ptr->publ.blocked = 1; 617 if (b_ptr->media->disable_bearer) { 618 spin_unlock_bh(&b_ptr->publ.lock); 619 write_unlock_bh(&net_lock); 620 b_ptr->media->disable_bearer(&b_ptr->publ); 621 write_lock_bh(&net_lock); 622 spin_lock_bh(&b_ptr->publ.lock); 623 } 624 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 625 link_delete(l_ptr); 626 } 627 spin_unlock_bh(&b_ptr->publ.lock); 628 info("Disabled bearer <%s>\n", name); 629 memset(b_ptr, 0, sizeof(struct bearer)); 630 return TIPC_OK; 631 } 632 633 int tipc_disable_bearer(const char *name) 634 { 635 int res; 636 637 write_lock_bh(&net_lock); 638 res = bearer_disable(name); 639 write_unlock_bh(&net_lock); 640 return res; 641 } 642 643 644 645 int bearer_init(void) 646 { 647 int res; 648 649 write_lock_bh(&net_lock); 650 bearers = kmalloc(MAX_BEARERS * sizeof(struct bearer), GFP_ATOMIC); 651 media_list = kmalloc(MAX_MEDIA * sizeof(struct media), GFP_ATOMIC); 652 if (bearers && media_list) { 653 memset(bearers, 0, MAX_BEARERS * sizeof(struct bearer)); 654 memset(media_list, 0, MAX_MEDIA * sizeof(struct media)); 655 res = TIPC_OK; 656 } else { 657 kfree(bearers); 658 kfree(media_list); 659 bearers = 0; 660 media_list = 0; 661 res = -ENOMEM; 662 } 663 write_unlock_bh(&net_lock); 664 return res; 665 } 666 667 void bearer_stop(void) 668 { 669 u32 i; 670 671 if (!bearers) 672 return; 673 674 for (i = 0; i < MAX_BEARERS; i++) { 675 if (bearers[i].active) 676 bearers[i].publ.blocked = 1; 677 } 678 for (i = 0; i < MAX_BEARERS; i++) { 679 if (bearers[i].active) 680 bearer_disable(bearers[i].publ.name); 681 } 682 kfree(bearers); 683 kfree(media_list); 684 bearers = 0; 685 media_list = 0; 686 media_count = 0; 687 } 688 689 690