@@ -316,6 +316,7 @@ ZTEST(arp_fn_tests, test_arp)
316
316
struct net_eth_addr dst_lladdr ;
317
317
struct net_pkt * pkt ;
318
318
struct net_pkt * pkt2 ;
319
+ struct net_pkt * pkt_arp ;
319
320
struct net_if * iface ;
320
321
struct net_if_addr * ifaddr ;
321
322
struct net_arp_hdr * arp_hdr ;
@@ -367,25 +368,30 @@ ZTEST(arp_fn_tests, test_arp)
367
368
368
369
memcpy (net_buf_add (pkt -> buffer , len ), app_data , len );
369
370
370
- ret = net_arp_prepare (pkt , & dst , NULL , & pkt2 );
371
+ /* Duplicate packet */
372
+ pkt2 = net_pkt_clone (pkt , K_SECONDS (1 ));
373
+ zassert_not_null (pkt2 , "out of mem" );
374
+
375
+ /* First ARP request */
376
+ ret = net_arp_prepare (pkt , & dst , NULL , & pkt_arp );
371
377
372
378
zassert_equal (NET_ARP_PKT_REPLACED , ret );
373
379
374
- /* pkt2 is the ARP packet and pkt is the IPv4 packet and it was
380
+ /* pkt_arp is the ARP packet and pkt is the IPv4 packet and it was
375
381
* stored in ARP table.
376
382
*/
377
383
378
- zassert_equal (net_pkt_ll_proto_type (pkt2 ), NET_ETH_PTYPE_ARP ,
384
+ zassert_equal (net_pkt_ll_proto_type (pkt_arp ), NET_ETH_PTYPE_ARP ,
379
385
"ARP packet type is wrong" );
380
386
381
387
/**TESTPOINTS: Check packets*/
382
- zassert_not_equal ((void * )(pkt2 ), (void * )(pkt ),
388
+ zassert_not_equal ((void * )(pkt_arp ), (void * )(pkt ),
383
389
/* The packets cannot be the same as the ARP cache has
384
390
* still room for the pkt.
385
391
*/
386
392
"ARP cache should still have free space" );
387
393
388
- zassert_not_null (pkt2 , "ARP pkt is empty" );
394
+ zassert_not_null (pkt_arp , "ARP pkt is empty" );
389
395
390
396
/* The ARP cache should now have a link to pending net_pkt
391
397
* that is to be sent after we have got an ARP reply.
@@ -395,8 +401,8 @@ ZTEST(arp_fn_tests, test_arp)
395
401
396
402
pending_pkt = pkt ;
397
403
398
- /* pkt2 should contain the arp header, verify it */
399
- arp_hdr = NET_ARP_HDR (pkt2 );
404
+ /* pkt_arp should contain the arp header, verify it */
405
+ arp_hdr = NET_ARP_HDR (pkt_arp );
400
406
401
407
if (arp_hdr -> hwtype != htons (NET_ARP_HTYPE_ETH )) {
402
408
printk ("ARP hwtype 0x%x, should be 0x%x\n" ,
@@ -447,26 +453,41 @@ ZTEST(arp_fn_tests, test_arp)
447
453
/* We could have send the new ARP request but for this test we
448
454
* just free it.
449
455
*/
450
- net_pkt_unref (pkt2 );
456
+ net_pkt_unref (pkt_arp );
451
457
452
458
zassert_equal (atomic_get (& pkt -> atomic_ref ), 2 ,
453
459
"ARP cache should own the original packet" );
454
460
461
+
462
+ /* A second packet going to the same destination */
463
+ pkt_arp = NULL ;
464
+ ret = net_arp_prepare (pkt2 , & dst , NULL , & pkt_arp );
465
+
466
+ /* Packet should have been queued, not generating an ARP request */
467
+ zassert_equal (NET_ARP_PKT_QUEUED , ret );
468
+ zassert_is_null (pkt_arp , "ARP packet should not have been generated" );
469
+
470
+ zassert_equal (atomic_get (& pkt2 -> atomic_ref ), 2 ,
471
+ "ARP cache should own the original packet" );
472
+
473
+ /* Done with the duplicate packet */
474
+ net_pkt_unref (pkt2 );
475
+
455
476
/* Then a case where target is not in the same subnet */
456
477
net_ipv4_addr_copy_raw (ipv4 -> dst , (uint8_t * )& dst_far );
457
478
458
- ret = net_arp_prepare (pkt , & dst_far , NULL , & pkt2 );
479
+ ret = net_arp_prepare (pkt , & dst_far , NULL , & pkt_arp );
459
480
460
481
zassert_equal (NET_ARP_PKT_REPLACED , ret );
461
482
462
- zassert_not_equal ((void * )(pkt2 ), (void * )(pkt ),
483
+ zassert_not_equal ((void * )(pkt_arp ), (void * )(pkt ),
463
484
"ARP cache should not find anything" );
464
485
465
486
/**TESTPOINTS: Check if packets not empty*/
466
- zassert_not_null (pkt2 ,
467
- "ARP pkt2 is empty" );
487
+ zassert_not_null (pkt_arp ,
488
+ "ARP pkt_arp is empty" );
468
489
469
- arp_hdr = NET_ARP_HDR (pkt2 );
490
+ arp_hdr = NET_ARP_HDR (pkt_arp );
470
491
471
492
if (!net_ipv4_addr_cmp_raw (arp_hdr -> dst_ipaddr ,
472
493
(uint8_t * )& iface -> config .ip .ipv4 -> gw )) {
@@ -476,7 +497,7 @@ ZTEST(arp_fn_tests, test_arp)
476
497
zassert_true (0 , "exiting" );
477
498
}
478
499
479
- net_pkt_unref (pkt2 );
500
+ net_pkt_unref (pkt_arp );
480
501
481
502
/* Try to find the same destination again, this should fail as there
482
503
* is a pending request in ARP cache.
@@ -488,14 +509,23 @@ ZTEST(arp_fn_tests, test_arp)
488
509
*/
489
510
net_pkt_ref (pkt );
490
511
491
- ret = net_arp_prepare (pkt , & dst_far , NULL , & pkt2 );
512
+ ret = net_arp_prepare (pkt , & dst_far , NULL , & pkt_arp );
492
513
493
514
zassert_equal (NET_ARP_PKT_REPLACED , ret );
494
515
495
- zassert_not_null (pkt2 ,
516
+ zassert_not_null (pkt_arp ,
496
517
"ARP cache is not sending the request again" );
497
518
498
- net_pkt_unref (pkt2 );
519
+ net_pkt_unref (pkt_arp );
520
+
521
+ ret = net_arp_prepare (pkt , & dst_far , NULL , & pkt_arp );
522
+
523
+ zassert_equal (NET_ARP_PKT_REPLACED , ret );
524
+
525
+ zassert_not_null (pkt_arp ,
526
+ "ARP cache is not sending the request again" );
527
+
528
+ net_pkt_unref (pkt_arp );
499
529
500
530
/* Try to find the different destination, this should fail too
501
531
* as the cache table should be full.
@@ -507,11 +537,11 @@ ZTEST(arp_fn_tests, test_arp)
507
537
*/
508
538
net_pkt_ref (pkt );
509
539
510
- ret = net_arp_prepare (pkt , & dst_far2 , NULL , & pkt2 );
540
+ ret = net_arp_prepare (pkt , & dst_far2 , NULL , & pkt_arp );
511
541
512
542
zassert_equal (NET_ARP_PKT_REPLACED , ret );
513
543
514
- zassert_not_null (pkt2 ,
544
+ zassert_not_null (pkt_arp ,
515
545
"ARP cache did not send a req" );
516
546
517
547
/* Restore the original address so that following test case can
@@ -535,13 +565,13 @@ ZTEST(arp_fn_tests, test_arp)
535
565
536
566
net_pkt_set_ll_proto_type (pkt , NET_ETH_PTYPE_ARP );
537
567
538
- pkt2 = prepare_arp_reply (iface , pkt , & eth_hwaddr , & eth_hdr );
568
+ pkt_arp = prepare_arp_reply (iface , pkt , & eth_hwaddr , & eth_hdr );
539
569
540
- zassert_not_null (pkt2 , "ARP reply generation failed." );
570
+ zassert_not_null (pkt_arp , "ARP reply generation failed." );
541
571
542
572
/* The pending packet should now be sent */
543
- switch (net_arp_input (pkt2 ,
544
- (struct net_eth_addr * )net_pkt_lladdr_src (pkt2 )-> addr ,
573
+ switch (net_arp_input (pkt_arp ,
574
+ (struct net_eth_addr * )net_pkt_lladdr_src (pkt_arp )-> addr ,
545
575
& dst_lladdr )) {
546
576
case NET_OK :
547
577
case NET_CONTINUE :
@@ -580,15 +610,15 @@ ZTEST(arp_fn_tests, test_arp)
580
610
581
611
net_pkt_set_ll_proto_type (pkt , NET_ETH_PTYPE_ARP );
582
612
583
- pkt2 = prepare_arp_request (iface , pkt , & eth_hwaddr , & eth_hdr );
613
+ pkt_arp = prepare_arp_request (iface , pkt , & eth_hwaddr , & eth_hdr );
584
614
585
615
/**TESTPOINT: Check if ARP request generation failed*/
586
- zassert_not_null (pkt2 , "ARP request generation failed." );
616
+ zassert_not_null (pkt_arp , "ARP request generation failed." );
587
617
588
618
req_test = true;
589
619
590
- switch (net_arp_input (pkt2 ,
591
- (struct net_eth_addr * )net_pkt_lladdr_src (pkt2 )-> addr ,
620
+ switch (net_arp_input (pkt_arp ,
621
+ (struct net_eth_addr * )net_pkt_lladdr_src (pkt_arp )-> addr ,
592
622
& dst_lladdr )) {
593
623
case NET_OK :
594
624
case NET_CONTINUE :
0 commit comments