1 /* 2 * net/tipc/msg.h: Include file for TIPC message header routines 3 * 4 * Copyright (c) 2000-2007, Ericsson AB 5 * Copyright (c) 2005-2008, 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 #ifndef _TIPC_MSG_H 38 #define _TIPC_MSG_H 39 40 #include "core.h" 41 42 #define TIPC_VERSION 2 43 44 #define SHORT_H_SIZE 24 /* Connected, in-cluster messages */ 45 #define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ 46 #define LONG_H_SIZE 40 /* Named messages */ 47 #define MCAST_H_SIZE 44 /* Multicast messages */ 48 #define INT_H_SIZE 40 /* Internal messages */ 49 #define MIN_H_SIZE 24 /* Smallest legal TIPC header size */ 50 #define MAX_H_SIZE 60 /* Largest possible TIPC header size */ 51 52 #define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) 53 54 55 /* 56 TIPC user data message header format, version 2 57 58 - Fundamental definitions available to privileged TIPC users 59 are located in tipc_msg.h. 60 - Remaining definitions available to TIPC internal users appear below. 61 */ 62 63 64 static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val) 65 { 66 m->hdr[w] = htonl(val); 67 } 68 69 static inline void msg_set_bits(struct tipc_msg *m, u32 w, 70 u32 pos, u32 mask, u32 val) 71 { 72 val = (val & mask) << pos; 73 mask = mask << pos; 74 m->hdr[w] &= ~htonl(mask); 75 m->hdr[w] |= htonl(val); 76 } 77 78 static inline void msg_swap_words(struct tipc_msg *msg, u32 a, u32 b) 79 { 80 u32 temp = msg->hdr[a]; 81 82 msg->hdr[a] = msg->hdr[b]; 83 msg->hdr[b] = temp; 84 } 85 86 /* 87 * Word 0 88 */ 89 90 static inline u32 msg_version(struct tipc_msg *m) 91 { 92 return msg_bits(m, 0, 29, 7); 93 } 94 95 static inline void msg_set_version(struct tipc_msg *m) 96 { 97 msg_set_bits(m, 0, 29, 7, TIPC_VERSION); 98 } 99 100 static inline u32 msg_user(struct tipc_msg *m) 101 { 102 return msg_bits(m, 0, 25, 0xf); 103 } 104 105 static inline u32 msg_isdata(struct tipc_msg *m) 106 { 107 return (msg_user(m) <= TIPC_CRITICAL_IMPORTANCE); 108 } 109 110 static inline void msg_set_user(struct tipc_msg *m, u32 n) 111 { 112 msg_set_bits(m, 0, 25, 0xf, n); 113 } 114 115 static inline void msg_set_importance(struct tipc_msg *m, u32 i) 116 { 117 msg_set_user(m, i); 118 } 119 120 static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n) 121 { 122 msg_set_bits(m, 0, 21, 0xf, n>>2); 123 } 124 125 static inline int msg_non_seq(struct tipc_msg *m) 126 { 127 return msg_bits(m, 0, 20, 1); 128 } 129 130 static inline void msg_set_non_seq(struct tipc_msg *m, u32 n) 131 { 132 msg_set_bits(m, 0, 20, 1, n); 133 } 134 135 static inline int msg_dest_droppable(struct tipc_msg *m) 136 { 137 return msg_bits(m, 0, 19, 1); 138 } 139 140 static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d) 141 { 142 msg_set_bits(m, 0, 19, 1, d); 143 } 144 145 static inline int msg_src_droppable(struct tipc_msg *m) 146 { 147 return msg_bits(m, 0, 18, 1); 148 } 149 150 static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d) 151 { 152 msg_set_bits(m, 0, 18, 1, d); 153 } 154 155 static inline void msg_set_size(struct tipc_msg *m, u32 sz) 156 { 157 m->hdr[0] = htonl((msg_word(m, 0) & ~0x1ffff) | sz); 158 } 159 160 161 /* 162 * Word 1 163 */ 164 165 static inline void msg_set_type(struct tipc_msg *m, u32 n) 166 { 167 msg_set_bits(m, 1, 29, 0x7, n); 168 } 169 170 static inline void msg_set_errcode(struct tipc_msg *m, u32 err) 171 { 172 msg_set_bits(m, 1, 25, 0xf, err); 173 } 174 175 static inline u32 msg_reroute_cnt(struct tipc_msg *m) 176 { 177 return msg_bits(m, 1, 21, 0xf); 178 } 179 180 static inline void msg_incr_reroute_cnt(struct tipc_msg *m) 181 { 182 msg_set_bits(m, 1, 21, 0xf, msg_reroute_cnt(m) + 1); 183 } 184 185 static inline void msg_reset_reroute_cnt(struct tipc_msg *m) 186 { 187 msg_set_bits(m, 1, 21, 0xf, 0); 188 } 189 190 static inline u32 msg_lookup_scope(struct tipc_msg *m) 191 { 192 return msg_bits(m, 1, 19, 0x3); 193 } 194 195 static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n) 196 { 197 msg_set_bits(m, 1, 19, 0x3, n); 198 } 199 200 static inline u32 msg_bcast_ack(struct tipc_msg *m) 201 { 202 return msg_bits(m, 1, 0, 0xffff); 203 } 204 205 static inline void msg_set_bcast_ack(struct tipc_msg *m, u32 n) 206 { 207 msg_set_bits(m, 1, 0, 0xffff, n); 208 } 209 210 211 /* 212 * Word 2 213 */ 214 215 static inline u32 msg_ack(struct tipc_msg *m) 216 { 217 return msg_bits(m, 2, 16, 0xffff); 218 } 219 220 static inline void msg_set_ack(struct tipc_msg *m, u32 n) 221 { 222 msg_set_bits(m, 2, 16, 0xffff, n); 223 } 224 225 static inline u32 msg_seqno(struct tipc_msg *m) 226 { 227 return msg_bits(m, 2, 0, 0xffff); 228 } 229 230 static inline void msg_set_seqno(struct tipc_msg *m, u32 n) 231 { 232 msg_set_bits(m, 2, 0, 0xffff, n); 233 } 234 235 /* 236 * TIPC may utilize the "link ack #" and "link seq #" fields of a short 237 * message header to hold the destination node for the message, since the 238 * normal "dest node" field isn't present. This cache is only referenced 239 * when required, so populating the cache of a longer message header is 240 * harmless (as long as the header has the two link sequence fields present). 241 * 242 * Note: Host byte order is OK here, since the info never goes off-card. 243 */ 244 245 static inline u32 msg_destnode_cache(struct tipc_msg *m) 246 { 247 return m->hdr[2]; 248 } 249 250 static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode) 251 { 252 m->hdr[2] = dnode; 253 } 254 255 /* 256 * Words 3-10 257 */ 258 259 260 static inline void msg_set_prevnode(struct tipc_msg *m, u32 a) 261 { 262 msg_set_word(m, 3, a); 263 } 264 265 static inline void msg_set_origport(struct tipc_msg *m, u32 p) 266 { 267 msg_set_word(m, 4, p); 268 } 269 270 static inline void msg_set_destport(struct tipc_msg *m, u32 p) 271 { 272 msg_set_word(m, 5, p); 273 } 274 275 static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p) 276 { 277 msg_set_word(m, 5, p); 278 } 279 280 static inline void msg_set_orignode(struct tipc_msg *m, u32 a) 281 { 282 msg_set_word(m, 6, a); 283 } 284 285 static inline void msg_set_destnode(struct tipc_msg *m, u32 a) 286 { 287 msg_set_word(m, 7, a); 288 } 289 290 static inline int msg_is_dest(struct tipc_msg *m, u32 d) 291 { 292 return(msg_short(m) || (msg_destnode(m) == d)); 293 } 294 295 static inline u32 msg_routed(struct tipc_msg *m) 296 { 297 if (likely(msg_short(m))) 298 return 0; 299 return(msg_destnode(m) ^ msg_orignode(m)) >> 11; 300 } 301 302 static inline void msg_set_nametype(struct tipc_msg *m, u32 n) 303 { 304 msg_set_word(m, 8, n); 305 } 306 307 static inline u32 msg_transp_seqno(struct tipc_msg *m) 308 { 309 return msg_word(m, 8); 310 } 311 312 static inline void msg_set_timestamp(struct tipc_msg *m, u32 n) 313 { 314 msg_set_word(m, 8, n); 315 } 316 317 static inline u32 msg_timestamp(struct tipc_msg *m) 318 { 319 return msg_word(m, 8); 320 } 321 322 static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n) 323 { 324 msg_set_word(m, 8, n); 325 } 326 327 static inline void msg_set_namelower(struct tipc_msg *m, u32 n) 328 { 329 msg_set_word(m, 9, n); 330 } 331 332 static inline void msg_set_nameinst(struct tipc_msg *m, u32 n) 333 { 334 msg_set_namelower(m, n); 335 } 336 337 static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) 338 { 339 msg_set_word(m, 10, n); 340 } 341 342 static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) 343 { 344 return (struct tipc_msg *)msg_data(m); 345 } 346 347 348 /* 349 TIPC internal message header format, version 2 350 351 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0 352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 353 w0:|vers |msg usr|hdr sz |n|resrv| packet size | 354 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 355 w1:|m typ| sequence gap | broadcast ack no | 356 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 357 w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | 358 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 359 w3:| previous node | 360 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 361 w4:| next sent broadcast/fragm no | next sent pkt/ fragm msg no | 362 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 363 w5:| session no |rsv=0|r|berid|link prio|netpl|p| 364 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 365 w6:| originating node | 366 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 367 w7:| destination node | 368 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 369 w8:| transport sequence number | 370 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 371 w9:| msg count / bcast tag | link tolerance | 372 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 373 \ \ 374 / User Specific Data / 375 \ \ 376 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 377 378 NB: CONN_MANAGER use data message format. LINK_CONFIG has own format. 379 */ 380 381 /* 382 * Internal users 383 */ 384 385 #define BCAST_PROTOCOL 5 386 #define MSG_BUNDLER 6 387 #define LINK_PROTOCOL 7 388 #define CONN_MANAGER 8 389 #define ROUTE_DISTRIBUTOR 9 390 #define CHANGEOVER_PROTOCOL 10 391 #define NAME_DISTRIBUTOR 11 392 #define MSG_FRAGMENTER 12 393 #define LINK_CONFIG 13 394 #define DSC_H_SIZE 40 395 396 /* 397 * Connection management protocol messages 398 */ 399 400 #define CONN_PROBE 0 401 #define CONN_PROBE_REPLY 1 402 #define CONN_ACK 2 403 404 /* 405 * Name distributor messages 406 */ 407 408 #define PUBLICATION 0 409 #define WITHDRAWAL 1 410 411 412 /* 413 * Word 1 414 */ 415 416 static inline u32 msg_seq_gap(struct tipc_msg *m) 417 { 418 return msg_bits(m, 1, 16, 0x1fff); 419 } 420 421 static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) 422 { 423 msg_set_bits(m, 1, 16, 0x1fff, n); 424 } 425 426 static inline u32 msg_req_links(struct tipc_msg *m) 427 { 428 return msg_bits(m, 1, 16, 0xfff); 429 } 430 431 static inline void msg_set_req_links(struct tipc_msg *m, u32 n) 432 { 433 msg_set_bits(m, 1, 16, 0xfff, n); 434 } 435 436 437 /* 438 * Word 2 439 */ 440 441 static inline u32 msg_dest_domain(struct tipc_msg *m) 442 { 443 return msg_word(m, 2); 444 } 445 446 static inline void msg_set_dest_domain(struct tipc_msg *m, u32 n) 447 { 448 msg_set_word(m, 2, n); 449 } 450 451 static inline u32 msg_bcgap_after(struct tipc_msg *m) 452 { 453 return msg_bits(m, 2, 16, 0xffff); 454 } 455 456 static inline void msg_set_bcgap_after(struct tipc_msg *m, u32 n) 457 { 458 msg_set_bits(m, 2, 16, 0xffff, n); 459 } 460 461 static inline u32 msg_bcgap_to(struct tipc_msg *m) 462 { 463 return msg_bits(m, 2, 0, 0xffff); 464 } 465 466 static inline void msg_set_bcgap_to(struct tipc_msg *m, u32 n) 467 { 468 msg_set_bits(m, 2, 0, 0xffff, n); 469 } 470 471 472 /* 473 * Word 4 474 */ 475 476 static inline u32 msg_last_bcast(struct tipc_msg *m) 477 { 478 return msg_bits(m, 4, 16, 0xffff); 479 } 480 481 static inline void msg_set_last_bcast(struct tipc_msg *m, u32 n) 482 { 483 msg_set_bits(m, 4, 16, 0xffff, n); 484 } 485 486 487 static inline u32 msg_fragm_no(struct tipc_msg *m) 488 { 489 return msg_bits(m, 4, 16, 0xffff); 490 } 491 492 static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n) 493 { 494 msg_set_bits(m, 4, 16, 0xffff, n); 495 } 496 497 498 static inline u32 msg_next_sent(struct tipc_msg *m) 499 { 500 return msg_bits(m, 4, 0, 0xffff); 501 } 502 503 static inline void msg_set_next_sent(struct tipc_msg *m, u32 n) 504 { 505 msg_set_bits(m, 4, 0, 0xffff, n); 506 } 507 508 509 static inline u32 msg_long_msgno(struct tipc_msg *m) 510 { 511 return msg_bits(m, 4, 0, 0xffff); 512 } 513 514 static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n) 515 { 516 msg_set_bits(m, 4, 0, 0xffff, n); 517 } 518 519 static inline u32 msg_bc_netid(struct tipc_msg *m) 520 { 521 return msg_word(m, 4); 522 } 523 524 static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id) 525 { 526 msg_set_word(m, 4, id); 527 } 528 529 static inline u32 msg_link_selector(struct tipc_msg *m) 530 { 531 return msg_bits(m, 4, 0, 1); 532 } 533 534 static inline void msg_set_link_selector(struct tipc_msg *m, u32 n) 535 { 536 msg_set_bits(m, 4, 0, 1, (n & 1)); 537 } 538 539 /* 540 * Word 5 541 */ 542 543 static inline u32 msg_session(struct tipc_msg *m) 544 { 545 return msg_bits(m, 5, 16, 0xffff); 546 } 547 548 static inline void msg_set_session(struct tipc_msg *m, u32 n) 549 { 550 msg_set_bits(m, 5, 16, 0xffff, n); 551 } 552 553 static inline u32 msg_probe(struct tipc_msg *m) 554 { 555 return msg_bits(m, 5, 0, 1); 556 } 557 558 static inline void msg_set_probe(struct tipc_msg *m, u32 val) 559 { 560 msg_set_bits(m, 5, 0, 1, (val & 1)); 561 } 562 563 static inline char msg_net_plane(struct tipc_msg *m) 564 { 565 return msg_bits(m, 5, 1, 7) + 'A'; 566 } 567 568 static inline void msg_set_net_plane(struct tipc_msg *m, char n) 569 { 570 msg_set_bits(m, 5, 1, 7, (n - 'A')); 571 } 572 573 static inline u32 msg_linkprio(struct tipc_msg *m) 574 { 575 return msg_bits(m, 5, 4, 0x1f); 576 } 577 578 static inline void msg_set_linkprio(struct tipc_msg *m, u32 n) 579 { 580 msg_set_bits(m, 5, 4, 0x1f, n); 581 } 582 583 static inline u32 msg_bearer_id(struct tipc_msg *m) 584 { 585 return msg_bits(m, 5, 9, 0x7); 586 } 587 588 static inline void msg_set_bearer_id(struct tipc_msg *m, u32 n) 589 { 590 msg_set_bits(m, 5, 9, 0x7, n); 591 } 592 593 static inline u32 msg_redundant_link(struct tipc_msg *m) 594 { 595 return msg_bits(m, 5, 12, 0x1); 596 } 597 598 static inline void msg_set_redundant_link(struct tipc_msg *m) 599 { 600 msg_set_bits(m, 5, 12, 0x1, 1); 601 } 602 603 static inline void msg_clear_redundant_link(struct tipc_msg *m) 604 { 605 msg_set_bits(m, 5, 12, 0x1, 0); 606 } 607 608 609 /* 610 * Word 9 611 */ 612 613 static inline u32 msg_msgcnt(struct tipc_msg *m) 614 { 615 return msg_bits(m, 9, 16, 0xffff); 616 } 617 618 static inline void msg_set_msgcnt(struct tipc_msg *m, u32 n) 619 { 620 msg_set_bits(m, 9, 16, 0xffff, n); 621 } 622 623 static inline u32 msg_bcast_tag(struct tipc_msg *m) 624 { 625 return msg_bits(m, 9, 16, 0xffff); 626 } 627 628 static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n) 629 { 630 msg_set_bits(m, 9, 16, 0xffff, n); 631 } 632 633 static inline u32 msg_max_pkt(struct tipc_msg *m) 634 { 635 return (msg_bits(m, 9, 16, 0xffff) * 4); 636 } 637 638 static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) 639 { 640 msg_set_bits(m, 9, 16, 0xffff, (n / 4)); 641 } 642 643 static inline u32 msg_link_tolerance(struct tipc_msg *m) 644 { 645 return msg_bits(m, 9, 0, 0xffff); 646 } 647 648 static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n) 649 { 650 msg_set_bits(m, 9, 0, 0xffff, n); 651 } 652 653 /* 654 * Routing table message data 655 */ 656 657 658 static inline u32 msg_remote_node(struct tipc_msg *m) 659 { 660 return msg_word(m, msg_hdr_sz(m)/4); 661 } 662 663 static inline void msg_set_remote_node(struct tipc_msg *m, u32 a) 664 { 665 msg_set_word(m, msg_hdr_sz(m)/4, a); 666 } 667 668 static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos) 669 { 670 msg_data(m)[pos + 4] = 1; 671 } 672 673 /* 674 * Segmentation message types 675 */ 676 677 #define FIRST_FRAGMENT 0 678 #define FRAGMENT 1 679 #define LAST_FRAGMENT 2 680 681 /* 682 * Link management protocol message types 683 */ 684 685 #define STATE_MSG 0 686 #define RESET_MSG 1 687 #define ACTIVATE_MSG 2 688 689 /* 690 * Changeover tunnel message types 691 */ 692 #define DUPLICATE_MSG 0 693 #define ORIGINAL_MSG 1 694 695 /* 696 * Routing table message types 697 */ 698 #define EXT_ROUTING_TABLE 0 699 #define LOCAL_ROUTING_TABLE 1 700 #define SLAVE_ROUTING_TABLE 2 701 #define ROUTE_ADDITION 3 702 #define ROUTE_REMOVAL 4 703 704 /* 705 * Config protocol message types 706 */ 707 708 #define DSC_REQ_MSG 0 709 #define DSC_RESP_MSG 1 710 711 static inline u32 msg_tot_importance(struct tipc_msg *m) 712 { 713 if (likely(msg_isdata(m))) { 714 if (likely(msg_orignode(m) == tipc_own_addr)) 715 return msg_importance(m); 716 return msg_importance(m) + 4; 717 } 718 if ((msg_user(m) == MSG_FRAGMENTER) && 719 (msg_type(m) == FIRST_FRAGMENT)) 720 return msg_importance(msg_get_wrapped(m)); 721 return msg_importance(m); 722 } 723 724 725 static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, 726 u32 hsize, u32 destnode) 727 { 728 memset(m, 0, hsize); 729 msg_set_version(m); 730 msg_set_user(m, user); 731 msg_set_hdr_sz(m, hsize); 732 msg_set_size(m, hsize); 733 msg_set_prevnode(m, tipc_own_addr); 734 msg_set_type(m, type); 735 if (!msg_short(m)) { 736 msg_set_orignode(m, tipc_own_addr); 737 msg_set_destnode(m, destnode); 738 } 739 } 740 741 /** 742 * msg_calc_data_size - determine total data size for message 743 */ 744 745 static inline int msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) 746 { 747 int dsz = 0; 748 int i; 749 750 for (i = 0; i < num_sect; i++) 751 dsz += msg_sect[i].iov_len; 752 return dsz; 753 } 754 755 /** 756 * msg_build - create message using specified header and data 757 * 758 * Note: Caller must not hold any locks in case copy_from_user() is interrupted! 759 * 760 * Returns message data size or errno 761 */ 762 763 static inline int msg_build(struct tipc_msg *hdr, 764 struct iovec const *msg_sect, u32 num_sect, 765 int max_size, int usrmem, struct sk_buff** buf) 766 { 767 int dsz, sz, hsz, pos, res, cnt; 768 769 dsz = msg_calc_data_size(msg_sect, num_sect); 770 if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) { 771 *buf = NULL; 772 return -EINVAL; 773 } 774 775 pos = hsz = msg_hdr_sz(hdr); 776 sz = hsz + dsz; 777 msg_set_size(hdr, sz); 778 if (unlikely(sz > max_size)) { 779 *buf = NULL; 780 return dsz; 781 } 782 783 *buf = buf_acquire(sz); 784 if (!(*buf)) 785 return -ENOMEM; 786 skb_copy_to_linear_data(*buf, hdr, hsz); 787 for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { 788 if (likely(usrmem)) 789 res = !copy_from_user((*buf)->data + pos, 790 msg_sect[cnt].iov_base, 791 msg_sect[cnt].iov_len); 792 else 793 skb_copy_to_linear_data_offset(*buf, pos, 794 msg_sect[cnt].iov_base, 795 msg_sect[cnt].iov_len); 796 pos += msg_sect[cnt].iov_len; 797 } 798 if (likely(res)) 799 return dsz; 800 801 buf_discard(*buf); 802 *buf = NULL; 803 return -EFAULT; 804 } 805 806 static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 807 { 808 memcpy(&((int *)m)[5], a, sizeof(*a)); 809 } 810 811 static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 812 { 813 memcpy(a, &((int*)m)[5], sizeof(*a)); 814 } 815 816 #endif 817