mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 21:03:32 +00:00
macsec: Detect if Rx skb is macsec-related for offloading devices that update md_dst
commit642c984dd0
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:860ead89b8
("net/macsec: Add MACsec skb_metadata_dst Rx Data path support") Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com> Reviewed-by: Benjamin Poirier <bpoirier@nvidia.com> Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://lore.kernel.org/r/20240423181319.115860-4-rrameshbabu@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
6536f12fe2
commit
21e042d29e
1 changed files with 37 additions and 7 deletions
|
@ -1007,10 +1007,12 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
|
||||||
struct metadata_dst *md_dst;
|
struct metadata_dst *md_dst;
|
||||||
struct macsec_rxh_data *rxd;
|
struct macsec_rxh_data *rxd;
|
||||||
struct macsec_dev *macsec;
|
struct macsec_dev *macsec;
|
||||||
|
bool is_macsec_md_dst;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
rxd = macsec_data_rcu(skb->dev);
|
rxd = macsec_data_rcu(skb->dev);
|
||||||
md_dst = skb_metadata_dst(skb);
|
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) {
|
list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
|
@ -1021,10 +1023,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.
|
* the SecTAG, so we have to deduce which port to deliver to.
|
||||||
*/
|
*/
|
||||||
if (macsec_is_offloaded(macsec) && netif_running(ndev)) {
|
if (macsec_is_offloaded(macsec) && netif_running(ndev)) {
|
||||||
if (md_dst && md_dst->type == METADATA_MACSEC &&
|
const struct macsec_ops *ops;
|
||||||
(!find_rx_sc(&macsec->secy, md_dst->u.macsec_info.sci)))
|
|
||||||
|
ops = macsec_get_ops(macsec, NULL);
|
||||||
|
|
||||||
|
if (ops->rx_uses_md_dst && !is_macsec_md_dst)
|
||||||
continue;
|
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,
|
if (ether_addr_equal_64bits(hdr->h_dest,
|
||||||
ndev->dev_addr)) {
|
ndev->dev_addr)) {
|
||||||
/* exact match, divert skb to this port */
|
/* exact match, divert skb to this port */
|
||||||
|
@ -1040,11 +1074,7 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nskb->dev = ndev;
|
nskb->dev = ndev;
|
||||||
if (ether_addr_equal_64bits(hdr->h_dest,
|
eth_skb_pkt_type(nskb, ndev);
|
||||||
ndev->broadcast))
|
|
||||||
nskb->pkt_type = PACKET_BROADCAST;
|
|
||||||
else
|
|
||||||
nskb->pkt_type = PACKET_MULTICAST;
|
|
||||||
|
|
||||||
__netif_rx(nskb);
|
__netif_rx(nskb);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue