linux/net/tipc/msg.h
<<
>>
Prefs
   1/*
   2 * net/tipc/msg.h: Include file for TIPC message header routines
   3 *
   4 * Copyright (c) 2000-2007, 2014-2015 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 <linux/tipc.h>
  41#include "core.h"
  42
  43/*
  44 * Constants and routines used to read and write TIPC payload message headers
  45 *
  46 * Note: Some items are also used with TIPC internal message headers
  47 */
  48#define TIPC_VERSION              2
  49struct plist;
  50
  51/*
  52 * Payload message users are defined in TIPC's public API:
  53 * - TIPC_LOW_IMPORTANCE
  54 * - TIPC_MEDIUM_IMPORTANCE
  55 * - TIPC_HIGH_IMPORTANCE
  56 * - TIPC_CRITICAL_IMPORTANCE
  57 */
  58#define TIPC_SYSTEM_IMPORTANCE  4
  59
  60
  61/*
  62 * Payload message types
  63 */
  64#define TIPC_CONN_MSG           0
  65#define TIPC_MCAST_MSG          1
  66#define TIPC_NAMED_MSG          2
  67#define TIPC_DIRECT_MSG         3
  68
  69/*
  70 * Internal message users
  71 */
  72#define  BCAST_PROTOCOL       5
  73#define  MSG_BUNDLER          6
  74#define  LINK_PROTOCOL        7
  75#define  CONN_MANAGER         8
  76#define  TUNNEL_PROTOCOL      10
  77#define  NAME_DISTRIBUTOR     11
  78#define  MSG_FRAGMENTER       12
  79#define  LINK_CONFIG          13
  80#define  SOCK_WAKEUP          14       /* pseudo user */
  81
  82/*
  83 * Message header sizes
  84 */
  85#define SHORT_H_SIZE              24    /* In-cluster basic payload message */
  86#define BASIC_H_SIZE              32    /* Basic payload message */
  87#define NAMED_H_SIZE              40    /* Named payload message */
  88#define MCAST_H_SIZE              44    /* Multicast payload message */
  89#define INT_H_SIZE                40    /* Internal messages */
  90#define MIN_H_SIZE                24    /* Smallest legal TIPC header size */
  91#define MAX_H_SIZE                60    /* Largest possible TIPC header size */
  92
  93#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE)
  94
  95#define TIPC_MEDIA_INFO_OFFSET  5
  96
  97struct tipc_skb_cb {
  98        u32 bytes_read;
  99        struct sk_buff *tail;
 100        bool validated;
 101        u16 chain_imp;
 102        u16 ackers;
 103};
 104
 105#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0]))
 106
 107struct tipc_msg {
 108        __be32 hdr[15];
 109};
 110
 111static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
 112{
 113        return (struct tipc_msg *)skb->data;
 114}
 115
 116static inline u32 msg_word(struct tipc_msg *m, u32 pos)
 117{
 118        return ntohl(m->hdr[pos]);
 119}
 120
 121static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val)
 122{
 123        m->hdr[w] = htonl(val);
 124}
 125
 126static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask)
 127{
 128        return (msg_word(m, w) >> pos) & mask;
 129}
 130
 131static inline void msg_set_bits(struct tipc_msg *m, u32 w,
 132                                u32 pos, u32 mask, u32 val)
 133{
 134        val = (val & mask) << pos;
 135        mask = mask << pos;
 136        m->hdr[w] &= ~htonl(mask);
 137        m->hdr[w] |= htonl(val);
 138}
 139
 140static inline void msg_swap_words(struct tipc_msg *msg, u32 a, u32 b)
 141{
 142        u32 temp = msg->hdr[a];
 143
 144        msg->hdr[a] = msg->hdr[b];
 145        msg->hdr[b] = temp;
 146}
 147
 148/*
 149 * Word 0
 150 */
 151static inline u32 msg_version(struct tipc_msg *m)
 152{
 153        return msg_bits(m, 0, 29, 7);
 154}
 155
 156static inline void msg_set_version(struct tipc_msg *m)
 157{
 158        msg_set_bits(m, 0, 29, 7, TIPC_VERSION);
 159}
 160
 161static inline u32 msg_user(struct tipc_msg *m)
 162{
 163        return msg_bits(m, 0, 25, 0xf);
 164}
 165
 166static inline u32 msg_isdata(struct tipc_msg *m)
 167{
 168        return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE;
 169}
 170
 171static inline void msg_set_user(struct tipc_msg *m, u32 n)
 172{
 173        msg_set_bits(m, 0, 25, 0xf, n);
 174}
 175
 176static inline u32 msg_hdr_sz(struct tipc_msg *m)
 177{
 178        return msg_bits(m, 0, 21, 0xf) << 2;
 179}
 180
 181static inline void msg_set_hdr_sz(struct tipc_msg *m, u32 n)
 182{
 183        msg_set_bits(m, 0, 21, 0xf, n>>2);
 184}
 185
 186static inline u32 msg_size(struct tipc_msg *m)
 187{
 188        return msg_bits(m, 0, 0, 0x1ffff);
 189}
 190
 191static inline u32 msg_data_sz(struct tipc_msg *m)
 192{
 193        return msg_size(m) - msg_hdr_sz(m);
 194}
 195
 196static inline int msg_non_seq(struct tipc_msg *m)
 197{
 198        return msg_bits(m, 0, 20, 1);
 199}
 200
 201static inline void msg_set_non_seq(struct tipc_msg *m, u32 n)
 202{
 203        msg_set_bits(m, 0, 20, 1, n);
 204}
 205
 206static inline int msg_dest_droppable(struct tipc_msg *m)
 207{
 208        return msg_bits(m, 0, 19, 1);
 209}
 210
 211static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d)
 212{
 213        msg_set_bits(m, 0, 19, 1, d);
 214}
 215
 216static inline int msg_src_droppable(struct tipc_msg *m)
 217{
 218        return msg_bits(m, 0, 18, 1);
 219}
 220
 221static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d)
 222{
 223        msg_set_bits(m, 0, 18, 1, d);
 224}
 225
 226static inline void msg_set_size(struct tipc_msg *m, u32 sz)
 227{
 228        m->hdr[0] = htonl((msg_word(m, 0) & ~0x1ffff) | sz);
 229}
 230
 231static inline unchar *msg_data(struct tipc_msg *m)
 232{
 233        return ((unchar *)m) + msg_hdr_sz(m);
 234}
 235
 236static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
 237{
 238        return (struct tipc_msg *)msg_data(m);
 239}
 240
 241/*
 242 * Word 1
 243 */
 244static inline u32 msg_type(struct tipc_msg *m)
 245{
 246        return msg_bits(m, 1, 29, 0x7);
 247}
 248
 249static inline void msg_set_type(struct tipc_msg *m, u32 n)
 250{
 251        msg_set_bits(m, 1, 29, 0x7, n);
 252}
 253
 254static inline u32 msg_named(struct tipc_msg *m)
 255{
 256        return msg_type(m) == TIPC_NAMED_MSG;
 257}
 258
 259static inline u32 msg_mcast(struct tipc_msg *m)
 260{
 261        return msg_type(m) == TIPC_MCAST_MSG;
 262}
 263
 264static inline u32 msg_connected(struct tipc_msg *m)
 265{
 266        return msg_type(m) == TIPC_CONN_MSG;
 267}
 268
 269static inline u32 msg_errcode(struct tipc_msg *m)
 270{
 271        return msg_bits(m, 1, 25, 0xf);
 272}
 273
 274static inline void msg_set_errcode(struct tipc_msg *m, u32 err)
 275{
 276        msg_set_bits(m, 1, 25, 0xf, err);
 277}
 278
 279static inline u32 msg_reroute_cnt(struct tipc_msg *m)
 280{
 281        return msg_bits(m, 1, 21, 0xf);
 282}
 283
 284static inline void msg_incr_reroute_cnt(struct tipc_msg *m)
 285{
 286        msg_set_bits(m, 1, 21, 0xf, msg_reroute_cnt(m) + 1);
 287}
 288
 289static inline void msg_reset_reroute_cnt(struct tipc_msg *m)
 290{
 291        msg_set_bits(m, 1, 21, 0xf, 0);
 292}
 293
 294static inline u32 msg_lookup_scope(struct tipc_msg *m)
 295{
 296        return msg_bits(m, 1, 19, 0x3);
 297}
 298
 299static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n)
 300{
 301        msg_set_bits(m, 1, 19, 0x3, n);
 302}
 303
 304static inline u16 msg_bcast_ack(struct tipc_msg *m)
 305{
 306        return msg_bits(m, 1, 0, 0xffff);
 307}
 308
 309static inline void msg_set_bcast_ack(struct tipc_msg *m, u16 n)
 310{
 311        msg_set_bits(m, 1, 0, 0xffff, n);
 312}
 313
 314
 315/*
 316 * Word 2
 317 */
 318static inline u16 msg_ack(struct tipc_msg *m)
 319{
 320        return msg_bits(m, 2, 16, 0xffff);
 321}
 322
 323static inline void msg_set_ack(struct tipc_msg *m, u16 n)
 324{
 325        msg_set_bits(m, 2, 16, 0xffff, n);
 326}
 327
 328static inline u16 msg_seqno(struct tipc_msg *m)
 329{
 330        return msg_bits(m, 2, 0, 0xffff);
 331}
 332
 333static inline void msg_set_seqno(struct tipc_msg *m, u16 n)
 334{
 335        msg_set_bits(m, 2, 0, 0xffff, n);
 336}
 337
 338/*
 339 * Words 3-10
 340 */
 341static inline u32 msg_importance(struct tipc_msg *m)
 342{
 343        int usr = msg_user(m);
 344
 345        if (likely((usr <= TIPC_CRITICAL_IMPORTANCE) && !msg_errcode(m)))
 346                return usr;
 347        if ((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER))
 348                return msg_bits(m, 9, 0, 0x7);
 349        return TIPC_SYSTEM_IMPORTANCE;
 350}
 351
 352static inline void msg_set_importance(struct tipc_msg *m, u32 i)
 353{
 354        int usr = msg_user(m);
 355
 356        if (likely((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER)))
 357                msg_set_bits(m, 9, 0, 0x7, i);
 358        else if (i < TIPC_SYSTEM_IMPORTANCE)
 359                msg_set_user(m, i);
 360        else
 361                pr_warn("Trying to set illegal importance in message\n");
 362}
 363
 364static inline u32 msg_prevnode(struct tipc_msg *m)
 365{
 366        return msg_word(m, 3);
 367}
 368
 369static inline void msg_set_prevnode(struct tipc_msg *m, u32 a)
 370{
 371        msg_set_word(m, 3, a);
 372}
 373
 374static inline u32 msg_origport(struct tipc_msg *m)
 375{
 376        if (msg_user(m) == MSG_FRAGMENTER)
 377                m = msg_get_wrapped(m);
 378        return msg_word(m, 4);
 379}
 380
 381static inline void msg_set_origport(struct tipc_msg *m, u32 p)
 382{
 383        msg_set_word(m, 4, p);
 384}
 385
 386static inline u32 msg_destport(struct tipc_msg *m)
 387{
 388        return msg_word(m, 5);
 389}
 390
 391static inline void msg_set_destport(struct tipc_msg *m, u32 p)
 392{
 393        msg_set_word(m, 5, p);
 394}
 395
 396static inline u32 msg_mc_netid(struct tipc_msg *m)
 397{
 398        return msg_word(m, 5);
 399}
 400
 401static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p)
 402{
 403        msg_set_word(m, 5, p);
 404}
 405
 406static inline int msg_short(struct tipc_msg *m)
 407{
 408        return msg_hdr_sz(m) == SHORT_H_SIZE;
 409}
 410
 411static inline u32 msg_orignode(struct tipc_msg *m)
 412{
 413        if (likely(msg_short(m)))
 414                return msg_prevnode(m);
 415        return msg_word(m, 6);
 416}
 417
 418static inline void msg_set_orignode(struct tipc_msg *m, u32 a)
 419{
 420        msg_set_word(m, 6, a);
 421}
 422
 423static inline u32 msg_destnode(struct tipc_msg *m)
 424{
 425        return msg_word(m, 7);
 426}
 427
 428static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
 429{
 430        msg_set_word(m, 7, a);
 431}
 432
 433static inline u32 msg_nametype(struct tipc_msg *m)
 434{
 435        return msg_word(m, 8);
 436}
 437
 438static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
 439{
 440        msg_set_word(m, 8, n);
 441}
 442
 443static inline u32 msg_nameinst(struct tipc_msg *m)
 444{
 445        return msg_word(m, 9);
 446}
 447
 448static inline u32 msg_namelower(struct tipc_msg *m)
 449{
 450        return msg_nameinst(m);
 451}
 452
 453static inline void msg_set_namelower(struct tipc_msg *m, u32 n)
 454{
 455        msg_set_word(m, 9, n);
 456}
 457
 458static inline void msg_set_nameinst(struct tipc_msg *m, u32 n)
 459{
 460        msg_set_namelower(m, n);
 461}
 462
 463static inline u32 msg_nameupper(struct tipc_msg *m)
 464{
 465        return msg_word(m, 10);
 466}
 467
 468static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
 469{
 470        msg_set_word(m, 10, n);
 471}
 472
 473/*
 474 * Constants and routines used to read and write TIPC internal message headers
 475 */
 476
 477/*
 478 *  Connection management protocol message types
 479 */
 480#define CONN_PROBE        0
 481#define CONN_PROBE_REPLY  1
 482#define CONN_ACK          2
 483
 484/*
 485 * Name distributor message types
 486 */
 487#define PUBLICATION       0
 488#define WITHDRAWAL        1
 489
 490/*
 491 * Segmentation message types
 492 */
 493#define FIRST_FRAGMENT          0
 494#define FRAGMENT                1
 495#define LAST_FRAGMENT           2
 496
 497/*
 498 * Link management protocol message types
 499 */
 500#define STATE_MSG               0
 501#define RESET_MSG               1
 502#define ACTIVATE_MSG            2
 503
 504/*
 505 * Changeover tunnel message types
 506 */
 507#define SYNCH_MSG               0
 508#define FAILOVER_MSG            1
 509
 510/*
 511 * Config protocol message types
 512 */
 513#define DSC_REQ_MSG             0
 514#define DSC_RESP_MSG            1
 515
 516/*
 517 * Word 1
 518 */
 519static inline u32 msg_seq_gap(struct tipc_msg *m)
 520{
 521        return msg_bits(m, 1, 16, 0x1fff);
 522}
 523
 524static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
 525{
 526        msg_set_bits(m, 1, 16, 0x1fff, n);
 527}
 528
 529static inline u32 msg_node_sig(struct tipc_msg *m)
 530{
 531        return msg_bits(m, 1, 0, 0xffff);
 532}
 533
 534static inline void msg_set_node_sig(struct tipc_msg *m, u32 n)
 535{
 536        msg_set_bits(m, 1, 0, 0xffff, n);
 537}
 538
 539static inline u32 msg_node_capabilities(struct tipc_msg *m)
 540{
 541        return msg_bits(m, 1, 15, 0x1fff);
 542}
 543
 544static inline void msg_set_node_capabilities(struct tipc_msg *m, u32 n)
 545{
 546        msg_set_bits(m, 1, 15, 0x1fff, n);
 547}
 548
 549/*
 550 * Word 2
 551 */
 552static inline u32 msg_dest_domain(struct tipc_msg *m)
 553{
 554        return msg_word(m, 2);
 555}
 556
 557static inline void msg_set_dest_domain(struct tipc_msg *m, u32 n)
 558{
 559        msg_set_word(m, 2, n);
 560}
 561
 562static inline u32 msg_bcgap_after(struct tipc_msg *m)
 563{
 564        return msg_bits(m, 2, 16, 0xffff);
 565}
 566
 567static inline void msg_set_bcgap_after(struct tipc_msg *m, u32 n)
 568{
 569        msg_set_bits(m, 2, 16, 0xffff, n);
 570}
 571
 572static inline u32 msg_bcgap_to(struct tipc_msg *m)
 573{
 574        return msg_bits(m, 2, 0, 0xffff);
 575}
 576
 577static inline void msg_set_bcgap_to(struct tipc_msg *m, u32 n)
 578{
 579        msg_set_bits(m, 2, 0, 0xffff, n);
 580}
 581
 582
 583/*
 584 * Word 4
 585 */
 586static inline u32 msg_last_bcast(struct tipc_msg *m)
 587{
 588        return msg_bits(m, 4, 16, 0xffff);
 589}
 590
 591static inline u32 msg_bc_snd_nxt(struct tipc_msg *m)
 592{
 593        return msg_last_bcast(m) + 1;
 594}
 595
 596static inline void msg_set_last_bcast(struct tipc_msg *m, u32 n)
 597{
 598        msg_set_bits(m, 4, 16, 0xffff, n);
 599}
 600
 601static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n)
 602{
 603        msg_set_bits(m, 4, 16, 0xffff, n);
 604}
 605
 606
 607static inline u16 msg_next_sent(struct tipc_msg *m)
 608{
 609        return msg_bits(m, 4, 0, 0xffff);
 610}
 611
 612static inline void msg_set_next_sent(struct tipc_msg *m, u16 n)
 613{
 614        msg_set_bits(m, 4, 0, 0xffff, n);
 615}
 616
 617static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n)
 618{
 619        msg_set_bits(m, 4, 0, 0xffff, n);
 620}
 621
 622static inline u32 msg_bc_netid(struct tipc_msg *m)
 623{
 624        return msg_word(m, 4);
 625}
 626
 627static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id)
 628{
 629        msg_set_word(m, 4, id);
 630}
 631
 632static inline u32 msg_link_selector(struct tipc_msg *m)
 633{
 634        if (msg_user(m) == MSG_FRAGMENTER)
 635                m = (void *)msg_data(m);
 636        return msg_bits(m, 4, 0, 1);
 637}
 638
 639/*
 640 * Word 5
 641 */
 642static inline u16 msg_session(struct tipc_msg *m)
 643{
 644        return msg_bits(m, 5, 16, 0xffff);
 645}
 646
 647static inline void msg_set_session(struct tipc_msg *m, u16 n)
 648{
 649        msg_set_bits(m, 5, 16, 0xffff, n);
 650}
 651
 652static inline u32 msg_probe(struct tipc_msg *m)
 653{
 654        return msg_bits(m, 5, 0, 1);
 655}
 656
 657static inline void msg_set_probe(struct tipc_msg *m, u32 val)
 658{
 659        msg_set_bits(m, 5, 0, 1, val);
 660}
 661
 662static inline char msg_net_plane(struct tipc_msg *m)
 663{
 664        return msg_bits(m, 5, 1, 7) + 'A';
 665}
 666
 667static inline void msg_set_net_plane(struct tipc_msg *m, char n)
 668{
 669        msg_set_bits(m, 5, 1, 7, (n - 'A'));
 670}
 671
 672static inline u32 msg_linkprio(struct tipc_msg *m)
 673{
 674        return msg_bits(m, 5, 4, 0x1f);
 675}
 676
 677static inline void msg_set_linkprio(struct tipc_msg *m, u32 n)
 678{
 679        msg_set_bits(m, 5, 4, 0x1f, n);
 680}
 681
 682static inline u32 msg_bearer_id(struct tipc_msg *m)
 683{
 684        return msg_bits(m, 5, 9, 0x7);
 685}
 686
 687static inline void msg_set_bearer_id(struct tipc_msg *m, u32 n)
 688{
 689        msg_set_bits(m, 5, 9, 0x7, n);
 690}
 691
 692static inline u32 msg_redundant_link(struct tipc_msg *m)
 693{
 694        return msg_bits(m, 5, 12, 0x1);
 695}
 696
 697static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r)
 698{
 699        msg_set_bits(m, 5, 12, 0x1, r);
 700}
 701
 702static inline u32 msg_peer_stopping(struct tipc_msg *m)
 703{
 704        return msg_bits(m, 5, 13, 0x1);
 705}
 706
 707static inline void msg_set_peer_stopping(struct tipc_msg *m, u32 s)
 708{
 709        msg_set_bits(m, 5, 13, 0x1, s);
 710}
 711
 712static inline bool msg_bc_ack_invalid(struct tipc_msg *m)
 713{
 714        switch (msg_user(m)) {
 715        case BCAST_PROTOCOL:
 716        case NAME_DISTRIBUTOR:
 717        case LINK_PROTOCOL:
 718                return msg_bits(m, 5, 14, 0x1);
 719        default:
 720                return false;
 721        }
 722}
 723
 724static inline void msg_set_bc_ack_invalid(struct tipc_msg *m, bool invalid)
 725{
 726        msg_set_bits(m, 5, 14, 0x1, invalid);
 727}
 728
 729static inline char *msg_media_addr(struct tipc_msg *m)
 730{
 731        return (char *)&m->hdr[TIPC_MEDIA_INFO_OFFSET];
 732}
 733
 734static inline u32 msg_bc_gap(struct tipc_msg *m)
 735{
 736        return msg_bits(m, 8, 0, 0x3ff);
 737}
 738
 739static inline void msg_set_bc_gap(struct tipc_msg *m, u32 n)
 740{
 741        msg_set_bits(m, 8, 0, 0x3ff, n);
 742}
 743
 744/*
 745 * Word 9
 746 */
 747static inline u16 msg_msgcnt(struct tipc_msg *m)
 748{
 749        return msg_bits(m, 9, 16, 0xffff);
 750}
 751
 752static inline void msg_set_msgcnt(struct tipc_msg *m, u16 n)
 753{
 754        msg_set_bits(m, 9, 16, 0xffff, n);
 755}
 756
 757static inline u32 msg_conn_ack(struct tipc_msg *m)
 758{
 759        return msg_bits(m, 9, 16, 0xffff);
 760}
 761
 762static inline void msg_set_conn_ack(struct tipc_msg *m, u32 n)
 763{
 764        msg_set_bits(m, 9, 16, 0xffff, n);
 765}
 766
 767static inline u32 msg_adv_win(struct tipc_msg *m)
 768{
 769        return msg_bits(m, 9, 0, 0xffff);
 770}
 771
 772static inline void msg_set_adv_win(struct tipc_msg *m, u32 n)
 773{
 774        msg_set_bits(m, 9, 0, 0xffff, n);
 775}
 776
 777static inline u32 msg_max_pkt(struct tipc_msg *m)
 778{
 779        return msg_bits(m, 9, 16, 0xffff) * 4;
 780}
 781
 782static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n)
 783{
 784        msg_set_bits(m, 9, 16, 0xffff, (n / 4));
 785}
 786
 787static inline u32 msg_link_tolerance(struct tipc_msg *m)
 788{
 789        return msg_bits(m, 9, 0, 0xffff);
 790}
 791
 792static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
 793{
 794        msg_set_bits(m, 9, 0, 0xffff, n);
 795}
 796
 797static inline bool msg_peer_link_is_up(struct tipc_msg *m)
 798{
 799        if (likely(msg_user(m) != LINK_PROTOCOL))
 800                return true;
 801        if (msg_type(m) == STATE_MSG)
 802                return true;
 803        return false;
 804}
 805
 806static inline bool msg_peer_node_is_up(struct tipc_msg *m)
 807{
 808        if (msg_peer_link_is_up(m))
 809                return true;
 810        return msg_redundant_link(m);
 811}
 812
 813static inline bool msg_is_reset(struct tipc_msg *hdr)
 814{
 815        return (msg_user(hdr) == LINK_PROTOCOL) && (msg_type(hdr) == RESET_MSG);
 816}
 817
 818struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp);
 819bool tipc_msg_validate(struct sk_buff *skb);
 820bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err);
 821void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
 822                   u32 hsize, u32 destnode);
 823struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
 824                                uint data_sz, u32 dnode, u32 onode,
 825                                u32 dport, u32 oport, int errcode);
 826int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
 827bool tipc_msg_bundle(struct sk_buff *skb, struct tipc_msg *msg, u32 mtu);
 828bool tipc_msg_make_bundle(struct sk_buff **skb, struct tipc_msg *msg,
 829                          u32 mtu, u32 dnode);
 830bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos);
 831int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
 832                   int offset, int dsz, int mtu, struct sk_buff_head *list);
 833bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err);
 834bool tipc_msg_reassemble(struct sk_buff_head *list, struct sk_buff_head *rcvq);
 835bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg,
 836                        struct sk_buff_head *cpy);
 837void __tipc_skb_queue_sorted(struct sk_buff_head *list, u16 seqno,
 838                             struct sk_buff *skb);
 839
 840static inline u16 buf_seqno(struct sk_buff *skb)
 841{
 842        return msg_seqno(buf_msg(skb));
 843}
 844
 845/* tipc_skb_peek(): peek and reserve first buffer in list
 846 * @list: list to be peeked in
 847 * Returns pointer to first buffer in list, if any
 848 */
 849static inline struct sk_buff *tipc_skb_peek(struct sk_buff_head *list,
 850                                            spinlock_t *lock)
 851{
 852        struct sk_buff *skb;
 853
 854        spin_lock_bh(lock);
 855        skb = skb_peek(list);
 856        if (skb)
 857                skb_get(skb);
 858        spin_unlock_bh(lock);
 859        return skb;
 860}
 861
 862/* tipc_skb_peek_port(): find a destination port, ignoring all destinations
 863 *                       up to and including 'filter'.
 864 * Note: ignoring previously tried destinations minimizes the risk of
 865 *       contention on the socket lock
 866 * @list: list to be peeked in
 867 * @filter: last destination to be ignored from search
 868 * Returns a destination port number, of applicable.
 869 */
 870static inline u32 tipc_skb_peek_port(struct sk_buff_head *list, u32 filter)
 871{
 872        struct sk_buff *skb;
 873        u32 dport = 0;
 874        bool ignore = true;
 875
 876        spin_lock_bh(&list->lock);
 877        skb_queue_walk(list, skb) {
 878                dport = msg_destport(buf_msg(skb));
 879                if (!filter || skb_queue_is_last(list, skb))
 880                        break;
 881                if (dport == filter)
 882                        ignore = false;
 883                else if (!ignore)
 884                        break;
 885        }
 886        spin_unlock_bh(&list->lock);
 887        return dport;
 888}
 889
 890/* tipc_skb_dequeue(): unlink first buffer with dest 'dport' from list
 891 * @list: list to be unlinked from
 892 * @dport: selection criteria for buffer to unlink
 893 */
 894static inline struct sk_buff *tipc_skb_dequeue(struct sk_buff_head *list,
 895                                               u32 dport)
 896{
 897        struct sk_buff *_skb, *tmp, *skb = NULL;
 898
 899        spin_lock_bh(&list->lock);
 900        skb_queue_walk_safe(list, _skb, tmp) {
 901                if (msg_destport(buf_msg(_skb)) == dport) {
 902                        __skb_unlink(_skb, list);
 903                        skb = _skb;
 904                        break;
 905                }
 906        }
 907        spin_unlock_bh(&list->lock);
 908        return skb;
 909}
 910
 911/* tipc_skb_queue_splice_tail - append an skb list to lock protected list
 912 * @list: the new list to append. Not lock protected
 913 * @head: target list. Lock protected.
 914 */
 915static inline void tipc_skb_queue_splice_tail(struct sk_buff_head *list,
 916                                              struct sk_buff_head *head)
 917{
 918        spin_lock_bh(&head->lock);
 919        skb_queue_splice_tail(list, head);
 920        spin_unlock_bh(&head->lock);
 921}
 922
 923/* tipc_skb_queue_splice_tail_init - merge two lock protected skb lists
 924 * @list: the new list to add. Lock protected. Will be reinitialized
 925 * @head: target list. Lock protected.
 926 */
 927static inline void tipc_skb_queue_splice_tail_init(struct sk_buff_head *list,
 928                                                   struct sk_buff_head *head)
 929{
 930        struct sk_buff_head tmp;
 931
 932        __skb_queue_head_init(&tmp);
 933
 934        spin_lock_bh(&list->lock);
 935        skb_queue_splice_tail_init(list, &tmp);
 936        spin_unlock_bh(&list->lock);
 937        tipc_skb_queue_splice_tail(&tmp, head);
 938}
 939
 940#endif
 941