@ -258,3 +258,89 @@ static int dm_test_net_retry(struct unit_test_state *uts)
return retval ;
}
DM_TEST ( dm_test_net_retry , DM_TESTF_SCAN_FDT ) ;
static int sb_check_arp_reply ( struct udevice * dev , void * packet ,
unsigned int len )
{
struct eth_sandbox_priv * priv = dev_get_priv ( dev ) ;
struct ethernet_hdr * eth = packet ;
struct arp_hdr * arp ;
/* Used by all of the ut_assert macros */
struct unit_test_state * uts = priv - > priv ;
if ( ntohs ( eth - > et_protlen ) ! = PROT_ARP )
return 0 ;
arp = packet + ETHER_HDR_SIZE ;
if ( ntohs ( arp - > ar_op ) ! = ARPOP_REPLY )
return 0 ;
/* This test would be worthless if we are not waiting */
ut_assert ( arp_is_waiting ( ) ) ;
/* Validate response */
ut_assert ( memcmp ( eth - > et_src , net_ethaddr , ARP_HLEN ) = = 0 ) ;
ut_assert ( memcmp ( eth - > et_dest , priv - > fake_host_hwaddr , ARP_HLEN ) = = 0 ) ;
ut_assert ( eth - > et_protlen = = htons ( PROT_ARP ) ) ;
ut_assert ( arp - > ar_hrd = = htons ( ARP_ETHER ) ) ;
ut_assert ( arp - > ar_pro = = htons ( PROT_IP ) ) ;
ut_assert ( arp - > ar_hln = = ARP_HLEN ) ;
ut_assert ( arp - > ar_pln = = ARP_PLEN ) ;
ut_assert ( memcmp ( & arp - > ar_sha , net_ethaddr , ARP_HLEN ) = = 0 ) ;
ut_assert ( net_read_ip ( & arp - > ar_spa ) . s_addr = = net_ip . s_addr ) ;
ut_assert ( memcmp ( & arp - > ar_tha , priv - > fake_host_hwaddr , ARP_HLEN ) = = 0 ) ;
ut_assert ( net_read_ip ( & arp - > ar_tpa ) . s_addr = =
string_to_ip ( " 1.1.2.4 " ) . s_addr ) ;
return 0 ;
}
static int sb_with_async_arp_handler ( struct udevice * dev , void * packet ,
unsigned int len )
{
struct eth_sandbox_priv * priv = dev_get_priv ( dev ) ;
struct ethernet_hdr * eth = packet ;
struct arp_hdr * arp = packet + ETHER_HDR_SIZE ;
int ret ;
/*
* If we are about to generate a reply to ARP , first inject a request
* from another host
*/
if ( ntohs ( eth - > et_protlen ) = = PROT_ARP & &
ntohs ( arp - > ar_op ) = = ARPOP_REQUEST ) {
/* Make sure sandbox_eth_recv_arp_req() knows who is asking */
priv - > fake_host_ipaddr = string_to_ip ( " 1.1.2.4 " ) ;
ret = sandbox_eth_recv_arp_req ( dev ) ;
if ( ret )
return ret ;
}
sandbox_eth_arp_req_to_reply ( dev , packet , len ) ;
sandbox_eth_ping_req_to_reply ( dev , packet , len ) ;
return sb_check_arp_reply ( dev , packet , len ) ;
}
static int dm_test_eth_async_arp_reply ( struct unit_test_state * uts )
{
net_ping_ip = string_to_ip ( " 1.1.2.2 " ) ;
sandbox_eth_set_tx_handler ( 0 , sb_with_async_arp_handler ) ;
/* Used by all of the ut_assert macros in the tx_handler */
sandbox_eth_set_priv ( 0 , uts ) ;
sandbox_eth_skip_timeout ( ) ;
env_set ( " ethact " , " eth@10002000 " ) ;
ut_assert ( net_loop ( PING ) = = - ETIMEDOUT ) ;
ut_asserteq_str ( " eth@10002000 " , env_get ( " ethact " ) ) ;
sandbox_eth_set_tx_handler ( 0 , NULL ) ;
return 0 ;
}
DM_TEST ( dm_test_eth_async_arp_reply , DM_TESTF_SCAN_FDT ) ;