@@ -905,20 +905,33 @@ static struct sk_buff *j1939_sk_alloc_skb(struct net_device *ndev,
905905 return NULL ;
906906}
907907
908- static size_t j1939_sk_opt_stats_get_size (void )
908+ static size_t j1939_sk_opt_stats_get_size (enum j1939_sk_errqueue_type type )
909909{
910- return
911- nla_total_size (sizeof (u32 )) + /* J1939_NLA_BYTES_ACKED */
912- 0 ;
910+ switch (type ) {
911+ case J1939_ERRQUEUE_RX_RTS :
912+ return
913+ nla_total_size (sizeof (u32 )) + /* J1939_NLA_TOTAL_SIZE */
914+ nla_total_size (sizeof (u32 )) + /* J1939_NLA_PGN */
915+ nla_total_size (sizeof (u64 )) + /* J1939_NLA_SRC_NAME */
916+ nla_total_size (sizeof (u64 )) + /* J1939_NLA_DEST_NAME */
917+ nla_total_size (sizeof (u8 )) + /* J1939_NLA_SRC_ADDR */
918+ nla_total_size (sizeof (u8 )) + /* J1939_NLA_DEST_ADDR */
919+ 0 ;
920+ default :
921+ return
922+ nla_total_size (sizeof (u32 )) + /* J1939_NLA_BYTES_ACKED */
923+ 0 ;
924+ }
913925}
914926
915927static struct sk_buff *
916- j1939_sk_get_timestamping_opt_stats (struct j1939_session * session )
928+ j1939_sk_get_timestamping_opt_stats (struct j1939_session * session ,
929+ enum j1939_sk_errqueue_type type )
917930{
918931 struct sk_buff * stats ;
919932 u32 size ;
920933
921- stats = alloc_skb (j1939_sk_opt_stats_get_size (), GFP_ATOMIC );
934+ stats = alloc_skb (j1939_sk_opt_stats_get_size (type ), GFP_ATOMIC );
922935 if (!stats )
923936 return NULL ;
924937
@@ -928,32 +941,67 @@ j1939_sk_get_timestamping_opt_stats(struct j1939_session *session)
928941 size = min (session -> pkt .tx_acked * 7 ,
929942 session -> total_message_size );
930943
931- nla_put_u32 (stats , J1939_NLA_BYTES_ACKED , size );
944+ switch (type ) {
945+ case J1939_ERRQUEUE_RX_RTS :
946+ nla_put_u32 (stats , J1939_NLA_TOTAL_SIZE ,
947+ session -> total_message_size );
948+ nla_put_u32 (stats , J1939_NLA_PGN ,
949+ session -> skcb .addr .pgn );
950+ nla_put_u64_64bit (stats , J1939_NLA_SRC_NAME ,
951+ session -> skcb .addr .src_name , J1939_NLA_PAD );
952+ nla_put_u64_64bit (stats , J1939_NLA_DEST_NAME ,
953+ session -> skcb .addr .dst_name , J1939_NLA_PAD );
954+ nla_put_u8 (stats , J1939_NLA_SRC_ADDR ,
955+ session -> skcb .addr .sa );
956+ nla_put_u8 (stats , J1939_NLA_DEST_ADDR ,
957+ session -> skcb .addr .da );
958+ break ;
959+ default :
960+ nla_put_u32 (stats , J1939_NLA_BYTES_ACKED , size );
961+ }
932962
933963 return stats ;
934964}
935965
936- void j1939_sk_errqueue (struct j1939_session * session ,
937- enum j1939_sk_errqueue_type type )
966+ static void __j1939_sk_errqueue (struct j1939_session * session , struct sock * sk ,
967+ enum j1939_sk_errqueue_type type )
938968{
939969 struct j1939_priv * priv = session -> priv ;
940- struct sock * sk = session -> sk ;
941970 struct j1939_sock * jsk ;
942971 struct sock_exterr_skb * serr ;
943972 struct sk_buff * skb ;
944973 char * state = "UNK" ;
945974 int err ;
946975
947- /* currently we have no sk for the RX session */
948- if (!sk )
949- return ;
950-
951976 jsk = j1939_sk (sk );
952977
953978 if (!(jsk -> state & J1939_SOCK_ERRQUEUE ))
954979 return ;
955980
956- skb = j1939_sk_get_timestamping_opt_stats (session );
981+ switch (type ) {
982+ case J1939_ERRQUEUE_TX_ACK :
983+ if (!(sk -> sk_tsflags & SOF_TIMESTAMPING_TX_ACK ))
984+ return ;
985+ break ;
986+ case J1939_ERRQUEUE_TX_SCHED :
987+ if (!(sk -> sk_tsflags & SOF_TIMESTAMPING_TX_SCHED ))
988+ return ;
989+ break ;
990+ case J1939_ERRQUEUE_TX_ABORT :
991+ break ;
992+ case J1939_ERRQUEUE_RX_RTS :
993+ fallthrough ;
994+ case J1939_ERRQUEUE_RX_DPO :
995+ fallthrough ;
996+ case J1939_ERRQUEUE_RX_ABORT :
997+ if (!(sk -> sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ))
998+ return ;
999+ break ;
1000+ default :
1001+ netdev_err (priv -> ndev , "Unknown errqueue type %i\n" , type );
1002+ }
1003+
1004+ skb = j1939_sk_get_timestamping_opt_stats (session , type );
9571005 if (!skb )
9581006 return ;
9591007
@@ -964,36 +1012,42 @@ void j1939_sk_errqueue(struct j1939_session *session,
9641012 serr = SKB_EXT_ERR (skb );
9651013 memset (serr , 0 , sizeof (* serr ));
9661014 switch (type ) {
967- case J1939_ERRQUEUE_ACK :
968- if (!(sk -> sk_tsflags & SOF_TIMESTAMPING_TX_ACK )) {
969- kfree_skb (skb );
970- return ;
971- }
972-
1015+ case J1939_ERRQUEUE_TX_ACK :
9731016 serr -> ee .ee_errno = ENOMSG ;
9741017 serr -> ee .ee_origin = SO_EE_ORIGIN_TIMESTAMPING ;
9751018 serr -> ee .ee_info = SCM_TSTAMP_ACK ;
976- state = "ACK" ;
1019+ state = "TX ACK" ;
9771020 break ;
978- case J1939_ERRQUEUE_SCHED :
979- if (!(sk -> sk_tsflags & SOF_TIMESTAMPING_TX_SCHED )) {
980- kfree_skb (skb );
981- return ;
982- }
983-
1021+ case J1939_ERRQUEUE_TX_SCHED :
9841022 serr -> ee .ee_errno = ENOMSG ;
9851023 serr -> ee .ee_origin = SO_EE_ORIGIN_TIMESTAMPING ;
9861024 serr -> ee .ee_info = SCM_TSTAMP_SCHED ;
987- state = "SCH" ;
1025+ state = "TX SCH" ;
9881026 break ;
989- case J1939_ERRQUEUE_ABORT :
1027+ case J1939_ERRQUEUE_TX_ABORT :
9901028 serr -> ee .ee_errno = session -> err ;
9911029 serr -> ee .ee_origin = SO_EE_ORIGIN_LOCAL ;
9921030 serr -> ee .ee_info = J1939_EE_INFO_TX_ABORT ;
993- state = "ABT" ;
1031+ state = "TX ABT" ;
1032+ break ;
1033+ case J1939_ERRQUEUE_RX_RTS :
1034+ serr -> ee .ee_errno = ENOMSG ;
1035+ serr -> ee .ee_origin = SO_EE_ORIGIN_LOCAL ;
1036+ serr -> ee .ee_info = J1939_EE_INFO_RX_RTS ;
1037+ state = "RX RTS" ;
1038+ break ;
1039+ case J1939_ERRQUEUE_RX_DPO :
1040+ serr -> ee .ee_errno = ENOMSG ;
1041+ serr -> ee .ee_origin = SO_EE_ORIGIN_LOCAL ;
1042+ serr -> ee .ee_info = J1939_EE_INFO_RX_DPO ;
1043+ state = "RX DPO" ;
1044+ break ;
1045+ case J1939_ERRQUEUE_RX_ABORT :
1046+ serr -> ee .ee_errno = session -> err ;
1047+ serr -> ee .ee_origin = SO_EE_ORIGIN_LOCAL ;
1048+ serr -> ee .ee_info = J1939_EE_INFO_RX_ABORT ;
1049+ state = "RX ABT" ;
9941050 break ;
995- default :
996- netdev_err (priv -> ndev , "Unknown errqueue type %i\n" , type );
9971051 }
9981052
9991053 serr -> opt_stats = true;
@@ -1008,6 +1062,27 @@ void j1939_sk_errqueue(struct j1939_session *session,
10081062 kfree_skb (skb );
10091063};
10101064
1065+ void j1939_sk_errqueue (struct j1939_session * session ,
1066+ enum j1939_sk_errqueue_type type )
1067+ {
1068+ struct j1939_priv * priv = session -> priv ;
1069+ struct j1939_sock * jsk ;
1070+
1071+ if (session -> sk ) {
1072+ /* send TX notifications to the socket of origin */
1073+ __j1939_sk_errqueue (session , session -> sk , type );
1074+ return ;
1075+ }
1076+
1077+ /* spread RX notifications to all sockets subscribed to this session */
1078+ spin_lock_bh (& priv -> j1939_socks_lock );
1079+ list_for_each_entry (jsk , & priv -> j1939_socks , list ) {
1080+ if (j1939_sk_recv_match_one (jsk , & session -> skcb ))
1081+ __j1939_sk_errqueue (session , & jsk -> sk , type );
1082+ }
1083+ spin_unlock_bh (& priv -> j1939_socks_lock );
1084+ };
1085+
10111086void j1939_sk_send_loop_abort (struct sock * sk , int err )
10121087{
10131088 sk -> sk_err = err ;
0 commit comments