@@ -5076,6 +5076,133 @@ START_TEST(test_regression_loopback_udp_tx_backpressure_retries_after_queue_drai
50765076}
50775077END_TEST
50785078
5079+ START_TEST (test_regression_ll_send_frame_returns_wolfip_error_codes )
5080+ {
5081+ struct wolfIP s ;
5082+ struct wolfIP_ll_dev * ll ;
5083+ uint8_t frame [ETH_HEADER_LEN + IP_HEADER_LEN + TCP_HEADER_LEN ] = {0 };
5084+
5085+ wolfIP_init (& s );
5086+ mock_link_init (& s );
5087+ ll = wolfIP_getdev_ex (& s , TEST_PRIMARY_IF );
5088+ ck_assert_ptr_nonnull (ll );
5089+
5090+ ck_assert_int_eq (
5091+ wolfIP_ll_send_frame (NULL , TEST_PRIMARY_IF , frame , sizeof (frame )),
5092+ - WOLFIP_EINVAL );
5093+ ck_assert_int_eq (
5094+ wolfIP_ll_send_frame (& s , WOLFIP_MAX_INTERFACES , frame , sizeof (frame )),
5095+ - WOLFIP_EINVAL );
5096+
5097+ ll -> send = NULL ;
5098+ ck_assert_int_eq (
5099+ wolfIP_ll_send_frame (& s , TEST_PRIMARY_IF , frame , sizeof (frame )),
5100+ - WOLFIP_EINVAL );
5101+
5102+ ll -> send = mock_send ;
5103+ ck_assert_int_eq (
5104+ wolfIP_ll_send_frame (& s , TEST_PRIMARY_IF , frame , LINK_MTU + 1U ),
5105+ - WOLFIP_EINVAL );
5106+
5107+ ll -> non_ethernet = 1 ;
5108+ ck_assert_int_eq (
5109+ wolfIP_ll_send_frame (& s , TEST_PRIMARY_IF , frame , ETH_HEADER_LEN ),
5110+ - WOLFIP_EINVAL );
5111+ }
5112+ END_TEST
5113+
5114+ START_TEST (test_regression_loopback_ack_retry_pending_requeued_on_poll )
5115+ {
5116+ struct wolfIP s ;
5117+ struct tsocket * ts ;
5118+ struct wolfIP_ll_dev * loop ;
5119+ uint8_t frame [16 ] = {0 };
5120+ uint8_t rx [IP_MTU_MAX ];
5121+ unsigned int i ;
5122+ uint64_t now = 300 ;
5123+
5124+ wolfIP_init (& s );
5125+ loop = wolfIP_getdev_ex (& s , TEST_LOOPBACK_IF );
5126+ ck_assert_ptr_nonnull (loop );
5127+
5128+ for (i = 0 ; i < WOLFIP_LOOPBACK_QUEUE_DEPTH ; i ++ ) {
5129+ ck_assert_int_eq (wolfIP_loopback_send (loop , frame , sizeof (frame )),
5130+ (int )sizeof (frame ));
5131+ }
5132+
5133+ ts = & s .tcpsockets [0 ];
5134+ memset (ts , 0 , sizeof (* ts ));
5135+ ts -> proto = WI_IPPROTO_TCP ;
5136+ ts -> S = & s ;
5137+ ts -> if_idx = TEST_LOOPBACK_IF ;
5138+ ts -> sock .tcp .state = TCP_ESTABLISHED ;
5139+ ts -> sock .tcp .ack = 100 ;
5140+ ts -> sock .tcp .seq = 1000 ;
5141+ ts -> src_port = 1234 ;
5142+ ts -> dst_port = 4321 ;
5143+ ts -> local_ip = 0x7F000001U ;
5144+ ts -> remote_ip = 0x7F000001U ;
5145+
5146+ tcp_send_ack (ts );
5147+ ck_assert_uint_eq (ts -> sock .tcp .ack_retry_pending , 1U );
5148+
5149+ ck_assert_int_gt (loop -> poll (loop , rx , sizeof (rx )), 0 );
5150+
5151+ loop -> poll = mock_poll ;
5152+ (void )wolfIP_poll (& s , now );
5153+
5154+ ck_assert_uint_eq (ts -> sock .tcp .ack_retry_pending , 0U );
5155+ ck_assert_uint_eq (s .loopback_count , WOLFIP_LOOPBACK_QUEUE_DEPTH );
5156+ }
5157+ END_TEST
5158+
5159+ START_TEST (test_regression_loopback_queue_full_pure_ack_backpressure_retry )
5160+ {
5161+ struct wolfIP s ;
5162+ struct tsocket * ts ;
5163+ struct wolfIP_ll_dev * loop ;
5164+ uint8_t frame [16 ] = {0 };
5165+ uint8_t rx [IP_MTU_MAX ];
5166+ unsigned int i ;
5167+ uint64_t now = 350 ;
5168+
5169+ wolfIP_init (& s );
5170+ loop = wolfIP_getdev_ex (& s , TEST_LOOPBACK_IF );
5171+ ck_assert_ptr_nonnull (loop );
5172+
5173+ for (i = 0 ; i < WOLFIP_LOOPBACK_QUEUE_DEPTH ; i ++ ) {
5174+ ck_assert_int_eq (wolfIP_loopback_send (loop , frame , sizeof (frame )),
5175+ (int )sizeof (frame ));
5176+ }
5177+
5178+ ts = & s .tcpsockets [1 ];
5179+ memset (ts , 0 , sizeof (* ts ));
5180+ ts -> proto = WI_IPPROTO_TCP ;
5181+ ts -> S = & s ;
5182+ ts -> if_idx = TEST_LOOPBACK_IF ;
5183+ ts -> sock .tcp .state = TCP_ESTABLISHED ;
5184+ ts -> sock .tcp .ack = 200 ;
5185+ ts -> sock .tcp .seq = 300 ;
5186+ ts -> src_port = 5000 ;
5187+ ts -> dst_port = 5001 ;
5188+ ts -> local_ip = 0x7F000001U ;
5189+ ts -> remote_ip = 0x7F000001U ;
5190+
5191+ /* Queue full -> pure ACK send must backpressure and mark retry pending. */
5192+ tcp_send_ack (ts );
5193+ ck_assert_uint_eq (ts -> sock .tcp .ack_retry_pending , 1U );
5194+ ck_assert_uint_eq (s .loopback_count , WOLFIP_LOOPBACK_QUEUE_DEPTH );
5195+
5196+ /* Free one slot, then poll should retry and enqueue the pending ACK. */
5197+ ck_assert_int_gt (loop -> poll (loop , rx , sizeof (rx )), 0 );
5198+ loop -> poll = mock_poll ;
5199+ (void )wolfIP_poll (& s , now );
5200+
5201+ ck_assert_uint_eq (ts -> sock .tcp .ack_retry_pending , 0U );
5202+ ck_assert_uint_eq (s .loopback_count , WOLFIP_LOOPBACK_QUEUE_DEPTH );
5203+ }
5204+ END_TEST
5205+
50795206START_TEST (test_regression_tcp_tx_desc_payload_len_keeps_descriptor_layout_sanity )
50805207{
50815208 struct wolfIP s ;
0 commit comments