From nobody Sat Jun 20 17:32:27 2026 Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B35F1375ABD for ; Sun, 12 Apr 2026 11:11:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992270; cv=none; b=CFD0pygxIiLxWXqaWRFi+KsjzdYpD57C1+eo2/+OwboB3d+hD+UrlOizaHP+BUpwUerBhwA0rP9hMJwp2yBO+UPUBtgKMsWFBolbX0MYEDUw/XNe5aupHMffarIVp/hF31uV+xMup6sITEEqNqQiKOIhoWJnUYDpO/ydc81oXbc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992270; c=relaxed/simple; bh=QBIfIvmBuIoYpMtoyqBsB8dAeiNlwvpVdnfKO8oA6aA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LuQC43CEis85z5RyZfaYfcPW8rANYYf+3lsxI+YZ9kbI8/WrPiSu0Y1WrVW5PeIlZH3NUnCR+M+yfp9jiAugXO/2ihf7rwJnP5eWm11yNJnmTWv3uv4SW/a2ur3IqWcchUE3LPNjNRfrYLl4WmryGyuanEQrtHwD+iOTkRQkVd8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=h01sREwr; arc=none smtp.client-ip=209.85.215.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="h01sREwr" Received: by mail-pg1-f173.google.com with SMTP id 41be03b00d2f7-c76b95e652bso1472449a12.3 for ; Sun, 12 Apr 2026 04:11:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775992269; x=1776597069; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qRagAfwxZRIpF0jJI41tPh4aZoJ+uueGkyeIJ7BFIUA=; b=h01sREwrw001DzcqXbu0jFHrnH9sgsH4r0gGSMfKnQIVPtouSqT+DsPCXdv5Il5YOq BGeyp4zf0NEHMNS1eIYCn0/o5oPBNGOMaleQWutO+eD8Q1yLjMWakgwy8YN12aZJuJ1M 9aGimuozHlAlpnmL63VDdFQdZ2LC4auxRI6h1FOJTwj2DmEr1T5Cwaq8bRn6VwPCqNwN ke1Ili8vbHKpBsNa5byT/HtQYpN77L2sl9CpZ07noDLMDozW+UiTPSXnYWGCnkEQBuZV qbSZ7tyN+CO6VOhbBccvxflnUrAOJp18orpR1dwWM46FfGJO7Dp4GG6dBJmnCgMR6NzL UNvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775992269; x=1776597069; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=qRagAfwxZRIpF0jJI41tPh4aZoJ+uueGkyeIJ7BFIUA=; b=LXmoK+Ks0hPFRp2kV7tIOygghloUvlnZJahFfCTDJh5t0mb5CohQYywzQ5Tae8KYA8 agz8woYI8DvwnFe5uoZ++qKmexGTVnCh3Vw+h0XkIlDj0l/D3xOi01tUfwsla+Ts1Gfd CYj1ZauV+iUsMqUGSEu3F4hqqxZA3jtYsoEA0IDSuaPDFhE2nXP+0ibXqVVzgvC9MkK8 B1j365BuD/rXV+dAHRE9gHeFugrFct3Z/ujsT0M1OZ6oBJOjH+BxnvKVpsRTi3D7K78B ACz1D4GrktZkTAC4Udr262Q9Kyxgx4nNMViW6HFps5AJCgVD81j4sTpOJ6nu7qGu79RR bwuA== X-Forwarded-Encrypted: i=1; AJvYcCUiVo/qQvOKnoEz/bfFSRVv95OgRs38T3aluJlSdQE+BRspAfY+fJqSKewj/SadllMbNVvzyYE3UZX9tOk=@vger.kernel.org X-Gm-Message-State: AOJu0Yz2rbj8dslt7GMntq2ZuWp5kyGbxs5LuY/cuqY41HgX1pUSFcmw DdIEiGak2urk5pWYe4zTxlj6DlJ1qGFacB00M5lpuYofcKtBhdCRWI48 X-Gm-Gg: AeBDietYGkIMrR4o6TbzOu/Bw4XcSHOp6WCdkl4EAYAvbvWHPQnVYZ0/zGVgFdBvqSW RoRChaRSF/dfO6xX6cGWe3I/jXyWO+oxZbfswvZh+XOrIt8oydxiLolezPPuYMBSvpG2bIVyjfE 6z7H6X1Tfgs127/oK+NSZ4fRyL34zSFFesiugx0h538AToDW7RmUfGtKBnAQINtGc8und28iu7u lOXT4Hhx5Sd8LdsznRipWAjgw2CcpEuoa30sJ5l3oLe6UevmHj1vMeHvmV11bLnApnVjpzIPEXR tH0kj9da2oA7mcFWa1qbxBAg9oCSp4nulPG1z7XyotH58xiQfV9af/BUMWuebYVU4P7u820tJ1Y LrhKHOHP1RwlDy+j0qbTye+DAsdVX+1xBWzB8qUahFU6pB6957oGvnCVUzG9D4k/u6lvTOvlH5r l69MzLPd+QlJGfkgauWsSMAwErNhpAUk9isUd3wYUSOqPfwHuDGdI= X-Received: by 2002:a05:6300:6a02:b0:39b:f9f5:7a74 with SMTP id adf61e73a8af0-39fe400f754mr7736909637.45.1775992269002; Sun, 12 Apr 2026 04:11:09 -0700 (PDT) Received: from DESKTOP-82PPU4A.localdomain ([202.8.116.169]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c7934c9ef38sm2522981a12.12.2026.04.12.04.11.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 Apr 2026 04:11:08 -0700 (PDT) From: Ujjal Roy To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Nikolay Aleksandrov , Ido Schimmel , David Ahern , Shuah Khan , Andy Roulin , Yong Wang , Petr Machata Cc: Ujjal Roy , bridge@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next v4 1/5] ipv4: igmp: get rid of IGMPV3_{QQIC,MRC} and simplify calculation Date: Sun, 12 Apr 2026 11:10:43 +0000 Message-ID: <20260412111047.1326-2-royujjal@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260412111047.1326-1-royujjal@gmail.com> References: <20260412111047.1326-1-royujjal@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Get rid of the IGMPV3_MRC macro and use the igmpv3_mrt() API to calculate the Max Resp Time from the Maximum Response Code. Similarly, for IGMPV3_QQIC, use the igmpv3_qqi() API to calculate the Querier's Query Interval from the QQIC field. Signed-off-by: Ujjal Roy Reviewed-by: Ido Schimmel --- include/linux/igmp.h | 80 +++++++++++++++++++++++++++++++++++---- net/bridge/br_multicast.c | 2 +- net/ipv4/igmp.c | 6 +-- 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 073b30a9b850..4443c914b3c8 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -92,15 +92,79 @@ struct ip_mc_list { struct rcu_head rcu; }; =20 +/* RFC3376, relevant sections: + * - 4.1.1. Maximum Response Code + * - 4.1.7. QQIC (Querier's Query Interval Code) + * + * For both MRC and QQIC, values >=3D 128 use the same floating-point + * encoding as follows: + * + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * |1| exp | mant | + * +-+-+-+-+-+-+-+-+ + */ +#define IGMPV3_FP_EXP(value) (((value) >> 4) & 0x07) +#define IGMPV3_FP_MAN(value) ((value) & 0x0f) + +/* IGMPV3 floating-point exponential field threshold */ +#define IGMPV3_EXP_MIN_THRESHOLD 128 + /* V3 exponential field decoding */ -#define IGMPV3_MASK(value, nb) ((nb)>=3D32 ? (value) : ((1<<(nb))-1) & (va= lue)) -#define IGMPV3_EXP(thresh, nbmant, nbexp, value) \ - ((value) < (thresh) ? (value) : \ - ((IGMPV3_MASK(value, nbmant) | (1<<(nbmant))) << \ - (IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp)))) - -#define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value) -#define IGMPV3_MRC(value) IGMPV3_EXP(0x80, 4, 3, value) + +/* IGMPv3 MRC/QQIC 8-bit exponential field decode + * + * RFC3376, 4.1.1 & 4.1.7. defines the decoding formula: + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * |1| exp | mant | + * +-+-+-+-+-+-+-+-+ + * Max Resp Time =3D (mant | 0x10) << (exp + 3) + * QQI =3D (mant | 0x10) << (exp + 3) + */ +static inline unsigned long igmpv3_exp_field_decode(const u8 code) +{ + if (code < IGMPV3_EXP_MIN_THRESHOLD) { + return code; + } else { + unsigned long mc_man, mc_exp; + + mc_exp =3D IGMPV3_FP_EXP(code); + mc_man =3D IGMPV3_FP_MAN(code); + + return (mc_man | 0x10) << (mc_exp + 3); + } +} + +/* Calculate Max Resp Time from Maximum Response Code + * + * RFC3376, relevant sections: + * - 4.1.1. Maximum Response Code + * - 8.3. Query Response Interval + * + * After decode, MRC represents the Maximum Response Time (MRT) in + * units of 0.1 seconds (100 ms). + */ +static inline unsigned long igmpv3_mrt(const struct igmpv3_query *ih3) +{ + return igmpv3_exp_field_decode(ih3->code); +} + +/* Calculate Querier's Query Interval from Querier's Query Interval Code + * + * RFC3376, relevant sections: + * - 4.1.7. QQIC (Querier's Query Interval Code) + * - 8.2. Query Interval + * - 8.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 igmpv3_qqi(const struct igmpv3_query *ih3) +{ + return igmpv3_exp_field_decode(ih3->qqic); +} =20 static inline int ip_mc_may_pull(struct sk_buff *skb, unsigned int len) { diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 881d866d687a..9fec76e887bc 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -3518,7 +3518,7 @@ static void br_ip4_multicast_query(struct net_bridge_= mcast *brmctx, goto out; =20 max_delay =3D ih3->code ? - IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; + igmpv3_mrt(ih3) * (HZ / IGMP_TIMER_SCALE) : 1; } else { goto out; } diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index a674fb44ec25..d7eff36d98c3 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -991,7 +991,7 @@ static bool igmp_heard_query(struct in_device *in_dev, = struct sk_buff *skb, * different encoding. We use the v3 encoding as more likely * to be intended in a v3 query. */ - max_delay =3D IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); + max_delay =3D igmpv3_mrt(ih3) * (HZ / IGMP_TIMER_SCALE); if (!max_delay) max_delay =3D 1; /* can't mod w/ 0 */ } else { /* v3 */ @@ -1006,7 +1006,7 @@ static bool igmp_heard_query(struct in_device *in_dev= , struct sk_buff *skb, ih3 =3D igmpv3_query_hdr(skb); } =20 - max_delay =3D IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); + max_delay =3D igmpv3_mrt(ih3) * (HZ / IGMP_TIMER_SCALE); if (!max_delay) max_delay =3D 1; /* can't mod w/ 0 */ WRITE_ONCE(in_dev->mr_maxdelay, max_delay); @@ -1016,7 +1016,7 @@ static bool igmp_heard_query(struct in_device *in_dev= , struct sk_buff *skb, * configured value. */ in_dev->mr_qrv =3D ih3->qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv); - in_dev->mr_qi =3D IGMPV3_QQIC(ih3->qqic)*HZ ?: IGMP_QUERY_INTERVAL; + in_dev->mr_qi =3D igmpv3_qqi(ih3) * HZ ? : IGMP_QUERY_INTERVAL; =20 /* RFC3376, 8.3. Query Response Interval: * The number of seconds represented by the [Query Response --=20 2.43.0 From nobody Sat Jun 20 17:32:27 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 18CE4231836 for ; Sun, 12 Apr 2026 11:11:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992277; cv=none; b=JC0F8J3X/stVsQByD1GMobrvgHcahOfw/cDf4NCzgp32y0o+8/W8eMFNOVWswgGHFXL8hPHIjjccHcdolyPlqNhezkNeMde+PTfsaH2A04CG6khk7l69ZEnwYRMFJhDP2TCVj+WN9tULxM90NAsyV7lEUAFfmr+LW6jp+V4nUig= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992277; c=relaxed/simple; bh=lsAEhzVS6tgX13xkojB6O97uyZ7wIxPYmdNpusmS5w8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kpEwtkI28BTdflUz4Dkf/YJs51heZVBBhloL2FpAbWcMHKnW8DjsHtrJ186gidHltTQxpL67heji3FDZG8JM49PhVI/H4vKdCq6BfCheXC9W/eVOzOMIcep4Pz0mZp0QlmOY9kwt9S5Tbi6d0hb/HZeZOqANctTXa6gcF81767Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Kc/RwIje; arc=none smtp.client-ip=209.85.215.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Kc/RwIje" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-c742d4df00cso1252892a12.1 for ; Sun, 12 Apr 2026 04:11:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775992275; x=1776597075; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GfVGhwZijWWeFrc0o2objX+emGxOrWrWWZpNkRkNMOc=; b=Kc/RwIjeksNgyyIrzt1ke+2u2I3Wtsv/igQQRQvgRdT6eOSevOllfi79qKiwF7tfIq iPjrsa6KiTTZ0jUo1kuPL0LX/TzlPVYTy+VwbGU8xMXkiPrCvJv0+2kQ4vVFQz9u+zWR Fj0BZBVjXPQ17ppqT/TKmh1exzMSnksFaZwJ25QfbdONaimZsxFit/E3sHycMtB8InIP 0Wkr8g/9tslF97g+a4K4kF6qFjqkEKEd4l2GUxTtF4DzpwRNI8vE53STHe3KnX2pbdS6 p3Y9/c94MVo4Une9N83TFU1wWikQXQr3tS6OX90av1mU6+9+ycZ0RFCBS/I4UBIBGhiW un3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775992275; x=1776597075; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=GfVGhwZijWWeFrc0o2objX+emGxOrWrWWZpNkRkNMOc=; b=sOqpl5Adbv7B4ivRvM8NliFyx7gso1fuxcySnz1kvIcA1U76AQQOzH6HUXc+IyelZj Yt5Ghri4OG7VhSlzDgO/j4FUk4y/VsNDCzYFCg148o5bGk+4IIaQmJnlubX5gg2TQXEz LvC/6f89CbbAVO2/HqIfR+nU4FQAKltdgZE/RtSmMm1xUu0xGjGwOJYMmrZ76i+TTdMS 7BqybjLi7Ou7M6D+1AtX65Rr7qBppRiW9m8jI0BB/BmGruu+u+sUJgSf5Fism6u3d3E3 7wNTXuVDdNIqqzlrMuD0pUa6WFzmhRT8QmuSJ+jq47S405llRlHbLjDDOE9IukVK0Mob hwCA== X-Forwarded-Encrypted: i=1; AJvYcCW7FdBuJFJRXRWEJX+zce2qz27xWp3OLHOXCAEQilLj3BLFobfsdS3XzTnWfDLh1mQZ/2hpQ9Jvsr5Nnws=@vger.kernel.org X-Gm-Message-State: AOJu0Yyd2WNhfeco3QiLyMJqrORUeOF7Xo2vGXU9NoLcQ7rgFc9Y+v0q JCURrNw4TaVViaofmFgEhwH/CT/NEH/mAxE826uSIOtXfV0BdEa56qx5 X-Gm-Gg: AeBDievawVQEov9z69QbeU+ITOi6uUNcYYs+lfNgzVgbv+sNAg48GdGy9BZulj+rzaU iQ+EtfhLPv7k2F3uaMCeY4YioIENQKcl0/OBH/2FmIuMfjcM0yMaXy9z8mto3ArkHrHdPJATVtd 4qTgcDMN71qfDZBEDeVvfRCFKLJuAGh/Ek/fdqUUYCJ0BHYAJN1n9vOfH2uRbrm6hQfprj55use 5+jTZ4aQT9rZnrs0DAYq9CU/xLrnfbpyl7kqnOsTlwmhwk85oJJW5aDhFTjwtqmJlX8RQ/h261T g3uvIwDvSVaPmVKat+543zDsuYc0PkVWVRXNao7RxiiL40Kz3BfE7fGlbbNsKgT+Iq2Iql9I5u5 MRoE8Ij9OChCakyJUdohXMvxypBj+kWcjGiAwII6LWInddS7lEbpLXJ+lwV+EVkd/ni672dfR7N tIx9n8yLoR0z8OeVAdsQ3o8FF8TRiXCkWR6pKn8kjQsvXA0viaUyQ= X-Received: by 2002:a05:6a21:99a9:b0:39f:561e:6fee with SMTP id adf61e73a8af0-39fc928c9cemr13477451637.6.1775992275505; Sun, 12 Apr 2026 04:11:15 -0700 (PDT) Received: from DESKTOP-82PPU4A.localdomain ([202.8.116.169]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c7934c9ef38sm2522981a12.12.2026.04.12.04.11.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 Apr 2026 04:11:14 -0700 (PDT) From: Ujjal Roy To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Nikolay Aleksandrov , Ido Schimmel , David Ahern , Shuah Khan , Andy Roulin , Yong Wang , Petr Machata Cc: Ujjal Roy , bridge@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next v4 2/5] ipv6: mld: rename mldv2_mrc() and add mldv2_qqi() Date: Sun, 12 Apr 2026 11:10:44 +0000 Message-ID: <20260412111047.1326-3-royujjal@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260412111047.1326-1-royujjal@gmail.com> References: <20260412111047.1326-1-royujjal@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Ujjal Roy Reviewed-by: Ido Schimmel --- include/net/mld.h | 64 +++++++++++++++++++++++++++++++++------ net/bridge/br_multicast.c | 2 +- net/ipv6/mcast.c | 19 ++---------- 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/include/net/mld.h b/include/net/mld.h index c07359808493..6ed467e23f12 100644 --- a/include/net/mld.h +++ b/include/net/mld.h @@ -89,29 +89,75 @@ struct mld2_query { #define MLDV2_QQIC_EXP(value) (((value) >> 4) & 0x07) #define MLDV2_QQIC_MAN(value) ((value) & 0x0f) =20 -#define MLD_EXP_MIN_LIMIT 32768UL -#define MLDV1_MRD_MAX_COMPAT (MLD_EXP_MIN_LIMIT - 1) +#define MLD_QQIC_MIN_THRESHOLD 128 +#define MLD_MRC_MIN_THRESHOLD 32768UL +#define MLDV1_MRD_MAX_COMPAT (MLD_MRC_MIN_THRESHOLD - 1) =20 #define MLD_MAX_QUEUE 8 #define MLD_MAX_SKBS 32 =20 -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 =3D (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 =3D ntohs(mlh2->mld2q_mrc); + unsigned long mc_mrc =3D ntohs(mlh2->mld2q_mrc); =20 - if (mc_mrc < MLD_EXP_MIN_LIMIT) { - ret =3D mc_mrc; + if (mc_mrc < MLD_MRC_MIN_THRESHOLD) { + return mc_mrc; } else { unsigned long mc_man, mc_exp; =20 mc_exp =3D MLDV2_MRC_EXP(mc_mrc); mc_man =3D MLDV2_MRC_MAN(mc_mrc); =20 - ret =3D (mc_man | 0x1000) << (mc_exp + 3); + return (mc_man | 0x1000) << (mc_exp + 3); } +} =20 - 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 for= mula: + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * |1| exp | mant | + * +-+-+-+-+-+-+-+-+ + * QQI =3D (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 =3D mlh2->mld2q_qqic; + + if (qqic < MLD_QQIC_MIN_THRESHOLD) { + return qqic; + } else { + unsigned long mc_man, mc_exp; + + mc_exp =3D MLDV2_QQIC_EXP(qqic); + mc_man =3D MLDV2_QQIC_MAN(qqic); + + return (mc_man | 0x10) << (mc_exp + 3); + } } =20 #endif diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 9fec76e887bc..1438c023db62 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -3606,7 +3606,7 @@ static int br_ip6_multicast_query(struct net_bridge_m= cast *brmctx, mld2q->mld2q_suppress) goto out; =20 - max_delay =3D max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL); + max_delay =3D max(msecs_to_jiffies(mldv2_mrd(mld2q)), 1UL); } =20 is_general_query =3D group && ipv6_addr_any(group); diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 3330adcf26db..6ddc18ac59b9 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -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 =3D mlh2->mld2q_qqic; - } else { - unsigned long mc_man, mc_exp; - - mc_exp =3D MLDV2_QQIC_EXP(mlh2->mld2q_qqic); - mc_man =3D MLDV2_QQIC_MAN(mlh2->mld2q_qqic); - - mc_qqi =3D (mc_man | 0x10) << (mc_exp + 3); - } - - idev->mc_qi =3D mc_qqi * HZ; + idev->mc_qi =3D mldv2_qqi(mlh2) * HZ; } =20 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 =3D msecs_to_jiffies(mldv2_mrc(mlh2)); + idev->mc_qri =3D msecs_to_jiffies(mldv2_mrd(mlh2)); } =20 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, str= uct mld_msg *mld, static void mld_process_v2(struct inet6_dev *idev, struct mld2_query *mld, unsigned long *max_delay) { - *max_delay =3D max(msecs_to_jiffies(mldv2_mrc(mld)), 1UL); + *max_delay =3D max(msecs_to_jiffies(mldv2_mrd(mld)), 1UL); =20 mld_update_qrv(idev, mld); mld_update_qi(idev, mld); --=20 2.43.0 From nobody Sat Jun 20 17:32:27 2026 Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8BD0B377020 for ; Sun, 12 Apr 2026 11:11:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992283; cv=none; b=iF7QEM8B6eM4Avao9IDYaAHnhw8ptolGoKZ6aK0eUvOMB0Dmd0jIhLBswbJNz0R1b/Msiezqfaga6zBTgi4xnrWkPv40P+8SXX4ek6XeH+3Xzu6LlE5PGwWhplI7BQfFwtJXapTCBmj7sRZGCl6wtrysl4qufXGdlN03hGVvULE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992283; c=relaxed/simple; bh=dj8E8sQuMvGGkeFgw8ZCRE6siDsAKhcLUq+TYgXiQ34=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MB0GrzeCOPIx8IJynOLPxSSTECOK7cDAJ8f8n77Ar+st7a1LdZEErF1MajhkAjNgaVDH/QAGtqy9xT8F9UoJFlzYuFzLEXzCOUuafGrnYZouXPz91hhZ1OJM2SpiNrGYmQb+fogLQvT+C9NLGc5LS8sIi2AHT0FkHt8zOk9W6lY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IGI7LEN9; arc=none smtp.client-ip=209.85.215.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IGI7LEN9" Received: by mail-pg1-f173.google.com with SMTP id 41be03b00d2f7-c742d4df00cso1252910a12.1 for ; Sun, 12 Apr 2026 04:11:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775992282; x=1776597082; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=I5YffUmzhaIkIbUoe3E2/Xuq3wXpeEBIn/sASnY+Ntk=; b=IGI7LEN9sfwwrFbqoegKXUcHxc/hWXDY1cz/df+uA7X+miZZ0+LNhgnjzS+7Xd31A3 V1jj8a9aRrz7qtWWrNK3p1r1Sj/S0OTu9T5JtOOn55JOE95uUZo679GolGKyFwMmEFst dkduT2MnXg5kgQdIVoi8agfkMJTpqF6QQdjctCtisDwhDCBxwYXj7goltFto63abH8nR Xjz9EZhXJczu0KVbpXNGACZoGVbH95dxOwU5nI8Uh4sXBsCWNDuqummwCXYtA+8vkN18 oIoc5K1aQgDGZ5F4AkA1REC53jzKbEs2FJClY63VXIqHGaxUTh+hUvZ7YDUxVVl6yyBG BJTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775992282; x=1776597082; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=I5YffUmzhaIkIbUoe3E2/Xuq3wXpeEBIn/sASnY+Ntk=; b=pl/8SW2z0AectbxTAmz77PkFEO4aRcN/xGCtsd8cILjMhEFEycYsXo+++avjVOBuFY tA2ipGv4ZQItVJlNzh/ADbv5F5yDmCM/9x68hWFXI6vE5Vrk5PP02W6GP7JqlCjMhyQn WoxH6oHIX5e1HtRd4oPRS/+Pt0ZcnW6O9a1Sh/HToz6c8uKRnWISEXW/aRivrOQSEFM4 PREzTXLkh5ae0IujHOhdaUPMoAdRJEGCv91EwmWsOQTyV4yhJQZK1Dc+PN4Izq+VqmTr /vqVBxbvWudbMl+yh8692pymwEhVVFO5kY/SIk+ghzkeMpt3bKu7FjttyeRu8twcFx+U N46Q== X-Forwarded-Encrypted: i=1; AJvYcCXITXzcE5mNzr/+UgwXO/vFLIS0K+TaxiuIYOZf+rKKx5pA4neg6f/geBGJ3SYN5XbDnJob+0R56ozanvU=@vger.kernel.org X-Gm-Message-State: AOJu0YxlL7BUgFPensmMCG+mE0qySwiEE2xxuwf9ow37eAeaEjocZE1I T2IDclFObyoJRCAaBM6GbQMM1pBquxuhTDp/ae2W6rZHlXQEZZa8+KeG7PnIHkSGw7s= X-Gm-Gg: AeBDietEmCPWl2fMp9e3Zlqd8iKIoWNDWMO/g+FC8Q56WeHREdVjyBDFoJt38IFe4+6 Sf4nAvBgO0uDrnURVq2DZ8+ydEZLvqYrR2Cmt5XhLSx791cyv+ugbnItunoT0fHrssraOPN941P 7plMI6eFFsdA8P3133vuXNVkVcOEZqV92DmuMY2Wz01i5KUa8MrlzIDHGuD94oRMC+Pt/89GEim TWPhwBFWMlhcMJ6ihwtxVgNv5O7QVJl7Hrwi7luXWh5MMXg2fzdxLZxfNGe4T16ms/+pIm4oSux Z64qOR+PMKcwUvM/vTw/1je7kgKNCj+iuu4ebPNS/QUwwl4WBAAeR97WAgHZqyLVLKN3cshdeNP vnVaHpSu6cz10oePv/jLU4c9zzcjTwdJXrZ2FK40hvHYkI46njOeTwI1Swjx+/8JG+BcXBDQ7eE 6602WkY3bnJlSsQ2Iaonj+kpEmD6+U6GbMT1u4ESjA X-Received: by 2002:a05:6a20:3d87:b0:398:7667:b2fb with SMTP id adf61e73a8af0-39fe466bbd7mr8477194637.19.1775992281819; Sun, 12 Apr 2026 04:11:21 -0700 (PDT) Received: from DESKTOP-82PPU4A.localdomain ([202.8.116.169]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c7934c9ef38sm2522981a12.12.2026.04.12.04.11.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 Apr 2026 04:11:21 -0700 (PDT) From: Ujjal Roy To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Nikolay Aleksandrov , Ido Schimmel , David Ahern , Shuah Khan , Andy Roulin , Yong Wang , Petr Machata Cc: Ujjal Roy , bridge@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next v4 3/5] ipv4: igmp: encode multicast exponential fields Date: Sun, 12 Apr 2026 11:10:45 +0000 Message-ID: <20260412111047.1326-4-royujjal@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260412111047.1326-1-royujjal@gmail.com> References: <20260412111047.1326-1-royujjal@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In IGMP, MRC and QQIC fields are not correctly encoded when generating query packets. Since the receiver of the query interprets these fields using the IGMPv3 floating- point decoding logic, any value that exceeds the linear threshold is incorrectly parsed as an exponential value, leading to an incorrect interval calculation. Encode and assign the corresponding protocol fields during query generation. Introduce the logic to dynamically calculate the exponent and mantissa using bit-scan (fls). This ensures MRC and QQIC fields (8-bit) are properly encoded when transmitting query packets with intervals that exceed their respective linear threshold value of 128 (for MRT/QQI). RFC3376: for both MRC and QQIC, values >=3D 128 represent the same floating-point encoding as follows: 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+ |1| exp | mant | +-+-+-+-+-+-+-+-+ Signed-off-by: Ujjal Roy Reviewed-by: Ido Schimmel --- include/linux/igmp.h | 87 +++++++++++++++++++++++++++++++++++++++ net/bridge/br_multicast.c | 14 +++---- 2 files changed, 93 insertions(+), 8 deletions(-) diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 4443c914b3c8..4d8af9031e18 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -109,6 +109,93 @@ struct ip_mc_list { =20 /* IGMPV3 floating-point exponential field threshold */ #define IGMPV3_EXP_MIN_THRESHOLD 128 +/* Max representable (mant =3D 0xF, exp =3D 7) -> 31744 */ +#define IGMPV3_EXP_MAX_THRESHOLD 31744 + +/* V3 exponential field encoding */ + +/* IGMPv3 MRC/QQIC 8-bit exponential field encode + * + * RFC3376, 4.1.1 & 4.1.7. defines only the decoding formula: + * MRT/QQI =3D (mant | 0x10) << (exp + 3) + * + * but does NOT define the encoding procedure. To derive exponent: + * + * For any value of mantissa and exponent, the decoding formula + * indicates that the "hidden bit" (0x10) is shifted 4 bits left + * to sit above the 4-bit mantissa. The RFC again shifts this + * entire block left by (exp + 3) to reconstruct the value. + * So, 'hidden bit' is the MSB which is shifted by (4 + exp + 3). + * + * Total left shift of the 'hidden bit' =3D 4 + (exp + 3) =3D exp + 7. + * This is the MSB at the 0-based bit position: (exp + 7). + * Since fls() is 1-based, fls(value) - 1 =3D exp + 7. + * + * Therefore: + * exp =3D fls(value) - 8 + * mant =3D (value >> (exp + 3)) & 0x0F + * + * Final encoding formula: + * 0x80 | (exp << 4) | mant + * + * Example (value =3D 3200): + * 0 1 + * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0| (value =3D 3200) + * | ^-^-mant^ ^..(exp+3)..^| exp =3D 4, mant =3D 9 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Encoded: + * 0x80 | (4 << 4) | 9 =3D 0xC9 + */ +static inline u8 igmpv3_exp_field_encode(unsigned long value) +{ + u8 mc_exp, mc_man; + + /* MRC/QQIC < 128 is literal */ + if (value < IGMPV3_EXP_MIN_THRESHOLD) + return value; + + /* Saturate at max representable (mant =3D 0xF, exp =3D 7) -> 31744 */ + if (value >=3D IGMPV3_EXP_MAX_THRESHOLD) + return 0xFF; + + mc_exp =3D fls(value) - 8; + mc_man =3D (value >> (mc_exp + 3)) & 0x0F; + + return 0x80 | (mc_exp << 4) | mc_man; +} + +/* Calculate Maximum Response Code from Max Resp Time + * + * RFC3376, relevant sections: + * - 4.1.1. Maximum Response Code + * - 8.3. Query Response Interval + * + * MRC represents the encoded form of Max Resp Time (MRT); once + * decoded, the resulting value is in units of 0.1 seconds (100 ms). + */ +static inline u8 igmpv3_mrc(unsigned long mrt) +{ + return igmpv3_exp_field_encode(mrt); +} + +/* Calculate Querier's Query Interval Code from Querier's Query Interval + * + * RFC3376, relevant sections: + * - 4.1.7. QQIC (Querier's Query Interval Code) + * - 8.2. Query Interval + * - 8.12. Older Version Querier Present Timeout + * (the [Query Interval] in the last Query received) + * + * QQIC represents the encoded form of Querier's Query Interval (QQI); + * once decoded, the resulting value is in units of seconds. + */ +static inline u8 igmpv3_qqic(unsigned long qi) +{ + return igmpv3_exp_field_encode(qi); +} =20 /* V3 exponential field decoding */ =20 diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 1438c023db62..27010744d7ae 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -934,12 +934,12 @@ static struct sk_buff *br_ip4_multicast_alloc_query(s= truct net_bridge_mcast *brm size_t pkt_size, igmp_hdr_size; unsigned long now =3D jiffies; struct igmpv3_query *ihv3; + unsigned long lmqt, mrt; void *csum_start =3D NULL; __sum16 *csum =3D NULL; struct sk_buff *skb; struct igmphdr *ih; struct ethhdr *eth; - unsigned long lmqt; struct iphdr *iph; u16 lmqt_srcs =3D 0; =20 @@ -1004,15 +1004,15 @@ static struct sk_buff *br_ip4_multicast_alloc_query= (struct net_bridge_mcast *brm skb_put(skb, 24); =20 skb_set_transport_header(skb, skb->len); + mrt =3D group ? brmctx->multicast_last_member_interval : + brmctx->multicast_query_response_interval; *igmp_type =3D IGMP_HOST_MEMBERSHIP_QUERY; =20 switch (brmctx->multicast_igmp_version) { case 2: ih =3D igmp_hdr(skb); ih->type =3D IGMP_HOST_MEMBERSHIP_QUERY; - ih->code =3D (group ? brmctx->multicast_last_member_interval : - brmctx->multicast_query_response_interval) / - (HZ / IGMP_TIMER_SCALE); + ih->code =3D mrt / (HZ / IGMP_TIMER_SCALE); ih->group =3D group; ih->csum =3D 0; csum =3D &ih->csum; @@ -1021,11 +1021,9 @@ static struct sk_buff *br_ip4_multicast_alloc_query(= struct net_bridge_mcast *brm case 3: ihv3 =3D igmpv3_query_hdr(skb); ihv3->type =3D IGMP_HOST_MEMBERSHIP_QUERY; - ihv3->code =3D (group ? brmctx->multicast_last_member_interval : - brmctx->multicast_query_response_interval) / - (HZ / IGMP_TIMER_SCALE); + ihv3->code =3D igmpv3_mrc(mrt / (HZ / IGMP_TIMER_SCALE)); ihv3->group =3D group; - ihv3->qqic =3D brmctx->multicast_query_interval / HZ; + ihv3->qqic =3D igmpv3_qqic(brmctx->multicast_query_interval / HZ); ihv3->nsrcs =3D htons(lmqt_srcs); ihv3->resv =3D 0; ihv3->suppress =3D sflag; --=20 2.43.0 From nobody Sat Jun 20 17:32:27 2026 Received: from mail-pg1-f174.google.com (mail-pg1-f174.google.com [209.85.215.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 00B5D3783AF for ; Sun, 12 Apr 2026 11:11:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992291; cv=none; b=M6Exooenrn6M//ouTxf2O/l6/DKEy+akneVDfkirPrTMSkJp57wn4Olf2eEagpznSCdd9iiZtb6mkqBuUMSz/GGE7wt33fL1+GBBVvuPy0OniXzgFmtghC9j+P9kGMpSwKy/32ECAcff6AimC/PdZAsRJOQrGB5QqKCvsf/mj3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992291; c=relaxed/simple; bh=7brjJEEot96W6bsrpWfLzJyx0E86TzSH+ZUnkfS6rLY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BYop6GLhh7BDEboBKnhEjhvuJ/wjx5THG+t9xEnfZOcXxnr+dawg07uJ0lZS+yqU+Oder9FvC5xlByOj1OFHTNTQyxzilzR8yYPFFhxvuvH/Ux1ZR1y9P1A2EFhZ8p8SWWvSJGcW+b+nGp4k00h0s6VPfCnby37GN37I3x0EdYw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KD5OYzbU; arc=none smtp.client-ip=209.85.215.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KD5OYzbU" Received: by mail-pg1-f174.google.com with SMTP id 41be03b00d2f7-c76b0cda2aeso1432867a12.2 for ; Sun, 12 Apr 2026 04:11:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775992288; x=1776597088; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oORmgD+tSajF1jecnR/BcGHNYT1tf2GF0qIgWz3LTVE=; b=KD5OYzbU8DGMWj7hvLk8G2KG8jOVXj+FKpsgA5Wl9S9LXKgtKT0ybhlrufJ0ELtqpc OgZBr/XuXJumxW/KHtt+o5F4BD6JWT0Bl/FDAvl+enC/s0B6PlwDOXdgeWCSMXlsfEse PnB58joYoUGJ3ccs2yGRI/YXJdA2+Vy1bbyxkGcdqDDXPTxlNrWE/XnacOD+PhR7LhSl hHxaRLjcE5J8vINcye+ynE6QCeKtuIZVCoahlXuCMt2LEDwLp9F4wfxWzJvb5cKExttA dicNkND9entWJJj+T7AalXYWuopJSFmTBI5UVN6Y8H584pXqNZWH/OdpF3TTeDhI+U3e SmfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775992288; x=1776597088; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=oORmgD+tSajF1jecnR/BcGHNYT1tf2GF0qIgWz3LTVE=; b=XRE+H5TCNvSbu8+dJmRXDfPL4p/xcvAKBrzOaYulc9JWzSO8x+n7pbZQi1gn17wClG m8h+8H3nzte7nkXxHrHzgaNkwMG70NzRTVKPxRl02eE7s5LS2o/zUMXLw6Ng6IdXDJ0s 2REEgikntdhZt65qt2Prllu51bpru/H3sARLGdrprM6EJGNE2QiwD1qGgreUl5iVUYR0 YtdJKrHaP844QkVsSyhwwQRsPpK9L+mvTLdiuBIrsyq2RecBYcv6rfqx91ki2s/T6Qyy IjtEVn92E+VAD0RRFYVrVBOVfglWk3ri3J5aiEFOB1IQp7F1/3MwB8p5Yxb/XkdGAR+g I5gw== X-Forwarded-Encrypted: i=1; AJvYcCX3ZiGD+Tmw8S5Pg5ZT7V40HHOjvib/OYV6ws0Y91kN3Sw1S8hOiWpzFSKefjRvo9JMI2U/m0uJEnVxCYE=@vger.kernel.org X-Gm-Message-State: AOJu0YyhJmAyC5Mfk+Tud/wJnME1+sEbBtLlyStzjjbBbVZfJPVCZgvS 6dNSWiv0o8QP4a9PLYjRZ58QVhosPeeixq4VDg2kmjIHUiAs5WCLysPz X-Gm-Gg: AeBDieu8K6gql743+W1Vr9z43wjBEouG3sAwsO7OMGp9wyq7nM3Bge/GOsxMC5Dlza7 0AGMf8ZWhgeKdkVmnYK/V8gaMT2Pm2PCLHMY3lkmXmoclEy6hMNMSWeZjq6wM3NBaDqdPNuBCCd nj9TnCEjFz+M5FygX3k+6ssAs8KFcA4UeFKDYBGyQCuSgwknuXAhLEq385yfoDQO1lUqpjqNOE6 k3aazm2mGl9wSc9+9Xz5kOBJgJbej97+DrgEXOTQGac6IlDsibUp+HS4KJQiC+/zrUq80oFeeEa JCk5VVE/WXvRv+Vf3k20tF+Q/DTH+N0OpZjxRcu4Tz27pP+vEEorfW41UmRGOfQADLSGmUV9Kqu tzwv91rXqF0CRAcGeBI5kUy00rY7hg1uevLiMwmgDjjUHnluWgT+8cOa1WX2iPOKKm1xzOxAhlJ 9QUJyLI7IFsNHxmA0cwnY1S48Jx8G3sZ9K2Gtlb25p X-Received: by 2002:a05:6a21:7912:20b0:39f:af98:6f92 with SMTP id adf61e73a8af0-39fe3c2d7a0mr7564178637.3.1775992288324; Sun, 12 Apr 2026 04:11:28 -0700 (PDT) Received: from DESKTOP-82PPU4A.localdomain ([202.8.116.169]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c7934c9ef38sm2522981a12.12.2026.04.12.04.11.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 Apr 2026 04:11:27 -0700 (PDT) From: Ujjal Roy To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Nikolay Aleksandrov , Ido Schimmel , David Ahern , Shuah Khan , Andy Roulin , Yong Wang , Petr Machata Cc: Ujjal Roy , bridge@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next v4 4/5] ipv6: mld: encode multicast exponential fields Date: Sun, 12 Apr 2026 11:10:46 +0000 Message-ID: <20260412111047.1326-5-royujjal@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260412111047.1326-1-royujjal@gmail.com> References: <20260412111047.1326-1-royujjal@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In MLD, MRC and QQIC fields are not correctly encoded when generating query packets. Since the receiver of the query interprets these fields using the MLDv2 floating-point decoding logic, any value that exceeds the linear threshold is incorrectly parsed as an exponential value, leading to an incorrect interval calculation. Encode and assign the corresponding protocol fields during query generation. Introduce the logic to dynamically calculate the exponent and mantissa using bit-scan (fls). This ensures MRC (16-bit) and QQIC (8-bit) fields are properly encoded when transmitting query packets with intervals that exceed their respective linear thresholds (32768 for MRD; 128 for QQI). RFC3810: If Maximum Response Code >=3D 32768, the Maximum Response Code field 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 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ RFC3810: If QQIC >=3D 128, the QQIC field represents a floating-point value as follows: 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+ |1| exp | mant | +-+-+-+-+-+-+-+-+ Reviewed-by: Ido Schimmel Signed-off-by: Ujjal Roy --- include/net/mld.h | 119 ++++++++++++++++++++++++++++++++++++++ net/bridge/br_multicast.c | 4 +- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/include/net/mld.h b/include/net/mld.h index 6ed467e23f12..5f79ea2257d5 100644 --- a/include/net/mld.h +++ b/include/net/mld.h @@ -90,12 +90,131 @@ struct mld2_query { #define MLDV2_QQIC_MAN(value) ((value) & 0x0f) =20 #define MLD_QQIC_MIN_THRESHOLD 128 +/* Max representable (mant =3D 0xF, exp =3D 7) -> 31744 */ +#define MLD_QQIC_MAX_THRESHOLD 31744 #define MLD_MRC_MIN_THRESHOLD 32768UL +/* Max representable (mant =3D 0xFFF, exp =3D 7) -> 8387584 */ +#define MLD_MRC_MAX_THRESHOLD 8387584 #define MLDV1_MRD_MAX_COMPAT (MLD_MRC_MIN_THRESHOLD - 1) =20 #define MLD_MAX_QUEUE 8 #define MLD_MAX_SKBS 32 =20 +/* V2 exponential field encoding */ + +/* + * Calculate Maximum Response Code from Maximum Response Delay + * + * MRC represents the 16-bit encoded form of Maximum Response Delay (MRD); + * once decoded, the resulting value is in milliseconds. + * + * RFC3810, 5.1.3. defines only the decoding formula: + * Maximum Response Delay =3D (mant | 0x1000) << (exp + 3) + * + * but does NOT define the encoding procedure. To derive exponent: + * + * For the 16-bit MRC, the "hidden bit" (0x1000) is left shifted by 12 to + * sit above the 12-bit mantissa. The RFC then shifts this entire block + * left by (exp + 3) to reconstruct the value. So, 'hidden bit' is the + * MSB which is shifted by (12 + exp + 3). + * + * Total left shift of the hidden bit =3D 12 + (exp + 3) =3D exp + 15. + * This is the MSB at the 0-based bit position: (exp + 15). + * Since fls() is 1-based, fls(value) - 1 =3D exp + 15. + * + * Therefore: + * exp =3D fls(value) - 16 + * mant =3D (value >> (exp + 3)) & 0x0FFF + * + * Final encoding formula: + * 0x8000 | (exp << 12) | mant + * + * Example (value =3D 1311744): + * 0 1 2 3 + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |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| 13117= 44 + * | ^-^--------mant---------^ ^...(exp+3)...^| exp= =3D5 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Encoded: + * 0x8000 | (5 << 12) | 0x404 =3D 0xD404 + */ +static inline u16 mldv2_mrc(unsigned long mrd) +{ + u16 mc_man, mc_exp; + + /* MRC < 32768 is literal */ + if (mrd < MLD_MRC_MIN_THRESHOLD) + return mrd; + + /* Saturate at max representable (mant =3D 0xFFF, exp =3D 7) -> 8387584 */ + if (mrd >=3D MLD_MRC_MAX_THRESHOLD) + return 0xFFFF; + + mc_exp =3D fls(mrd) - 16; + mc_man =3D (mrd >> (mc_exp + 3)) & 0x0FFF; + + return 0x8000 | (mc_exp << 12) | mc_man; +} + +/* + * Calculate Querier's Query Interval Code from Querier's Query Interval + * + * QQIC represents the 8-bit encoded form of Querier's Query Interval (QQI= ); + * once decoded, the resulting value is in seconds. + * + * RFC3810, 5.1.9. defines only the decoding formula: + * QQI =3D (mant | 0x10) << (exp + 3) + * + * but does NOT define the encoding procedure. To derive exponent: + * + * For any value of mantissa and exponent, the decoding formula indicates + * that the "hidden bit" (0x10) is shifted 4 bits left to sit above the + * 4-bit mantissa. The RFC again shifts this entire block left by (exp + 3) + * to reconstruct the value. So, 'hidden bit' is the MSB which is shifted + * by (4 + exp + 3). + * + * Total left shift of the 'hidden bit' =3D 4 + (exp + 3) =3D exp + 7. + * This is the MSB at the 0-based bit position: (exp + 7). + * Since fls() is 1-based, fls(value) - 1 =3D exp + 7. + * + * Therefore: + * exp =3D fls(value) - 8 + * mant =3D (value >> (exp + 3)) & 0x0F + * + * Final encoding formula: + * 0x80 | (exp << 4) | mant + * + * Example (value =3D 3200): + * 0 1 + * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0| (value =3D 3200) + * | ^-^-mant^ ^..(exp+3)..^| exp =3D 4, mant =3D 9 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Encoded: + * 0x80 | (4 << 4) | 9 =3D 0xC9 + */ +static inline u8 mldv2_qqic(unsigned long value) +{ + u8 mc_man, mc_exp; + + /* QQIC < 128 is literal */ + if (value < MLD_QQIC_MIN_THRESHOLD) + return value; + + /* Saturate at max representable (mant =3D 0xF, exp =3D 7) -> 31744 */ + if (value >=3D MLD_QQIC_MAX_THRESHOLD) + return 0xFF; + + mc_exp =3D fls(value) - 8; + mc_man =3D (value >> (mc_exp + 3)) & 0x0F; + + return 0x80 | (mc_exp << 4) | mc_man; +} + /* V2 exponential field decoding */ =20 /* Calculate Maximum Response Delay from Maximum Response Code diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 27010744d7ae..49ceea3ff974 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1181,7 +1181,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(s= truct net_bridge_mcast *brm break; case 2: mld2q =3D (struct mld2_query *)icmp6_hdr(skb); - mld2q->mld2q_mrc =3D htons((u16)jiffies_to_msecs(interval)); + mld2q->mld2q_mrc =3D htons(mldv2_mrc(jiffies_to_msecs(interval))); mld2q->mld2q_type =3D ICMPV6_MGM_QUERY; mld2q->mld2q_code =3D 0; mld2q->mld2q_cksum =3D 0; @@ -1190,7 +1190,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(s= truct net_bridge_mcast *brm mld2q->mld2q_suppress =3D sflag; mld2q->mld2q_qrv =3D 2; mld2q->mld2q_nsrcs =3D htons(llqt_srcs); - mld2q->mld2q_qqic =3D brmctx->multicast_query_interval / HZ; + mld2q->mld2q_qqic =3D mldv2_qqic(brmctx->multicast_query_interval / HZ); mld2q->mld2q_mca =3D *group; csum =3D &mld2q->mld2q_cksum; csum_start =3D (void *)mld2q; --=20 2.43.0 From nobody Sat Jun 20 17:32:27 2026 Received: from mail-pg1-f182.google.com (mail-pg1-f182.google.com [209.85.215.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B352327A107 for ; Sun, 12 Apr 2026 11:11:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992297; cv=none; b=KLAKPnHMIp0UaGbpD3JP6z19MnQqF/2n4ARF/bT2Mci0W2xho4fSjwO914SdgT6orH3VlrLTB28Z/2oLVvjg//xCHNSJIlZaqXFmdENLuWqCsqDxeHXxE2+KAOC/Y4gGTMHxXe2+lHltHX04rxcVLMRnWJTC4VfoXz3JW/Ij6pQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775992297; c=relaxed/simple; bh=Komn/jtzHBJBVBAbBcG1/JcOKIK4WPmcOOz8EffA+vs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lqXMRpab2As++UQdU9baHXM1bSTdo0VyiGjmxOTa5JAMkTmArQz12aB5BAv8KU0MPooYIEHYdpYEWhvPlArbon/7Cu5r9VqEoqbsDNczqGxL0N5b1FhrNSk5y5v/pf2hwVsO9nusD8cVcymtO6fIm6sGGLCqUGZfIcDrwB0PQ+I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=TAEocMP/; arc=none smtp.client-ip=209.85.215.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TAEocMP/" Received: by mail-pg1-f182.google.com with SMTP id 41be03b00d2f7-c76bde70ec9so1273679a12.2 for ; Sun, 12 Apr 2026 04:11:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775992295; x=1776597095; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jVGxqOACJLFxmxnpIjWVVcYX7bPeWpPr5Ieb+rKdDo4=; b=TAEocMP/TMAbOHKlmoXbvyqbBlK4/n/xdaiUVfApKz4ZrrhGQTw2OG2N+i/cDRKlfh aERSjb6cEfOrD0P4VlQvuUzQgtb/uCgfD/HgjQZu+2tis1UQTKioofaWwN3E3uypKtgL JK8Udjav8lcxjRe1AOHpTz3xA+hgzzetK3kOgrfvcPkHLbjUMmYY6dVEXHDKv+/9Z/7d YA/GSwCMvB+7C0S7jtmrOnS6aYw1ZHT/hYQ3PKJeqB9j8taMZtbBXZv5xUvbafuMWqV/ FfIWXJG3nJifZqjEtBCthp0PLj9vlYnl5JYd8gJtJ/EOhhKOPvbQzJ21oeE/ivmbWmA6 rdWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775992295; x=1776597095; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=jVGxqOACJLFxmxnpIjWVVcYX7bPeWpPr5Ieb+rKdDo4=; b=V8PW1+ZKSpnG+OUYVqRPmBcsaNp1lyhXhF9ALyh1R3z3dQvSmTQrRBX3rLzel5BrmC Pf1WDoq/JBG4hx3/K29XZsUerPPREnA0Z4vZajG1TD1yH0Gy0v1WE6gDHZLqGd/DzUOc KIpY0UyMTQ1S4rhcpEdKrIC/7ZHH4TPK8/mBEukbChAU/jD9adNPRaraj5wdyFNf529p H+FR3hZfQsfwvXjE2p0duo6Ahd13EVa5IY1oEUVQ8NAhS1k718A9wc5SNWn4w3Zlm2K3 rJ1wKYDTh3i7CTpGzk788/pa4/UNKMZHLxkeGodNFYRX9K02ABDEF+Cg+SD6tG7gJXhz 2STw== X-Forwarded-Encrypted: i=1; AJvYcCWlHanzvlUSzoDVcbsPx2Y38qg13pxmXmvTEypER1yfzviu1F5Qita9G84jSHf3dK+IFBpnixUt2BzFMo8=@vger.kernel.org X-Gm-Message-State: AOJu0YxmvcwYJ+84Y+oNRz2hMdyOvi+WHi3g1P0RNjYyn1iOJUNb+Yg2 CWVD1cAtSSiRAQiwb2CFS5kJnhnXthkvBwtsAlGJd+7/4megpxAODWiQ X-Gm-Gg: AeBDietYe9BAnw3GZN2juSZEFeYYtzAlWjQYZMJXGPoNr0RzyWJZC/DCYCOivQbSn9m jOLNCJmeqCpAyXK/CmHJvqmB3UkShBnbrA+ClopvGGcS0YpJDJrVnG171h7tbyRE589CDpxZsar c9taaWsTV1hXJcqZ0gI0Pugd0dpdDHYoCxxzqANcrxfbqHPLVhntJpMrTdKLpvUiv6sV3DDv94b in2gr6fZGU3oDRc9DOtTov9QMmlq6W2fr/qYg0nz4tTX8qb2bqxkbiBG1yCbgs7xEkzmHz5VBd2 MmZ087v/tPyeZpZyLEb6EsFcHMFcLl+318rTlwVmfBnqiMyTV/9VwJq0hMWpr0seFObtLI4CPHd WnYzRhv+7F8r7amp96XomaHATGbyAHiOAVC8pHNDzBH3B9NPrnoQIWWOyDWd+wiWv/zoSVVl+zg fyZGTpX2XC7S2bc5pfjXAtAAmIchaOz2xMbgTcpm0X X-Received: by 2002:a05:6a21:3284:b0:39f:94cb:1bc with SMTP id adf61e73a8af0-39fe3c64c48mr10313543637.1.1775992295009; Sun, 12 Apr 2026 04:11:35 -0700 (PDT) Received: from DESKTOP-82PPU4A.localdomain ([202.8.116.169]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c7934c9ef38sm2522981a12.12.2026.04.12.04.11.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 Apr 2026 04:11:34 -0700 (PDT) From: Ujjal Roy To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Nikolay Aleksandrov , Ido Schimmel , David Ahern , Shuah Khan , Andy Roulin , Yong Wang , Petr Machata Cc: Ujjal Roy , bridge@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH net-next v4 5/5] selftests: net: bridge: add MRC and QQIC field encoding tests Date: Sun, 12 Apr 2026 11:10:47 +0000 Message-ID: <20260412111047.1326-6-royujjal@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260412111047.1326-1-royujjal@gmail.com> References: <20260412111047.1326-1-royujjal@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Enhance vlmc_query_intvl_test and vlmc_query_response_intvl_test in bridge_vlan_mcast.sh to validate IGMPv3/MLDv2 protocol compliance for MRC and QQIC field encoding across both linear and exponential ranges. TEST: Vlan multicast snooping enable [ OK ] TEST: Vlan mcast_query_interval global option default value [ OK ] INFO: Vlan 10 mcast_query_interval (QQIC) test cases: TEST: Number of tagged IGMPv2 general query [ OK ] TEST: IGMPv3 QQIC linear value 60 [ OK ] TEST: MLDv2 QQIC linear value 60 [ OK ] TEST: IGMPv3 QQIC non linear value 160 [ OK ] TEST: MLDv2 QQIC non linear value 160 [ OK ] TEST: Vlan mcast_query_response_interval global option default value [ OK= ] INFO: Vlan 10 mcast_query_response_interval (MRC) test cases: TEST: IGMPv3 MRC linear value 60 [ OK ] TEST: IGMPv3 MRC non linear value 160 [ OK ] TEST: MLDv2 MRC linear value 30000 [ OK ] TEST: MLDv2 MRC non linear value 60000 [ OK ] Signed-off-by: Ujjal Roy --- .../net/forwarding/bridge_vlan_mcast.sh | 150 +++++++++++++++++- 1 file changed, 142 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/net/forwarding/bridge_vlan_mcast.sh b/= tools/testing/selftests/net/forwarding/bridge_vlan_mcast.sh index e8031f68200a..9f9f33d58286 100755 --- a/tools/testing/selftests/net/forwarding/bridge_vlan_mcast.sh +++ b/tools/testing/selftests/net/forwarding/bridge_vlan_mcast.sh @@ -162,14 +162,27 @@ vlmc_query_cnt_setup() { local type=3D$1 local dev=3D$2 + local match=3D$3 =20 if [[ $type =3D=3D "igmp" ]]; then - tc filter add dev $dev egress pref 10 prot 802.1Q \ + # This matches: IP Protocol 2 (IGMP) + tc filter add dev "$dev" egress pref 10 prot 802.1Q \ flower vlan_id 10 vlan_ethtype ipv4 dst_ip 224.0.0.1 ip_proto 2 \ + action continue + # AND Type 0x11 (Query) at offset 24 after IP + # IP (20 byte IP + 4 bytes Option) + match=3D(match u8 0x11 0xff at 24 $match) + tc filter add dev "$dev" egress pref 20 prot 802.1Q u32 "${match[@]}" \ action pass else - tc filter add dev $dev egress pref 10 prot 802.1Q \ + # This matches: ICMPv6 + tc filter add dev "$dev" egress pref 10 prot 802.1Q \ flower vlan_id 10 vlan_ethtype ipv6 dst_ip ff02::1 ip_proto icmpv6 \ + action continue + # AND Type 0x82 (Query) at offset 48 after IPv6 + # IPv6 (40 bytes IPv6 + 2 bytes next HDR + 4 bytes Option + 2 byte pad) + match=3D(match u8 0x82 0xff at 48 $match) + tc filter add dev "$dev" egress pref 20 prot 802.1Q u32 "${match[@]}" \ action pass fi =20 @@ -181,7 +194,53 @@ vlmc_query_cnt_cleanup() local dev=3D$1 =20 ip link set dev br0 type bridge mcast_stats_enabled 0 - tc filter del dev $dev egress pref 10 + tc filter del dev "$dev" egress pref 20 + tc filter del dev "$dev" egress pref 10 +} + +vlmc_query_get_intvl_match() +{ + local type=3D$1 + local version=3D$2 + local test=3D$3 + local interval=3D$4 + + if [ "$test" =3D "qqic" ]; then + # QQIC is 8-bit floating point encoding for IGMPv3 and MLDv2 + if [ "${type}v${version}" =3D "igmpv3" ]; then + # IP 20 bytes + 4 bytes Option + IGMPv3[9] + if [[ $interval -lt 128 ]]; then + echo "match u8 0x3c 0xff at 33" + else + echo "match u8 0x84 0xff at 33" + fi + elif [ "${type}v${version}" =3D "mldv2" ]; then + # IPv6 40 + 2 next HDR + 4 Option + 2 pad + MLDv2[25] + if [[ $interval -lt 128 ]]; then + echo "match u8 0x3c 0xff at 73" + else + echo "match u8 0x84 0xff at 73" + fi + fi + elif [ "$test" =3D "mrc" ]; then + if [ "${type}v${version}" =3D "igmpv3" ]; then + # MRC is 8-bit floating point encoding for IGMPv3 + # IP 20 bytes + 4 bytes Option + IGMPv3[1] + if [[ $interval -lt 128 ]]; then + echo "match u8 0x3c 0xff at 25" + else + echo "match u8 0x84 0xff at 25" + fi + elif [ "${type}v${version}" =3D "mldv2" ]; then + # MRC is 16-bit floating point encoding for MLDv2 + # IPv6 40 + 2 next HDR + 4 Option + 2 pad + MLDv2[4] + if [[ $interval -lt 32768 ]]; then + echo "match u16 0x7530 0xffff at 52" + else + echo "match u16 0x8d4c 0xffff at 52" + fi + fi + fi } =20 vlmc_check_query() @@ -191,9 +250,13 @@ vlmc_check_query() local dev=3D$3 local expect=3D$4 local time=3D$5 + local test=3D$6 + local interval=3D$7 + local intvl_match=3D"" local ret=3D0 =20 - vlmc_query_cnt_setup $type $dev + intvl_match=3D"$(vlmc_query_get_intvl_match "$type" "$version" "$test" "$= interval")" + vlmc_query_cnt_setup "$type" "$dev" "$intvl_match" =20 local pre_tx_xstats=3D$(vlmc_query_cnt_xstats $type $version $dev) bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_querier 1 @@ -201,7 +264,7 @@ vlmc_check_query() if [[ $ret -eq 0 ]]; then sleep $time =20 - local tcstats=3D$(tc_rule_stats_get $dev 10 egress) + local tcstats=3D$(tc_rule_stats_get "$dev" 20 egress) local post_tx_xstats=3D$(vlmc_query_cnt_xstats $type $version $dev) =20 if [[ $tcstats !=3D $expect || \ @@ -441,6 +504,7 @@ vlmc_query_intvl_test() check_err $? "Wrong default mcast_query_interval global vlan option value" log_test "Vlan mcast_query_interval global option default value" =20 + log_info "Vlan 10 mcast_query_interval (QQIC) test cases:" RET=3D0 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_quer= y_count 0 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_interv= al 200 @@ -448,8 +512,42 @@ vlmc_query_intvl_test() # 1 is sent immediately, then 2 more in the next 5 seconds vlmc_check_query igmp 2 $swp1 3 5 check_err $? "Wrong number of tagged IGMPv2 general queries sent" - log_test "Vlan 10 mcast_query_interval option changed to 200" + log_test "Number of tagged IGMPv2 general query" =20 + RET=3D0 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_igmp_version= 3 + check_err $? "Could not set mcast_igmp_version in vlan 10" + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_mld_version 2 + check_err $? "Could not set mcast_mld_version in vlan 10" + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_interv= al 6000 + check_err $? "Could not set mcast_query_interval in vlan 10" + # 1 is sent immediately, IGMPv3 QQIC should match with linear value 60s + vlmc_check_query igmp 3 $swp1 1 1 qqic 60 + check_err $? "Wrong QQIC in generated IGMPv3 general queries" + log_test "IGMPv3 QQIC linear value 60" + + RET=3D0 + # 1 is sent immediately, MLDv2 QQIC should match with linear value 60s + vlmc_check_query mld 2 $swp1 1 1 qqic 60 + check_err $? "Wrong QQIC in generated MLDv2 general queries" + log_test "MLDv2 QQIC linear value 60" + + RET=3D0 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_interv= al 16000 + check_err $? "Could not set mcast_query_interval in vlan 10" + # 1 is sent immediately, IGMPv3 QQIC should match with non linear value 1= 60s + vlmc_check_query igmp 3 $swp1 1 1 qqic 160 + check_err $? "Wrong QQIC in generated IGMPv3 general queries" + log_test "IGMPv3 QQIC non linear value 160" + + RET=3D0 + # 1 is sent immediately, MLDv2 QQIC should match with non linear value 16= 0s + vlmc_check_query mld 2 $swp1 1 1 qqic 160 + check_err $? "Wrong QQIC in generated MLDv2 general queries" + log_test "MLDv2 QQIC non linear value 160" + + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_igmp_version= 2 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_mld_version 1 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_quer= y_count 2 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_interv= al 12500 } @@ -468,11 +566,47 @@ vlmc_query_response_intvl_test() check_err $? "Wrong default mcast_query_response_interval global vlan opt= ion value" log_test "Vlan mcast_query_response_interval global option default value" =20 + log_info "Vlan 10 mcast_query_response_interval (MRC) test cases:" + RET=3D0 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_quer= y_count 0 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_igmp_version= 3 + check_err $? "Could not set mcast_igmp_version in vlan 10" + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_respon= se_interval 600 + check_err $? "Could not set mcast_query_response_interval in vlan 10" + # 1 is sent immediately, IGMPv3 MRC should match with linear value 60 uni= ts of 1/10s + vlmc_check_query igmp 3 $swp1 1 1 mrc 60 + check_err $? "Wrong MRC in generated IGMPv3 general queries" + log_test "IGMPv3 MRC linear value 60" + + RET=3D0 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_respon= se_interval 1600 + check_err $? "Could not set mcast_query_response_interval in vlan 10" + # 1 is sent immediately, IGMPv3 MRC should match with non linear value 16= 0 unit of 1/10s + vlmc_check_query igmp 3 $swp1 1 1 mrc 160 + check_err $? "Wrong MRC in generated IGMPv3 general queries" + log_test "IGMPv3 MRC non linear value 160" + + RET=3D0 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_mld_version 2 + check_err $? "Could not set mcast_mld_version in vlan 10" + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_respon= se_interval 3000 + check_err $? "Could not set mcast_query_response_interval in vlan 10" + # 1 is sent immediately, MLDv2 MRC should match with linear value 30000(m= s) + vlmc_check_query mld 2 $swp1 1 1 mrc 30000 + check_err $? "Wrong MRC in generated MLDv2 general queries" + log_test "MLDv2 MRC linear value 30000" + RET=3D0 - bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_respon= se_interval 200 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_respon= se_interval 6000 check_err $? "Could not set mcast_query_response_interval in vlan 10" - log_test "Vlan 10 mcast_query_response_interval option changed to 200" + # 1 is sent immediately, MLDv2 MRC should match with non linear value 600= 00(ms) + vlmc_check_query mld 2 $swp1 1 1 mrc 60000 + check_err $? "Wrong MRC in generated MLDv2 general queries" + log_test "MLDv2 MRC non linear value 60000" =20 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_igmp_version= 2 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_mld_version 1 + bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_startup_quer= y_count 2 bridge vlan global set vid 10 dev br0 mcast_snooping 1 mcast_query_respon= se_interval 1000 } =20 --=20 2.43.0