developer | 7e32f7e | 2022-05-18 21:10:08 +0800 | [diff] [blame] | 1 | From f428011b90ec0de7429886f753b7c3293392761c Mon Sep 17 00:00:00 2001 |
| 2 | From: Mark Starovoytov <mstarovoitov@marvell.com> |
| 3 | Date: Wed, 25 Mar 2020 15:52:36 +0300 |
| 4 | Subject: net: macsec: support multicast/broadcast when offloading |
| 5 | |
| 6 | The idea is simple. If the frame is an exact match for the controlled port |
| 7 | (based on DA comparison), then we simply divert this skb to matching port. |
| 8 | |
| 9 | Multicast/broadcast messages are delivered to all ports. |
| 10 | |
| 11 | Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com> |
| 12 | Signed-off-by: Igor Russkikh <irusskikh@marvell.com> |
| 13 | Signed-off-by: David S. Miller <davem@davemloft.net> |
| 14 | --- |
| 15 | drivers/net/macsec.c | 51 ++++++++++++++++++++++++++++++++++++++------------- |
| 16 | 1 file changed, 38 insertions(+), 13 deletions(-) |
| 17 | |
| 18 | diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c |
| 19 | index 146a7881a20ac..c7ad7c6f1d1ec 100644 |
| 20 | --- a/drivers/net/macsec.c |
| 21 | +++ b/drivers/net/macsec.c |
| 22 | @@ -1006,22 +1006,53 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb) |
| 23 | { |
| 24 | /* Deliver to the uncontrolled port by default */ |
| 25 | enum rx_handler_result ret = RX_HANDLER_PASS; |
| 26 | + struct ethhdr *hdr = eth_hdr(skb); |
| 27 | struct macsec_rxh_data *rxd; |
| 28 | struct macsec_dev *macsec; |
| 29 | |
| 30 | rcu_read_lock(); |
| 31 | rxd = macsec_data_rcu(skb->dev); |
| 32 | |
| 33 | - /* 10.6 If the management control validateFrames is not |
| 34 | - * Strict, frames without a SecTAG are received, counted, and |
| 35 | - * delivered to the Controlled Port |
| 36 | - */ |
| 37 | list_for_each_entry_rcu(macsec, &rxd->secys, secys) { |
| 38 | struct sk_buff *nskb; |
| 39 | struct pcpu_secy_stats *secy_stats = this_cpu_ptr(macsec->stats); |
| 40 | + struct net_device *ndev = macsec->secy.netdev; |
| 41 | |
| 42 | - if (!macsec_is_offloaded(macsec) && |
| 43 | - macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) { |
| 44 | + /* If h/w offloading is enabled, HW decodes frames and strips |
| 45 | + * the SecTAG, so we have to deduce which port to deliver to. |
| 46 | + */ |
| 47 | + if (macsec_is_offloaded(macsec) && netif_running(ndev)) { |
| 48 | + if (ether_addr_equal_64bits(hdr->h_dest, |
| 49 | + ndev->dev_addr)) { |
| 50 | + /* exact match, divert skb to this port */ |
| 51 | + skb->dev = ndev; |
| 52 | + skb->pkt_type = PACKET_HOST; |
| 53 | + ret = RX_HANDLER_ANOTHER; |
| 54 | + goto out; |
| 55 | + } else if (is_multicast_ether_addr_64bits( |
| 56 | + hdr->h_dest)) { |
| 57 | + /* multicast frame, deliver on this port too */ |
| 58 | + nskb = skb_clone(skb, GFP_ATOMIC); |
| 59 | + if (!nskb) |
| 60 | + break; |
| 61 | + |
| 62 | + nskb->dev = ndev; |
| 63 | + if (ether_addr_equal_64bits(hdr->h_dest, |
| 64 | + ndev->broadcast)) |
| 65 | + nskb->pkt_type = PACKET_BROADCAST; |
| 66 | + else |
| 67 | + nskb->pkt_type = PACKET_MULTICAST; |
| 68 | + |
| 69 | + netif_rx(nskb); |
| 70 | + } |
| 71 | + continue; |
| 72 | + } |
| 73 | + |
| 74 | + /* 10.6 If the management control validateFrames is not |
| 75 | + * Strict, frames without a SecTAG are received, counted, and |
| 76 | + * delivered to the Controlled Port |
| 77 | + */ |
| 78 | + if (macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) { |
| 79 | u64_stats_update_begin(&secy_stats->syncp); |
| 80 | secy_stats->stats.InPktsNoTag++; |
| 81 | u64_stats_update_end(&secy_stats->syncp); |
| 82 | @@ -1033,19 +1064,13 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb) |
| 83 | if (!nskb) |
| 84 | break; |
| 85 | |
| 86 | - nskb->dev = macsec->secy.netdev; |
| 87 | + nskb->dev = ndev; |
| 88 | |
| 89 | if (netif_rx(nskb) == NET_RX_SUCCESS) { |
| 90 | u64_stats_update_begin(&secy_stats->syncp); |
| 91 | secy_stats->stats.InPktsUntagged++; |
| 92 | u64_stats_update_end(&secy_stats->syncp); |
| 93 | } |
| 94 | - |
| 95 | - if (netif_running(macsec->secy.netdev) && |
| 96 | - macsec_is_offloaded(macsec)) { |
| 97 | - ret = RX_HANDLER_EXACT; |
| 98 | - goto out; |
| 99 | - } |
| 100 | } |
| 101 | |
| 102 | out: |
| 103 | -- |
| 104 | cgit 1.2.3-1.el7 |
| 105 | |