mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
net: macsec: support multicast/broadcast when offloading
The idea is simple. If the frame is an exact match for the controlled port (based on DA comparison), then we simply divert this skb to matching port. Multicast/broadcast messages are delivered to all ports. Change-Id: Iaa716e14c1a178a99b51b1104e7c68eb2f8e592e Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com> Signed-off-by: Igor Russkikh <irusskikh@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net> Git-commit: f428011b90ec0de7429886f753b7c3293392761c Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Signed-off-by: Karthik Rudrapatna <quic_krudrapa@quicinc.com>
This commit is contained in:
parent
93e3092501
commit
811cdefef1
1 changed files with 38 additions and 13 deletions
|
|
@ -992,22 +992,53 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
|
|||
{
|
||||
/* Deliver to the uncontrolled port by default */
|
||||
enum rx_handler_result ret = RX_HANDLER_PASS;
|
||||
struct ethhdr *hdr = eth_hdr(skb);
|
||||
struct macsec_rxh_data *rxd;
|
||||
struct macsec_dev *macsec;
|
||||
|
||||
rcu_read_lock();
|
||||
rxd = macsec_data_rcu(skb->dev);
|
||||
|
||||
/* 10.6 If the management control validateFrames is not
|
||||
* Strict, frames without a SecTAG are received, counted, and
|
||||
* delivered to the Controlled Port
|
||||
*/
|
||||
list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
|
||||
struct sk_buff *nskb;
|
||||
struct pcpu_secy_stats *secy_stats = this_cpu_ptr(macsec->stats);
|
||||
struct net_device *ndev = macsec->secy.netdev;
|
||||
|
||||
if (!macsec_is_offloaded(macsec) &&
|
||||
macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) {
|
||||
/* If h/w offloading is enabled, HW decodes frames and strips
|
||||
* the SecTAG, so we have to deduce which port to deliver to.
|
||||
*/
|
||||
if (macsec_is_offloaded(macsec) && netif_running(ndev)) {
|
||||
if (ether_addr_equal_64bits(hdr->h_dest,
|
||||
ndev->dev_addr)) {
|
||||
/* exact match, divert skb to this port */
|
||||
skb->dev = ndev;
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
ret = RX_HANDLER_ANOTHER;
|
||||
goto out;
|
||||
} else if (is_multicast_ether_addr_64bits(
|
||||
hdr->h_dest)) {
|
||||
/* multicast frame, deliver on this port too */
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
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;
|
||||
|
||||
netif_rx(nskb);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 10.6 If the management control validateFrames is not
|
||||
* Strict, frames without a SecTAG are received, counted, and
|
||||
* delivered to the Controlled Port
|
||||
*/
|
||||
if (macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) {
|
||||
u64_stats_update_begin(&secy_stats->syncp);
|
||||
secy_stats->stats.InPktsNoTag++;
|
||||
u64_stats_update_end(&secy_stats->syncp);
|
||||
|
|
@ -1019,19 +1050,13 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
|
|||
if (!nskb)
|
||||
break;
|
||||
|
||||
nskb->dev = macsec->secy.netdev;
|
||||
nskb->dev = ndev;
|
||||
|
||||
if (netif_rx(nskb) == NET_RX_SUCCESS) {
|
||||
u64_stats_update_begin(&secy_stats->syncp);
|
||||
secy_stats->stats.InPktsUntagged++;
|
||||
u64_stats_update_end(&secy_stats->syncp);
|
||||
}
|
||||
|
||||
if (netif_running(macsec->secy.netdev) &&
|
||||
macsec_is_offloaded(macsec)) {
|
||||
ret = RX_HANDLER_EXACT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
Loading…
Reference in a new issue