xref: /linux/net/tipc/msg.h (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
1 /*
2  * net/tipc/msg.h: Include file for TIPC message header routines
3  *
4  * Copyright (c) 2000-2006, Ericsson AB
5  * Copyright (c) 2005, Wind River Systems
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the names of the copyright holders nor the names of its
17  *    contributors may be used to endorse or promote products derived from
18  *    this software without specific prior written permission.
19  *
20  * Alternatively, this software may be distributed under the terms of the
21  * GNU General Public License ("GPL") version 2 as published by the Free
22  * Software Foundation.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #ifndef _TIPC_MSG_H
38 #define _TIPC_MSG_H
39 
40 #include "core.h"
41 
42 #define TIPC_VERSION              2
43 #define DATA_LOW                  TIPC_LOW_IMPORTANCE
44 #define DATA_MEDIUM               TIPC_MEDIUM_IMPORTANCE
45 #define DATA_HIGH                 TIPC_HIGH_IMPORTANCE
46 #define DATA_CRITICAL             TIPC_CRITICAL_IMPORTANCE
47 #define SHORT_H_SIZE              24	/* Connected,in cluster */
48 #define DIR_MSG_H_SIZE            32	/* Directly addressed messages */
49 #define CONN_MSG_H_SIZE           36	/* Routed connected msgs*/
50 #define LONG_H_SIZE               40	/* Named Messages */
51 #define MCAST_H_SIZE              44	/* Multicast messages */
52 #define MAX_H_SIZE                60	/* Inclusive full options */
53 #define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE)
54 #define LINK_CONFIG               13
55 
56 
57 /*
58 		TIPC user data message header format, version 2
59 
60 	- Fundamental definitions available to privileged TIPC users
61 	  are located in tipc_msg.h.
62 	- Remaining definitions available to TIPC internal users appear below.
63 */
64 
65 
66 static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val)
67 {
68 	m->hdr[w] = htonl(val);
69 }
70 
71 static inline void msg_set_bits(struct tipc_msg *m, u32 w,
72 				u32 pos, u32 mask, u32 val)
73 {
74 	u32 word = msg_word(m,w) & ~(mask << pos);
75 	msg_set_word(m, w, (word |= (val << pos)));
76 }
77 
78 /*
79  * Word 0
80  */
81 
82 static inline u32 msg_version(struct tipc_msg *m)
83 {
84 	return msg_bits(m, 0, 29, 7);
85 }
86 
87 static inline void msg_set_version(struct tipc_msg *m)
88 {
89 	msg_set_bits(m, 0, 29, 0xf, TIPC_VERSION);
90 }
91 
92 static inline u32 msg_user(struct tipc_msg *m)
93 {
94 	return msg_bits(m, 0, 25, 0xf);
95 }
96 
97 static inline u32 msg_isdata(struct tipc_msg *m)
98 {
99 	return (msg_user(m) <= DATA_CRITICAL);
100 }
101 
102 static inline void msg_set_user(struct tipc_msg *m, u32 n)
103 {
104 	msg_set_bits(m, 0, 25, 0xf, n);
105 }
106 
107 static inline void msg_set_importance(struct tipc_msg *m, u32 i)
108 {
109 	msg_set_user(m, i);
110 }
111 
112 static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n)
113 {
114 	msg_set_bits(m, 0, 21, 0xf, n>>2);
115 }
116 
117 static inline int msg_non_seq(struct tipc_msg *m)
118 {
119 	return msg_bits(m, 0, 20, 1);
120 }
121 
122 static inline void msg_set_non_seq(struct tipc_msg *m)
123 {
124 	msg_set_bits(m, 0, 20, 1, 1);
125 }
126 
127 static inline int msg_dest_droppable(struct tipc_msg *m)
128 {
129 	return msg_bits(m, 0, 19, 1);
130 }
131 
132 static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d)
133 {
134 	msg_set_bits(m, 0, 19, 1, d);
135 }
136 
137 static inline int msg_src_droppable(struct tipc_msg *m)
138 {
139 	return msg_bits(m, 0, 18, 1);
140 }
141 
142 static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d)
143 {
144 	msg_set_bits(m, 0, 18, 1, d);
145 }
146 
147 static inline void msg_set_size(struct tipc_msg *m, u32 sz)
148 {
149 	m->hdr[0] = htonl((msg_word(m, 0) & ~0x1ffff) | sz);
150 }
151 
152 
153 /*
154  * Word 1
155  */
156 
157 static inline void msg_set_type(struct tipc_msg *m, u32 n)
158 {
159 	msg_set_bits(m, 1, 29, 0x7, n);
160 }
161 
162 static inline void msg_set_errcode(struct tipc_msg *m, u32 err)
163 {
164 	msg_set_bits(m, 1, 25, 0xf, err);
165 }
166 
167 static inline u32 msg_reroute_cnt(struct tipc_msg *m)
168 {
169 	return msg_bits(m, 1, 21, 0xf);
170 }
171 
172 static inline void msg_incr_reroute_cnt(struct tipc_msg *m)
173 {
174 	msg_set_bits(m, 1, 21, 0xf, msg_reroute_cnt(m) + 1);
175 }
176 
177 static inline void msg_reset_reroute_cnt(struct tipc_msg *m)
178 {
179 	msg_set_bits(m, 1, 21, 0xf, 0);
180 }
181 
182 static inline u32 msg_lookup_scope(struct tipc_msg *m)
183 {
184 	return msg_bits(m, 1, 19, 0x3);
185 }
186 
187 static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n)
188 {
189 	msg_set_bits(m, 1, 19, 0x3, n);
190 }
191 
192 static inline void msg_set_options(struct tipc_msg *m, const char *opt, u32 sz)
193 {
194 	u32 hsz = msg_hdr_sz(m);
195 	char *to = (char *)&m->hdr[hsz/4];
196 
197 	if ((hsz < DIR_MSG_H_SIZE) || ((hsz + sz) > MAX_H_SIZE))
198 		return;
199 	msg_set_bits(m, 1, 16, 0x7, (hsz - 28)/4);
200 	msg_set_hdr_sz(m, hsz + sz);
201 	memcpy(to, opt, sz);
202 }
203 
204 static inline u32 msg_bcast_ack(struct tipc_msg *m)
205 {
206 	return msg_bits(m, 1, 0, 0xffff);
207 }
208 
209 static inline void msg_set_bcast_ack(struct tipc_msg *m, u32 n)
210 {
211 	msg_set_bits(m, 1, 0, 0xffff, n);
212 }
213 
214 
215 /*
216  * Word 2
217  */
218 
219 static inline u32 msg_ack(struct tipc_msg *m)
220 {
221 	return msg_bits(m, 2, 16, 0xffff);
222 }
223 
224 static inline void msg_set_ack(struct tipc_msg *m, u32 n)
225 {
226 	msg_set_bits(m, 2, 16, 0xffff, n);
227 }
228 
229 static inline u32 msg_seqno(struct tipc_msg *m)
230 {
231 	return msg_bits(m, 2, 0, 0xffff);
232 }
233 
234 static inline void msg_set_seqno(struct tipc_msg *m, u32 n)
235 {
236 	msg_set_bits(m, 2, 0, 0xffff, n);
237 }
238 
239 
240 /*
241  * Words 3-10
242  */
243 
244 
245 static inline void msg_set_prevnode(struct tipc_msg *m, u32 a)
246 {
247 	msg_set_word(m, 3, a);
248 }
249 
250 static inline void msg_set_origport(struct tipc_msg *m, u32 p)
251 {
252 	msg_set_word(m, 4, p);
253 }
254 
255 static inline void msg_set_destport(struct tipc_msg *m, u32 p)
256 {
257 	msg_set_word(m, 5, p);
258 }
259 
260 static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p)
261 {
262 	msg_set_word(m, 5, p);
263 }
264 
265 static inline void msg_set_orignode(struct tipc_msg *m, u32 a)
266 {
267 	msg_set_word(m, 6, a);
268 }
269 
270 static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
271 {
272 	msg_set_word(m, 7, a);
273 }
274 
275 static inline int msg_is_dest(struct tipc_msg *m, u32 d)
276 {
277 	return(msg_short(m) || (msg_destnode(m) == d));
278 }
279 
280 static inline u32 msg_routed(struct tipc_msg *m)
281 {
282 	if (likely(msg_short(m)))
283 		return 0;
284 	return(msg_destnode(m) ^ msg_orignode(m)) >> 11;
285 }
286 
287 static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
288 {
289 	msg_set_word(m, 8, n);
290 }
291 
292 static inline u32 msg_transp_seqno(struct tipc_msg *m)
293 {
294 	return msg_word(m, 8);
295 }
296 
297 static inline void msg_set_timestamp(struct tipc_msg *m, u32 n)
298 {
299 	msg_set_word(m, 8, n);
300 }
301 
302 static inline u32 msg_timestamp(struct tipc_msg *m)
303 {
304 	return msg_word(m, 8);
305 }
306 
307 static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n)
308 {
309 	msg_set_word(m, 8, n);
310 }
311 
312 static inline void msg_set_namelower(struct tipc_msg *m, u32 n)
313 {
314 	msg_set_word(m, 9, n);
315 }
316 
317 static inline void msg_set_nameinst(struct tipc_msg *m, u32 n)
318 {
319 	msg_set_namelower(m, n);
320 }
321 
322 static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
323 {
324 	msg_set_word(m, 10, n);
325 }
326 
327 static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
328 {
329 	return (struct tipc_msg *)msg_data(m);
330 }
331 
332 static inline void msg_expand(struct tipc_msg *m, u32 destnode)
333 {
334 	if (!msg_short(m))
335 		return;
336 	msg_set_hdr_sz(m, LONG_H_SIZE);
337 	msg_set_orignode(m, msg_prevnode(m));
338 	msg_set_destnode(m, destnode);
339 	memset(&m->hdr[8], 0, 12);
340 }
341 
342 
343 
344 /*
345 		TIPC internal message header format, version 2
346 
347        1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0
348       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
349    w0:|vers |msg usr|hdr sz |n|resrv|            packet size          |
350       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
351    w1:|m typ|rsv=0|   sequence gap    |       broadcast ack no        |
352       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
353    w2:| link level ack no/bc_gap_from |     seq no / bcast_gap_to     |
354       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
355    w3:|                       previous node                           |
356       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
357    w4:|  next sent broadcast/fragm no | next sent pkt/ fragm msg no   |
358       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
359    w5:|          session no           |rsv=0|r|berid|link prio|netpl|p|
360       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
361    w6:|                      originating node                         |
362       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363    w7:|                      destination node                         |
364       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365    w8:|                   transport sequence number                   |
366       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367    w9:|   msg count / bcast tag       |       link tolerance          |
368       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369       \                                                               \
370       /                     User Specific Data                        /
371       \                                                               \
372       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
373 
374       NB: CONN_MANAGER use data message format. LINK_CONFIG has own format.
375 */
376 
377 /*
378  * Internal users
379  */
380 
381 #define  BCAST_PROTOCOL       5
382 #define  MSG_BUNDLER          6
383 #define  LINK_PROTOCOL        7
384 #define  CONN_MANAGER         8
385 #define  ROUTE_DISTRIBUTOR    9
386 #define  CHANGEOVER_PROTOCOL  10
387 #define  NAME_DISTRIBUTOR     11
388 #define  MSG_FRAGMENTER       12
389 #define  LINK_CONFIG          13
390 #define  INT_H_SIZE           40
391 #define  DSC_H_SIZE           40
392 
393 /*
394  *  Connection management protocol messages
395  */
396 
397 #define CONN_PROBE        0
398 #define CONN_PROBE_REPLY  1
399 #define CONN_ACK          2
400 
401 /*
402  * Name distributor messages
403  */
404 
405 #define PUBLICATION       0
406 #define WITHDRAWAL        1
407 
408 
409 /*
410  * Word 1
411  */
412 
413 static inline u32 msg_seq_gap(struct tipc_msg *m)
414 {
415 	return msg_bits(m, 1, 16, 0xff);
416 }
417 
418 static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
419 {
420 	msg_set_bits(m, 1, 16, 0xff, n);
421 }
422 
423 static inline u32 msg_req_links(struct tipc_msg *m)
424 {
425 	return msg_bits(m, 1, 16, 0xfff);
426 }
427 
428 static inline void msg_set_req_links(struct tipc_msg *m, u32 n)
429 {
430 	msg_set_bits(m, 1, 16, 0xfff, n);
431 }
432 
433 
434 /*
435  * Word 2
436  */
437 
438 static inline u32 msg_dest_domain(struct tipc_msg *m)
439 {
440 	return msg_word(m, 2);
441 }
442 
443 static inline void msg_set_dest_domain(struct tipc_msg *m, u32 n)
444 {
445 	msg_set_word(m, 2, n);
446 }
447 
448 static inline u32 msg_bcgap_after(struct tipc_msg *m)
449 {
450 	return msg_bits(m, 2, 16, 0xffff);
451 }
452 
453 static inline void msg_set_bcgap_after(struct tipc_msg *m, u32 n)
454 {
455 	msg_set_bits(m, 2, 16, 0xffff, n);
456 }
457 
458 static inline u32 msg_bcgap_to(struct tipc_msg *m)
459 {
460 	return msg_bits(m, 2, 0, 0xffff);
461 }
462 
463 static inline void msg_set_bcgap_to(struct tipc_msg *m, u32 n)
464 {
465 	msg_set_bits(m, 2, 0, 0xffff, n);
466 }
467 
468 
469 /*
470  * Word 4
471  */
472 
473 static inline u32 msg_last_bcast(struct tipc_msg *m)
474 {
475 	return msg_bits(m, 4, 16, 0xffff);
476 }
477 
478 static inline void msg_set_last_bcast(struct tipc_msg *m, u32 n)
479 {
480 	msg_set_bits(m, 4, 16, 0xffff, n);
481 }
482 
483 
484 static inline u32 msg_fragm_no(struct tipc_msg *m)
485 {
486 	return msg_bits(m, 4, 16, 0xffff);
487 }
488 
489 static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n)
490 {
491 	msg_set_bits(m, 4, 16, 0xffff, n);
492 }
493 
494 
495 static inline u32 msg_next_sent(struct tipc_msg *m)
496 {
497 	return msg_bits(m, 4, 0, 0xffff);
498 }
499 
500 static inline void msg_set_next_sent(struct tipc_msg *m, u32 n)
501 {
502 	msg_set_bits(m, 4, 0, 0xffff, n);
503 }
504 
505 
506 static inline u32 msg_long_msgno(struct tipc_msg *m)
507 {
508 	return msg_bits(m, 4, 0, 0xffff);
509 }
510 
511 static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n)
512 {
513 	msg_set_bits(m, 4, 0, 0xffff, n);
514 }
515 
516 static inline u32 msg_bc_netid(struct tipc_msg *m)
517 {
518 	return msg_word(m, 4);
519 }
520 
521 static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id)
522 {
523 	msg_set_word(m, 4, id);
524 }
525 
526 static inline u32 msg_link_selector(struct tipc_msg *m)
527 {
528 	return msg_bits(m, 4, 0, 1);
529 }
530 
531 static inline void msg_set_link_selector(struct tipc_msg *m, u32 n)
532 {
533 	msg_set_bits(m, 4, 0, 1, (n & 1));
534 }
535 
536 /*
537  * Word 5
538  */
539 
540 static inline u32 msg_session(struct tipc_msg *m)
541 {
542 	return msg_bits(m, 5, 16, 0xffff);
543 }
544 
545 static inline void msg_set_session(struct tipc_msg *m, u32 n)
546 {
547 	msg_set_bits(m, 5, 16, 0xffff, n);
548 }
549 
550 static inline u32 msg_probe(struct tipc_msg *m)
551 {
552 	return msg_bits(m, 5, 0, 1);
553 }
554 
555 static inline void msg_set_probe(struct tipc_msg *m, u32 val)
556 {
557 	msg_set_bits(m, 5, 0, 1, (val & 1));
558 }
559 
560 static inline char msg_net_plane(struct tipc_msg *m)
561 {
562 	return msg_bits(m, 5, 1, 7) + 'A';
563 }
564 
565 static inline void msg_set_net_plane(struct tipc_msg *m, char n)
566 {
567 	msg_set_bits(m, 5, 1, 7, (n - 'A'));
568 }
569 
570 static inline u32 msg_linkprio(struct tipc_msg *m)
571 {
572 	return msg_bits(m, 5, 4, 0x1f);
573 }
574 
575 static inline void msg_set_linkprio(struct tipc_msg *m, u32 n)
576 {
577 	msg_set_bits(m, 5, 4, 0x1f, n);
578 }
579 
580 static inline u32 msg_bearer_id(struct tipc_msg *m)
581 {
582 	return msg_bits(m, 5, 9, 0x7);
583 }
584 
585 static inline void msg_set_bearer_id(struct tipc_msg *m, u32 n)
586 {
587 	msg_set_bits(m, 5, 9, 0x7, n);
588 }
589 
590 static inline u32 msg_redundant_link(struct tipc_msg *m)
591 {
592 	return msg_bits(m, 5, 12, 0x1);
593 }
594 
595 static inline void msg_set_redundant_link(struct tipc_msg *m)
596 {
597 	msg_set_bits(m, 5, 12, 0x1, 1);
598 }
599 
600 static inline void msg_clear_redundant_link(struct tipc_msg *m)
601 {
602 	msg_set_bits(m, 5, 12, 0x1, 0);
603 }
604 
605 
606 /*
607  * Word 9
608  */
609 
610 static inline u32 msg_msgcnt(struct tipc_msg *m)
611 {
612 	return msg_bits(m, 9, 16, 0xffff);
613 }
614 
615 static inline void msg_set_msgcnt(struct tipc_msg *m, u32 n)
616 {
617 	msg_set_bits(m, 9, 16, 0xffff, n);
618 }
619 
620 static inline u32 msg_bcast_tag(struct tipc_msg *m)
621 {
622 	return msg_bits(m, 9, 16, 0xffff);
623 }
624 
625 static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n)
626 {
627 	msg_set_bits(m, 9, 16, 0xffff, n);
628 }
629 
630 static inline u32 msg_max_pkt(struct tipc_msg *m)
631 {
632 	return (msg_bits(m, 9, 16, 0xffff) * 4);
633 }
634 
635 static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n)
636 {
637 	msg_set_bits(m, 9, 16, 0xffff, (n / 4));
638 }
639 
640 static inline u32 msg_link_tolerance(struct tipc_msg *m)
641 {
642 	return msg_bits(m, 9, 0, 0xffff);
643 }
644 
645 static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
646 {
647 	msg_set_bits(m, 9, 0, 0xffff, n);
648 }
649 
650 /*
651  * Routing table message data
652  */
653 
654 
655 static inline u32 msg_remote_node(struct tipc_msg *m)
656 {
657 	return msg_word(m, msg_hdr_sz(m)/4);
658 }
659 
660 static inline void msg_set_remote_node(struct tipc_msg *m, u32 a)
661 {
662 	msg_set_word(m, msg_hdr_sz(m)/4, a);
663 }
664 
665 static inline int msg_dataoctet(struct tipc_msg *m, u32 pos)
666 {
667 	return(msg_data(m)[pos + 4] != 0);
668 }
669 
670 static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
671 {
672 	msg_data(m)[pos + 4] = 1;
673 }
674 
675 /*
676  * Segmentation message types
677  */
678 
679 #define FIRST_FRAGMENT     0
680 #define FRAGMENT           1
681 #define LAST_FRAGMENT      2
682 
683 /*
684  * Link management protocol message types
685  */
686 
687 #define STATE_MSG       0
688 #define RESET_MSG       1
689 #define ACTIVATE_MSG    2
690 
691 /*
692  * Changeover tunnel message types
693  */
694 #define DUPLICATE_MSG    0
695 #define ORIGINAL_MSG     1
696 
697 /*
698  * Routing table message types
699  */
700 #define EXT_ROUTING_TABLE    0
701 #define LOCAL_ROUTING_TABLE  1
702 #define SLAVE_ROUTING_TABLE  2
703 #define ROUTE_ADDITION       3
704 #define ROUTE_REMOVAL        4
705 
706 /*
707  * Config protocol message types
708  */
709 
710 #define DSC_REQ_MSG          0
711 #define DSC_RESP_MSG         1
712 
713 static inline u32 msg_tot_importance(struct tipc_msg *m)
714 {
715 	if (likely(msg_isdata(m))) {
716 		if (likely(msg_orignode(m) == tipc_own_addr))
717 			return msg_importance(m);
718 		return msg_importance(m) + 4;
719 	}
720 	if ((msg_user(m) == MSG_FRAGMENTER)  &&
721 	    (msg_type(m) == FIRST_FRAGMENT))
722 		return msg_importance(msg_get_wrapped(m));
723 	return msg_importance(m);
724 }
725 
726 
727 static inline void msg_init(struct tipc_msg *m, u32 user, u32 type,
728 			    u32 err, u32 hsize, u32 destnode)
729 {
730 	memset(m, 0, hsize);
731 	msg_set_version(m);
732 	msg_set_user(m, user);
733 	msg_set_hdr_sz(m, hsize);
734 	msg_set_size(m, hsize);
735 	msg_set_prevnode(m, tipc_own_addr);
736 	msg_set_type(m, type);
737 	msg_set_errcode(m, err);
738 	if (!msg_short(m)) {
739 		msg_set_orignode(m, tipc_own_addr);
740 		msg_set_destnode(m, destnode);
741 	}
742 }
743 
744 /**
745  * msg_calc_data_size - determine total data size for message
746  */
747 
748 static inline int msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect)
749 {
750 	int dsz = 0;
751 	int i;
752 
753 	for (i = 0; i < num_sect; i++)
754 		dsz += msg_sect[i].iov_len;
755 	return dsz;
756 }
757 
758 /**
759  * msg_build - create message using specified header and data
760  *
761  * Note: Caller must not hold any locks in case copy_from_user() is interrupted!
762  *
763  * Returns message data size or errno
764  */
765 
766 static inline int msg_build(struct tipc_msg *hdr,
767 			    struct iovec const *msg_sect, u32 num_sect,
768 			    int max_size, int usrmem, struct sk_buff** buf)
769 {
770 	int dsz, sz, hsz, pos, res, cnt;
771 
772 	dsz = msg_calc_data_size(msg_sect, num_sect);
773 	if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) {
774 		*buf = NULL;
775 		return -EINVAL;
776 	}
777 
778 	pos = hsz = msg_hdr_sz(hdr);
779 	sz = hsz + dsz;
780 	msg_set_size(hdr, sz);
781 	if (unlikely(sz > max_size)) {
782 		*buf = NULL;
783 		return dsz;
784 	}
785 
786 	*buf = buf_acquire(sz);
787 	if (!(*buf))
788 		return -ENOMEM;
789 	memcpy((*buf)->data, (unchar *)hdr, hsz);
790 	for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) {
791 		if (likely(usrmem))
792 			res = !copy_from_user((*buf)->data + pos,
793 					      msg_sect[cnt].iov_base,
794 					      msg_sect[cnt].iov_len);
795 		else
796 			memcpy((*buf)->data + pos, msg_sect[cnt].iov_base,
797 			       msg_sect[cnt].iov_len);
798 		pos += msg_sect[cnt].iov_len;
799 	}
800 	if (likely(res))
801 		return dsz;
802 
803 	buf_discard(*buf);
804 	*buf = NULL;
805 	return -EFAULT;
806 }
807 
808 static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
809 {
810 	memcpy(&((int *)m)[5], a, sizeof(*a));
811 }
812 
813 static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
814 {
815 	memcpy(a, &((int*)m)[5], sizeof(*a));
816 }
817 
818 #endif
819