1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#ifndef _TIPC_MSG_H
38#define _TIPC_MSG_H
39
40#include "core.h"
41
42#define TIPC_VERSION 2
43
44#define SHORT_H_SIZE 24
45#define DIR_MSG_H_SIZE 32
46#define LONG_H_SIZE 40
47#define MCAST_H_SIZE 44
48#define INT_H_SIZE 40
49#define MIN_H_SIZE 24
50#define MAX_H_SIZE 60
51
52#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE)
53
54
55
56
57
58
59
60
61
62
63
64static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val)
65{
66 m->hdr[w] = htonl(val);
67}
68
69static inline void msg_set_bits(struct tipc_msg *m, u32 w,
70 u32 pos, u32 mask, u32 val)
71{
72 val = (val & mask) << pos;
73 mask = mask << pos;
74 m->hdr[w] &= ~htonl(mask);
75 m->hdr[w] |= htonl(val);
76}
77
78static inline void msg_swap_words(struct tipc_msg *msg, u32 a, u32 b)
79{
80 u32 temp = msg->hdr[a];
81
82 msg->hdr[a] = msg->hdr[b];
83 msg->hdr[b] = temp;
84}
85
86
87
88
89
90static inline u32 msg_version(struct tipc_msg *m)
91{
92 return msg_bits(m, 0, 29, 7);
93}
94
95static inline void msg_set_version(struct tipc_msg *m)
96{
97 msg_set_bits(m, 0, 29, 7, TIPC_VERSION);
98}
99
100static inline u32 msg_user(struct tipc_msg *m)
101{
102 return msg_bits(m, 0, 25, 0xf);
103}
104
105static inline u32 msg_isdata(struct tipc_msg *m)
106{
107 return (msg_user(m) <= TIPC_CRITICAL_IMPORTANCE);
108}
109
110static inline void msg_set_user(struct tipc_msg *m, u32 n)
111{
112 msg_set_bits(m, 0, 25, 0xf, n);
113}
114
115static inline void msg_set_importance(struct tipc_msg *m, u32 i)
116{
117 msg_set_user(m, i);
118}
119
120static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n)
121{
122 msg_set_bits(m, 0, 21, 0xf, n>>2);
123}
124
125static inline int msg_non_seq(struct tipc_msg *m)
126{
127 return msg_bits(m, 0, 20, 1);
128}
129
130static inline void msg_set_non_seq(struct tipc_msg *m, u32 n)
131{
132 msg_set_bits(m, 0, 20, 1, n);
133}
134
135static inline int msg_dest_droppable(struct tipc_msg *m)
136{
137 return msg_bits(m, 0, 19, 1);
138}
139
140static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d)
141{
142 msg_set_bits(m, 0, 19, 1, d);
143}
144
145static inline int msg_src_droppable(struct tipc_msg *m)
146{
147 return msg_bits(m, 0, 18, 1);
148}
149
150static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d)
151{
152 msg_set_bits(m, 0, 18, 1, d);
153}
154
155static inline void msg_set_size(struct tipc_msg *m, u32 sz)
156{
157 m->hdr[0] = htonl((msg_word(m, 0) & ~0x1ffff) | sz);
158}
159
160
161
162
163
164
165static inline void msg_set_type(struct tipc_msg *m, u32 n)
166{
167 msg_set_bits(m, 1, 29, 0x7, n);
168}
169
170static inline void msg_set_errcode(struct tipc_msg *m, u32 err)
171{
172 msg_set_bits(m, 1, 25, 0xf, err);
173}
174
175static inline u32 msg_reroute_cnt(struct tipc_msg *m)
176{
177 return msg_bits(m, 1, 21, 0xf);
178}
179
180static inline void msg_incr_reroute_cnt(struct tipc_msg *m)
181{
182 msg_set_bits(m, 1, 21, 0xf, msg_reroute_cnt(m) + 1);
183}
184
185static inline void msg_reset_reroute_cnt(struct tipc_msg *m)
186{
187 msg_set_bits(m, 1, 21, 0xf, 0);
188}
189
190static inline u32 msg_lookup_scope(struct tipc_msg *m)
191{
192 return msg_bits(m, 1, 19, 0x3);
193}
194
195static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n)
196{
197 msg_set_bits(m, 1, 19, 0x3, n);
198}
199
200static inline u32 msg_bcast_ack(struct tipc_msg *m)
201{
202 return msg_bits(m, 1, 0, 0xffff);
203}
204
205static inline void msg_set_bcast_ack(struct tipc_msg *m, u32 n)
206{
207 msg_set_bits(m, 1, 0, 0xffff, n);
208}
209
210
211
212
213
214
215static inline u32 msg_ack(struct tipc_msg *m)
216{
217 return msg_bits(m, 2, 16, 0xffff);
218}
219
220static inline void msg_set_ack(struct tipc_msg *m, u32 n)
221{
222 msg_set_bits(m, 2, 16, 0xffff, n);
223}
224
225static inline u32 msg_seqno(struct tipc_msg *m)
226{
227 return msg_bits(m, 2, 0, 0xffff);
228}
229
230static inline void msg_set_seqno(struct tipc_msg *m, u32 n)
231{
232 msg_set_bits(m, 2, 0, 0xffff, n);
233}
234
235
236
237
238
239
240
241
242
243
244
245static inline u32 msg_destnode_cache(struct tipc_msg *m)
246{
247 return m->hdr[2];
248}
249
250static inline void msg_set_destnode_cache(struct tipc_msg *m, u32 dnode)
251{
252 m->hdr[2] = dnode;
253}
254
255
256
257
258
259
260static inline void msg_set_prevnode(struct tipc_msg *m, u32 a)
261{
262 msg_set_word(m, 3, a);
263}
264
265static inline void msg_set_origport(struct tipc_msg *m, u32 p)
266{
267 msg_set_word(m, 4, p);
268}
269
270static inline void msg_set_destport(struct tipc_msg *m, u32 p)
271{
272 msg_set_word(m, 5, p);
273}
274
275static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p)
276{
277 msg_set_word(m, 5, p);
278}
279
280static inline void msg_set_orignode(struct tipc_msg *m, u32 a)
281{
282 msg_set_word(m, 6, a);
283}
284
285static inline void msg_set_destnode(struct tipc_msg *m, u32 a)
286{
287 msg_set_word(m, 7, a);
288}
289
290static inline int msg_is_dest(struct tipc_msg *m, u32 d)
291{
292 return(msg_short(m) || (msg_destnode(m) == d));
293}
294
295static inline u32 msg_routed(struct tipc_msg *m)
296{
297 if (likely(msg_short(m)))
298 return 0;
299 return(msg_destnode(m) ^ msg_orignode(m)) >> 11;
300}
301
302static inline void msg_set_nametype(struct tipc_msg *m, u32 n)
303{
304 msg_set_word(m, 8, n);
305}
306
307static inline u32 msg_transp_seqno(struct tipc_msg *m)
308{
309 return msg_word(m, 8);
310}
311
312static inline void msg_set_timestamp(struct tipc_msg *m, u32 n)
313{
314 msg_set_word(m, 8, n);
315}
316
317static inline u32 msg_timestamp(struct tipc_msg *m)
318{
319 return msg_word(m, 8);
320}
321
322static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n)
323{
324 msg_set_word(m, 8, n);
325}
326
327static inline void msg_set_namelower(struct tipc_msg *m, u32 n)
328{
329 msg_set_word(m, 9, n);
330}
331
332static inline void msg_set_nameinst(struct tipc_msg *m, u32 n)
333{
334 msg_set_namelower(m, n);
335}
336
337static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
338{
339 msg_set_word(m, 10, n);
340}
341
342static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
343{
344 return (struct tipc_msg *)msg_data(m);
345}
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385#define BCAST_PROTOCOL 5
386#define MSG_BUNDLER 6
387#define LINK_PROTOCOL 7
388#define CONN_MANAGER 8
389#define ROUTE_DISTRIBUTOR 9
390#define CHANGEOVER_PROTOCOL 10
391#define NAME_DISTRIBUTOR 11
392#define MSG_FRAGMENTER 12
393#define LINK_CONFIG 13
394#define DSC_H_SIZE 40
395
396
397
398
399
400#define CONN_PROBE 0
401#define CONN_PROBE_REPLY 1
402#define CONN_ACK 2
403
404
405
406
407
408#define PUBLICATION 0
409#define WITHDRAWAL 1
410
411
412
413
414
415
416static inline u32 msg_seq_gap(struct tipc_msg *m)
417{
418 return msg_bits(m, 1, 16, 0x1fff);
419}
420
421static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n)
422{
423 msg_set_bits(m, 1, 16, 0x1fff, n);
424}
425
426static inline u32 msg_req_links(struct tipc_msg *m)
427{
428 return msg_bits(m, 1, 16, 0xfff);
429}
430
431static inline void msg_set_req_links(struct tipc_msg *m, u32 n)
432{
433 msg_set_bits(m, 1, 16, 0xfff, n);
434}
435
436
437
438
439
440
441static inline u32 msg_dest_domain(struct tipc_msg *m)
442{
443 return msg_word(m, 2);
444}
445
446static inline void msg_set_dest_domain(struct tipc_msg *m, u32 n)
447{
448 msg_set_word(m, 2, n);
449}
450
451static inline u32 msg_bcgap_after(struct tipc_msg *m)
452{
453 return msg_bits(m, 2, 16, 0xffff);
454}
455
456static inline void msg_set_bcgap_after(struct tipc_msg *m, u32 n)
457{
458 msg_set_bits(m, 2, 16, 0xffff, n);
459}
460
461static inline u32 msg_bcgap_to(struct tipc_msg *m)
462{
463 return msg_bits(m, 2, 0, 0xffff);
464}
465
466static inline void msg_set_bcgap_to(struct tipc_msg *m, u32 n)
467{
468 msg_set_bits(m, 2, 0, 0xffff, n);
469}
470
471
472
473
474
475
476static inline u32 msg_last_bcast(struct tipc_msg *m)
477{
478 return msg_bits(m, 4, 16, 0xffff);
479}
480
481static inline void msg_set_last_bcast(struct tipc_msg *m, u32 n)
482{
483 msg_set_bits(m, 4, 16, 0xffff, n);
484}
485
486
487static inline u32 msg_fragm_no(struct tipc_msg *m)
488{
489 return msg_bits(m, 4, 16, 0xffff);
490}
491
492static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n)
493{
494 msg_set_bits(m, 4, 16, 0xffff, n);
495}
496
497
498static inline u32 msg_next_sent(struct tipc_msg *m)
499{
500 return msg_bits(m, 4, 0, 0xffff);
501}
502
503static inline void msg_set_next_sent(struct tipc_msg *m, u32 n)
504{
505 msg_set_bits(m, 4, 0, 0xffff, n);
506}
507
508
509static inline u32 msg_long_msgno(struct tipc_msg *m)
510{
511 return msg_bits(m, 4, 0, 0xffff);
512}
513
514static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n)
515{
516 msg_set_bits(m, 4, 0, 0xffff, n);
517}
518
519static inline u32 msg_bc_netid(struct tipc_msg *m)
520{
521 return msg_word(m, 4);
522}
523
524static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id)
525{
526 msg_set_word(m, 4, id);
527}
528
529static inline u32 msg_link_selector(struct tipc_msg *m)
530{
531 return msg_bits(m, 4, 0, 1);
532}
533
534static inline void msg_set_link_selector(struct tipc_msg *m, u32 n)
535{
536 msg_set_bits(m, 4, 0, 1, (n & 1));
537}
538
539
540
541
542
543static inline u32 msg_session(struct tipc_msg *m)
544{
545 return msg_bits(m, 5, 16, 0xffff);
546}
547
548static inline void msg_set_session(struct tipc_msg *m, u32 n)
549{
550 msg_set_bits(m, 5, 16, 0xffff, n);
551}
552
553static inline u32 msg_probe(struct tipc_msg *m)
554{
555 return msg_bits(m, 5, 0, 1);
556}
557
558static inline void msg_set_probe(struct tipc_msg *m, u32 val)
559{
560 msg_set_bits(m, 5, 0, 1, (val & 1));
561}
562
563static inline char msg_net_plane(struct tipc_msg *m)
564{
565 return msg_bits(m, 5, 1, 7) + 'A';
566}
567
568static inline void msg_set_net_plane(struct tipc_msg *m, char n)
569{
570 msg_set_bits(m, 5, 1, 7, (n - 'A'));
571}
572
573static inline u32 msg_linkprio(struct tipc_msg *m)
574{
575 return msg_bits(m, 5, 4, 0x1f);
576}
577
578static inline void msg_set_linkprio(struct tipc_msg *m, u32 n)
579{
580 msg_set_bits(m, 5, 4, 0x1f, n);
581}
582
583static inline u32 msg_bearer_id(struct tipc_msg *m)
584{
585 return msg_bits(m, 5, 9, 0x7);
586}
587
588static inline void msg_set_bearer_id(struct tipc_msg *m, u32 n)
589{
590 msg_set_bits(m, 5, 9, 0x7, n);
591}
592
593static inline u32 msg_redundant_link(struct tipc_msg *m)
594{
595 return msg_bits(m, 5, 12, 0x1);
596}
597
598static inline void msg_set_redundant_link(struct tipc_msg *m)
599{
600 msg_set_bits(m, 5, 12, 0x1, 1);
601}
602
603static inline void msg_clear_redundant_link(struct tipc_msg *m)
604{
605 msg_set_bits(m, 5, 12, 0x1, 0);
606}
607
608
609
610
611
612
613static inline u32 msg_msgcnt(struct tipc_msg *m)
614{
615 return msg_bits(m, 9, 16, 0xffff);
616}
617
618static inline void msg_set_msgcnt(struct tipc_msg *m, u32 n)
619{
620 msg_set_bits(m, 9, 16, 0xffff, n);
621}
622
623static inline u32 msg_bcast_tag(struct tipc_msg *m)
624{
625 return msg_bits(m, 9, 16, 0xffff);
626}
627
628static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n)
629{
630 msg_set_bits(m, 9, 16, 0xffff, n);
631}
632
633static inline u32 msg_max_pkt(struct tipc_msg *m)
634{
635 return (msg_bits(m, 9, 16, 0xffff) * 4);
636}
637
638static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n)
639{
640 msg_set_bits(m, 9, 16, 0xffff, (n / 4));
641}
642
643static inline u32 msg_link_tolerance(struct tipc_msg *m)
644{
645 return msg_bits(m, 9, 0, 0xffff);
646}
647
648static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
649{
650 msg_set_bits(m, 9, 0, 0xffff, n);
651}
652
653
654
655
656
657
658static inline u32 msg_remote_node(struct tipc_msg *m)
659{
660 return msg_word(m, msg_hdr_sz(m)/4);
661}
662
663static inline void msg_set_remote_node(struct tipc_msg *m, u32 a)
664{
665 msg_set_word(m, msg_hdr_sz(m)/4, a);
666}
667
668static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos)
669{
670 msg_data(m)[pos + 4] = 1;
671}
672
673
674
675
676
677#define FIRST_FRAGMENT 0
678#define FRAGMENT 1
679#define LAST_FRAGMENT 2
680
681
682
683
684
685#define STATE_MSG 0
686#define RESET_MSG 1
687#define ACTIVATE_MSG 2
688
689
690
691
692#define DUPLICATE_MSG 0
693#define ORIGINAL_MSG 1
694
695
696
697
698#define EXT_ROUTING_TABLE 0
699#define LOCAL_ROUTING_TABLE 1
700#define SLAVE_ROUTING_TABLE 2
701#define ROUTE_ADDITION 3
702#define ROUTE_REMOVAL 4
703
704
705
706
707
708#define DSC_REQ_MSG 0
709#define DSC_RESP_MSG 1
710
711static inline u32 msg_tot_importance(struct tipc_msg *m)
712{
713 if (likely(msg_isdata(m))) {
714 if (likely(msg_orignode(m) == tipc_own_addr))
715 return msg_importance(m);
716 return msg_importance(m) + 4;
717 }
718 if ((msg_user(m) == MSG_FRAGMENTER) &&
719 (msg_type(m) == FIRST_FRAGMENT))
720 return msg_importance(msg_get_wrapped(m));
721 return msg_importance(m);
722}
723
724
725static inline void msg_init(struct tipc_msg *m, u32 user, u32 type,
726 u32 hsize, u32 destnode)
727{
728 memset(m, 0, hsize);
729 msg_set_version(m);
730 msg_set_user(m, user);
731 msg_set_hdr_sz(m, hsize);
732 msg_set_size(m, hsize);
733 msg_set_prevnode(m, tipc_own_addr);
734 msg_set_type(m, type);
735 if (!msg_short(m)) {
736 msg_set_orignode(m, tipc_own_addr);
737 msg_set_destnode(m, destnode);
738 }
739}
740
741
742
743
744
745static 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
757
758
759
760
761
762
763static 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 skb_copy_to_linear_data(*buf, 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 skb_copy_to_linear_data_offset(*buf, pos,
794 msg_sect[cnt].iov_base,
795 msg_sect[cnt].iov_len);
796 pos += msg_sect[cnt].iov_len;
797 }
798 if (likely(res))
799 return dsz;
800
801 buf_discard(*buf);
802 *buf = NULL;
803 return -EFAULT;
804}
805
806static inline void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
807{
808 memcpy(&((int *)m)[5], a, sizeof(*a));
809}
810
811static inline void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a)
812{
813 memcpy(a, &((int*)m)[5], sizeof(*a));
814}
815
816#endif
817