1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef LINUX_MLD_H 3 #define LINUX_MLD_H 4 5 #include <linux/in6.h> 6 #include <linux/icmpv6.h> 7 8 /* MLDv1 Query/Report/Done */ 9 struct mld_msg { 10 struct icmp6hdr mld_hdr; 11 struct in6_addr mld_mca; 12 }; 13 14 #define mld_type mld_hdr.icmp6_type 15 #define mld_code mld_hdr.icmp6_code 16 #define mld_cksum mld_hdr.icmp6_cksum 17 #define mld_maxdelay mld_hdr.icmp6_maxdelay 18 #define mld_reserved mld_hdr.icmp6_dataun.un_data16[1] 19 20 /* Multicast Listener Discovery version 2 headers */ 21 /* MLDv2 Report */ 22 struct mld2_grec { 23 __u8 grec_type; 24 __u8 grec_auxwords; 25 __be16 grec_nsrcs; 26 struct in6_addr grec_mca; 27 struct in6_addr grec_src[]; 28 }; 29 30 struct mld2_report { 31 struct icmp6hdr mld2r_hdr; 32 struct mld2_grec mld2r_grec[]; 33 }; 34 35 #define mld2r_type mld2r_hdr.icmp6_type 36 #define mld2r_resv1 mld2r_hdr.icmp6_code 37 #define mld2r_cksum mld2r_hdr.icmp6_cksum 38 #define mld2r_resv2 mld2r_hdr.icmp6_dataun.un_data16[0] 39 #define mld2r_ngrec mld2r_hdr.icmp6_dataun.un_data16[1] 40 41 /* MLDv2 Query */ 42 struct mld2_query { 43 struct icmp6hdr mld2q_hdr; 44 struct in6_addr mld2q_mca; 45 #if defined(__LITTLE_ENDIAN_BITFIELD) 46 __u8 mld2q_qrv:3, 47 mld2q_suppress:1, 48 mld2q_resv2:4; 49 #elif defined(__BIG_ENDIAN_BITFIELD) 50 __u8 mld2q_resv2:4, 51 mld2q_suppress:1, 52 mld2q_qrv:3; 53 #else 54 #error "Please fix <asm/byteorder.h>" 55 #endif 56 __u8 mld2q_qqic; 57 __be16 mld2q_nsrcs; 58 struct in6_addr mld2q_srcs[]; 59 }; 60 61 #define mld2q_type mld2q_hdr.icmp6_type 62 #define mld2q_code mld2q_hdr.icmp6_code 63 #define mld2q_cksum mld2q_hdr.icmp6_cksum 64 #define mld2q_mrc mld2q_hdr.icmp6_maxdelay 65 #define mld2q_resv1 mld2q_hdr.icmp6_dataun.un_data16[1] 66 67 /* RFC3810, 5.1.3. Maximum Response Code: 68 * 69 * If Maximum Response Code >= 32768, Maximum Response Code represents a 70 * floating-point value as follows: 71 * 72 * 0 1 2 3 4 5 6 7 8 9 A B C D E F 73 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 74 * |1| exp | mant | 75 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 76 */ 77 #define MLDV2_MRC_EXP(value) (((value) >> 12) & 0x0007) 78 #define MLDV2_MRC_MAN(value) ((value) & 0x0fff) 79 80 /* RFC3810, 5.1.9. QQIC (Querier's Query Interval Code): 81 * 82 * If QQIC >= 128, QQIC represents a floating-point value as follows: 83 * 84 * 0 1 2 3 4 5 6 7 85 * +-+-+-+-+-+-+-+-+ 86 * |1| exp | mant | 87 * +-+-+-+-+-+-+-+-+ 88 */ 89 #define MLDV2_QQIC_EXP(value) (((value) >> 4) & 0x07) 90 #define MLDV2_QQIC_MAN(value) ((value) & 0x0f) 91 92 /* MLDv2 QQIC floating-point exponential field min threshold */ 93 #define MLD_QQIC_MIN_THRESHOLD 128 94 /* MLDv2 QQIC FP max threshold (mant = 0xF, exp = 7) -> 31744 */ 95 #define MLD_QQIC_MAX_THRESHOLD 31744 96 /* MLDv2 MRC floating-point exponential field min threshold */ 97 #define MLD_MRC_MIN_THRESHOLD 32768UL 98 /* MLDv2 MRC FP max threshold (mant = 0xFFF, exp = 7) -> 8387584 */ 99 #define MLD_MRC_MAX_THRESHOLD 8387584 100 #define MLDV1_MRD_MAX_COMPAT (MLD_MRC_MIN_THRESHOLD - 1) 101 102 #define MLD_MAX_QUEUE 8 103 #define MLD_MAX_SKBS 32 104 105 /* V2 exponential field encoding */ 106 107 /* 108 * Calculate Maximum Response Code from Maximum Response Delay 109 * 110 * MRC represents the 16-bit encoded form of Maximum Response Delay (MRD); 111 * once decoded, the resulting value is in milliseconds. 112 * 113 * RFC3810, 5.1.3. defines only the decoding formula: 114 * Maximum Response Delay = (mant | 0x1000) << (exp + 3) 115 * 116 * but does NOT define the encoding procedure. To derive exponent: 117 * 118 * For the 16-bit MRC, the "hidden bit" (0x1000) is left shifted by 12 to 119 * sit above the 12-bit mantissa. The RFC then shifts this entire block 120 * left by (exp + 3) to reconstruct the value. So, 'hidden bit' is the 121 * MSB which is shifted by (12 + exp + 3). 122 * 123 * Total left shift of the hidden bit = 12 + (exp + 3) = exp + 15. 124 * This is the MSB at the 0-based bit position: (exp + 15). 125 * Since fls() is 1-based, fls(value) - 1 = exp + 15. 126 * 127 * Therefore: 128 * exp = fls(value) - 16 129 * mant = (value >> (exp + 3)) & 0x0FFF 130 * 131 * Final encoding formula: 132 * 0x8000 | (exp << 12) | mant 133 * 134 * Example (value = 1311744): 135 * 0 1 2 3 136 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 137 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 138 * |0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0| 1311744 139 * | ^-^--------mant---------^ ^...(exp+3)...^| exp=5 140 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 141 * 142 * Encoded: 143 * 0x8000 | (5 << 12) | 0x404 = 0xD404 144 */ 145 static inline u16 mldv2_mrc(unsigned long mrd) 146 { 147 u16 mc_man, mc_exp; 148 149 /* MRC < 32768 is literal */ 150 if (mrd < MLD_MRC_MIN_THRESHOLD) 151 return mrd; 152 153 /* Saturate at max representable (mant = 0xFFF, exp = 7) -> 8387584 */ 154 if (mrd >= MLD_MRC_MAX_THRESHOLD) 155 return 0xFFFF; 156 157 mc_exp = fls(mrd) - 16; 158 mc_man = (mrd >> (mc_exp + 3)) & 0x0FFF; 159 160 return 0x8000 | (mc_exp << 12) | mc_man; 161 } 162 163 /* 164 * Calculate Querier's Query Interval Code from Querier's Query Interval 165 * 166 * QQIC represents the 8-bit encoded form of Querier's Query Interval (QQI); 167 * once decoded, the resulting value is in seconds. 168 * 169 * RFC3810, 5.1.9. defines only the decoding formula: 170 * QQI = (mant | 0x10) << (exp + 3) 171 * 172 * but does NOT define the encoding procedure. To derive exponent: 173 * 174 * For any value of mantissa and exponent, the decoding formula indicates 175 * that the "hidden bit" (0x10) is shifted 4 bits left to sit above the 176 * 4-bit mantissa. The RFC again shifts this entire block left by (exp + 3) 177 * to reconstruct the value. So, 'hidden bit' is the MSB which is shifted 178 * by (4 + exp + 3). 179 * 180 * Total left shift of the 'hidden bit' = 4 + (exp + 3) = exp + 7. 181 * This is the MSB at the 0-based bit position: (exp + 7). 182 * Since fls() is 1-based, fls(value) - 1 = exp + 7. 183 * 184 * Therefore: 185 * exp = fls(value) - 8 186 * mant = (value >> (exp + 3)) & 0x0F 187 * 188 * Final encoding formula: 189 * 0x80 | (exp << 4) | mant 190 * 191 * Example (value = 3200): 192 * 0 1 193 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 194 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 195 * |0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0| (value = 3200) 196 * | ^-^-mant^ ^..(exp+3)..^| exp = 4, mant = 9 197 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 198 * 199 * Encoded: 200 * 0x80 | (4 << 4) | 9 = 0xC9 201 */ 202 static inline u8 mldv2_qqic(unsigned long value) 203 { 204 u8 mc_man, mc_exp; 205 206 /* QQIC < 128 is literal */ 207 if (value < MLD_QQIC_MIN_THRESHOLD) 208 return value; 209 210 /* Saturate at max representable (mant = 0xF, exp = 7) -> 31744 */ 211 if (value >= MLD_QQIC_MAX_THRESHOLD) 212 return 0xFF; 213 214 mc_exp = fls(value) - 8; 215 mc_man = (value >> (mc_exp + 3)) & 0x0F; 216 217 return 0x80 | (mc_exp << 4) | mc_man; 218 } 219 220 /* V2 exponential field decoding */ 221 222 /* Calculate Maximum Response Delay from Maximum Response Code 223 * 224 * RFC3810, relevant sections: 225 * - 5.1.3. Maximum Response Code defines the decoding formula: 226 * 0 1 2 3 4 5 6 7 8 9 A B C D E F 227 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 228 * |1| exp | mant | 229 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 230 * Maximum Response Delay = (mant | 0x1000) << (exp+3) 231 * - 9.3. Query Response Interval 232 * 233 * After decode, MRC represents the Maximum Response Delay (MRD) in 234 * units of milliseconds. 235 */ 236 static inline unsigned long mldv2_mrd(const struct mld2_query *mlh2) 237 { 238 unsigned long mc_mrc = ntohs(mlh2->mld2q_mrc); 239 240 if (mc_mrc < MLD_MRC_MIN_THRESHOLD) { 241 return mc_mrc; 242 } else { 243 unsigned long mc_man, mc_exp; 244 245 mc_exp = MLDV2_MRC_EXP(mc_mrc); 246 mc_man = MLDV2_MRC_MAN(mc_mrc); 247 248 return (mc_man | 0x1000) << (mc_exp + 3); 249 } 250 } 251 252 /* Calculate Querier's Query Interval from Querier's Query Interval Code 253 * 254 * RFC3810, relevant sections: 255 * - 5.1.9. QQIC (Querier's Query Interval Code) defines the decoding formula: 256 * 0 1 2 3 4 5 6 7 257 * +-+-+-+-+-+-+-+-+ 258 * |1| exp | mant | 259 * +-+-+-+-+-+-+-+-+ 260 * QQI = (mant | 0x10) << (exp + 3) 261 * - 9.2. Query Interval 262 * - 9.12. Older Version Querier Present Timeout 263 * (the [Query Interval] in the last Query received) 264 * 265 * After decode, QQIC represents the Querier's Query Interval in units 266 * of seconds. 267 */ 268 static inline unsigned long mldv2_qqi(const struct mld2_query *mlh2) 269 { 270 unsigned long qqic = mlh2->mld2q_qqic; 271 272 if (qqic < MLD_QQIC_MIN_THRESHOLD) { 273 return qqic; 274 } else { 275 unsigned long mc_man, mc_exp; 276 277 mc_exp = MLDV2_QQIC_EXP(qqic); 278 mc_man = MLDV2_QQIC_MAN(qqic); 279 280 return (mc_man | 0x10) << (mc_exp + 3); 281 } 282 } 283 284 #endif 285