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