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, 2010-2011, 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 "bearer.h" 41 42 /* 43 * Constants and routines used to read and write TIPC payload message headers 44 * 45 * Note: Some items are also used with TIPC internal message headers 46 */ 47 48 #define TIPC_VERSION 2 49 50 /* 51 * Payload message users are defined in TIPC's public API: 52 * - TIPC_LOW_IMPORTANCE 53 * - TIPC_MEDIUM_IMPORTANCE 54 * - TIPC_HIGH_IMPORTANCE 55 * - TIPC_CRITICAL_IMPORTANCE 56 */ 57 58 /* 59 * Payload message types 60 */ 61 62 #define TIPC_CONN_MSG 0 63 #define TIPC_MCAST_MSG 1 64 #define TIPC_NAMED_MSG 2 65 #define TIPC_DIRECT_MSG 3 66 67 /* 68 * Message header sizes 69 */ 70 71 #define SHORT_H_SIZE 24 /* In-cluster basic payload message */ 72 #define BASIC_H_SIZE 32 /* Basic payload message */ 73 #define NAMED_H_SIZE 40 /* Named payload message */ 74 #define MCAST_H_SIZE 44 /* Multicast payload message */ 75 #define INT_H_SIZE 40 /* Internal messages */ 76 #define MIN_H_SIZE 24 /* Smallest legal TIPC header size */ 77 #define MAX_H_SIZE 60 /* Largest possible TIPC header size */ 78 79 #define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) 80 81 #define TIPC_MEDIA_ADDR_OFFSET 5 82 83 84 struct tipc_msg { 85 __be32 hdr[15]; 86 }; 87 88 89 static inline u32 msg_word(struct tipc_msg *m, u32 pos) 90 { 91 return ntohl(m->hdr[pos]); 92 } 93 94 static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val) 95 { 96 m->hdr[w] = htonl(val); 97 } 98 99 static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask) 100 { 101 return (msg_word(m, w) >> pos) & mask; 102 } 103 104 static inline void msg_set_bits(struct tipc_msg *m, u32 w, 105 u32 pos, u32 mask, u32 val) 106 { 107 val = (val & mask) << pos; 108 mask = mask << pos; 109 m->hdr[w] &= ~htonl(mask); 110 m->hdr[w] |= htonl(val); 111 } 112 113 static inline void msg_swap_words(struct tipc_msg *msg, u32 a, u32 b) 114 { 115 u32 temp = msg->hdr[a]; 116 117 msg->hdr[a] = msg->hdr[b]; 118 msg->hdr[b] = temp; 119 } 120 121 /* 122 * Word 0 123 */ 124 125 static inline u32 msg_version(struct tipc_msg *m) 126 { 127 return msg_bits(m, 0, 29, 7); 128 } 129 130 static inline void msg_set_version(struct tipc_msg *m) 131 { 132 msg_set_bits(m, 0, 29, 7, TIPC_VERSION); 133 } 134 135 static inline u32 msg_user(struct tipc_msg *m) 136 { 137 return msg_bits(m, 0, 25, 0xf); 138 } 139 140 static inline u32 msg_isdata(struct tipc_msg *m) 141 { 142 return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE; 143 } 144 145 static inline void msg_set_user(struct tipc_msg *m, u32 n) 146 { 147 msg_set_bits(m, 0, 25, 0xf, n); 148 } 149 150 static inline u32 msg_importance(struct tipc_msg *m) 151 { 152 return msg_bits(m, 0, 25, 0xf); 153 } 154 155 static inline void msg_set_importance(struct tipc_msg *m, u32 i) 156 { 157 msg_set_user(m, i); 158 } 159 160 static inline u32 msg_hdr_sz(struct tipc_msg *m) 161 { 162 return msg_bits(m, 0, 21, 0xf) << 2; 163 } 164 165 static inline void msg_set_hdr_sz(struct tipc_msg *m, u32 n) 166 { 167 msg_set_bits(m, 0, 21, 0xf, n>>2); 168 } 169 170 static inline u32 msg_size(struct tipc_msg *m) 171 { 172 return msg_bits(m, 0, 0, 0x1ffff); 173 } 174 175 static inline u32 msg_data_sz(struct tipc_msg *m) 176 { 177 return msg_size(m) - msg_hdr_sz(m); 178 } 179 180 static inline int msg_non_seq(struct tipc_msg *m) 181 { 182 return msg_bits(m, 0, 20, 1); 183 } 184 185 static inline void msg_set_non_seq(struct tipc_msg *m, u32 n) 186 { 187 msg_set_bits(m, 0, 20, 1, n); 188 } 189 190 static inline int msg_dest_droppable(struct tipc_msg *m) 191 { 192 return msg_bits(m, 0, 19, 1); 193 } 194 195 static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d) 196 { 197 msg_set_bits(m, 0, 19, 1, d); 198 } 199 200 static inline int msg_src_droppable(struct tipc_msg *m) 201 { 202 return msg_bits(m, 0, 18, 1); 203 } 204 205 static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d) 206 { 207 msg_set_bits(m, 0, 18, 1, d); 208 } 209 210 static inline void msg_set_size(struct tipc_msg *m, u32 sz) 211 { 212 m->hdr[0] = htonl((msg_word(m, 0) & ~0x1ffff) | sz); 213 } 214 215 216 /* 217 * Word 1 218 */ 219 220 static inline u32 msg_type(struct tipc_msg *m) 221 { 222 return msg_bits(m, 1, 29, 0x7); 223 } 224 225 static inline void msg_set_type(struct tipc_msg *m, u32 n) 226 { 227 msg_set_bits(m, 1, 29, 0x7, n); 228 } 229 230 static inline u32 msg_named(struct tipc_msg *m) 231 { 232 return msg_type(m) == TIPC_NAMED_MSG; 233 } 234 235 static inline u32 msg_mcast(struct tipc_msg *m) 236 { 237 return msg_type(m) == TIPC_MCAST_MSG; 238 } 239 240 static inline u32 msg_connected(struct tipc_msg *m) 241 { 242 return msg_type(m) == TIPC_CONN_MSG; 243 } 244 245 static inline u32 msg_errcode(struct tipc_msg *m) 246 { 247 return msg_bits(m, 1, 25, 0xf); 248 } 249 250 static inline void msg_set_errcode(struct tipc_msg *m, u32 err) 251 { 252 msg_set_bits(m, 1, 25, 0xf, err); 253 } 254 255 static inline u32 msg_reroute_cnt(struct tipc_msg *m) 256 { 257 return msg_bits(m, 1, 21, 0xf); 258 } 259 260 static inline void msg_incr_reroute_cnt(struct tipc_msg *m) 261 { 262 msg_set_bits(m, 1, 21, 0xf, msg_reroute_cnt(m) + 1); 263 } 264 265 static inline void msg_reset_reroute_cnt(struct tipc_msg *m) 266 { 267 msg_set_bits(m, 1, 21, 0xf, 0); 268 } 269 270 static inline u32 msg_lookup_scope(struct tipc_msg *m) 271 { 272 return msg_bits(m, 1, 19, 0x3); 273 } 274 275 static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n) 276 { 277 msg_set_bits(m, 1, 19, 0x3, n); 278 } 279 280 static inline u32 msg_bcast_ack(struct tipc_msg *m) 281 { 282 return msg_bits(m, 1, 0, 0xffff); 283 } 284 285 static inline void msg_set_bcast_ack(struct tipc_msg *m, u32 n) 286 { 287 msg_set_bits(m, 1, 0, 0xffff, n); 288 } 289 290 291 /* 292 * Word 2 293 */ 294 295 static inline u32 msg_ack(struct tipc_msg *m) 296 { 297 return msg_bits(m, 2, 16, 0xffff); 298 } 299 300 static inline void msg_set_ack(struct tipc_msg *m, u32 n) 301 { 302 msg_set_bits(m, 2, 16, 0xffff, n); 303 } 304 305 static inline u32 msg_seqno(struct tipc_msg *m) 306 { 307 return msg_bits(m, 2, 0, 0xffff); 308 } 309 310 static inline void msg_set_seqno(struct tipc_msg *m, u32 n) 311 { 312 msg_set_bits(m, 2, 0, 0xffff, n); 313 } 314 315 /* 316 * Words 3-10 317 */ 318 319 320 static inline u32 msg_prevnode(struct tipc_msg *m) 321 { 322 return msg_word(m, 3); 323 } 324 325 static inline void msg_set_prevnode(struct tipc_msg *m, u32 a) 326 { 327 msg_set_word(m, 3, a); 328 } 329 330 static inline u32 msg_origport(struct tipc_msg *m) 331 { 332 return msg_word(m, 4); 333 } 334 335 static inline void msg_set_origport(struct tipc_msg *m, u32 p) 336 { 337 msg_set_word(m, 4, p); 338 } 339 340 static inline u32 msg_destport(struct tipc_msg *m) 341 { 342 return msg_word(m, 5); 343 } 344 345 static inline void msg_set_destport(struct tipc_msg *m, u32 p) 346 { 347 msg_set_word(m, 5, p); 348 } 349 350 static inline u32 msg_mc_netid(struct tipc_msg *m) 351 { 352 return msg_word(m, 5); 353 } 354 355 static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p) 356 { 357 msg_set_word(m, 5, p); 358 } 359 360 static inline int msg_short(struct tipc_msg *m) 361 { 362 return msg_hdr_sz(m) == SHORT_H_SIZE; 363 } 364 365 static inline u32 msg_orignode(struct tipc_msg *m) 366 { 367 if (likely(msg_short(m))) 368 return msg_prevnode(m); 369 return msg_word(m, 6); 370 } 371 372 static inline void msg_set_orignode(struct tipc_msg *m, u32 a) 373 { 374 msg_set_word(m, 6, a); 375 } 376 377 static inline u32 msg_destnode(struct tipc_msg *m) 378 { 379 return msg_word(m, 7); 380 } 381 382 static inline void msg_set_destnode(struct tipc_msg *m, u32 a) 383 { 384 msg_set_word(m, 7, a); 385 } 386 387 static inline int msg_is_dest(struct tipc_msg *m, u32 d) 388 { 389 return msg_short(m) || (msg_destnode(m) == d); 390 } 391 392 static inline u32 msg_nametype(struct tipc_msg *m) 393 { 394 return msg_word(m, 8); 395 } 396 397 static inline void msg_set_nametype(struct tipc_msg *m, u32 n) 398 { 399 msg_set_word(m, 8, n); 400 } 401 402 static inline u32 msg_nameinst(struct tipc_msg *m) 403 { 404 return msg_word(m, 9); 405 } 406 407 static inline u32 msg_namelower(struct tipc_msg *m) 408 { 409 return msg_nameinst(m); 410 } 411 412 static inline void msg_set_namelower(struct tipc_msg *m, u32 n) 413 { 414 msg_set_word(m, 9, n); 415 } 416 417 static inline void msg_set_nameinst(struct tipc_msg *m, u32 n) 418 { 419 msg_set_namelower(m, n); 420 } 421 422 static inline u32 msg_nameupper(struct tipc_msg *m) 423 { 424 return msg_word(m, 10); 425 } 426 427 static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) 428 { 429 msg_set_word(m, 10, n); 430 } 431 432 static inline unchar *msg_data(struct tipc_msg *m) 433 { 434 return ((unchar *)m) + msg_hdr_sz(m); 435 } 436 437 static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) 438 { 439 return (struct tipc_msg *)msg_data(m); 440 } 441 442 443 /* 444 * Constants and routines used to read and write TIPC internal message headers 445 */ 446 447 /* 448 * Internal message users 449 */ 450 451 #define BCAST_PROTOCOL 5 452 #define MSG_BUNDLER 6 453 #define LINK_PROTOCOL 7 454 #define CONN_MANAGER 8 455 #define ROUTE_DISTRIBUTOR 9 /* obsoleted */ 456 #define CHANGEOVER_PROTOCOL 10 457 #define NAME_DISTRIBUTOR 11 458 #define MSG_FRAGMENTER 12 459 #define LINK_CONFIG 13 460 461 /* 462 * Connection management protocol message types 463 */ 464 465 #define CONN_PROBE 0 466 #define CONN_PROBE_REPLY 1 467 #define CONN_ACK 2 468 469 /* 470 * Name distributor message types 471 */ 472 473 #define PUBLICATION 0 474 #define WITHDRAWAL 1 475 476 /* 477 * Segmentation message types 478 */ 479 480 #define FIRST_FRAGMENT 0 481 #define FRAGMENT 1 482 #define LAST_FRAGMENT 2 483 484 /* 485 * Link management protocol message types 486 */ 487 488 #define STATE_MSG 0 489 #define RESET_MSG 1 490 #define ACTIVATE_MSG 2 491 492 /* 493 * Changeover tunnel message types 494 */ 495 #define DUPLICATE_MSG 0 496 #define ORIGINAL_MSG 1 497 498 /* 499 * Config protocol message types 500 */ 501 502 #define DSC_REQ_MSG 0 503 #define DSC_RESP_MSG 1 504 505 506 /* 507 * Word 1 508 */ 509 510 static inline u32 msg_seq_gap(struct tipc_msg *m) 511 { 512 return msg_bits(m, 1, 16, 0x1fff); 513 } 514 515 static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) 516 { 517 msg_set_bits(m, 1, 16, 0x1fff, n); 518 } 519 520 521 /* 522 * Word 2 523 */ 524 525 static inline u32 msg_dest_domain(struct tipc_msg *m) 526 { 527 return msg_word(m, 2); 528 } 529 530 static inline void msg_set_dest_domain(struct tipc_msg *m, u32 n) 531 { 532 msg_set_word(m, 2, n); 533 } 534 535 static inline u32 msg_bcgap_after(struct tipc_msg *m) 536 { 537 return msg_bits(m, 2, 16, 0xffff); 538 } 539 540 static inline void msg_set_bcgap_after(struct tipc_msg *m, u32 n) 541 { 542 msg_set_bits(m, 2, 16, 0xffff, n); 543 } 544 545 static inline u32 msg_bcgap_to(struct tipc_msg *m) 546 { 547 return msg_bits(m, 2, 0, 0xffff); 548 } 549 550 static inline void msg_set_bcgap_to(struct tipc_msg *m, u32 n) 551 { 552 msg_set_bits(m, 2, 0, 0xffff, n); 553 } 554 555 556 /* 557 * Word 4 558 */ 559 560 static inline u32 msg_last_bcast(struct tipc_msg *m) 561 { 562 return msg_bits(m, 4, 16, 0xffff); 563 } 564 565 static inline void msg_set_last_bcast(struct tipc_msg *m, u32 n) 566 { 567 msg_set_bits(m, 4, 16, 0xffff, n); 568 } 569 570 571 static inline u32 msg_fragm_no(struct tipc_msg *m) 572 { 573 return msg_bits(m, 4, 16, 0xffff); 574 } 575 576 static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n) 577 { 578 msg_set_bits(m, 4, 16, 0xffff, n); 579 } 580 581 582 static inline u32 msg_next_sent(struct tipc_msg *m) 583 { 584 return msg_bits(m, 4, 0, 0xffff); 585 } 586 587 static inline void msg_set_next_sent(struct tipc_msg *m, u32 n) 588 { 589 msg_set_bits(m, 4, 0, 0xffff, n); 590 } 591 592 593 static inline u32 msg_long_msgno(struct tipc_msg *m) 594 { 595 return msg_bits(m, 4, 0, 0xffff); 596 } 597 598 static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n) 599 { 600 msg_set_bits(m, 4, 0, 0xffff, n); 601 } 602 603 static inline u32 msg_bc_netid(struct tipc_msg *m) 604 { 605 return msg_word(m, 4); 606 } 607 608 static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id) 609 { 610 msg_set_word(m, 4, id); 611 } 612 613 static inline u32 msg_link_selector(struct tipc_msg *m) 614 { 615 return msg_bits(m, 4, 0, 1); 616 } 617 618 static inline void msg_set_link_selector(struct tipc_msg *m, u32 n) 619 { 620 msg_set_bits(m, 4, 0, 1, n); 621 } 622 623 /* 624 * Word 5 625 */ 626 627 static inline u32 msg_session(struct tipc_msg *m) 628 { 629 return msg_bits(m, 5, 16, 0xffff); 630 } 631 632 static inline void msg_set_session(struct tipc_msg *m, u32 n) 633 { 634 msg_set_bits(m, 5, 16, 0xffff, n); 635 } 636 637 static inline u32 msg_probe(struct tipc_msg *m) 638 { 639 return msg_bits(m, 5, 0, 1); 640 } 641 642 static inline void msg_set_probe(struct tipc_msg *m, u32 val) 643 { 644 msg_set_bits(m, 5, 0, 1, val); 645 } 646 647 static inline char msg_net_plane(struct tipc_msg *m) 648 { 649 return msg_bits(m, 5, 1, 7) + 'A'; 650 } 651 652 static inline void msg_set_net_plane(struct tipc_msg *m, char n) 653 { 654 msg_set_bits(m, 5, 1, 7, (n - 'A')); 655 } 656 657 static inline u32 msg_linkprio(struct tipc_msg *m) 658 { 659 return msg_bits(m, 5, 4, 0x1f); 660 } 661 662 static inline void msg_set_linkprio(struct tipc_msg *m, u32 n) 663 { 664 msg_set_bits(m, 5, 4, 0x1f, n); 665 } 666 667 static inline u32 msg_bearer_id(struct tipc_msg *m) 668 { 669 return msg_bits(m, 5, 9, 0x7); 670 } 671 672 static inline void msg_set_bearer_id(struct tipc_msg *m, u32 n) 673 { 674 msg_set_bits(m, 5, 9, 0x7, n); 675 } 676 677 static inline u32 msg_redundant_link(struct tipc_msg *m) 678 { 679 return msg_bits(m, 5, 12, 0x1); 680 } 681 682 static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r) 683 { 684 msg_set_bits(m, 5, 12, 0x1, r); 685 } 686 687 static inline char *msg_media_addr(struct tipc_msg *m) 688 { 689 return (char *)&m->hdr[TIPC_MEDIA_ADDR_OFFSET]; 690 } 691 692 /* 693 * Word 9 694 */ 695 696 static inline u32 msg_msgcnt(struct tipc_msg *m) 697 { 698 return msg_bits(m, 9, 16, 0xffff); 699 } 700 701 static inline void msg_set_msgcnt(struct tipc_msg *m, u32 n) 702 { 703 msg_set_bits(m, 9, 16, 0xffff, n); 704 } 705 706 static inline u32 msg_bcast_tag(struct tipc_msg *m) 707 { 708 return msg_bits(m, 9, 16, 0xffff); 709 } 710 711 static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n) 712 { 713 msg_set_bits(m, 9, 16, 0xffff, n); 714 } 715 716 static inline u32 msg_max_pkt(struct tipc_msg *m) 717 { 718 return msg_bits(m, 9, 16, 0xffff) * 4; 719 } 720 721 static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) 722 { 723 msg_set_bits(m, 9, 16, 0xffff, (n / 4)); 724 } 725 726 static inline u32 msg_link_tolerance(struct tipc_msg *m) 727 { 728 return msg_bits(m, 9, 0, 0xffff); 729 } 730 731 static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n) 732 { 733 msg_set_bits(m, 9, 0, 0xffff, n); 734 } 735 736 u32 tipc_msg_tot_importance(struct tipc_msg *m); 737 void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, 738 u32 hsize, u32 destnode); 739 int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, 740 u32 num_sect, unsigned int total_len, 741 int max_size, int usrmem, struct sk_buff **buf); 742 743 #endif 744