cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

msg.h (29600B)


      1/*
      2 * net/tipc/msg.h: Include file for TIPC message header routines
      3 *
      4 * Copyright (c) 2000-2007, 2014-2017 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#define TIPC_GRP_MEMBER_EVT     4
     69#define TIPC_GRP_BCAST_MSG      5
     70#define TIPC_GRP_MCAST_MSG      6
     71#define TIPC_GRP_UCAST_MSG      7
     72
     73/*
     74 * Internal message users
     75 */
     76#define  BCAST_PROTOCOL       5
     77#define  MSG_BUNDLER          6
     78#define  LINK_PROTOCOL        7
     79#define  CONN_MANAGER         8
     80#define  GROUP_PROTOCOL       9
     81#define  TUNNEL_PROTOCOL      10
     82#define  NAME_DISTRIBUTOR     11
     83#define  MSG_FRAGMENTER       12
     84#define  LINK_CONFIG          13
     85#define  MSG_CRYPTO           14
     86#define  SOCK_WAKEUP          14       /* pseudo user */
     87#define  TOP_SRV              15       /* pseudo user */
     88
     89/*
     90 * Message header sizes
     91 */
     92#define SHORT_H_SIZE              24	/* In-cluster basic payload message */
     93#define BASIC_H_SIZE              32	/* Basic payload message */
     94#define NAMED_H_SIZE              40	/* Named payload message */
     95#define MCAST_H_SIZE              44	/* Multicast payload message */
     96#define GROUP_H_SIZE              44	/* Group payload message */
     97#define INT_H_SIZE                40	/* Internal messages */
     98#define MIN_H_SIZE                24	/* Smallest legal TIPC header size */
     99#define MAX_H_SIZE                60	/* Largest possible TIPC header size */
    100
    101#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE)
    102#define TIPC_MEDIA_INFO_OFFSET	5
    103
    104extern const int one_page_mtu;
    105
    106struct tipc_skb_cb {
    107	union {
    108		struct {
    109			struct sk_buff *tail;
    110			unsigned long nxt_retr;
    111			unsigned long retr_stamp;
    112			u32 bytes_read;
    113			u32 orig_member;
    114			u16 chain_imp;
    115			u16 ackers;
    116			u16 retr_cnt;
    117		} __packed;
    118#ifdef CONFIG_TIPC_CRYPTO
    119		struct {
    120			struct tipc_crypto *rx;
    121			struct tipc_aead *last;
    122			u8 recurs;
    123		} tx_clone_ctx __packed;
    124#endif
    125	} __packed;
    126	union {
    127		struct {
    128			u8 validated:1;
    129#ifdef CONFIG_TIPC_CRYPTO
    130			u8 encrypted:1;
    131			u8 decrypted:1;
    132#define SKB_PROBING	1
    133#define SKB_GRACING	2
    134			u8 xmit_type:2;
    135			u8 tx_clone_deferred:1;
    136#endif
    137		};
    138		u8 flags;
    139	};
    140	u8 reserved;
    141#ifdef CONFIG_TIPC_CRYPTO
    142	void *crypto_ctx;
    143#endif
    144} __packed;
    145
    146#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0]))
    147
    148struct tipc_msg {
    149	__be32 hdr[15];
    150};
    151
    152/* struct tipc_gap_ack - TIPC Gap ACK block
    153 * @ack: seqno of the last consecutive packet in link deferdq
    154 * @gap: number of gap packets since the last ack
    155 *
    156 * E.g:
    157 *       link deferdq: 1 2 3 4      10 11      13 14 15       20
    158 * --> Gap ACK blocks:      <4, 5>,   <11, 1>,      <15, 4>, <20, 0>
    159 */
    160struct tipc_gap_ack {
    161	__be16 ack;
    162	__be16 gap;
    163};
    164
    165/* struct tipc_gap_ack_blks
    166 * @len: actual length of the record
    167 * @ugack_cnt: number of Gap ACK blocks for unicast (following the broadcast
    168 *             ones)
    169 * @start_index: starting index for "valid" broadcast Gap ACK blocks
    170 * @bgack_cnt: number of Gap ACK blocks for broadcast in the record
    171 * @gacks: array of Gap ACK blocks
    172 *
    173 *  31                       16 15                        0
    174 * +-------------+-------------+-------------+-------------+
    175 * |  bgack_cnt  |  ugack_cnt  |            len            |
    176 * +-------------+-------------+-------------+-------------+  -
    177 * |            gap            |            ack            |   |
    178 * +-------------+-------------+-------------+-------------+    > bc gacks
    179 * :                           :                           :   |
    180 * +-------------+-------------+-------------+-------------+  -
    181 * |            gap            |            ack            |   |
    182 * +-------------+-------------+-------------+-------------+    > uc gacks
    183 * :                           :                           :   |
    184 * +-------------+-------------+-------------+-------------+  -
    185 */
    186struct tipc_gap_ack_blks {
    187	__be16 len;
    188	union {
    189		u8 ugack_cnt;
    190		u8 start_index;
    191	};
    192	u8 bgack_cnt;
    193	struct tipc_gap_ack gacks[];
    194};
    195
    196#define MAX_GAP_ACK_BLKS	128
    197#define MAX_GAP_ACK_BLKS_SZ	(sizeof(struct tipc_gap_ack_blks) + \
    198				 sizeof(struct tipc_gap_ack) * MAX_GAP_ACK_BLKS)
    199
    200static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
    201{
    202	return (struct tipc_msg *)skb->data;
    203}
    204
    205static inline u32 msg_word(struct tipc_msg *m, u32 pos)
    206{
    207	return ntohl(m->hdr[pos]);
    208}
    209
    210static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val)
    211{
    212	m->hdr[w] = htonl(val);
    213}
    214
    215static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask)
    216{
    217	return (msg_word(m, w) >> pos) & mask;
    218}
    219
    220static inline void msg_set_bits(struct tipc_msg *m, u32 w,
    221				u32 pos, u32 mask, u32 val)
    222{
    223	val = (val & mask) << pos;
    224	mask = mask << pos;
    225	m->hdr[w] &= ~htonl(mask);
    226	m->hdr[w] |= htonl(val);
    227}
    228
    229/*
    230 * Word 0
    231 */
    232static inline u32 msg_version(struct tipc_msg *m)
    233{
    234	return msg_bits(m, 0, 29, 7);
    235}
    236
    237static inline void msg_set_version(struct tipc_msg *m)
    238{
    239	msg_set_bits(m, 0, 29, 7, TIPC_VERSION);
    240}
    241
    242static inline u32 msg_user(struct tipc_msg *m)
    243{
    244	return msg_bits(m, 0, 25, 0xf);
    245}
    246
    247static inline u32 msg_isdata(struct tipc_msg *m)
    248{
    249	return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE;
    250}
    251
    252static inline void msg_set_user(struct tipc_msg *m, u32 n)
    253{
    254	msg_set_bits(m, 0, 25, 0xf, n);
    255}
    256
    257static inline u32 msg_hdr_sz(struct tipc_msg *m)
    258{
    259	return msg_bits(m, 0, 21, 0xf) << 2;
    260}
    261
    262static inline void msg_set_hdr_sz(struct tipc_msg *m, u32 n)
    263{
    264	msg_set_bits(m, 0, 21, 0xf, n>>2);
    265}
    266
    267static inline u32 msg_size(struct tipc_msg *m)
    268{
    269	return msg_bits(m, 0, 0, 0x1ffff);
    270}
    271
    272static inline u32 msg_blocks(struct tipc_msg *m)
    273{
    274	return (msg_size(m) / 1024) + 1;
    275}
    276
    277static inline u32 msg_data_sz(struct tipc_msg *m)
    278{
    279	return msg_size(m) - msg_hdr_sz(m);
    280}
    281
    282static inline int msg_non_seq(struct tipc_msg *m)
    283{
    284	return msg_bits(m, 0, 20, 1);
    285}
    286
    287static inline void msg_set_non_seq(struct tipc_msg *m, u32 n)
    288{
    289	msg_set_bits(m, 0, 20, 1, n);
    290}
    291
    292static inline int msg_is_syn(struct tipc_msg *m)
    293{
    294	return msg_bits(m, 0, 17, 1);
    295}
    296
    297static inline void msg_set_syn(struct tipc_msg *m, u32 d)
    298{
    299	msg_set_bits(m, 0, 17, 1, d);
    300}
    301
    302static inline int msg_dest_droppable(struct tipc_msg *m)
    303{
    304	return msg_bits(m, 0, 19, 1);
    305}
    306
    307static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d)
    308{
    309	msg_set_bits(m, 0, 19, 1, d);
    310}
    311
    312static inline int msg_is_keepalive(struct tipc_msg *m)
    313{
    314	return msg_bits(m, 0, 19, 1);
    315}
    316
    317static inline void msg_set_is_keepalive(struct tipc_msg *m, u32 d)
    318{
    319	msg_set_bits(m, 0, 19, 1, d);
    320}
    321
    322static inline int msg_src_droppable(struct tipc_msg *m)
    323{
    324	return msg_bits(m, 0, 18, 1);
    325}
    326
    327static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d)
    328{
    329	msg_set_bits(m, 0, 18, 1, d);
    330}
    331
    332static inline int msg_ack_required(struct tipc_msg *m)
    333{
    334	return msg_bits(m, 0, 18, 1);
    335}
    336
    337static inline void msg_set_ack_required(struct tipc_msg *m)
    338{
    339	msg_set_bits(m, 0, 18, 1, 1);
    340}
    341
    342static inline int msg_nagle_ack(struct tipc_msg *m)
    343{
    344	return msg_bits(m, 0, 18, 1);
    345}
    346
    347static inline void msg_set_nagle_ack(struct tipc_msg *m)
    348{
    349	msg_set_bits(m, 0, 18, 1, 1);
    350}
    351
    352static inline bool msg_is_rcast(struct tipc_msg *m)
    353{
    354	return msg_bits(m, 0, 18, 0x1);
    355}
    356
    357static inline void msg_set_is_rcast(struct tipc_msg *m, bool d)
    358{
    359	msg_set_bits(m, 0, 18, 0x1, d);
    360}
    361
    362static inline void msg_set_size(struct tipc_msg *m, u32 sz)
    363{
    364	m->hdr[0] = htonl((msg_word(m, 0) & ~0x1ffff) | sz);
    365}
    366
    367static inline unchar *msg_data(struct tipc_msg *m)
    368{
    369	return ((unchar *)m) + msg_hdr_sz(m);
    370}
    371
    372static inline struct tipc_msg *msg_inner_hdr(struct tipc_msg *m)
    373{
    374	return (struct tipc_msg *)msg_data(m);
    375}
    376
    377/*
    378 * Word 1
    379 */
    380static inline u32 msg_type(struct tipc_msg *m)
    381{
    382	return msg_bits(m, 1, 29, 0x7);
    383}
    384
    385static inline void msg_set_type(struct tipc_msg *m, u32 n)
    386{
    387	msg_set_bits(m, 1, 29, 0x7, n);
    388}
    389
    390static inline int msg_in_group(struct tipc_msg *m)
    391{
    392	int mtyp = msg_type(m);
    393
    394	return mtyp >= TIPC_GRP_MEMBER_EVT && mtyp <= TIPC_GRP_UCAST_MSG;
    395}
    396
    397static inline bool msg_is_grp_evt(struct tipc_msg *m)
    398{
    399	return msg_type(m) == TIPC_GRP_MEMBER_EVT;
    400}
    401
    402static inline u32 msg_named(struct tipc_msg *m)
    403{
    404	return msg_type(m) == TIPC_NAMED_MSG;
    405}
    406
    407static inline u32 msg_mcast(struct tipc_msg *m)
    408{
    409	int mtyp = msg_type(m);
    410
    411	return ((mtyp == TIPC_MCAST_MSG) || (mtyp == TIPC_GRP_BCAST_MSG) ||
    412		(mtyp == TIPC_GRP_MCAST_MSG));
    413}
    414
    415static inline u32 msg_connected(struct tipc_msg *m)
    416{
    417	return msg_type(m) == TIPC_CONN_MSG;
    418}
    419
    420static inline u32 msg_direct(struct tipc_msg *m)
    421{
    422	return msg_type(m) == TIPC_DIRECT_MSG;
    423}
    424
    425static inline u32 msg_errcode(struct tipc_msg *m)
    426{
    427	return msg_bits(m, 1, 25, 0xf);
    428}
    429
    430static inline void msg_set_errcode(struct tipc_msg *m, u32 err)
    431{
    432	msg_set_bits(m, 1, 25, 0xf, err);
    433}
    434
    435static inline void msg_set_bulk(struct tipc_msg *m)
    436{
    437	msg_set_bits(m, 1, 28, 0x1, 1);
    438}
    439
    440static inline u32 msg_is_bulk(struct tipc_msg *m)
    441{
    442	return msg_bits(m, 1, 28, 0x1);
    443}
    444
    445static inline void msg_set_last_bulk(struct tipc_msg *m)
    446{
    447	msg_set_bits(m, 1, 27, 0x1, 1);
    448}
    449
    450static inline u32 msg_is_last_bulk(struct tipc_msg *m)
    451{
    452	return msg_bits(m, 1, 27, 0x1);
    453}
    454
    455static inline void msg_set_non_legacy(struct tipc_msg *m)
    456{
    457	msg_set_bits(m, 1, 26, 0x1, 1);
    458}
    459
    460static inline u32 msg_is_legacy(struct tipc_msg *m)
    461{
    462	return !msg_bits(m, 1, 26, 0x1);
    463}
    464
    465static inline u32 msg_reroute_cnt(struct tipc_msg *m)
    466{
    467	return msg_bits(m, 1, 21, 0xf);
    468}
    469
    470static inline void msg_incr_reroute_cnt(struct tipc_msg *m)
    471{
    472	msg_set_bits(m, 1, 21, 0xf, msg_reroute_cnt(m) + 1);
    473}
    474
    475static inline u32 msg_lookup_scope(struct tipc_msg *m)
    476{
    477	return msg_bits(m, 1, 19, 0x3);
    478}
    479
    480static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n)
    481{
    482	msg_set_bits(m, 1, 19, 0x3, n);
    483}
    484
    485static inline u16 msg_bcast_ack(struct tipc_msg *m)
    486{
    487	return msg_bits(m, 1, 0, 0xffff);
    488}
    489
    490static inline void msg_set_bcast_ack(struct tipc_msg *m, u16 n)
    491{
    492	msg_set_bits(m, 1, 0, 0xffff, n);
    493}
    494
    495/* Note: reusing bits in word 1 for ACTIVATE_MSG only, to re-synch
    496 * link peer session number
    497 */
    498static inline bool msg_dest_session_valid(struct tipc_msg *m)
    499{
    500	return msg_bits(m, 1, 16, 0x1);
    501}
    502
    503static inline void msg_set_dest_session_valid(struct tipc_msg *m, bool valid)
    504{
    505	msg_set_bits(m, 1, 16, 0x1, valid);
    506}
    507
    508static inline u16 msg_dest_session(struct tipc_msg *m)
    509{
    510	return msg_bits(m, 1, 0, 0xffff);
    511}
    512
    513static inline void msg_set_dest_session(struct tipc_msg *m, u16 n)
    514{
    515	msg_set_bits(m, 1, 0, 0xffff, n);
    516}
    517
    518/*
    519 * Word 2
    520 */
    521static inline u16 msg_ack(struct tipc_msg *m)
    522{
    523	return msg_bits(m, 2, 16, 0xffff);
    524}
    525
    526static inline void msg_set_ack(struct tipc_msg *m, u16 n)
    527{
    528	msg_set_bits(m, 2, 16, 0xffff, n);
    529}
    530
    531static inline u16 msg_seqno(struct tipc_msg *m)
    532{
    533	return msg_bits(m, 2, 0, 0xffff);
    534}
    535
    536static inline void msg_set_seqno(struct tipc_msg *m, u16 n)
    537{
    538	msg_set_bits(m, 2, 0, 0xffff, n);
    539}
    540
    541/*
    542 * Words 3-10
    543 */
    544static inline u32 msg_importance(struct tipc_msg *m)
    545{
    546	int usr = msg_user(m);
    547
    548	if (likely((usr <= TIPC_CRITICAL_IMPORTANCE) && !msg_errcode(m)))
    549		return usr;
    550	if ((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER))
    551		return msg_bits(m, 9, 0, 0x7);
    552	return TIPC_SYSTEM_IMPORTANCE;
    553}
    554
    555static inline void msg_set_importance(struct tipc_msg *m, u32 i)
    556{
    557	int usr = msg_user(m);
    558
    559	if (likely((usr == MSG_FRAGMENTER) || (usr == MSG_BUNDLER)))
    560		msg_set_bits(m, 9, 0, 0x7, i);
    561	else if (i < TIPC_SYSTEM_IMPORTANCE)
    562		msg_set_user(m, i);
    563	else
    564		pr_warn("Trying to set illegal importance in message\n");
    565}
    566
    567static inline u32 msg_prevnode(struct tipc_msg *m)
    568{
    569	return msg_word(m, 3);
    570}
    571
    572static inline void msg_set_prevnode(struct tipc_msg *m, u32 a)
    573{
    574	msg_set_word(m, 3, a);
    575}
    576
    577static inline u32 msg_origport(struct tipc_msg *m)
    578{
    579	if (msg_user(m) == MSG_FRAGMENTER)
    580		m = msg_inner_hdr(m);
    581	return msg_word(m, 4);
    582}
    583
    584static inline void msg_set_origport(struct tipc_msg *m, u32 p)
    585{
    586	msg_set_word(m, 4, p);
    587}
    588
    589static inline u16 msg_named_seqno(struct tipc_msg *m)
    590{
    591	return msg_bits(m, 4, 0, 0xffff);
    592}
    593
    594static inline void msg_set_named_seqno(struct tipc_msg *m, u16 n)
    595{
    596	msg_set_bits(m, 4, 0, 0xffff, n);
    597}
    598
    599static inline u32 msg_destport(struct tipc_msg *m)
    600{
    601	return msg_word(m, 5);
    602}
    603
    604static inline void msg_set_destport(struct tipc_msg *m, u32 p)
    605{
    606	msg_set_word(m, 5, p);
    607}
    608
    609static inline u32 msg_mc_netid(struct tipc_msg *m)
    610{
    611	return msg_word(m, 5);
    612}
    613
    614static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p)
    615{
    616	msg_set_word(m, 5, p);
    617}
    618
    619static inline int msg_short(struct tipc_msg *m)
    620{
    621	return msg_hdr_sz(m) == SHORT_H_SIZE;
    622}
    623
    624static inline u32 msg_orignode(struct tipc_msg *m)
    625{
    626	if (likely(msg_short(m)))
    627		return msg_prevnode(m);
    628	return msg_word(m, 6);
    629}
    630
    631static inline void msg_set_orignode(struct tipc_msg *m, u32 a)
    632{
    633	msg_set_word(m, 6, a);
    634}
    635
    636static inline u32 msg_destnode(struct tipc_msg *m)
    637{
    638	return msg_word(m, 7);
    639}
    640
    641static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
    642{
    643	msg_set_word(m, 7, a);
    644}
    645
    646static inline u32 msg_nametype(struct tipc_msg *m)
    647{
    648	return msg_word(m, 8);
    649}
    650
    651static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
    652{
    653	msg_set_word(m, 8, n);
    654}
    655
    656static inline u32 msg_nameinst(struct tipc_msg *m)
    657{
    658	return msg_word(m, 9);
    659}
    660
    661static inline u32 msg_namelower(struct tipc_msg *m)
    662{
    663	return msg_nameinst(m);
    664}
    665
    666static inline void msg_set_namelower(struct tipc_msg *m, u32 n)
    667{
    668	msg_set_word(m, 9, n);
    669}
    670
    671static inline void msg_set_nameinst(struct tipc_msg *m, u32 n)
    672{
    673	msg_set_namelower(m, n);
    674}
    675
    676static inline u32 msg_nameupper(struct tipc_msg *m)
    677{
    678	return msg_word(m, 10);
    679}
    680
    681static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
    682{
    683	msg_set_word(m, 10, n);
    684}
    685
    686/*
    687 * Constants and routines used to read and write TIPC internal message headers
    688 */
    689
    690/*
    691 *  Connection management protocol message types
    692 */
    693#define CONN_PROBE        0
    694#define CONN_PROBE_REPLY  1
    695#define CONN_ACK          2
    696
    697/*
    698 * Name distributor message types
    699 */
    700#define PUBLICATION       0
    701#define WITHDRAWAL        1
    702
    703/*
    704 * Segmentation message types
    705 */
    706#define FIRST_FRAGMENT		0
    707#define FRAGMENT		1
    708#define LAST_FRAGMENT		2
    709
    710/*
    711 * Link management protocol message types
    712 */
    713#define STATE_MSG		0
    714#define RESET_MSG		1
    715#define ACTIVATE_MSG		2
    716
    717/*
    718 * Changeover tunnel message types
    719 */
    720#define SYNCH_MSG		0
    721#define FAILOVER_MSG		1
    722
    723/*
    724 * Config protocol message types
    725 */
    726#define DSC_REQ_MSG		0
    727#define DSC_RESP_MSG		1
    728#define DSC_TRIAL_MSG		2
    729#define DSC_TRIAL_FAIL_MSG	3
    730
    731/*
    732 * Group protocol message types
    733 */
    734#define GRP_JOIN_MSG         0
    735#define GRP_LEAVE_MSG        1
    736#define GRP_ADV_MSG          2
    737#define GRP_ACK_MSG          3
    738#define GRP_RECLAIM_MSG      4
    739#define GRP_REMIT_MSG        5
    740
    741/* Crypto message types */
    742#define KEY_DISTR_MSG		0
    743
    744/*
    745 * Word 1
    746 */
    747static inline u32 msg_seq_gap(struct tipc_msg *m)
    748{
    749	return msg_bits(m, 1, 16, 0x1fff);
    750}
    751
    752static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
    753{
    754	msg_set_bits(m, 1, 16, 0x1fff, n);
    755}
    756
    757static inline u32 msg_node_sig(struct tipc_msg *m)
    758{
    759	return msg_bits(m, 1, 0, 0xffff);
    760}
    761
    762static inline void msg_set_node_sig(struct tipc_msg *m, u32 n)
    763{
    764	msg_set_bits(m, 1, 0, 0xffff, n);
    765}
    766
    767static inline u32 msg_node_capabilities(struct tipc_msg *m)
    768{
    769	return msg_bits(m, 1, 15, 0x1fff);
    770}
    771
    772static inline void msg_set_node_capabilities(struct tipc_msg *m, u32 n)
    773{
    774	msg_set_bits(m, 1, 15, 0x1fff, n);
    775}
    776
    777/*
    778 * Word 2
    779 */
    780static inline u32 msg_dest_domain(struct tipc_msg *m)
    781{
    782	return msg_word(m, 2);
    783}
    784
    785static inline void msg_set_dest_domain(struct tipc_msg *m, u32 n)
    786{
    787	msg_set_word(m, 2, n);
    788}
    789
    790static inline void msg_set_bcgap_after(struct tipc_msg *m, u32 n)
    791{
    792	msg_set_bits(m, 2, 16, 0xffff, n);
    793}
    794
    795static inline u32 msg_bcgap_to(struct tipc_msg *m)
    796{
    797	return msg_bits(m, 2, 0, 0xffff);
    798}
    799
    800static inline void msg_set_bcgap_to(struct tipc_msg *m, u32 n)
    801{
    802	msg_set_bits(m, 2, 0, 0xffff, n);
    803}
    804
    805/*
    806 * Word 4
    807 */
    808static inline u32 msg_last_bcast(struct tipc_msg *m)
    809{
    810	return msg_bits(m, 4, 16, 0xffff);
    811}
    812
    813static inline u32 msg_bc_snd_nxt(struct tipc_msg *m)
    814{
    815	return msg_last_bcast(m) + 1;
    816}
    817
    818static inline void msg_set_last_bcast(struct tipc_msg *m, u32 n)
    819{
    820	msg_set_bits(m, 4, 16, 0xffff, n);
    821}
    822
    823static inline u32 msg_nof_fragms(struct tipc_msg *m)
    824{
    825	return msg_bits(m, 4, 0, 0xffff);
    826}
    827
    828static inline void msg_set_nof_fragms(struct tipc_msg *m, u32 n)
    829{
    830	msg_set_bits(m, 4, 0, 0xffff, n);
    831}
    832
    833static inline u32 msg_fragm_no(struct tipc_msg *m)
    834{
    835	return msg_bits(m, 4, 16, 0xffff);
    836}
    837
    838static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n)
    839{
    840	msg_set_bits(m, 4, 16, 0xffff, n);
    841}
    842
    843static inline u16 msg_next_sent(struct tipc_msg *m)
    844{
    845	return msg_bits(m, 4, 0, 0xffff);
    846}
    847
    848static inline void msg_set_next_sent(struct tipc_msg *m, u16 n)
    849{
    850	msg_set_bits(m, 4, 0, 0xffff, n);
    851}
    852
    853static inline u32 msg_bc_netid(struct tipc_msg *m)
    854{
    855	return msg_word(m, 4);
    856}
    857
    858static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id)
    859{
    860	msg_set_word(m, 4, id);
    861}
    862
    863static inline u32 msg_link_selector(struct tipc_msg *m)
    864{
    865	if (msg_user(m) == MSG_FRAGMENTER)
    866		m = (void *)msg_data(m);
    867	return msg_bits(m, 4, 0, 1);
    868}
    869
    870/*
    871 * Word 5
    872 */
    873static inline u16 msg_session(struct tipc_msg *m)
    874{
    875	return msg_bits(m, 5, 16, 0xffff);
    876}
    877
    878static inline void msg_set_session(struct tipc_msg *m, u16 n)
    879{
    880	msg_set_bits(m, 5, 16, 0xffff, n);
    881}
    882
    883static inline u32 msg_probe(struct tipc_msg *m)
    884{
    885	return msg_bits(m, 5, 0, 1);
    886}
    887
    888static inline void msg_set_probe(struct tipc_msg *m, u32 val)
    889{
    890	msg_set_bits(m, 5, 0, 1, val);
    891}
    892
    893static inline char msg_net_plane(struct tipc_msg *m)
    894{
    895	return msg_bits(m, 5, 1, 7) + 'A';
    896}
    897
    898static inline void msg_set_net_plane(struct tipc_msg *m, char n)
    899{
    900	msg_set_bits(m, 5, 1, 7, (n - 'A'));
    901}
    902
    903static inline u32 msg_linkprio(struct tipc_msg *m)
    904{
    905	return msg_bits(m, 5, 4, 0x1f);
    906}
    907
    908static inline void msg_set_linkprio(struct tipc_msg *m, u32 n)
    909{
    910	msg_set_bits(m, 5, 4, 0x1f, n);
    911}
    912
    913static inline u32 msg_bearer_id(struct tipc_msg *m)
    914{
    915	return msg_bits(m, 5, 9, 0x7);
    916}
    917
    918static inline void msg_set_bearer_id(struct tipc_msg *m, u32 n)
    919{
    920	msg_set_bits(m, 5, 9, 0x7, n);
    921}
    922
    923static inline u32 msg_redundant_link(struct tipc_msg *m)
    924{
    925	return msg_bits(m, 5, 12, 0x1);
    926}
    927
    928static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r)
    929{
    930	msg_set_bits(m, 5, 12, 0x1, r);
    931}
    932
    933static inline u32 msg_peer_stopping(struct tipc_msg *m)
    934{
    935	return msg_bits(m, 5, 13, 0x1);
    936}
    937
    938static inline void msg_set_peer_stopping(struct tipc_msg *m, u32 s)
    939{
    940	msg_set_bits(m, 5, 13, 0x1, s);
    941}
    942
    943static inline bool msg_bc_ack_invalid(struct tipc_msg *m)
    944{
    945	switch (msg_user(m)) {
    946	case BCAST_PROTOCOL:
    947	case NAME_DISTRIBUTOR:
    948	case LINK_PROTOCOL:
    949		return msg_bits(m, 5, 14, 0x1);
    950	default:
    951		return false;
    952	}
    953}
    954
    955static inline void msg_set_bc_ack_invalid(struct tipc_msg *m, bool invalid)
    956{
    957	msg_set_bits(m, 5, 14, 0x1, invalid);
    958}
    959
    960static inline char *msg_media_addr(struct tipc_msg *m)
    961{
    962	return (char *)&m->hdr[TIPC_MEDIA_INFO_OFFSET];
    963}
    964
    965static inline u32 msg_bc_gap(struct tipc_msg *m)
    966{
    967	return msg_bits(m, 8, 0, 0x3ff);
    968}
    969
    970static inline void msg_set_bc_gap(struct tipc_msg *m, u32 n)
    971{
    972	msg_set_bits(m, 8, 0, 0x3ff, n);
    973}
    974
    975/*
    976 * Word 9
    977 */
    978static inline u16 msg_msgcnt(struct tipc_msg *m)
    979{
    980	return msg_bits(m, 9, 16, 0xffff);
    981}
    982
    983static inline void msg_set_msgcnt(struct tipc_msg *m, u16 n)
    984{
    985	msg_set_bits(m, 9, 16, 0xffff, n);
    986}
    987
    988static inline u16 msg_syncpt(struct tipc_msg *m)
    989{
    990	return msg_bits(m, 9, 16, 0xffff);
    991}
    992
    993static inline void msg_set_syncpt(struct tipc_msg *m, u16 n)
    994{
    995	msg_set_bits(m, 9, 16, 0xffff, n);
    996}
    997
    998static inline u32 msg_conn_ack(struct tipc_msg *m)
    999{
   1000	return msg_bits(m, 9, 16, 0xffff);
   1001}
   1002
   1003static inline void msg_set_conn_ack(struct tipc_msg *m, u32 n)
   1004{
   1005	msg_set_bits(m, 9, 16, 0xffff, n);
   1006}
   1007
   1008static inline u16 msg_adv_win(struct tipc_msg *m)
   1009{
   1010	return msg_bits(m, 9, 0, 0xffff);
   1011}
   1012
   1013static inline void msg_set_adv_win(struct tipc_msg *m, u16 n)
   1014{
   1015	msg_set_bits(m, 9, 0, 0xffff, n);
   1016}
   1017
   1018static inline u32 msg_max_pkt(struct tipc_msg *m)
   1019{
   1020	return msg_bits(m, 9, 16, 0xffff) * 4;
   1021}
   1022
   1023static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n)
   1024{
   1025	msg_set_bits(m, 9, 16, 0xffff, (n / 4));
   1026}
   1027
   1028static inline u32 msg_link_tolerance(struct tipc_msg *m)
   1029{
   1030	return msg_bits(m, 9, 0, 0xffff);
   1031}
   1032
   1033static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
   1034{
   1035	msg_set_bits(m, 9, 0, 0xffff, n);
   1036}
   1037
   1038static inline u16 msg_grp_bc_syncpt(struct tipc_msg *m)
   1039{
   1040	return msg_bits(m, 9, 16, 0xffff);
   1041}
   1042
   1043static inline void msg_set_grp_bc_syncpt(struct tipc_msg *m, u16 n)
   1044{
   1045	msg_set_bits(m, 9, 16, 0xffff, n);
   1046}
   1047
   1048static inline u16 msg_grp_bc_acked(struct tipc_msg *m)
   1049{
   1050	return msg_bits(m, 9, 16, 0xffff);
   1051}
   1052
   1053static inline void msg_set_grp_bc_acked(struct tipc_msg *m, u16 n)
   1054{
   1055	msg_set_bits(m, 9, 16, 0xffff, n);
   1056}
   1057
   1058static inline u16 msg_grp_remitted(struct tipc_msg *m)
   1059{
   1060	return msg_bits(m, 9, 16, 0xffff);
   1061}
   1062
   1063static inline void msg_set_grp_remitted(struct tipc_msg *m, u16 n)
   1064{
   1065	msg_set_bits(m, 9, 16, 0xffff, n);
   1066}
   1067
   1068/* Word 10
   1069 */
   1070static inline u16 msg_grp_evt(struct tipc_msg *m)
   1071{
   1072	return msg_bits(m, 10, 0, 0x3);
   1073}
   1074
   1075static inline void msg_set_grp_evt(struct tipc_msg *m, int n)
   1076{
   1077	msg_set_bits(m, 10, 0, 0x3, n);
   1078}
   1079
   1080static inline u16 msg_grp_bc_ack_req(struct tipc_msg *m)
   1081{
   1082	return msg_bits(m, 10, 0, 0x1);
   1083}
   1084
   1085static inline void msg_set_grp_bc_ack_req(struct tipc_msg *m, bool n)
   1086{
   1087	msg_set_bits(m, 10, 0, 0x1, n);
   1088}
   1089
   1090static inline u16 msg_grp_bc_seqno(struct tipc_msg *m)
   1091{
   1092	return msg_bits(m, 10, 16, 0xffff);
   1093}
   1094
   1095static inline void msg_set_grp_bc_seqno(struct tipc_msg *m, u32 n)
   1096{
   1097	msg_set_bits(m, 10, 16, 0xffff, n);
   1098}
   1099
   1100static inline bool msg_peer_link_is_up(struct tipc_msg *m)
   1101{
   1102	if (likely(msg_user(m) != LINK_PROTOCOL))
   1103		return true;
   1104	if (msg_type(m) == STATE_MSG)
   1105		return true;
   1106	return false;
   1107}
   1108
   1109static inline bool msg_peer_node_is_up(struct tipc_msg *m)
   1110{
   1111	if (msg_peer_link_is_up(m))
   1112		return true;
   1113	return msg_redundant_link(m);
   1114}
   1115
   1116static inline bool msg_is_reset(struct tipc_msg *hdr)
   1117{
   1118	return (msg_user(hdr) == LINK_PROTOCOL) && (msg_type(hdr) == RESET_MSG);
   1119}
   1120
   1121/* Word 13
   1122 */
   1123static inline void msg_set_peer_net_hash(struct tipc_msg *m, u32 n)
   1124{
   1125	msg_set_word(m, 13, n);
   1126}
   1127
   1128static inline u32 msg_peer_net_hash(struct tipc_msg *m)
   1129{
   1130	return msg_word(m, 13);
   1131}
   1132
   1133/* Word 14
   1134 */
   1135static inline u32 msg_sugg_node_addr(struct tipc_msg *m)
   1136{
   1137	return msg_word(m, 14);
   1138}
   1139
   1140static inline void msg_set_sugg_node_addr(struct tipc_msg *m, u32 n)
   1141{
   1142	msg_set_word(m, 14, n);
   1143}
   1144
   1145static inline void msg_set_node_id(struct tipc_msg *hdr, u8 *id)
   1146{
   1147	memcpy(msg_data(hdr), id, 16);
   1148}
   1149
   1150static inline u8 *msg_node_id(struct tipc_msg *hdr)
   1151{
   1152	return (u8 *)msg_data(hdr);
   1153}
   1154
   1155struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp);
   1156bool tipc_msg_validate(struct sk_buff **_skb);
   1157bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err);
   1158void tipc_skb_reject(struct net *net, int err, struct sk_buff *skb,
   1159		     struct sk_buff_head *xmitq);
   1160void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
   1161		   u32 hsize, u32 destnode);
   1162struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
   1163				uint data_sz, u32 dnode, u32 onode,
   1164				u32 dport, u32 oport, int errcode);
   1165int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
   1166bool tipc_msg_try_bundle(struct sk_buff *tskb, struct sk_buff **skb, u32 mss,
   1167			 u32 dnode, bool *new_bundle);
   1168bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos);
   1169int tipc_msg_fragment(struct sk_buff *skb, const struct tipc_msg *hdr,
   1170		      int pktmax, struct sk_buff_head *frags);
   1171int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
   1172		   int offset, int dsz, int mtu, struct sk_buff_head *list);
   1173int tipc_msg_append(struct tipc_msg *hdr, struct msghdr *m, int dlen,
   1174		    int mss, struct sk_buff_head *txq);
   1175bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err);
   1176bool tipc_msg_assemble(struct sk_buff_head *list);
   1177bool tipc_msg_reassemble(struct sk_buff_head *list, struct sk_buff_head *rcvq);
   1178bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg,
   1179			struct sk_buff_head *cpy);
   1180bool __tipc_skb_queue_sorted(struct sk_buff_head *list, u16 seqno,
   1181			     struct sk_buff *skb);
   1182bool tipc_msg_skb_clone(struct sk_buff_head *msg, struct sk_buff_head *cpy);
   1183
   1184static inline u16 buf_seqno(struct sk_buff *skb)
   1185{
   1186	return msg_seqno(buf_msg(skb));
   1187}
   1188
   1189static inline int buf_roundup_len(struct sk_buff *skb)
   1190{
   1191	return (skb->len / 1024 + 1) * 1024;
   1192}
   1193
   1194/* tipc_skb_peek(): peek and reserve first buffer in list
   1195 * @list: list to be peeked in
   1196 * Returns pointer to first buffer in list, if any
   1197 */
   1198static inline struct sk_buff *tipc_skb_peek(struct sk_buff_head *list,
   1199					    spinlock_t *lock)
   1200{
   1201	struct sk_buff *skb;
   1202
   1203	spin_lock_bh(lock);
   1204	skb = skb_peek(list);
   1205	if (skb)
   1206		skb_get(skb);
   1207	spin_unlock_bh(lock);
   1208	return skb;
   1209}
   1210
   1211/* tipc_skb_peek_port(): find a destination port, ignoring all destinations
   1212 *                       up to and including 'filter'.
   1213 * Note: ignoring previously tried destinations minimizes the risk of
   1214 *       contention on the socket lock
   1215 * @list: list to be peeked in
   1216 * @filter: last destination to be ignored from search
   1217 * Returns a destination port number, of applicable.
   1218 */
   1219static inline u32 tipc_skb_peek_port(struct sk_buff_head *list, u32 filter)
   1220{
   1221	struct sk_buff *skb;
   1222	u32 dport = 0;
   1223	bool ignore = true;
   1224
   1225	spin_lock_bh(&list->lock);
   1226	skb_queue_walk(list, skb) {
   1227		dport = msg_destport(buf_msg(skb));
   1228		if (!filter || skb_queue_is_last(list, skb))
   1229			break;
   1230		if (dport == filter)
   1231			ignore = false;
   1232		else if (!ignore)
   1233			break;
   1234	}
   1235	spin_unlock_bh(&list->lock);
   1236	return dport;
   1237}
   1238
   1239/* tipc_skb_dequeue(): unlink first buffer with dest 'dport' from list
   1240 * @list: list to be unlinked from
   1241 * @dport: selection criteria for buffer to unlink
   1242 */
   1243static inline struct sk_buff *tipc_skb_dequeue(struct sk_buff_head *list,
   1244					       u32 dport)
   1245{
   1246	struct sk_buff *_skb, *tmp, *skb = NULL;
   1247
   1248	spin_lock_bh(&list->lock);
   1249	skb_queue_walk_safe(list, _skb, tmp) {
   1250		if (msg_destport(buf_msg(_skb)) == dport) {
   1251			__skb_unlink(_skb, list);
   1252			skb = _skb;
   1253			break;
   1254		}
   1255	}
   1256	spin_unlock_bh(&list->lock);
   1257	return skb;
   1258}
   1259
   1260/* tipc_skb_queue_splice_tail - append an skb list to lock protected list
   1261 * @list: the new list to append. Not lock protected
   1262 * @head: target list. Lock protected.
   1263 */
   1264static inline void tipc_skb_queue_splice_tail(struct sk_buff_head *list,
   1265					      struct sk_buff_head *head)
   1266{
   1267	spin_lock_bh(&head->lock);
   1268	skb_queue_splice_tail(list, head);
   1269	spin_unlock_bh(&head->lock);
   1270}
   1271
   1272/* tipc_skb_queue_splice_tail_init - merge two lock protected skb lists
   1273 * @list: the new list to add. Lock protected. Will be reinitialized
   1274 * @head: target list. Lock protected.
   1275 */
   1276static inline void tipc_skb_queue_splice_tail_init(struct sk_buff_head *list,
   1277						   struct sk_buff_head *head)
   1278{
   1279	struct sk_buff_head tmp;
   1280
   1281	__skb_queue_head_init(&tmp);
   1282
   1283	spin_lock_bh(&list->lock);
   1284	skb_queue_splice_tail_init(list, &tmp);
   1285	spin_unlock_bh(&list->lock);
   1286	tipc_skb_queue_splice_tail(&tmp, head);
   1287}
   1288
   1289/* __tipc_skb_dequeue() - dequeue the head skb according to expected seqno
   1290 * @list: list to be dequeued from
   1291 * @seqno: seqno of the expected msg
   1292 *
   1293 * returns skb dequeued from the list if its seqno is less than or equal to
   1294 * the expected one, otherwise the skb is still hold
   1295 *
   1296 * Note: must be used with appropriate locks held only
   1297 */
   1298static inline struct sk_buff *__tipc_skb_dequeue(struct sk_buff_head *list,
   1299						 u16 seqno)
   1300{
   1301	struct sk_buff *skb = skb_peek(list);
   1302
   1303	if (skb && less_eq(buf_seqno(skb), seqno)) {
   1304		__skb_unlink(skb, list);
   1305		return skb;
   1306	}
   1307	return NULL;
   1308}
   1309
   1310#endif