@@ -921,6 +921,114 @@ static void mctp_test_route_input_sk_fail_frag(struct kunit *test)
921
921
__mctp_route_test_fini (test , dev , rt , sock );
922
922
}
923
923
924
+ /* Input route to socket, using a fragmented message created from clones.
925
+ */
926
+ static void mctp_test_route_input_cloned_frag (struct kunit * test )
927
+ {
928
+ /* 5 packet fragments, forming 2 complete messages */
929
+ const struct mctp_hdr hdrs [5 ] = {
930
+ RX_FRAG (FL_S , 0 ),
931
+ RX_FRAG (0 , 1 ),
932
+ RX_FRAG (FL_E , 2 ),
933
+ RX_FRAG (FL_S , 0 ),
934
+ RX_FRAG (FL_E , 1 ),
935
+ };
936
+ struct mctp_test_route * rt ;
937
+ struct mctp_test_dev * dev ;
938
+ struct sk_buff * skb [5 ];
939
+ struct sk_buff * rx_skb ;
940
+ struct socket * sock ;
941
+ size_t data_len ;
942
+ u8 compare [100 ];
943
+ u8 flat [100 ];
944
+ size_t total ;
945
+ void * p ;
946
+ int rc ;
947
+
948
+ /* Arbitrary length */
949
+ data_len = 3 ;
950
+ total = data_len + sizeof (struct mctp_hdr );
951
+
952
+ __mctp_route_test_init (test , & dev , & rt , & sock , MCTP_NET_ANY );
953
+
954
+ /* Create a single skb initially with concatenated packets */
955
+ skb [0 ] = mctp_test_create_skb (& hdrs [0 ], 5 * total );
956
+ mctp_test_skb_set_dev (skb [0 ], dev );
957
+ memset (skb [0 ]-> data , 0 * 0x11 , skb [0 ]-> len );
958
+ memcpy (skb [0 ]-> data , & hdrs [0 ], sizeof (struct mctp_hdr ));
959
+
960
+ /* Extract and populate packets */
961
+ for (int i = 1 ; i < 5 ; i ++ ) {
962
+ skb [i ] = skb_clone (skb [i - 1 ], GFP_ATOMIC );
963
+ KUNIT_ASSERT_TRUE (test , skb [i ]);
964
+ p = skb_pull (skb [i ], total );
965
+ KUNIT_ASSERT_TRUE (test , p );
966
+ skb_reset_network_header (skb [i ]);
967
+ memcpy (skb [i ]-> data , & hdrs [i ], sizeof (struct mctp_hdr ));
968
+ memset (& skb [i ]-> data [sizeof (struct mctp_hdr )], i * 0x11 , data_len );
969
+ }
970
+ for (int i = 0 ; i < 5 ; i ++ )
971
+ skb_trim (skb [i ], total );
972
+
973
+ /* SOM packets have a type byte to match the socket */
974
+ skb [0 ]-> data [4 ] = 0 ;
975
+ skb [3 ]-> data [4 ] = 0 ;
976
+
977
+ skb_dump ("pkt1 " , skb [0 ], false);
978
+ skb_dump ("pkt2 " , skb [1 ], false);
979
+ skb_dump ("pkt3 " , skb [2 ], false);
980
+ skb_dump ("pkt4 " , skb [3 ], false);
981
+ skb_dump ("pkt5 " , skb [4 ], false);
982
+
983
+ for (int i = 0 ; i < 5 ; i ++ ) {
984
+ KUNIT_EXPECT_EQ (test , refcount_read (& skb [i ]-> users ), 1 );
985
+ /* Take a reference so we can check refcounts at the end */
986
+ skb_get (skb [i ]);
987
+ }
988
+
989
+ /* Feed the fragments into MCTP core */
990
+ for (int i = 0 ; i < 5 ; i ++ ) {
991
+ rc = mctp_route_input (& rt -> rt , skb [i ]);
992
+ KUNIT_EXPECT_EQ (test , rc , 0 );
993
+ }
994
+
995
+ /* Receive first reassembled message */
996
+ rx_skb = skb_recv_datagram (sock -> sk , MSG_DONTWAIT , & rc );
997
+ KUNIT_EXPECT_EQ (test , rc , 0 );
998
+ KUNIT_EXPECT_EQ (test , rx_skb -> len , 3 * data_len );
999
+ rc = skb_copy_bits (rx_skb , 0 , flat , rx_skb -> len );
1000
+ for (int i = 0 ; i < rx_skb -> len ; i ++ )
1001
+ compare [i ] = (i / data_len ) * 0x11 ;
1002
+ /* Set type byte */
1003
+ compare [0 ] = 0 ;
1004
+
1005
+ KUNIT_EXPECT_MEMEQ (test , flat , compare , rx_skb -> len );
1006
+ KUNIT_EXPECT_EQ (test , refcount_read (& rx_skb -> users ), 1 );
1007
+ kfree_skb (rx_skb );
1008
+
1009
+ /* Receive second reassembled message */
1010
+ rx_skb = skb_recv_datagram (sock -> sk , MSG_DONTWAIT , & rc );
1011
+ KUNIT_EXPECT_EQ (test , rc , 0 );
1012
+ KUNIT_EXPECT_EQ (test , rx_skb -> len , 2 * data_len );
1013
+ rc = skb_copy_bits (rx_skb , 0 , flat , rx_skb -> len );
1014
+ for (int i = 0 ; i < rx_skb -> len ; i ++ )
1015
+ compare [i ] = (i / data_len + 3 ) * 0x11 ;
1016
+ /* Set type byte */
1017
+ compare [0 ] = 0 ;
1018
+
1019
+ KUNIT_EXPECT_MEMEQ (test , flat , compare , rx_skb -> len );
1020
+ KUNIT_EXPECT_EQ (test , refcount_read (& rx_skb -> users ), 1 );
1021
+ kfree_skb (rx_skb );
1022
+
1023
+ /* Check input skb refcounts */
1024
+ for (int i = 0 ; i < 5 ; i ++ ) {
1025
+ KUNIT_EXPECT_EQ (test , refcount_read (& skb [i ]-> users ), 1 );
1026
+ kfree_skb (skb [i ]);
1027
+ }
1028
+
1029
+ __mctp_route_test_fini (test , dev , rt , sock );
1030
+ }
1031
+
924
1032
#if IS_ENABLED (CONFIG_MCTP_FLOWS )
925
1033
926
1034
static void mctp_test_flow_init (struct kunit * test ,
@@ -1144,6 +1252,7 @@ static struct kunit_case mctp_test_cases[] = {
1144
1252
KUNIT_CASE (mctp_test_packet_flow ),
1145
1253
KUNIT_CASE (mctp_test_fragment_flow ),
1146
1254
KUNIT_CASE (mctp_test_route_output_key_create ),
1255
+ KUNIT_CASE (mctp_test_route_input_cloned_frag ),
1147
1256
{}
1148
1257
};
1149
1258
0 commit comments