Archive-only list for patches
 help / color / mirror / Atom feed
diff for duplicates of <20260917151554.424713469@linuxfoundation.org>

diff --git a/a/1.txt b/N1/1.txt
index da95306..fcf1e74 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,42 +1,202 @@
-6.18-stable review patch.  If anyone has any objections, please let me know.
+6.12-stable review patch.  If anyone has any objections, please let me know.
 
 ------------------
 
-From: Yevgeny Kliteynik <kliteyn@nvidia.com>
+From: Eric Dumazet <edumazet@google.com>
 
-[ Upstream commit 60e9e82f162ab7399373ff2185119289e4f6dc06 ]
+[ Upstream commit c073d1b070f171d206b19c98d71739a97f15b3f1 ]
 
-If a table has a miss table that was created by
-'mlx5hws_table_set_default_miss' API function, its miss_tbl
-keeps the table that points to it in a list.
-If such table is deleted, we need to also remove it from the
-miss_tbl list, otherwise the node in miss_tbl list will contain
-garbage.
+pmc->sflist is read locklessly under rcu_read_lock() by
+inet6_mc_check() during packet reception in the UDP and RAW
+multicast receive paths.
 
-Signed-off-by: Erez Shitrit <erezsh@nvidia.com>
-Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
-Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
-Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
-Link: https://patch.msgid.link/20260507173443.320465-3-tariqt@nvidia.com
+ip6_mc_source() mutated psl->sl_addr and psl->sl_count in-place
+when adding or removing a source filter. Additionally, when expanding
+the filter buffer, newpsl was published via rcu_assign_pointer()
+before writing the new source into the array.
+
+Because 16-byte struct in6_addr writes are not atomic and array
+shifting is not synchronized with RCU readers, concurrent readers in
+inet6_mc_check() could read torn IPv6 addresses or observe
+duplicated/missed source entries.
+
+Fix this by switching ip6_mc_source() to copy-on-write RCU updates:
+allocate and fully populate newpsl before publishing it via
+rcu_assign_pointer(), and reclaim the old filter via kfree_rcu(),
+matching ip6_mc_msfilter().
+
+Also remove the now unused IP6_SFBLOCK macro.
+
+Fixes: 882ba1f73c06 ("mld: convert ipv6_mc_socklist->sflist to RCU")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Taehee Yoo <ap420073@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260828084531.1826790-3-edumazet@google.com
 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
- drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c
-index 6113383ae47bb..07a3dd1248c77 100644
---- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c
-+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c
-@@ -282,6 +282,9 @@ int mlx5hws_table_destroy(struct mlx5hws_table *tbl)
- 		goto unlock_err;
- 	}
+ include/net/if_inet6.h |  2 -
+ net/ipv6/mcast.c       | 98 ++++++++++++++++++++++++------------------
+ 2 files changed, 56 insertions(+), 44 deletions(-)
+
+diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
+index 238ad3349456a..795fb41b45f5d 100644
+--- a/include/net/if_inet6.h
++++ b/include/net/if_inet6.h
+@@ -88,8 +88,6 @@ struct ip6_sf_socklist {
+ 	struct in6_addr		sl_addr[] __counted_by(sl_max);
+ };
+ 
+-#define IP6_SFBLOCK	10	/* allocate this many at once */
+-
+ struct ipv6_mc_socklist {
+ 	struct in6_addr		addr;
+ 	int			ifindex;
+diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
+index 8b7f5d4be2151..68eebfd70223f 100644
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -380,12 +380,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
+ {
+ 	struct ipv6_pinfo *inet6 = inet6_sk(sk);
+ 	struct in6_addr *source, *group;
++	struct ip6_sf_socklist *newpsl, *psl;
+ 	struct net *net = sock_net(sk);
+ 	struct ipv6_mc_socklist *pmc;
+-	struct ip6_sf_socklist *psl;
+ 	struct inet6_dev *idev;
+ 	int leavegroup = 0;
+-	int i, j, rv;
++	int i, j;
+ 	int err;
+ 
+ 	source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
+@@ -434,13 +434,11 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
+ 	if (!add) {
+ 		if (!psl)
+ 			goto done;	/* err = -EADDRNOTAVAIL */
+-		rv = !0;
+ 		for (i = 0; i < psl->sl_count; i++) {
+-			rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
+-			if (rv == 0)
++			if (ipv6_addr_equal(&psl->sl_addr[i], source))
+ 				break;
+ 		}
+-		if (rv)		/* source not found */
++		if (i == psl->sl_count)		/* source not found */
+ 			goto done;	/* err = -EADDRNOTAVAIL */
+ 
+ 		/* special case - (INCLUDE, empty) == LEAVE_GROUP */
+@@ -449,58 +447,74 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
+ 			goto done;
+ 		}
  
-+	if (tbl->default_miss.miss_tbl)
-+		list_del_init(&tbl->default_miss.next);
++		atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
++			   &sk->sk_omem_alloc);
 +
- 	list_del_init(&tbl->tbl_list_node);
- 	mutex_unlock(&ctx->ctrl_lock);
++		if (psl->sl_count == 1) {
++			newpsl = NULL;
++		} else {
++			newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr,
++							      psl->sl_count - 1),
++					      GFP_KERNEL);
++			if (!newpsl) {
++				atomic_add(struct_size(psl, sl_addr, psl->sl_max),
++					   &sk->sk_omem_alloc);
++				err = -ENOBUFS;
++				goto done;
++			}
++			newpsl->sl_max = psl->sl_count - 1;
++			newpsl->sl_count = psl->sl_count - 1;
++			for (j = 0; j < i; j++)
++				newpsl->sl_addr[j] = psl->sl_addr[j];
++			for (j = i + 1; j < psl->sl_count; j++)
++				newpsl->sl_addr[j - 1] = psl->sl_addr[j];
++		}
++
+ 		/* update the interface filter */
+ 		ip6_mc_del_src(idev, group, omode, 1, source, 1);
+ 
+-		for (j = i+1; j < psl->sl_count; j++)
+-			psl->sl_addr[j-1] = psl->sl_addr[j];
+-		psl->sl_count--;
++		rcu_assign_pointer(pmc->sflist, newpsl);
++		kfree_rcu(psl, rcu);
+ 		err = 0;
+ 		goto done;
+ 	}
+ 	/* else, add a new source to the filter */
  
+-	if (psl && psl->sl_count >= sysctl_mld_max_msf) {
++	if (psl && psl->sl_count >= READ_ONCE(sysctl_mld_max_msf)) {
+ 		err = -ENOBUFS;
+ 		goto done;
+ 	}
+-	if (!psl || psl->sl_count == psl->sl_max) {
+-		struct ip6_sf_socklist *newpsl;
+-		int count = IP6_SFBLOCK;
+-
+-		if (psl)
+-			count += psl->sl_max;
+-		newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, count),
+-				      GFP_KERNEL);
+-		if (!newpsl) {
+-			err = -ENOBUFS;
+-			goto done;
+-		}
+-		newpsl->sl_max = count;
+-		newpsl->sl_count = count - IP6_SFBLOCK;
+-		if (psl) {
+-			for (i = 0; i < psl->sl_count; i++)
+-				newpsl->sl_addr[i] = psl->sl_addr[i];
+-			atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
+-				   &sk->sk_omem_alloc);
++	if (psl) {
++		for (i = 0; i < psl->sl_count; i++) {
++			if (ipv6_addr_equal(&psl->sl_addr[i], source))
++				goto done; /* err = -EADDRNOTAVAIL */
+ 		}
+-		rcu_assign_pointer(pmc->sflist, newpsl);
+-		kfree_rcu(psl, rcu);
+-		psl = newpsl;
+ 	}
+-	rv = 1;	/* > 0 for insert logic below if sl_count is 0 */
+-	for (i = 0; i < psl->sl_count; i++) {
+-		rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
+-		if (rv == 0) /* There is an error in the address. */
+-			goto done;
++
++	i = psl ? psl->sl_count + 1 : 1;
++	newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, i),
++			      GFP_KERNEL);
++	if (!newpsl) {
++		err = -ENOBUFS;
++		goto done;
+ 	}
+-	for (j = psl->sl_count-1; j >= i; j--)
+-		psl->sl_addr[j+1] = psl->sl_addr[j];
+-	psl->sl_addr[i] = *source;
+-	psl->sl_count++;
+-	err = 0;
++	newpsl->sl_max = i;
++	newpsl->sl_count = i;
++	if (psl) {
++		for (j = 0; j < psl->sl_count; j++)
++			newpsl->sl_addr[j] = psl->sl_addr[j];
++	}
++	newpsl->sl_addr[i - 1] = *source;
++
+ 	/* update the interface list */
+ 	ip6_mc_add_src(idev, group, omode, 1, source, 1);
++
++	if (psl)
++		atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
++			   &sk->sk_omem_alloc);
++	rcu_assign_pointer(pmc->sflist, newpsl);
++	kfree_rcu(psl, rcu);
++	err = 0;
+ done:
+ 	mutex_unlock(&idev->mc_lock);
+ 	in6_dev_put(idev);
 -- 
 2.53.0
diff --git a/a/content_digest b/N1/content_digest
index 9bdf909..5e0c89a 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,59 +1,218 @@
- "ref\020260917151551.901433442@linuxfoundation.org\0"
+ "ref\020260917151539.408551884@linuxfoundation.org\0"
  "From\0Greg Kroah-Hartman <gregkh@linuxfoundation.org>\0"
- "Subject\0[PATCH 6.18 0090/1250] net/mlx5: HWS, Handle destroying table that has a miss table\0"
- "Date\0Thu, 17 Sep 2026 15:58:05 +0100\0"
+ "Subject\0[PATCH 6.12 0577/1102] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source()\0"
+ "Date\0Thu, 17 Sep 2026 16:08:40 +0100\0"
  "To\0stable@vger.kernel.org\0"
  "Cc\0Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
   patches@lists.linux.dev
-  Erez Shitrit <erezsh@nvidia.com>
-  Yevgeny Kliteynik <kliteyn@nvidia.com>
-  Moshe Shemesh <moshe@nvidia.com>
-  Tariq Toukan <tariqt@nvidia.com>
+  Eric Dumazet <edumazet@google.com>
+  Taehee Yoo <ap420073@gmail.com>
+  Ido Schimmel <idosch@nvidia.com>
   Jakub Kicinski <kuba@kernel.org>
  " Sasha Levin <sashal@kernel.org>\0"
  "\00:1\0"
  "b\0"
- "6.18-stable review patch.  If anyone has any objections, please let me know.\n"
+ "6.12-stable review patch.  If anyone has any objections, please let me know.\n"
  "\n"
  "------------------\n"
  "\n"
- "From: Yevgeny Kliteynik <kliteyn@nvidia.com>\n"
+ "From: Eric Dumazet <edumazet@google.com>\n"
  "\n"
- "[ Upstream commit 60e9e82f162ab7399373ff2185119289e4f6dc06 ]\n"
+ "[ Upstream commit c073d1b070f171d206b19c98d71739a97f15b3f1 ]\n"
  "\n"
- "If a table has a miss table that was created by\n"
- "'mlx5hws_table_set_default_miss' API function, its miss_tbl\n"
- "keeps the table that points to it in a list.\n"
- "If such table is deleted, we need to also remove it from the\n"
- "miss_tbl list, otherwise the node in miss_tbl list will contain\n"
- "garbage.\n"
+ "pmc->sflist is read locklessly under rcu_read_lock() by\n"
+ "inet6_mc_check() during packet reception in the UDP and RAW\n"
+ "multicast receive paths.\n"
  "\n"
- "Signed-off-by: Erez Shitrit <erezsh@nvidia.com>\n"
- "Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com>\n"
- "Reviewed-by: Moshe Shemesh <moshe@nvidia.com>\n"
- "Signed-off-by: Tariq Toukan <tariqt@nvidia.com>\n"
- "Link: https://patch.msgid.link/20260507173443.320465-3-tariqt@nvidia.com\n"
+ "ip6_mc_source() mutated psl->sl_addr and psl->sl_count in-place\n"
+ "when adding or removing a source filter. Additionally, when expanding\n"
+ "the filter buffer, newpsl was published via rcu_assign_pointer()\n"
+ "before writing the new source into the array.\n"
+ "\n"
+ "Because 16-byte struct in6_addr writes are not atomic and array\n"
+ "shifting is not synchronized with RCU readers, concurrent readers in\n"
+ "inet6_mc_check() could read torn IPv6 addresses or observe\n"
+ "duplicated/missed source entries.\n"
+ "\n"
+ "Fix this by switching ip6_mc_source() to copy-on-write RCU updates:\n"
+ "allocate and fully populate newpsl before publishing it via\n"
+ "rcu_assign_pointer(), and reclaim the old filter via kfree_rcu(),\n"
+ "matching ip6_mc_msfilter().\n"
+ "\n"
+ "Also remove the now unused IP6_SFBLOCK macro.\n"
+ "\n"
+ "Fixes: 882ba1f73c06 (\"mld: convert ipv6_mc_socklist->sflist to RCU\")\n"
+ "Signed-off-by: Eric Dumazet <edumazet@google.com>\n"
+ "Cc: Taehee Yoo <ap420073@gmail.com>\n"
+ "Reviewed-by: Ido Schimmel <idosch@nvidia.com>\n"
+ "Link: https://patch.msgid.link/20260828084531.1826790-3-edumazet@google.com\n"
  "Signed-off-by: Jakub Kicinski <kuba@kernel.org>\n"
  "Signed-off-by: Sasha Levin <sashal@kernel.org>\n"
  "---\n"
- " drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c | 3 +++\n"
- " 1 file changed, 3 insertions(+)\n"
- "\n"
- "diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c\n"
- "index 6113383ae47bb..07a3dd1248c77 100644\n"
- "--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c\n"
- "+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c\n"
- "@@ -282,6 +282,9 @@ int mlx5hws_table_destroy(struct mlx5hws_table *tbl)\n"
- " \t\tgoto unlock_err;\n"
- " \t}\n"
+ " include/net/if_inet6.h |  2 -\n"
+ " net/ipv6/mcast.c       | 98 ++++++++++++++++++++++++------------------\n"
+ " 2 files changed, 56 insertions(+), 44 deletions(-)\n"
+ "\n"
+ "diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h\n"
+ "index 238ad3349456a..795fb41b45f5d 100644\n"
+ "--- a/include/net/if_inet6.h\n"
+ "+++ b/include/net/if_inet6.h\n"
+ "@@ -88,8 +88,6 @@ struct ip6_sf_socklist {\n"
+ " \tstruct in6_addr\t\tsl_addr[] __counted_by(sl_max);\n"
+ " };\n"
+ " \n"
+ "-#define IP6_SFBLOCK\t10\t/* allocate this many at once */\n"
+ "-\n"
+ " struct ipv6_mc_socklist {\n"
+ " \tstruct in6_addr\t\taddr;\n"
+ " \tint\t\t\tifindex;\n"
+ "diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c\n"
+ "index 8b7f5d4be2151..68eebfd70223f 100644\n"
+ "--- a/net/ipv6/mcast.c\n"
+ "+++ b/net/ipv6/mcast.c\n"
+ "@@ -380,12 +380,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,\n"
+ " {\n"
+ " \tstruct ipv6_pinfo *inet6 = inet6_sk(sk);\n"
+ " \tstruct in6_addr *source, *group;\n"
+ "+\tstruct ip6_sf_socklist *newpsl, *psl;\n"
+ " \tstruct net *net = sock_net(sk);\n"
+ " \tstruct ipv6_mc_socklist *pmc;\n"
+ "-\tstruct ip6_sf_socklist *psl;\n"
+ " \tstruct inet6_dev *idev;\n"
+ " \tint leavegroup = 0;\n"
+ "-\tint i, j, rv;\n"
+ "+\tint i, j;\n"
+ " \tint err;\n"
+ " \n"
+ " \tsource = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;\n"
+ "@@ -434,13 +434,11 @@ int ip6_mc_source(int add, int omode, struct sock *sk,\n"
+ " \tif (!add) {\n"
+ " \t\tif (!psl)\n"
+ " \t\t\tgoto done;\t/* err = -EADDRNOTAVAIL */\n"
+ "-\t\trv = !0;\n"
+ " \t\tfor (i = 0; i < psl->sl_count; i++) {\n"
+ "-\t\t\trv = !ipv6_addr_equal(&psl->sl_addr[i], source);\n"
+ "-\t\t\tif (rv == 0)\n"
+ "+\t\t\tif (ipv6_addr_equal(&psl->sl_addr[i], source))\n"
+ " \t\t\t\tbreak;\n"
+ " \t\t}\n"
+ "-\t\tif (rv)\t\t/* source not found */\n"
+ "+\t\tif (i == psl->sl_count)\t\t/* source not found */\n"
+ " \t\t\tgoto done;\t/* err = -EADDRNOTAVAIL */\n"
+ " \n"
+ " \t\t/* special case - (INCLUDE, empty) == LEAVE_GROUP */\n"
+ "@@ -449,58 +447,74 @@ int ip6_mc_source(int add, int omode, struct sock *sk,\n"
+ " \t\t\tgoto done;\n"
+ " \t\t}\n"
  " \n"
- "+\tif (tbl->default_miss.miss_tbl)\n"
- "+\t\tlist_del_init(&tbl->default_miss.next);\n"
+ "+\t\tatomic_sub(struct_size(psl, sl_addr, psl->sl_max),\n"
+ "+\t\t\t   &sk->sk_omem_alloc);\n"
  "+\n"
- " \tlist_del_init(&tbl->tbl_list_node);\n"
- " \tmutex_unlock(&ctx->ctrl_lock);\n"
+ "+\t\tif (psl->sl_count == 1) {\n"
+ "+\t\t\tnewpsl = NULL;\n"
+ "+\t\t} else {\n"
+ "+\t\t\tnewpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr,\n"
+ "+\t\t\t\t\t\t\t      psl->sl_count - 1),\n"
+ "+\t\t\t\t\t      GFP_KERNEL);\n"
+ "+\t\t\tif (!newpsl) {\n"
+ "+\t\t\t\tatomic_add(struct_size(psl, sl_addr, psl->sl_max),\n"
+ "+\t\t\t\t\t   &sk->sk_omem_alloc);\n"
+ "+\t\t\t\terr = -ENOBUFS;\n"
+ "+\t\t\t\tgoto done;\n"
+ "+\t\t\t}\n"
+ "+\t\t\tnewpsl->sl_max = psl->sl_count - 1;\n"
+ "+\t\t\tnewpsl->sl_count = psl->sl_count - 1;\n"
+ "+\t\t\tfor (j = 0; j < i; j++)\n"
+ "+\t\t\t\tnewpsl->sl_addr[j] = psl->sl_addr[j];\n"
+ "+\t\t\tfor (j = i + 1; j < psl->sl_count; j++)\n"
+ "+\t\t\t\tnewpsl->sl_addr[j - 1] = psl->sl_addr[j];\n"
+ "+\t\t}\n"
+ "+\n"
+ " \t\t/* update the interface filter */\n"
+ " \t\tip6_mc_del_src(idev, group, omode, 1, source, 1);\n"
+ " \n"
+ "-\t\tfor (j = i+1; j < psl->sl_count; j++)\n"
+ "-\t\t\tpsl->sl_addr[j-1] = psl->sl_addr[j];\n"
+ "-\t\tpsl->sl_count--;\n"
+ "+\t\trcu_assign_pointer(pmc->sflist, newpsl);\n"
+ "+\t\tkfree_rcu(psl, rcu);\n"
+ " \t\terr = 0;\n"
+ " \t\tgoto done;\n"
+ " \t}\n"
+ " \t/* else, add a new source to the filter */\n"
  " \n"
+ "-\tif (psl && psl->sl_count >= sysctl_mld_max_msf) {\n"
+ "+\tif (psl && psl->sl_count >= READ_ONCE(sysctl_mld_max_msf)) {\n"
+ " \t\terr = -ENOBUFS;\n"
+ " \t\tgoto done;\n"
+ " \t}\n"
+ "-\tif (!psl || psl->sl_count == psl->sl_max) {\n"
+ "-\t\tstruct ip6_sf_socklist *newpsl;\n"
+ "-\t\tint count = IP6_SFBLOCK;\n"
+ "-\n"
+ "-\t\tif (psl)\n"
+ "-\t\t\tcount += psl->sl_max;\n"
+ "-\t\tnewpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, count),\n"
+ "-\t\t\t\t      GFP_KERNEL);\n"
+ "-\t\tif (!newpsl) {\n"
+ "-\t\t\terr = -ENOBUFS;\n"
+ "-\t\t\tgoto done;\n"
+ "-\t\t}\n"
+ "-\t\tnewpsl->sl_max = count;\n"
+ "-\t\tnewpsl->sl_count = count - IP6_SFBLOCK;\n"
+ "-\t\tif (psl) {\n"
+ "-\t\t\tfor (i = 0; i < psl->sl_count; i++)\n"
+ "-\t\t\t\tnewpsl->sl_addr[i] = psl->sl_addr[i];\n"
+ "-\t\t\tatomic_sub(struct_size(psl, sl_addr, psl->sl_max),\n"
+ "-\t\t\t\t   &sk->sk_omem_alloc);\n"
+ "+\tif (psl) {\n"
+ "+\t\tfor (i = 0; i < psl->sl_count; i++) {\n"
+ "+\t\t\tif (ipv6_addr_equal(&psl->sl_addr[i], source))\n"
+ "+\t\t\t\tgoto done; /* err = -EADDRNOTAVAIL */\n"
+ " \t\t}\n"
+ "-\t\trcu_assign_pointer(pmc->sflist, newpsl);\n"
+ "-\t\tkfree_rcu(psl, rcu);\n"
+ "-\t\tpsl = newpsl;\n"
+ " \t}\n"
+ "-\trv = 1;\t/* > 0 for insert logic below if sl_count is 0 */\n"
+ "-\tfor (i = 0; i < psl->sl_count; i++) {\n"
+ "-\t\trv = !ipv6_addr_equal(&psl->sl_addr[i], source);\n"
+ "-\t\tif (rv == 0) /* There is an error in the address. */\n"
+ "-\t\t\tgoto done;\n"
+ "+\n"
+ "+\ti = psl ? psl->sl_count + 1 : 1;\n"
+ "+\tnewpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, i),\n"
+ "+\t\t\t      GFP_KERNEL);\n"
+ "+\tif (!newpsl) {\n"
+ "+\t\terr = -ENOBUFS;\n"
+ "+\t\tgoto done;\n"
+ " \t}\n"
+ "-\tfor (j = psl->sl_count-1; j >= i; j--)\n"
+ "-\t\tpsl->sl_addr[j+1] = psl->sl_addr[j];\n"
+ "-\tpsl->sl_addr[i] = *source;\n"
+ "-\tpsl->sl_count++;\n"
+ "-\terr = 0;\n"
+ "+\tnewpsl->sl_max = i;\n"
+ "+\tnewpsl->sl_count = i;\n"
+ "+\tif (psl) {\n"
+ "+\t\tfor (j = 0; j < psl->sl_count; j++)\n"
+ "+\t\t\tnewpsl->sl_addr[j] = psl->sl_addr[j];\n"
+ "+\t}\n"
+ "+\tnewpsl->sl_addr[i - 1] = *source;\n"
+ "+\n"
+ " \t/* update the interface list */\n"
+ " \tip6_mc_add_src(idev, group, omode, 1, source, 1);\n"
+ "+\n"
+ "+\tif (psl)\n"
+ "+\t\tatomic_sub(struct_size(psl, sl_addr, psl->sl_max),\n"
+ "+\t\t\t   &sk->sk_omem_alloc);\n"
+ "+\trcu_assign_pointer(pmc->sflist, newpsl);\n"
+ "+\tkfree_rcu(psl, rcu);\n"
+ "+\terr = 0;\n"
+ " done:\n"
+ " \tmutex_unlock(&idev->mc_lock);\n"
+ " \tin6_dev_put(idev);\n"
  "-- \n"
  2.53.0
 
-41dc7b779d789c293dfa072edc368b2513f8ab60c5bd76f41202a71c1e94dbe0
+ef81c91cc468daa8b376296752eea3410bba60035a92f67d80e9501c3c953ac5

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox