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-2007, 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 #define DATA_LOW TIPC_LOW_IMPORTANCE 44 #define DATA_MEDIUM TIPC_MEDIUM_IMPORTANCE 45 #define DATA_HIGH TIPC_HIGH_IMPORTANCE 46 #define DATA_CRITICAL TIPC_CRITICAL_IMPORTANCE 47 #define SHORT_H_SIZE 24 /* Connected,in cluster */ 48 #define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ 49 #define CONN_MSG_H_SIZE 36 /* Routed connected msgs*/ 50 #define LONG_H_SIZE 40 /* Named Messages */ 51 #define MCAST_H_SIZE 44 /* Multicast messages */ 52 #define MAX_H_SIZE 60 /* Inclusive full options */ 53 #define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) 54 #define LINK_CONFIG 13 55 56 57 /* 58 TIPC user data message header format, version 2 59 60 - Fundamental definitions available to privileged TIPC users 61 are located in tipc_msg.h. 62 - Remaining definitions available to TIPC internal users appear below. 63 */ 64 65 66 static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val) 67 { 68 m->hdr[w] = htonl(val); 69 } 70 71 static inline void msg_set_bits(struct tipc_msg *m, u32 w, 72 u32 pos, u32 mask, u32 val) 73 { 74 val = (val & mask) << pos; 75 val = htonl(val); 76 mask = htonl(mask << pos); 77 m->hdr[w] &= ~mask; 78 m->hdr[w] |= val; 79 } 80 81 /* 82 * Word 0 83 */ 84 85 static inline u32 msg_version(struct tipc_msg *m) 86 { 87 return msg_bits(m, 0, 29, 7); 88 } 89 90 static inline void msg_set_version(struct tipc_msg *m) 91 { 92 msg_set_bits(m, 0, 29, 0xf, TIPC_VERSION); 93 } 94 95 static inline u32 msg_user(struct tipc_msg *m) 96 { 97 return msg_bits(m, 0, 25, 0xf); 98 } 99 100 static inline u32 msg_isdata(struct tipc_msg *m) 101 { 102 return (msg_user(m) <= DATA_CRITICAL); 103 } 104 105 static inline void msg_set_user(struct tipc_msg *m, u32 n) 106 { 107 msg_set_bits(m, 0, 25, 0xf, n); 108 } 109 110 static inline void msg_set_importance(struct tipc_msg *m, u32 i) 111 { 112 msg_set_user(m, i); 113 } 114 115 static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n) 116 { 117 msg_set_bits(m, 0, 21, 0xf, n>>2); 118 } 119 120 static inline int msg_non_seq(struct tipc_msg *m) 121 { 122 return msg_bits(m, 0, 20, 1); 123 } 124 125 static inline void msg_set_non_seq(struct tipc_msg *m) 126 { 127 msg_set_bits(m, 0, 20, 1, 1); 128 } 129 130 static inline int msg_dest_droppable(struct tipc_msg *m) 131 { 132 return msg_bits(m, 0, 19, 1); 133 } 134 135 static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d) 136 { 137 msg_set_bits(m, 0, 19, 1, d); 138 } 139 140 static inline int msg_src_droppable(struct tipc_msg *m) 141 { 142 return msg_bits(m, 0, 18, 1); 143 } 144 145 static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d) 146 { 147 msg_set_bits(m, 0, 18, 1, d); 148 } 149 150 static inline void msg_set_size(struct tipc_msg *m, u32 sz) 151 { 152 m->hdr[0] = htonl((msg_word(m, 0) & ~0x1ffff) | sz); 153 } 154 155 156 /* 157 * Word 1 158 */ 159 160 static inline void msg_set_type(struct tipc_msg *m, u32 n) 161 { 162 msg_set_bits(m, 1, 29, 0x7, n); 163 } 164 165 static inline void msg_set_errcode(struct tipc_msg *m, u32 err) 166 { 167 msg_set_bits(m, 1, 25, 0xf, err); 168 } 169 170 static inline u32 msg_reroute_cnt(struct tipc_msg *m) 171 { 172 return msg_bits(m, 1, 21, 0xf); 173 } 174 175 static inline void msg_incr_reroute_cnt(struct tipc_msg *m) 176 { 177 msg_set_bits(m, 1, 21, 0xf, msg_reroute_cnt(m) + 1); 178 } 179 180 static inline void msg_reset_reroute_cnt(struct tipc_msg *m) 181 { 182 msg_set_bits(m, 1, 21, 0xf, 0); 183 } 184 185 static inline u32 msg_lookup_scope(struct tipc_msg *m) 186 { 187 return msg_bits(m, 1, 19, 0x3); 188 } 189 190 static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n) 191 { 192 msg_set_bits(m, 1, 19, 0x3, n); 193 } 194 195 static inline void msg_set_options(struct tipc_msg *m, const char *opt, u32 sz) 196 { 197 u32 hsz = msg_hdr_sz(m); 198 char *to = (char *)&m->hdr[hsz/4]; 199 200 if ((hsz < DIR_MSG_H_SIZE) || ((hsz + sz) > MAX_H_SIZE)) 201 return; 202 msg_set_bits(m, 1, 16, 0x7, (hsz - 28)/4); 203 msg_set_hdr_sz(m, hsz + sz); 204 memcpy(to, opt, sz); 205 } 206 207 static inline u32 msg_bcast_ack(struct tipc_msg *m) 208 { 209 return msg_bits(m, 1, 0, 0xffff); 210 } 211 212 static inline void msg_set_bcast_ack(struct tipc_msg *m, u32 n) 213 { 214 msg_set_bits(m, 1, 0, 0xffff, n); 215 } 216 217 218 /* 219 * Word 2 220 */ 221 222 static inline u32 msg_ack(struct tipc_msg *m) 223 { 224 return msg_bits(m, 2, 16, 0xffff); 225 } 226 227 static inline void msg_set_ack(struct tipc_msg *m, u32 n) 228 { 229 msg_set_bits(m, 2, 16, 0xffff, n); 230 } 231 232 static inline u32 msg_seqno(struct tipc_msg *m) 233 { 234 return msg_bits(m, 2, 0, 0xffff); 235 } 236 237 static inline void msg_set_seqno(struct tipc_msg *m, u32 n) 238 { 239 msg_set_bits(m, 2, 0, 0xffff, n); 240 } 241 242 243 /* 244 * Words 3-10 245 */ 246 247 248 static inline void msg_set_prevnode(struct tipc_msg *m, u32 a) 249 { 250 msg_set_word(m, 3, a); 251 } 252 253 static inline void msg_set_origport(struct tipc_msg *m, u32 p) 254 { 255 msg_set_word(m, 4, p); 256 } 257 258 static inline void msg_set_destport(struct tipc_msg *m, u32 p) 259 { 260 msg_set_word(m, 5, p); 261 } 262 263 static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p) 264 { 265 msg_set_word(m, 5, p); 266 } 267 268 static inline void msg_set_orignode(struct tipc_msg *m, u32 a) 269 { 270 msg_set_word(m, 6, a); 271 } 272 273 static inline void msg_set_destnode(struct tipc_msg *m, u32 a) 274 { 275 msg_set_word(m, 7, a); 276 } 277 278 static inline int msg_is_dest(struct tipc_msg *m, u32 d) 279 { 280 return(msg_short(m) || (msg_destnode(m) == d)); 281 } 282 283 static inline u32 msg_routed(struct tipc_msg *m) 284 { 285 if (likely(msg_short(m))) 286 return 0; 287 return(msg_destnode(m) ^ msg_orignode(m)) >> 11; 288 } 289 290 static inline void msg_set_nametype(struct tipc_msg *m, u32 n) 291 { 292 msg_set_word(m, 8, n); 293 } 294 295 static inline u32 msg_transp_seqno(struct tipc_msg *m) 296 { 297 return msg_word(m, 8); 298 } 299 300 static inline void msg_set_timestamp(struct tipc_msg *m, u32 n) 301 { 302 msg_set_word(m, 8, n); 303 } 304 305 static inline u32 msg_timestamp(struct tipc_msg *m) 306 { 307 return msg_word(m, 8); 308 } 309 310 static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n) 311 { 312 msg_set_word(m, 8, n); 313 } 314 315 static inline void msg_set_namelower(struct tipc_msg *m, u32 n) 316 { 317 msg_set_word(m, 9, n); 318 } 319 320 static inline void msg_set_nameinst(struct tipc_msg *m, u32 n) 321 { 322 msg_set_namelower(m, n); 323 } 324 325 static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) 326 { 327 msg_set_word(m, 10, n); 328 } 329 330 static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) 331 { 332 return (struct tipc_msg *)msg_data(m); 333 } 334 335 static inline void msg_expand(struct tipc_msg *m, u32 destnode) 336 { 337 if (!msg_short(m)) 338 return; 339 msg_set_hdr_sz(m, LONG_H_SIZE); 340 msg_set_orignode(m, msg_prevnode(m)); 341 msg_set_destnode(m, destnode); 342 memset(&m->hdr[8], 0, 12); 343 } 344 345 346 347 /* 348 TIPC internal message header format, version 2 349 350 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 351 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 352 w0:|vers |msg usr|hdr sz |n|resrv| packet size | 353 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 354 w1:|m typ|rsv=0| sequence gap | broadcast ack no | 355 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 356 w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | 357 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 358 w3:| previous node | 359 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 360 w4:| next sent broadcast/fragm no | next sent pkt/ fragm msg no | 361 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 362 w5:| session no |rsv=0|r|berid|link prio|netpl|p| 363 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 364 w6:| originating node | 365 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 366 w7:| destination node | 367 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 368 w8:| transport sequence number | 369 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 370 w9:| msg count / bcast tag | link tolerance | 371 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 372 \ \ 373 / User Specific Data / 374 \ \ 375 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 376 377 NB: CONN_MANAGER use data message format. LINK_CONFIG has own format. 378 */ 379 380 /* 381 * Internal users 382 */ 383 384 #define BCAST_PROTOCOL 5 385 #define MSG_BUNDLER 6 386 #define LINK_PROTOCOL 7 387 #define CONN_MANAGER 8 388 #define ROUTE_DISTRIBUTOR 9 389 #define CHANGEOVER_PROTOCOL 10 390 #define NAME_DISTRIBUTOR 11 391 #define MSG_FRAGMENTER 12 392 #define LINK_CONFIG 13 393 #define INT_H_SIZE 40 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, 0xff); 419 } 420 421 static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) 422 { 423 msg_set_bits(m, 1, 16, 0xff, 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 int msg_dataoctet(struct tipc_msg *m, u32 pos) 669 { 670 return(msg_data(m)[pos + 4] != 0); 671 } 672 673 static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos) 674 { 675 msg_data(m)[pos + 4] = 1; 676 } 677 678 /* 679 * Segmentation message types 680 */ 681 682 #define FIRST_FRAGMENT 0 683 #define FRAGMENT 1 684 #define LAST_FRAGMENT 2 685 686 /* 687 * Link management protocol message types 688 */ 689 690 #define STATE_MSG 0 691 #define RESET_MSG 1 692 #define ACTIVATE_MSG 2 693 694 /* 695 * Changeover tunnel message types 696 */ 697 #define DUPLICATE_MSG 0 698 #define ORIGINAL_MSG 1 699 700 /* 701 * Routing table message types 702 */ 703 #define EXT_ROUTING_TABLE 0 704 #define LOCAL_ROUTING_TABLE 1 705 #define SLAVE_ROUTING_TABLE 2 706 #define ROUTE_ADDITION 3 707 #define ROUTE_REMOVAL 4 708 709 /* 710 * Config protocol message types 711 */ 712 713 #define DSC_REQ_MSG 0 714 #define DSC_RESP_MSG 1 715 716 static inline u32 msg_tot_importance(struct tipc_msg *m) 717 { 718 if (likely(msg_isdata(m))) { 719 if (likely(msg_orignode(m) == tipc_own_addr)) 720 return msg_importance(m); 721 return msg_importance(m) + 4; 722 } 723 if ((msg_user(m) == MSG_FRAGMENTER) && 724 (msg_type(m) == FIRST_FRAGMENT)) 725 return msg_importance(msg_get_wrapped(m)); 726 return msg_importance(m); 727 } 728 729 730 static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, 731 u32 err, u32 hsize, u32 destnode) 732 { 733 memset(m, 0, hsize); 734 msg_set_version(m); 735 msg_set_user(m, user); 736 msg_set_hdr_sz(m, hsize); 737 msg_set_size(m, hsize); 738 msg_set_prevnode(m, tipc_own_addr); 739 msg_set_type(m, type); 740 msg_set_errcode(m, err); 741 if (!msg_short(m)) { 742 msg_set_orignode(m, tipc_own_addr); 743 msg_set_destnode(m, destnode); 744 } 745 } 746 747 /** 748 * msg_calc_data_size - determine total data size for message 749 */ 750 751 static inline int msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) 752 { 753 int dsz = 0; 754 int i; 755 756 for (i = 0; i < num_sect; i++) 757 dsz += msg_sect[i].iov_len; 758 return dsz; 759 } 760 761 /** 762 * msg_build - create message using specified header and data 763 * 764 * Note: Caller must not hold any locks in case copy_from_user() is interrupted! 765 * 766 * Returns message data size or errno 767 */ 768 769 static inline int msg_build(struct tipc_msg *hdr, 770 struct iovec const *msg_sect, u32 num_sect, 771 int max_size, int usrmem, struct sk_buff** buf) 772 { 773 int dsz, sz, hsz, pos, res, cnt; 774 775 dsz = msg_calc_data_size(msg_sect, num_sect); 776 if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) { 777 *buf = NULL; 778 return -EINVAL; 779 } 780 781 pos = hsz = msg_hdr_sz(hdr); 782 sz = hsz + dsz; 783 msg_set_size(hdr, sz); 784 if (unlikely(sz > max_size)) { 785 *buf = NULL; 786 return dsz; 787 } 788 789 *buf = buf_acquire(sz); 790 if (!(*buf)) 791 return -ENOMEM; 792 skb_copy_to_linear_data(*buf, hdr, hsz); 793 for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { 794 if (likely(usrmem)) 795 res = !copy_from_user((*buf)->data + pos, 796 msg_sect[cnt].iov_base, 797 msg_sect[cnt].iov_len); 798 else 799 skb_copy_to_linear_data_offset(*buf, pos, 800 msg_sect[cnt].iov_base, 801 msg_sect[cnt].iov_len); 802 pos += msg_sect[cnt].iov_len; 803 } 804 if (likely(res)) 805 return dsz; 806 807 buf_discard(*buf); 808 *buf = NULL; 809 return -EFAULT; 810 } 811 812 static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 813 { 814 memcpy(&((int *)m)[5], a, sizeof(*a)); 815 } 816 817 static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 818 { 819 memcpy(a, &((int*)m)[5], sizeof(*a)); 820 } 821 822 #endif 823