Branch data Line data Source code
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[0]; 28 : : }; 29 : : 30 : : struct mld2_report { 31 : : struct icmp6hdr mld2r_hdr; 32 : : struct mld2_grec mld2r_grec[0]; 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[0]; 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 : : #define MLD_EXP_MIN_LIMIT 32768UL 93 : : #define MLDV1_MRD_MAX_COMPAT (MLD_EXP_MIN_LIMIT - 1) 94 : : 95 : : static inline unsigned long mldv2_mrc(const struct mld2_query *mlh2) 96 : : { 97 : : /* RFC3810, 5.1.3. Maximum Response Code */ 98 : 0 : unsigned long ret, mc_mrc = ntohs(mlh2->mld2q_mrc); 99 : : 100 [ # # # # ]: 0 : if (mc_mrc < MLD_EXP_MIN_LIMIT) { 101 : : ret = mc_mrc; 102 : : } else { 103 : : unsigned long mc_man, mc_exp; 104 : : 105 : 0 : mc_exp = MLDV2_MRC_EXP(mc_mrc); 106 : 0 : mc_man = MLDV2_MRC_MAN(mc_mrc); 107 : : 108 : 0 : ret = (mc_man | 0x1000) << (mc_exp + 3); 109 : : } 110 : : 111 : : return ret; 112 : : } 113 : : 114 : : #endif