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