--- zzzz-none-000/linux-3.10.107/include/net/mld.h 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/include/net/mld.h 2021-11-10 11:53:56.000000000 +0000 @@ -72,4 +72,55 @@ #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) +/* AVM: backport from v3.15 + * + * commits: + * 89225d1ce6af3916bf32aecbe9d83f571a098588 net: ipv6: mld: fix v1/v2 switchback timeout to rfc3810, 9.12. + * e3f5b17047dec4acd8957dad053e70d87f18d97e net: ipv6: mld: get rid of MLDV2_MRC and simplify calculation + */ +/* RFC3810, 5.1.3. Maximum Response Code: + * + * If Maximum Response Code >= 32768, Maximum Response Code represents a + * floating-point value as follows: + * + * 0 1 2 3 4 5 6 7 8 9 A B C D E F + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |1| exp | mant | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +#define MLDV2_MRC_EXP(value) (((value) >> 12) & 0x0007) +#define MLDV2_MRC_MAN(value) ((value) & 0x0fff) + +/* RFC3810, 5.1.9. QQIC (Querier's Query Interval Code): + * + * If QQIC >= 128, QQIC represents a floating-point value as follows: + * + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * |1| exp | mant | + * +-+-+-+-+-+-+-+-+ + */ +#define MLDV2_QQIC_EXP(value) (((value) >> 4) & 0x07) +#define MLDV2_QQIC_MAN(value) ((value) & 0x0f) + +static inline unsigned long mldv2_mrc(const struct mld2_query *mlh2) +{ + /* RFC3810, 5.1.3. Maximum Response Code */ + unsigned long ret, mc_mrc = ntohs(mlh2->mld2q_mrc); + + if (mc_mrc < 32768) { + ret = mc_mrc; + } else { + unsigned long mc_man, mc_exp; + + mc_exp = MLDV2_MRC_EXP(mc_mrc); + mc_man = MLDV2_MRC_MAN(mc_mrc); + + ret = (mc_man | 0x1000) << (mc_exp + 3); + } + + return ret; +} + + #endif