@@ -518,14 +518,8 @@ static void macsec_count_tx(struct sk_buff *skb, struct macsec_tx_sc *tx_sc,
518518
519519static void count_tx (struct net_device * dev , int ret , int len )
520520{
521- if (likely (ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN )) {
522- struct pcpu_sw_netstats * stats = this_cpu_ptr (dev -> tstats );
523-
524- u64_stats_update_begin (& stats -> syncp );
525- u64_stats_inc (& stats -> tx_packets );
526- u64_stats_add (& stats -> tx_bytes , len );
527- u64_stats_update_end (& stats -> syncp );
528- }
521+ if (likely (ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN ))
522+ dev_sw_netstats_tx_add (dev , 1 , len );
529523}
530524
531525static void macsec_encrypt_done (struct crypto_async_request * base , int err )
@@ -743,7 +737,7 @@ static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u
743737 u64_stats_update_begin (& rxsc_stats -> syncp );
744738 rxsc_stats -> stats .InPktsLate ++ ;
745739 u64_stats_update_end (& rxsc_stats -> syncp );
746- secy -> netdev -> stats . rx_dropped ++ ;
740+ DEV_STATS_INC ( secy -> netdev , rx_dropped ) ;
747741 return false;
748742 }
749743
@@ -767,7 +761,7 @@ static bool macsec_post_decrypt(struct sk_buff *skb, struct macsec_secy *secy, u
767761 rxsc_stats -> stats .InPktsNotValid ++ ;
768762 u64_stats_update_end (& rxsc_stats -> syncp );
769763 this_cpu_inc (rx_sa -> stats -> InPktsNotValid );
770- secy -> netdev -> stats . rx_errors ++ ;
764+ DEV_STATS_INC ( secy -> netdev , rx_errors ) ;
771765 return false;
772766 }
773767
@@ -827,12 +821,7 @@ static void macsec_finalize_skb(struct sk_buff *skb, u8 icv_len, u8 hdr_len)
827821
828822static void count_rx (struct net_device * dev , int len )
829823{
830- struct pcpu_sw_netstats * stats = this_cpu_ptr (dev -> tstats );
831-
832- u64_stats_update_begin (& stats -> syncp );
833- u64_stats_inc (& stats -> rx_packets );
834- u64_stats_add (& stats -> rx_bytes , len );
835- u64_stats_update_end (& stats -> syncp );
824+ dev_sw_netstats_rx_add (dev , len );
836825}
837826
838827static void macsec_decrypt_done (struct crypto_async_request * base , int err )
@@ -1007,10 +996,12 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
1007996 struct metadata_dst * md_dst ;
1008997 struct macsec_rxh_data * rxd ;
1009998 struct macsec_dev * macsec ;
999+ bool is_macsec_md_dst ;
10101000
10111001 rcu_read_lock ();
10121002 rxd = macsec_data_rcu (skb -> dev );
10131003 md_dst = skb_metadata_dst (skb );
1004+ is_macsec_md_dst = md_dst && md_dst -> type == METADATA_MACSEC ;
10141005
10151006 list_for_each_entry_rcu (macsec , & rxd -> secys , secys ) {
10161007 struct sk_buff * nskb ;
@@ -1021,14 +1012,42 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
10211012 * the SecTAG, so we have to deduce which port to deliver to.
10221013 */
10231014 if (macsec_is_offloaded (macsec ) && netif_running (ndev )) {
1024- struct macsec_rx_sc * rx_sc = NULL ;
1015+ const struct macsec_ops * ops ;
10251016
1026- if (md_dst && md_dst -> type == METADATA_MACSEC )
1027- rx_sc = find_rx_sc (& macsec -> secy , md_dst -> u .macsec_info .sci );
1017+ ops = macsec_get_ops (macsec , NULL );
10281018
1029- if (md_dst && md_dst -> type == METADATA_MACSEC && !rx_sc )
1019+ if (ops -> rx_uses_md_dst && !is_macsec_md_dst )
10301020 continue ;
10311021
1022+ if (is_macsec_md_dst ) {
1023+ struct macsec_rx_sc * rx_sc ;
1024+
1025+ /* All drivers that implement MACsec offload
1026+ * support using skb metadata destinations must
1027+ * indicate that they do so.
1028+ */
1029+ DEBUG_NET_WARN_ON_ONCE (!ops -> rx_uses_md_dst );
1030+ rx_sc = find_rx_sc (& macsec -> secy ,
1031+ md_dst -> u .macsec_info .sci );
1032+ if (!rx_sc )
1033+ continue ;
1034+ /* device indicated macsec offload occurred */
1035+ skb -> dev = ndev ;
1036+ skb -> pkt_type = PACKET_HOST ;
1037+ eth_skb_pkt_type (skb , ndev );
1038+ ret = RX_HANDLER_ANOTHER ;
1039+ goto out ;
1040+ }
1041+
1042+ /* This datapath is insecure because it is unable to
1043+ * enforce isolation of broadcast/multicast traffic and
1044+ * unicast traffic with promiscuous mode on the macsec
1045+ * netdev. Since the core stack has no mechanism to
1046+ * check that the hardware did indeed receive MACsec
1047+ * traffic, it is possible that the response handling
1048+ * done by the MACsec port was to a plaintext packet.
1049+ * This violates the MACsec protocol standard.
1050+ */
10321051 if (ether_addr_equal_64bits (hdr -> h_dest ,
10331052 ndev -> dev_addr )) {
10341053 /* exact match, divert skb to this port */
@@ -1044,14 +1063,10 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
10441063 break ;
10451064
10461065 nskb -> dev = ndev ;
1047- if (ether_addr_equal_64bits (hdr -> h_dest ,
1048- ndev -> broadcast ))
1049- nskb -> pkt_type = PACKET_BROADCAST ;
1050- else
1051- nskb -> pkt_type = PACKET_MULTICAST ;
1066+ eth_skb_pkt_type (nskb , ndev );
10521067
10531068 __netif_rx (nskb );
1054- } else if (rx_sc || ndev -> flags & IFF_PROMISC ) {
1069+ } else if (ndev -> flags & IFF_PROMISC ) {
10551070 skb -> dev = ndev ;
10561071 skb -> pkt_type = PACKET_HOST ;
10571072 ret = RX_HANDLER_ANOTHER ;
@@ -1069,7 +1084,7 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
10691084 u64_stats_update_begin (& secy_stats -> syncp );
10701085 secy_stats -> stats .InPktsNoTag ++ ;
10711086 u64_stats_update_end (& secy_stats -> syncp );
1072- macsec -> secy .netdev -> stats . rx_dropped ++ ;
1087+ DEV_STATS_INC ( macsec -> secy .netdev , rx_dropped ) ;
10731088 continue ;
10741089 }
10751090
@@ -1179,7 +1194,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
11791194 u64_stats_update_begin (& secy_stats -> syncp );
11801195 secy_stats -> stats .InPktsBadTag ++ ;
11811196 u64_stats_update_end (& secy_stats -> syncp );
1182- secy -> netdev -> stats . rx_errors ++ ;
1197+ DEV_STATS_INC ( secy -> netdev , rx_errors ) ;
11831198 goto drop_nosa ;
11841199 }
11851200
@@ -1196,7 +1211,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
11961211 u64_stats_update_begin (& rxsc_stats -> syncp );
11971212 rxsc_stats -> stats .InPktsNotUsingSA ++ ;
11981213 u64_stats_update_end (& rxsc_stats -> syncp );
1199- secy -> netdev -> stats . rx_errors ++ ;
1214+ DEV_STATS_INC ( secy -> netdev , rx_errors ) ;
12001215 if (active_rx_sa )
12011216 this_cpu_inc (active_rx_sa -> stats -> InPktsNotUsingSA );
12021217 goto drop_nosa ;
@@ -1230,7 +1245,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
12301245 u64_stats_update_begin (& rxsc_stats -> syncp );
12311246 rxsc_stats -> stats .InPktsLate ++ ;
12321247 u64_stats_update_end (& rxsc_stats -> syncp );
1233- macsec -> secy .netdev -> stats . rx_dropped ++ ;
1248+ DEV_STATS_INC ( macsec -> secy .netdev , rx_dropped ) ;
12341249 goto drop ;
12351250 }
12361251 }
@@ -1271,7 +1286,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
12711286 if (ret == NET_RX_SUCCESS )
12721287 count_rx (dev , len );
12731288 else
1274- macsec -> secy .netdev -> stats . rx_dropped ++ ;
1289+ DEV_STATS_INC ( macsec -> secy .netdev , rx_dropped ) ;
12751290
12761291 rcu_read_unlock ();
12771292
@@ -1308,7 +1323,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
13081323 u64_stats_update_begin (& secy_stats -> syncp );
13091324 secy_stats -> stats .InPktsNoSCI ++ ;
13101325 u64_stats_update_end (& secy_stats -> syncp );
1311- macsec -> secy .netdev -> stats . rx_errors ++ ;
1326+ DEV_STATS_INC ( macsec -> secy .netdev , rx_errors ) ;
13121327 continue ;
13131328 }
13141329
@@ -1327,7 +1342,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
13271342 secy_stats -> stats .InPktsUnknownSCI ++ ;
13281343 u64_stats_update_end (& secy_stats -> syncp );
13291344 } else {
1330- macsec -> secy .netdev -> stats . rx_dropped ++ ;
1345+ DEV_STATS_INC ( macsec -> secy .netdev , rx_dropped ) ;
13311346 }
13321347 }
13331348
@@ -1673,7 +1688,6 @@ static int macsec_offload(int (* const func)(struct macsec_context *),
16731688 if (ctx -> offload == MACSEC_OFFLOAD_PHY )
16741689 mutex_lock (& ctx -> phydev -> lock );
16751690
1676- ctx -> prepare = false;
16771691 ret = (* func )(ctx );
16781692
16791693 if (ctx -> offload == MACSEC_OFFLOAD_PHY )
@@ -3424,15 +3438,15 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
34243438
34253439 if (!secy -> operational ) {
34263440 kfree_skb (skb );
3427- dev -> stats . tx_dropped ++ ;
3441+ DEV_STATS_INC ( dev , tx_dropped ) ;
34283442 return NETDEV_TX_OK ;
34293443 }
34303444
34313445 len = skb -> len ;
34323446 skb = macsec_encrypt (skb , dev );
34333447 if (IS_ERR (skb )) {
34343448 if (PTR_ERR (skb ) != - EINPROGRESS )
3435- dev -> stats . tx_dropped ++ ;
3449+ DEV_STATS_INC ( dev , tx_dropped ) ;
34363450 return NETDEV_TX_OK ;
34373451 }
34383452
@@ -3616,21 +3630,19 @@ static int macsec_set_mac_address(struct net_device *dev, void *p)
36163630 struct macsec_dev * macsec = macsec_priv (dev );
36173631 struct net_device * real_dev = macsec -> real_dev ;
36183632 struct sockaddr * addr = p ;
3633+ u8 old_addr [ETH_ALEN ];
36193634 int err ;
36203635
36213636 if (!is_valid_ether_addr (addr -> sa_data ))
36223637 return - EADDRNOTAVAIL ;
36233638
3624- if (!(dev -> flags & IFF_UP ))
3625- goto out ;
3626-
3627- err = dev_uc_add (real_dev , addr -> sa_data );
3628- if (err < 0 )
3629- return err ;
3630-
3631- dev_uc_del (real_dev , dev -> dev_addr );
3639+ if (dev -> flags & IFF_UP ) {
3640+ err = dev_uc_add (real_dev , addr -> sa_data );
3641+ if (err < 0 )
3642+ return err ;
3643+ }
36323644
3633- out :
3645+ ether_addr_copy ( old_addr , dev -> dev_addr );
36343646 eth_hw_addr_set (dev , addr -> sa_data );
36353647
36363648 /* If h/w offloading is available, propagate to the device */
@@ -3639,13 +3651,29 @@ static int macsec_set_mac_address(struct net_device *dev, void *p)
36393651 struct macsec_context ctx ;
36403652
36413653 ops = macsec_get_ops (macsec , & ctx );
3642- if (ops ) {
3643- ctx . secy = & macsec -> secy ;
3644- macsec_offload ( ops -> mdo_upd_secy , & ctx ) ;
3654+ if (! ops ) {
3655+ err = - EOPNOTSUPP ;
3656+ goto restore_old_addr ;
36453657 }
3658+
3659+ ctx .secy = & macsec -> secy ;
3660+ err = macsec_offload (ops -> mdo_upd_secy , & ctx );
3661+ if (err )
3662+ goto restore_old_addr ;
36463663 }
36473664
3665+ if (dev -> flags & IFF_UP )
3666+ dev_uc_del (real_dev , old_addr );
3667+
36483668 return 0 ;
3669+
3670+ restore_old_addr :
3671+ if (dev -> flags & IFF_UP )
3672+ dev_uc_del (real_dev , addr -> sa_data );
3673+
3674+ eth_hw_addr_set (dev , old_addr );
3675+
3676+ return err ;
36493677}
36503678
36513679static int macsec_change_mtu (struct net_device * dev , int new_mtu )
@@ -3669,9 +3697,9 @@ static void macsec_get_stats64(struct net_device *dev,
36693697
36703698 dev_fetch_sw_netstats (s , dev -> tstats );
36713699
3672- s -> rx_dropped = dev -> stats . rx_dropped ;
3673- s -> tx_dropped = dev -> stats . tx_dropped ;
3674- s -> rx_errors = dev -> stats . rx_errors ;
3700+ s -> rx_dropped = DEV_STATS_READ ( dev , rx_dropped ) ;
3701+ s -> tx_dropped = DEV_STATS_READ ( dev , tx_dropped ) ;
3702+ s -> rx_errors = DEV_STATS_READ ( dev , rx_errors ) ;
36753703}
36763704
36773705static int macsec_get_iflink (const struct net_device * dev )
0 commit comments