@@ -1006,22 +1006,53 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
1006
1006
{
1007
1007
/* Deliver to the uncontrolled port by default */
1008
1008
enum rx_handler_result ret = RX_HANDLER_PASS ;
1009
+ struct ethhdr * hdr = eth_hdr (skb );
1009
1010
struct macsec_rxh_data * rxd ;
1010
1011
struct macsec_dev * macsec ;
1011
1012
1012
1013
rcu_read_lock ();
1013
1014
rxd = macsec_data_rcu (skb -> dev );
1014
1015
1015
- /* 10.6 If the management control validateFrames is not
1016
- * Strict, frames without a SecTAG are received, counted, and
1017
- * delivered to the Controlled Port
1018
- */
1019
1016
list_for_each_entry_rcu (macsec , & rxd -> secys , secys ) {
1020
1017
struct sk_buff * nskb ;
1021
1018
struct pcpu_secy_stats * secy_stats = this_cpu_ptr (macsec -> stats );
1019
+ struct net_device * ndev = macsec -> secy .netdev ;
1022
1020
1023
- if (!macsec_is_offloaded (macsec ) &&
1024
- macsec -> secy .validate_frames == MACSEC_VALIDATE_STRICT ) {
1021
+ /* If h/w offloading is enabled, HW decodes frames and strips
1022
+ * the SecTAG, so we have to deduce which port to deliver to.
1023
+ */
1024
+ if (macsec_is_offloaded (macsec ) && netif_running (ndev )) {
1025
+ if (ether_addr_equal_64bits (hdr -> h_dest ,
1026
+ ndev -> dev_addr )) {
1027
+ /* exact match, divert skb to this port */
1028
+ skb -> dev = ndev ;
1029
+ skb -> pkt_type = PACKET_HOST ;
1030
+ ret = RX_HANDLER_ANOTHER ;
1031
+ goto out ;
1032
+ } else if (is_multicast_ether_addr_64bits (
1033
+ hdr -> h_dest )) {
1034
+ /* multicast frame, deliver on this port too */
1035
+ nskb = skb_clone (skb , GFP_ATOMIC );
1036
+ if (!nskb )
1037
+ break ;
1038
+
1039
+ nskb -> dev = ndev ;
1040
+ if (ether_addr_equal_64bits (hdr -> h_dest ,
1041
+ ndev -> broadcast ))
1042
+ nskb -> pkt_type = PACKET_BROADCAST ;
1043
+ else
1044
+ nskb -> pkt_type = PACKET_MULTICAST ;
1045
+
1046
+ netif_rx (nskb );
1047
+ }
1048
+ continue ;
1049
+ }
1050
+
1051
+ /* 10.6 If the management control validateFrames is not
1052
+ * Strict, frames without a SecTAG are received, counted, and
1053
+ * delivered to the Controlled Port
1054
+ */
1055
+ if (macsec -> secy .validate_frames == MACSEC_VALIDATE_STRICT ) {
1025
1056
u64_stats_update_begin (& secy_stats -> syncp );
1026
1057
secy_stats -> stats .InPktsNoTag ++ ;
1027
1058
u64_stats_update_end (& secy_stats -> syncp );
@@ -1033,19 +1064,13 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
1033
1064
if (!nskb )
1034
1065
break ;
1035
1066
1036
- nskb -> dev = macsec -> secy . netdev ;
1067
+ nskb -> dev = ndev ;
1037
1068
1038
1069
if (netif_rx (nskb ) == NET_RX_SUCCESS ) {
1039
1070
u64_stats_update_begin (& secy_stats -> syncp );
1040
1071
secy_stats -> stats .InPktsUntagged ++ ;
1041
1072
u64_stats_update_end (& secy_stats -> syncp );
1042
1073
}
1043
-
1044
- if (netif_running (macsec -> secy .netdev ) &&
1045
- macsec_is_offloaded (macsec )) {
1046
- ret = RX_HANDLER_EXACT ;
1047
- goto out ;
1048
- }
1049
1074
}
1050
1075
1051
1076
out :
0 commit comments