]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ipv6: mld: rename mldv2_mrc() and add mldv2_qqi()
authorUjjal Roy <royujjal@gmail.com>
Sat, 2 May 2026 13:19:03 +0000 (13:19 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 5 May 2026 02:09:41 +0000 (19:09 -0700)
Rename mldv2_mrc() to mldv2_mrd() as it is used to calculate
the Maximum Response Delay from the Maximum Response Code.

Introduce a new API mldv2_qqi() to define the existing
calculation logic of QQI from QQIC. This also organizes
the existing mld_update_qi() API.

Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Ujjal Roy <royujjal@gmail.com>
Link: https://patch.msgid.link/20260502131907.987-3-royujjal@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/mld.h
net/bridge/br_multicast.c
net/ipv6/mcast.c

index c073598084934d7368a27ddf6a6e6aff4890e2b2..10e402e0fe08c633896e3dbefee28c977f1c32a4 100644 (file)
@@ -89,29 +89,77 @@ struct mld2_query {
 #define MLDV2_QQIC_EXP(value)  (((value) >> 4) & 0x07)
 #define MLDV2_QQIC_MAN(value)  ((value) & 0x0f)
 
-#define MLD_EXP_MIN_LIMIT      32768UL
-#define MLDV1_MRD_MAX_COMPAT   (MLD_EXP_MIN_LIMIT - 1)
+/* MLDv2 QQIC floating-point exponential field min threshold */
+#define MLD_QQIC_MIN_THRESHOLD 128
+/* MLDv2 MRC floating-point exponential field min threshold */
+#define MLD_MRC_MIN_THRESHOLD  32768UL
+#define MLDV1_MRD_MAX_COMPAT   (MLD_MRC_MIN_THRESHOLD - 1)
 
 #define MLD_MAX_QUEUE          8
 #define MLD_MAX_SKBS           32
 
-static inline unsigned long mldv2_mrc(const struct mld2_query *mlh2)
+/* V2 exponential field decoding */
+
+/* Calculate Maximum Response Delay from Maximum Response Code
+ *
+ * RFC3810, relevant sections:
+ *  - 5.1.3. Maximum Response Code defines the decoding formula:
+ *      0 1 2 3 4 5 6 7 8 9 A B C D E F
+ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *     |1| exp |          mant         |
+ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    Maximum Response Delay = (mant | 0x1000) << (exp+3)
+ *  - 9.3. Query Response Interval
+ *
+ * After decode, MRC represents the Maximum Response Delay (MRD) in
+ * units of milliseconds.
+ */
+static inline unsigned long mldv2_mrd(const struct mld2_query *mlh2)
 {
-       /* RFC3810, 5.1.3. Maximum Response Code */
-       unsigned long ret, mc_mrc = ntohs(mlh2->mld2q_mrc);
+       unsigned long mc_mrc = ntohs(mlh2->mld2q_mrc);
 
-       if (mc_mrc < MLD_EXP_MIN_LIMIT) {
-               ret = mc_mrc;
+       if (mc_mrc < MLD_MRC_MIN_THRESHOLD) {
+               return 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 (mc_man | 0x1000) << (mc_exp + 3);
        }
+}
 
-       return ret;
+/* Calculate Querier's Query Interval from Querier's Query Interval Code
+ *
+ * RFC3810, relevant sections:
+ *  - 5.1.9. QQIC (Querier's Query Interval Code) defines the decoding formula:
+ *      0 1 2 3 4 5 6 7
+ *     +-+-+-+-+-+-+-+-+
+ *     |1| exp | mant  |
+ *     +-+-+-+-+-+-+-+-+
+ *    QQI = (mant | 0x10) << (exp + 3)
+ *  - 9.2. Query Interval
+ *  - 9.12. Older Version Querier Present Timeout
+ *    (the [Query Interval] in the last Query received)
+ *
+ * After decode, QQIC represents the Querier's Query Interval in units
+ * of seconds.
+ */
+static inline unsigned long mldv2_qqi(const struct mld2_query *mlh2)
+{
+       unsigned long qqic = mlh2->mld2q_qqic;
+
+       if (qqic < MLD_QQIC_MIN_THRESHOLD) {
+               return qqic;
+       } else {
+               unsigned long mc_man, mc_exp;
+
+               mc_exp = MLDV2_QQIC_EXP(qqic);
+               mc_man = MLDV2_QQIC_MAN(qqic);
+
+               return (mc_man | 0x10) << (mc_exp + 3);
+       }
 }
 
 #endif
index 9fec76e887bc9c5dcaf8f207d061137101d510b8..1438c023db62bc054adc1c1d89ea6c536f742ae7 100644 (file)
@@ -3606,7 +3606,7 @@ static int br_ip6_multicast_query(struct net_bridge_mcast *brmctx,
                    mld2q->mld2q_suppress)
                        goto out;
 
-               max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL);
+               max_delay = max(msecs_to_jiffies(mldv2_mrd(mld2q)), 1UL);
        }
 
        is_general_query = group && ipv6_addr_any(group);
index 3330adcf26db2434d298aa9caae4c8bd8f859561..6ddc18ac59b951e84a49fcce7972bc1989ef2dae 100644 (file)
@@ -1315,20 +1315,7 @@ static void mld_update_qi(struct inet6_dev *idev,
         *  - 9.12. Older Version Querier Present Timeout
         *    (the [Query Interval] in the last Query received)
         */
-       unsigned long mc_qqi;
-
-       if (mlh2->mld2q_qqic < 128) {
-               mc_qqi = mlh2->mld2q_qqic;
-       } else {
-               unsigned long mc_man, mc_exp;
-
-               mc_exp = MLDV2_QQIC_EXP(mlh2->mld2q_qqic);
-               mc_man = MLDV2_QQIC_MAN(mlh2->mld2q_qqic);
-
-               mc_qqi = (mc_man | 0x10) << (mc_exp + 3);
-       }
-
-       idev->mc_qi = mc_qqi * HZ;
+       idev->mc_qi = mldv2_qqi(mlh2) * HZ;
 }
 
 static void mld_update_qri(struct inet6_dev *idev,
@@ -1338,7 +1325,7 @@ static void mld_update_qri(struct inet6_dev *idev,
         *  - 5.1.3. Maximum Response Code
         *  - 9.3. Query Response Interval
         */
-       idev->mc_qri = msecs_to_jiffies(mldv2_mrc(mlh2));
+       idev->mc_qri = msecs_to_jiffies(mldv2_mrd(mlh2));
 }
 
 static int mld_process_v1(struct inet6_dev *idev, struct mld_msg *mld,
@@ -1390,7 +1377,7 @@ static int mld_process_v1(struct inet6_dev *idev, struct mld_msg *mld,
 static void mld_process_v2(struct inet6_dev *idev, struct mld2_query *mld,
                           unsigned long *max_delay)
 {
-       *max_delay = max(msecs_to_jiffies(mldv2_mrc(mld)), 1UL);
+       *max_delay = max(msecs_to_jiffies(mldv2_mrd(mld)), 1UL);
 
        mld_update_qrv(idev, mld);
        mld_update_qi(idev, mld);