Branch data Line data Source code
1 : : #ifndef LINUX_MLD_H
2 : : #define LINUX_MLD_H
3 : :
4 : : #include <linux/in6.h>
5 : : #include <linux/icmpv6.h>
6 : :
7 : : /* MLDv1 Query/Report/Done */
8 : : struct mld_msg {
9 : : struct icmp6hdr mld_hdr;
10 : : struct in6_addr mld_mca;
11 : : };
12 : :
13 : : #define mld_type mld_hdr.icmp6_type
14 : : #define mld_code mld_hdr.icmp6_code
15 : : #define mld_cksum mld_hdr.icmp6_cksum
16 : : #define mld_maxdelay mld_hdr.icmp6_maxdelay
17 : : #define mld_reserved mld_hdr.icmp6_dataun.un_data16[1]
18 : :
19 : : /* Multicast Listener Discovery version 2 headers */
20 : : /* MLDv2 Report */
21 : : struct mld2_grec {
22 : : __u8 grec_type;
23 : : __u8 grec_auxwords;
24 : : __be16 grec_nsrcs;
25 : : struct in6_addr grec_mca;
26 : : struct in6_addr grec_src[0];
27 : : };
28 : :
29 : : struct mld2_report {
30 : : struct icmp6hdr mld2r_hdr;
31 : : struct mld2_grec mld2r_grec[0];
32 : : };
33 : :
34 : : #define mld2r_type mld2r_hdr.icmp6_type
35 : : #define mld2r_resv1 mld2r_hdr.icmp6_code
36 : : #define mld2r_cksum mld2r_hdr.icmp6_cksum
37 : : #define mld2r_resv2 mld2r_hdr.icmp6_dataun.un_data16[0]
38 : : #define mld2r_ngrec mld2r_hdr.icmp6_dataun.un_data16[1]
39 : :
40 : : /* MLDv2 Query */
41 : : struct mld2_query {
42 : : struct icmp6hdr mld2q_hdr;
43 : : struct in6_addr mld2q_mca;
44 : : #if defined(__LITTLE_ENDIAN_BITFIELD)
45 : : __u8 mld2q_qrv:3,
46 : : mld2q_suppress:1,
47 : : mld2q_resv2:4;
48 : : #elif defined(__BIG_ENDIAN_BITFIELD)
49 : : __u8 mld2q_resv2:4,
50 : : mld2q_suppress:1,
51 : : mld2q_qrv:3;
52 : : #else
53 : : #error "Please fix <asm/byteorder.h>"
54 : : #endif
55 : : __u8 mld2q_qqic;
56 : : __be16 mld2q_nsrcs;
57 : : struct in6_addr mld2q_srcs[0];
58 : : };
59 : :
60 : : #define mld2q_type mld2q_hdr.icmp6_type
61 : : #define mld2q_code mld2q_hdr.icmp6_code
62 : : #define mld2q_cksum mld2q_hdr.icmp6_cksum
63 : : #define mld2q_mrc mld2q_hdr.icmp6_maxdelay
64 : : #define mld2q_resv1 mld2q_hdr.icmp6_dataun.un_data16[1]
65 : :
66 : : /* RFC3810, 5.1.3. Maximum Response Code:
67 : : *
68 : : * If Maximum Response Code >= 32768, Maximum Response Code represents a
69 : : * floating-point value as follows:
70 : : *
71 : : * 0 1 2 3 4 5 6 7 8 9 A B C D E F
72 : : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73 : : * |1| exp | mant |
74 : : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 : : */
76 : : #define MLDV2_MRC_EXP(value) (((value) >> 12) & 0x0007)
77 : : #define MLDV2_MRC_MAN(value) ((value) & 0x0fff)
78 : :
79 : : /* RFC3810, 5.1.9. QQIC (Querier's Query Interval Code):
80 : : *
81 : : * If QQIC >= 128, QQIC represents a floating-point value as follows:
82 : : *
83 : : * 0 1 2 3 4 5 6 7
84 : : * +-+-+-+-+-+-+-+-+
85 : : * |1| exp | mant |
86 : : * +-+-+-+-+-+-+-+-+
87 : : */
88 : : #define MLDV2_QQIC_EXP(value) (((value) >> 4) & 0x07)
89 : : #define MLDV2_QQIC_MAN(value) ((value) & 0x0f)
90 : :
91 : : static inline unsigned long mldv2_mrc(const struct mld2_query *mlh2)
92 : : {
93 : : /* RFC3810, 5.1.3. Maximum Response Code */
94 [ # # ][ # # ]: 0 : unsigned long ret, mc_mrc = ntohs(mlh2->mld2q_mrc);
95 : :
96 [ # # ][ # # ]: 0 : if (mc_mrc < 32768) {
97 : : ret = mc_mrc;
98 : : } else {
99 : : unsigned long mc_man, mc_exp;
100 : :
101 : 0 : mc_exp = MLDV2_MRC_EXP(mc_mrc);
102 : 0 : mc_man = MLDV2_MRC_MAN(mc_mrc);
103 : :
104 : 0 : ret = (mc_man | 0x1000) << (mc_exp + 3);
105 : : }
106 : :
107 : : return ret;
108 : : }
109 : :
110 : : #endif
|