Skip to content

Commit 642c984

Browse files
Binary-Eaterkuba-moo
authored andcommitted
macsec: Detect if Rx skb is macsec-related for offloading devices that update md_dst
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 <[email protected]> Cc: [email protected] Fixes: 860ead8 ("net/macsec: Add MACsec skb_metadata_dst Rx Data path support") Signed-off-by: Rahul Rameshbabu <[email protected]> Reviewed-by: Benjamin Poirier <[email protected]> Reviewed-by: Cosmin Ratiu <[email protected]> Reviewed-by: Sabrina Dubroca <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6e159fd commit 642c984

File tree

1 file changed

+36
-10
lines changed

1 file changed

+36
-10
lines changed

drivers/net/macsec.c

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -999,10 +999,12 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
999999
struct metadata_dst *md_dst;
10001000
struct macsec_rxh_data *rxd;
10011001
struct macsec_dev *macsec;
1002+
bool is_macsec_md_dst;
10021003

10031004
rcu_read_lock();
10041005
rxd = macsec_data_rcu(skb->dev);
10051006
md_dst = skb_metadata_dst(skb);
1007+
is_macsec_md_dst = md_dst && md_dst->type == METADATA_MACSEC;
10061008

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

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

1021-
if (md_dst && md_dst->type == METADATA_MACSEC && !rx_sc)
1022+
if (ops->rx_uses_md_dst && !is_macsec_md_dst)
10221023
continue;
10231024

1025+
if (is_macsec_md_dst) {
1026+
struct macsec_rx_sc *rx_sc;
1027+
1028+
/* All drivers that implement MACsec offload
1029+
* support using skb metadata destinations must
1030+
* indicate that they do so.
1031+
*/
1032+
DEBUG_NET_WARN_ON_ONCE(!ops->rx_uses_md_dst);
1033+
rx_sc = find_rx_sc(&macsec->secy,
1034+
md_dst->u.macsec_info.sci);
1035+
if (!rx_sc)
1036+
continue;
1037+
/* device indicated macsec offload occurred */
1038+
skb->dev = ndev;
1039+
skb->pkt_type = PACKET_HOST;
1040+
eth_skb_pkt_type(skb, ndev);
1041+
ret = RX_HANDLER_ANOTHER;
1042+
goto out;
1043+
}
1044+
1045+
/* This datapath is insecure because it is unable to
1046+
* enforce isolation of broadcast/multicast traffic and
1047+
* unicast traffic with promiscuous mode on the macsec
1048+
* netdev. Since the core stack has no mechanism to
1049+
* check that the hardware did indeed receive MACsec
1050+
* traffic, it is possible that the response handling
1051+
* done by the MACsec port was to a plaintext packet.
1052+
* This violates the MACsec protocol standard.
1053+
*/
10241054
if (ether_addr_equal_64bits(hdr->h_dest,
10251055
ndev->dev_addr)) {
10261056
/* exact match, divert skb to this port */
@@ -1036,14 +1066,10 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
10361066
break;
10371067

10381068
nskb->dev = ndev;
1039-
if (ether_addr_equal_64bits(hdr->h_dest,
1040-
ndev->broadcast))
1041-
nskb->pkt_type = PACKET_BROADCAST;
1042-
else
1043-
nskb->pkt_type = PACKET_MULTICAST;
1069+
eth_skb_pkt_type(nskb, ndev);
10441070

10451071
__netif_rx(nskb);
1046-
} else if (rx_sc || ndev->flags & IFF_PROMISC) {
1072+
} else if (ndev->flags & IFF_PROMISC) {
10471073
skb->dev = ndev;
10481074
skb->pkt_type = PACKET_HOST;
10491075
ret = RX_HANDLER_ANOTHER;

0 commit comments

Comments
 (0)