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