linux/include/net/mld.h
<<
>>
Prefs
   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 */
   8struct 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 */
  21struct 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
  29struct 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 */
  41struct 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#define MLD_EXP_MIN_LIMIT       32768UL
  92#define MLDV1_MRD_MAX_COMPAT    (MLD_EXP_MIN_LIMIT - 1)
  93
  94static inline unsigned long mldv2_mrc(const struct mld2_query *mlh2)
  95{
  96        /* RFC3810, 5.1.3. Maximum Response Code */
  97        unsigned long ret, mc_mrc = ntohs(mlh2->mld2q_mrc);
  98
  99        if (mc_mrc < MLD_EXP_MIN_LIMIT) {
 100                ret = mc_mrc;
 101        } else {
 102                unsigned long mc_man, mc_exp;
 103
 104                mc_exp = MLDV2_MRC_EXP(mc_mrc);
 105                mc_man = MLDV2_MRC_MAN(mc_mrc);
 106
 107                ret = (mc_man | 0x1000) << (mc_exp + 3);
 108        }
 109
 110        return ret;
 111}
 112
 113#endif
 114