Commit 6b33f64e authored by Rahul Rameshbabu's avatar Rahul Rameshbabu Committed by Ma Wupeng
Browse files

macsec: Detect if Rx skb is macsec-related for offloading devices that update md_dst

stable inclusion
from stable-v6.6.30
commit 6c3020dc817f8d08fc0ea48dd004782e7c204d92
bugzilla: https://gitee.com/openeuler/kernel/issues/I9MPZ8

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=6c3020dc817f8d08fc0ea48dd004782e7c204d92

--------------------------------

commit 642c984dd0e37dbaec9f87bd1211e5fac1f142bf upstream.

Can now correctly identify where the packets should be delivered by using
md_dst or its absence on devices that provide it.

This detection is not possible without device drivers that update md_dst. A
fallback pattern should be used for supporting such device drivers. This
fallback mode causes multicast messages to be cloned to both the non-macsec
and macsec ports, independent of whether the multicast message received was
encrypted over MACsec or not. Other non-macsec traffic may also fail to be
handled correctly for devices in promiscuous mode.

Link: https://lore.kernel.org/netdev/ZULRxX9eIbFiVi7v@hog/


Cc: Sabrina Dubroca <sd@queasysnail.net>
Cc: stable@vger.kernel.org
Fixes: 860ead89 ("net/macsec: Add MACsec skb_metadata_dst Rx Data path support")
Signed-off-by: default avatarRahul Rameshbabu <rrameshbabu@nvidia.com>
Reviewed-by: default avatarBenjamin Poirier <bpoirier@nvidia.com>
Reviewed-by: default avatarCosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Link: https://lore.kernel.org/r/20240423181319.115860-4-rrameshbabu@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarZhangPeng <zhangpeng362@huawei.com>
parent 68e48278
Loading
Loading
Loading
Loading
+36 −10
Original line number Diff line number Diff line
@@ -996,10 +996,12 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
	struct metadata_dst *md_dst;
	struct macsec_rxh_data *rxd;
	struct macsec_dev *macsec;
	bool is_macsec_md_dst;

	rcu_read_lock();
	rxd = macsec_data_rcu(skb->dev);
	md_dst = skb_metadata_dst(skb);
	is_macsec_md_dst = md_dst && md_dst->type == METADATA_MACSEC;

	list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
		struct sk_buff *nskb;
@@ -1010,14 +1012,42 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
		 * the SecTAG, so we have to deduce which port to deliver to.
		 */
		if (macsec_is_offloaded(macsec) && netif_running(ndev)) {
			struct macsec_rx_sc *rx_sc = NULL;
			const struct macsec_ops *ops;

			if (md_dst && md_dst->type == METADATA_MACSEC)
				rx_sc = find_rx_sc(&macsec->secy, md_dst->u.macsec_info.sci);
			ops = macsec_get_ops(macsec, NULL);

			if (md_dst && md_dst->type == METADATA_MACSEC && !rx_sc)
			if (ops->rx_uses_md_dst && !is_macsec_md_dst)
				continue;

			if (is_macsec_md_dst) {
				struct macsec_rx_sc *rx_sc;

				/* All drivers that implement MACsec offload
				 * support using skb metadata destinations must
				 * indicate that they do so.
				 */
				DEBUG_NET_WARN_ON_ONCE(!ops->rx_uses_md_dst);
				rx_sc = find_rx_sc(&macsec->secy,
						   md_dst->u.macsec_info.sci);
				if (!rx_sc)
					continue;
				/* device indicated macsec offload occurred */
				skb->dev = ndev;
				skb->pkt_type = PACKET_HOST;
				eth_skb_pkt_type(skb, ndev);
				ret = RX_HANDLER_ANOTHER;
				goto out;
			}

			/* This datapath is insecure because it is unable to
			 * enforce isolation of broadcast/multicast traffic and
			 * unicast traffic with promiscuous mode on the macsec
			 * netdev. Since the core stack has no mechanism to
			 * check that the hardware did indeed receive MACsec
			 * traffic, it is possible that the response handling
			 * done by the MACsec port was to a plaintext packet.
			 * This violates the MACsec protocol standard.
			 */
			if (ether_addr_equal_64bits(hdr->h_dest,
						    ndev->dev_addr)) {
				/* exact match, divert skb to this port */
@@ -1033,14 +1063,10 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
					break;

				nskb->dev = ndev;
				if (ether_addr_equal_64bits(hdr->h_dest,
							    ndev->broadcast))
					nskb->pkt_type = PACKET_BROADCAST;
				else
					nskb->pkt_type = PACKET_MULTICAST;
				eth_skb_pkt_type(nskb, ndev);

				__netif_rx(nskb);
			} else if (rx_sc || ndev->flags & IFF_PROMISC) {
			} else if (ndev->flags & IFF_PROMISC) {
				skb->dev = ndev;
				skb->pkt_type = PACKET_HOST;
				ret = RX_HANDLER_ANOTHER;