at v2.6.23-rc5 820 lines 19 kB view raw
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 66static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val) 67{ 68 m->hdr[w] = htonl(val); 69} 70 71static 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 83static inline u32 msg_version(struct tipc_msg *m) 84{ 85 return msg_bits(m, 0, 29, 7); 86} 87 88static inline void msg_set_version(struct tipc_msg *m) 89{ 90 msg_set_bits(m, 0, 29, 0xf, TIPC_VERSION); 91} 92 93static inline u32 msg_user(struct tipc_msg *m) 94{ 95 return msg_bits(m, 0, 25, 0xf); 96} 97 98static inline u32 msg_isdata(struct tipc_msg *m) 99{ 100 return (msg_user(m) <= DATA_CRITICAL); 101} 102 103static inline void msg_set_user(struct tipc_msg *m, u32 n) 104{ 105 msg_set_bits(m, 0, 25, 0xf, n); 106} 107 108static inline void msg_set_importance(struct tipc_msg *m, u32 i) 109{ 110 msg_set_user(m, i); 111} 112 113static 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 118static inline int msg_non_seq(struct tipc_msg *m) 119{ 120 return msg_bits(m, 0, 20, 1); 121} 122 123static inline void msg_set_non_seq(struct tipc_msg *m) 124{ 125 msg_set_bits(m, 0, 20, 1, 1); 126} 127 128static inline int msg_dest_droppable(struct tipc_msg *m) 129{ 130 return msg_bits(m, 0, 19, 1); 131} 132 133static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d) 134{ 135 msg_set_bits(m, 0, 19, 1, d); 136} 137 138static inline int msg_src_droppable(struct tipc_msg *m) 139{ 140 return msg_bits(m, 0, 18, 1); 141} 142 143static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d) 144{ 145 msg_set_bits(m, 0, 18, 1, d); 146} 147 148static 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 158static inline void msg_set_type(struct tipc_msg *m, u32 n) 159{ 160 msg_set_bits(m, 1, 29, 0x7, n); 161} 162 163static inline void msg_set_errcode(struct tipc_msg *m, u32 err) 164{ 165 msg_set_bits(m, 1, 25, 0xf, err); 166} 167 168static inline u32 msg_reroute_cnt(struct tipc_msg *m) 169{ 170 return msg_bits(m, 1, 21, 0xf); 171} 172 173static 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 178static inline void msg_reset_reroute_cnt(struct tipc_msg *m) 179{ 180 msg_set_bits(m, 1, 21, 0xf, 0); 181} 182 183static inline u32 msg_lookup_scope(struct tipc_msg *m) 184{ 185 return msg_bits(m, 1, 19, 0x3); 186} 187 188static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n) 189{ 190 msg_set_bits(m, 1, 19, 0x3, n); 191} 192 193static 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 205static inline u32 msg_bcast_ack(struct tipc_msg *m) 206{ 207 return msg_bits(m, 1, 0, 0xffff); 208} 209 210static 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 220static inline u32 msg_ack(struct tipc_msg *m) 221{ 222 return msg_bits(m, 2, 16, 0xffff); 223} 224 225static inline void msg_set_ack(struct tipc_msg *m, u32 n) 226{ 227 msg_set_bits(m, 2, 16, 0xffff, n); 228} 229 230static inline u32 msg_seqno(struct tipc_msg *m) 231{ 232 return msg_bits(m, 2, 0, 0xffff); 233} 234 235static 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 246static inline void msg_set_prevnode(struct tipc_msg *m, u32 a) 247{ 248 msg_set_word(m, 3, a); 249} 250 251static inline void msg_set_origport(struct tipc_msg *m, u32 p) 252{ 253 msg_set_word(m, 4, p); 254} 255 256static inline void msg_set_destport(struct tipc_msg *m, u32 p) 257{ 258 msg_set_word(m, 5, p); 259} 260 261static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p) 262{ 263 msg_set_word(m, 5, p); 264} 265 266static inline void msg_set_orignode(struct tipc_msg *m, u32 a) 267{ 268 msg_set_word(m, 6, a); 269} 270 271static inline void msg_set_destnode(struct tipc_msg *m, u32 a) 272{ 273 msg_set_word(m, 7, a); 274} 275 276static inline int msg_is_dest(struct tipc_msg *m, u32 d) 277{ 278 return(msg_short(m) || (msg_destnode(m) == d)); 279} 280 281static 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 288static inline void msg_set_nametype(struct tipc_msg *m, u32 n) 289{ 290 msg_set_word(m, 8, n); 291} 292 293static inline u32 msg_transp_seqno(struct tipc_msg *m) 294{ 295 return msg_word(m, 8); 296} 297 298static inline void msg_set_timestamp(struct tipc_msg *m, u32 n) 299{ 300 msg_set_word(m, 8, n); 301} 302 303static inline u32 msg_timestamp(struct tipc_msg *m) 304{ 305 return msg_word(m, 8); 306} 307 308static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n) 309{ 310 msg_set_word(m, 8, n); 311} 312 313static inline void msg_set_namelower(struct tipc_msg *m, u32 n) 314{ 315 msg_set_word(m, 9, n); 316} 317 318static inline void msg_set_nameinst(struct tipc_msg *m, u32 n) 319{ 320 msg_set_namelower(m, n); 321} 322 323static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) 324{ 325 msg_set_word(m, 10, n); 326} 327 328static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) 329{ 330 return (struct tipc_msg *)msg_data(m); 331} 332 333static 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 414static inline u32 msg_seq_gap(struct tipc_msg *m) 415{ 416 return msg_bits(m, 1, 16, 0xff); 417} 418 419static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) 420{ 421 msg_set_bits(m, 1, 16, 0xff, n); 422} 423 424static inline u32 msg_req_links(struct tipc_msg *m) 425{ 426 return msg_bits(m, 1, 16, 0xfff); 427} 428 429static 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 439static inline u32 msg_dest_domain(struct tipc_msg *m) 440{ 441 return msg_word(m, 2); 442} 443 444static inline void msg_set_dest_domain(struct tipc_msg *m, u32 n) 445{ 446 msg_set_word(m, 2, n); 447} 448 449static inline u32 msg_bcgap_after(struct tipc_msg *m) 450{ 451 return msg_bits(m, 2, 16, 0xffff); 452} 453 454static inline void msg_set_bcgap_after(struct tipc_msg *m, u32 n) 455{ 456 msg_set_bits(m, 2, 16, 0xffff, n); 457} 458 459static inline u32 msg_bcgap_to(struct tipc_msg *m) 460{ 461 return msg_bits(m, 2, 0, 0xffff); 462} 463 464static 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 474static inline u32 msg_last_bcast(struct tipc_msg *m) 475{ 476 return msg_bits(m, 4, 16, 0xffff); 477} 478 479static 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 485static inline u32 msg_fragm_no(struct tipc_msg *m) 486{ 487 return msg_bits(m, 4, 16, 0xffff); 488} 489 490static 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 496static inline u32 msg_next_sent(struct tipc_msg *m) 497{ 498 return msg_bits(m, 4, 0, 0xffff); 499} 500 501static 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 507static inline u32 msg_long_msgno(struct tipc_msg *m) 508{ 509 return msg_bits(m, 4, 0, 0xffff); 510} 511 512static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n) 513{ 514 msg_set_bits(m, 4, 0, 0xffff, n); 515} 516 517static inline u32 msg_bc_netid(struct tipc_msg *m) 518{ 519 return msg_word(m, 4); 520} 521 522static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id) 523{ 524 msg_set_word(m, 4, id); 525} 526 527static inline u32 msg_link_selector(struct tipc_msg *m) 528{ 529 return msg_bits(m, 4, 0, 1); 530} 531 532static 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 541static inline u32 msg_session(struct tipc_msg *m) 542{ 543 return msg_bits(m, 5, 16, 0xffff); 544} 545 546static inline void msg_set_session(struct tipc_msg *m, u32 n) 547{ 548 msg_set_bits(m, 5, 16, 0xffff, n); 549} 550 551static inline u32 msg_probe(struct tipc_msg *m) 552{ 553 return msg_bits(m, 5, 0, 1); 554} 555 556static inline void msg_set_probe(struct tipc_msg *m, u32 val) 557{ 558 msg_set_bits(m, 5, 0, 1, (val & 1)); 559} 560 561static inline char msg_net_plane(struct tipc_msg *m) 562{ 563 return msg_bits(m, 5, 1, 7) + 'A'; 564} 565 566static 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 571static inline u32 msg_linkprio(struct tipc_msg *m) 572{ 573 return msg_bits(m, 5, 4, 0x1f); 574} 575 576static inline void msg_set_linkprio(struct tipc_msg *m, u32 n) 577{ 578 msg_set_bits(m, 5, 4, 0x1f, n); 579} 580 581static inline u32 msg_bearer_id(struct tipc_msg *m) 582{ 583 return msg_bits(m, 5, 9, 0x7); 584} 585 586static inline void msg_set_bearer_id(struct tipc_msg *m, u32 n) 587{ 588 msg_set_bits(m, 5, 9, 0x7, n); 589} 590 591static inline u32 msg_redundant_link(struct tipc_msg *m) 592{ 593 return msg_bits(m, 5, 12, 0x1); 594} 595 596static inline void msg_set_redundant_link(struct tipc_msg *m) 597{ 598 msg_set_bits(m, 5, 12, 0x1, 1); 599} 600 601static 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 611static inline u32 msg_msgcnt(struct tipc_msg *m) 612{ 613 return msg_bits(m, 9, 16, 0xffff); 614} 615 616static inline void msg_set_msgcnt(struct tipc_msg *m, u32 n) 617{ 618 msg_set_bits(m, 9, 16, 0xffff, n); 619} 620 621static inline u32 msg_bcast_tag(struct tipc_msg *m) 622{ 623 return msg_bits(m, 9, 16, 0xffff); 624} 625 626static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n) 627{ 628 msg_set_bits(m, 9, 16, 0xffff, n); 629} 630 631static inline u32 msg_max_pkt(struct tipc_msg *m) 632{ 633 return (msg_bits(m, 9, 16, 0xffff) * 4); 634} 635 636static 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 641static inline u32 msg_link_tolerance(struct tipc_msg *m) 642{ 643 return msg_bits(m, 9, 0, 0xffff); 644} 645 646static 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 656static inline u32 msg_remote_node(struct tipc_msg *m) 657{ 658 return msg_word(m, msg_hdr_sz(m)/4); 659} 660 661static 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 666static inline int msg_dataoctet(struct tipc_msg *m, u32 pos) 667{ 668 return(msg_data(m)[pos + 4] != 0); 669} 670 671static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos) 672{ 673 msg_data(m)[pos + 4] = 1; 674} 675 676/* 677 * Segmentation message types 678 */ 679 680#define FIRST_FRAGMENT 0 681#define FRAGMENT 1 682#define LAST_FRAGMENT 2 683 684/* 685 * Link management protocol message types 686 */ 687 688#define STATE_MSG 0 689#define RESET_MSG 1 690#define ACTIVATE_MSG 2 691 692/* 693 * Changeover tunnel message types 694 */ 695#define DUPLICATE_MSG 0 696#define ORIGINAL_MSG 1 697 698/* 699 * Routing table message types 700 */ 701#define EXT_ROUTING_TABLE 0 702#define LOCAL_ROUTING_TABLE 1 703#define SLAVE_ROUTING_TABLE 2 704#define ROUTE_ADDITION 3 705#define ROUTE_REMOVAL 4 706 707/* 708 * Config protocol message types 709 */ 710 711#define DSC_REQ_MSG 0 712#define DSC_RESP_MSG 1 713 714static inline u32 msg_tot_importance(struct tipc_msg *m) 715{ 716 if (likely(msg_isdata(m))) { 717 if (likely(msg_orignode(m) == tipc_own_addr)) 718 return msg_importance(m); 719 return msg_importance(m) + 4; 720 } 721 if ((msg_user(m) == MSG_FRAGMENTER) && 722 (msg_type(m) == FIRST_FRAGMENT)) 723 return msg_importance(msg_get_wrapped(m)); 724 return msg_importance(m); 725} 726 727 728static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, 729 u32 err, u32 hsize, u32 destnode) 730{ 731 memset(m, 0, hsize); 732 msg_set_version(m); 733 msg_set_user(m, user); 734 msg_set_hdr_sz(m, hsize); 735 msg_set_size(m, hsize); 736 msg_set_prevnode(m, tipc_own_addr); 737 msg_set_type(m, type); 738 msg_set_errcode(m, err); 739 if (!msg_short(m)) { 740 msg_set_orignode(m, tipc_own_addr); 741 msg_set_destnode(m, destnode); 742 } 743} 744 745/** 746 * msg_calc_data_size - determine total data size for message 747 */ 748 749static inline int msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) 750{ 751 int dsz = 0; 752 int i; 753 754 for (i = 0; i < num_sect; i++) 755 dsz += msg_sect[i].iov_len; 756 return dsz; 757} 758 759/** 760 * msg_build - create message using specified header and data 761 * 762 * Note: Caller must not hold any locks in case copy_from_user() is interrupted! 763 * 764 * Returns message data size or errno 765 */ 766 767static inline int msg_build(struct tipc_msg *hdr, 768 struct iovec const *msg_sect, u32 num_sect, 769 int max_size, int usrmem, struct sk_buff** buf) 770{ 771 int dsz, sz, hsz, pos, res, cnt; 772 773 dsz = msg_calc_data_size(msg_sect, num_sect); 774 if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) { 775 *buf = NULL; 776 return -EINVAL; 777 } 778 779 pos = hsz = msg_hdr_sz(hdr); 780 sz = hsz + dsz; 781 msg_set_size(hdr, sz); 782 if (unlikely(sz > max_size)) { 783 *buf = NULL; 784 return dsz; 785 } 786 787 *buf = buf_acquire(sz); 788 if (!(*buf)) 789 return -ENOMEM; 790 skb_copy_to_linear_data(*buf, hdr, hsz); 791 for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { 792 if (likely(usrmem)) 793 res = !copy_from_user((*buf)->data + pos, 794 msg_sect[cnt].iov_base, 795 msg_sect[cnt].iov_len); 796 else 797 skb_copy_to_linear_data_offset(*buf, pos, 798 msg_sect[cnt].iov_base, 799 msg_sect[cnt].iov_len); 800 pos += msg_sect[cnt].iov_len; 801 } 802 if (likely(res)) 803 return dsz; 804 805 buf_discard(*buf); 806 *buf = NULL; 807 return -EFAULT; 808} 809 810static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 811{ 812 memcpy(&((int *)m)[5], a, sizeof(*a)); 813} 814 815static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) 816{ 817 memcpy(a, &((int*)m)[5], sizeof(*a)); 818} 819 820#endif