@@ -396,3 +396,359 @@ def test_VlanMgrdPortSyncdWarmRestart(dvs):
396
396
# To clean up test env.
397
397
dvs .runcmd ("redis-cli flushall" )
398
398
399
+
400
+ # function to check the restart counter
401
+ def check_restart_cnt (warmtbl , restart_cnt ):
402
+ keys = warmtbl .getKeys ()
403
+ print (keys )
404
+ for key in keys :
405
+ (status , fvs ) = warmtbl .get (key )
406
+ assert status == True
407
+ for fv in fvs :
408
+ if fv [0 ] == "restart_count" :
409
+ assert fv [1 ] == str (restart_cnt )
410
+ elif fv [0 ] == "state_restored" :
411
+ assert fv [1 ] == "true"
412
+
413
+
414
+ # function to stop swss service and clear syslog and sairedis records
415
+ def stop_swss_clear_syslog_sairedis (dvs , save_number ):
416
+ dvs .runcmd ("/usr/bin/stop_swss.sh" )
417
+ time .sleep (3 )
418
+ dvs .runcmd ("mv /var/log/swss/sairedis.rec /var/log/swss/sairedis.rec.back1" )
419
+ dvs .runcmd ("cp /var/log/syslog /var/log/syslog.back{}" .format (save_number ))
420
+ dvs .runcmd (['sh' , '-c' , '> /var/log/syslog' ])
421
+
422
+
423
+ # function to check neighbor entry reconciliation status written in syslog
424
+ def check_syslog_for_neighbor_entry (dvs , new_cnt , delete_cnt , iptype ):
425
+ # check reconciliation results (new or delete entries) for ipv4 and ipv6
426
+ if iptype == "ipv4" :
427
+ num = dvs .runcmd (['sh' , '-c' , 'grep neighsyncd /var/log/syslog| grep cache-state:NEW | grep IPv4 | wc -l' ])
428
+ assert num .strip () == str (new_cnt )
429
+ num = dvs .runcmd (['sh' , '-c' , 'grep neighsyncd /var/log/syslog| grep cache-state:DELETE | grep IPv4 | wc -l' ])
430
+ assert num .strip () == str (delete_cnt )
431
+ elif iptype == "ipv6" :
432
+ num = dvs .runcmd (['sh' , '-c' , 'grep neighsyncd /var/log/syslog| grep cache-state:NEW | grep IPv6 | wc -l' ])
433
+ assert num .strip () == str (new_cnt )
434
+ num = dvs .runcmd (['sh' , '-c' , 'grep neighsyncd /var/log/syslog| grep cache-state:DELETE | grep IPv6 | wc -l' ])
435
+ assert num .strip () == str (delete_cnt )
436
+ else :
437
+ assert "iptype is unknown" == ""
438
+
439
+
440
+ # function to check sairedis record for neighbor entries
441
+ def check_sairedis_for_neighbor_entry (dvs , create_cnt , set_cnt , remove_cnt ):
442
+ # check create/set/remove operations for neighbor entries during warm restart
443
+ num = dvs .runcmd (['sh' , '-c' , 'grep \|c\| /var/log/swss/sairedis.rec | grep NEIGHBOR_ENTRY | wc -l' ])
444
+ assert num .strip () == str (create_cnt )
445
+ num = dvs .runcmd (['sh' , '-c' , 'grep \|s\| /var/log/swss/sairedis.rec | grep NEIGHBOR_ENTRY | wc -l' ])
446
+ assert num .strip () == str (set_cnt )
447
+ num = dvs .runcmd (['sh' , '-c' , 'grep \|r\| /var/log/swss/sairedis.rec | grep NEIGHBOR_ENTRY | wc -l' ])
448
+ assert num .strip () == str (remove_cnt )
449
+
450
+
451
+ def test_swss_neighbor_syncup (dvs ):
452
+ # syncd warm start with temp view not supported yet
453
+ if dvs .tmpview == True :
454
+ return
455
+
456
+ # previous warm restart cnt
457
+ restart_cnt = 4
458
+
459
+ # Prepare neighbor entry before swss stop
460
+ appl_db = swsscommon .DBConnector (swsscommon .APPL_DB , dvs .redis_sock , 0 )
461
+ asic_db = swsscommon .DBConnector (swsscommon .ASIC_DB , dvs .redis_sock , 0 )
462
+ conf_db = swsscommon .DBConnector (swsscommon .CONFIG_DB , dvs .redis_sock , 0 )
463
+
464
+ #
465
+ # Testcase1:
466
+ # Add neighbor entries in linux kernel, appDB should get all of them
467
+ #
468
+
469
+ # create neighbor entries (4 ipv4 and 4 ip6, two each on each interface) in linux kernel
470
+ intfs = ["Ethernet24" , "Ethernet28" ]
471
+ #enable ipv6 on docker
472
+ dvs .runcmd ("sysctl net.ipv6.conf.all.disable_ipv6=0" )
473
+
474
+ dvs .runcmd ("ifconfig {} 24.0.0.1/24 up" .format (intfs [0 ]))
475
+ dvs .runcmd ("ip -6 addr add 2400::1/64 dev {}" .format (intfs [0 ]))
476
+
477
+ dvs .runcmd ("ifconfig {} 28.0.0.1/24 up" .format (intfs [1 ]))
478
+ dvs .runcmd ("ip -6 addr add 2800::1/64 dev {}" .format (intfs [1 ]))
479
+
480
+ ips = ["24.0.0.2" , "24.0.0.3" , "28.0.0.2" , "28.0.0.3" ]
481
+ v6ips = ["2400::2" , "2400::3" , "2800::2" , "2800::3" ]
482
+
483
+ macs = ["00:00:00:00:24:02" , "00:00:00:00:24:03" , "00:00:00:00:28:02" , "00:00:00:00:28:03" ]
484
+
485
+ for i in range (len (ips )):
486
+ dvs .runcmd ("ip neigh add {} dev {} lladdr {}" .format (ips [i ], intfs [i % 2 ], macs [i ]))
487
+
488
+ for i in range (len (v6ips )):
489
+ dvs .runcmd ("ip -6 neigh add {} dev {} lladdr {}" .format (v6ips [i ], intfs [i % 2 ], macs [i ]))
490
+
491
+ time .sleep (1 )
492
+
493
+ # Check the neighbor entries are inserted correctly
494
+ db = swsscommon .DBConnector (0 , dvs .redis_sock , 0 )
495
+ tbl = swsscommon .Table (db , "NEIGH_TABLE" )
496
+
497
+ for i in range (len (ips )):
498
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], ips [i ]))
499
+ assert status == True
500
+
501
+ for v in fvs :
502
+ if v [0 ] == "neigh" :
503
+ assert v [1 ] == macs [i ]
504
+ if v [0 ] == "family" :
505
+ assert v [1 ] == "IPv4"
506
+
507
+ for i in range (len (v6ips )):
508
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], v6ips [i ]))
509
+ assert status == True
510
+
511
+ for v in fvs :
512
+ if v [0 ] == "neigh" :
513
+ assert v [1 ] == macs [i ]
514
+ if v [0 ] == "family" :
515
+ assert v [1 ] == "IPv6"
516
+
517
+ #
518
+ # Testcase 2:
519
+ # Restart swss without change neighbor entries, nothing should be sent to appDB or sairedis,
520
+ # appDB should be kept the same.
521
+ #
522
+
523
+ # stop swss service and clear syslog and sairedis.rec
524
+ stop_swss_clear_syslog_sairedis (dvs , 1 )
525
+
526
+ dvs .runcmd ("/usr/bin/start_swss.sh" )
527
+ time .sleep (10 )
528
+
529
+ # check restart_count for each process in SWSS
530
+ restart_cnt += 1
531
+ warmtbl = swsscommon .Table (appl_db , "WARM_START_TABLE" )
532
+ check_restart_cnt (warmtbl , restart_cnt )
533
+
534
+ # Check the neighbor entries are still in appDB correctly
535
+ for i in range (len (ips )):
536
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], ips [i ]))
537
+ assert status == True
538
+
539
+ for v in fvs :
540
+ if v [0 ] == "neigh" :
541
+ assert v [1 ] == macs [i ]
542
+ if v [0 ] == "family" :
543
+ assert v [1 ] == "IPv4"
544
+
545
+ for i in range (len (v6ips )):
546
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], v6ips [i ]))
547
+ assert status == True
548
+
549
+ for v in fvs :
550
+ if v [0 ] == "neigh" :
551
+ assert v [1 ] == macs [i ]
552
+ if v [0 ] == "family" :
553
+ assert v [1 ] == "IPv6"
554
+
555
+ # check syslog and sairedis.rec file for activities
556
+ check_syslog_for_neighbor_entry (dvs , 0 , 0 , "ipv4" )
557
+ check_syslog_for_neighbor_entry (dvs , 0 , 0 , "ipv6" )
558
+ check_sairedis_for_neighbor_entry (dvs , 0 , 0 , 0 )
559
+
560
+ #
561
+ # Testcase 3:
562
+ # stop swss, delete even nummber ipv4/ipv6 neighbor entries from each interface, warm start swss.
563
+ # the neighsyncd is supposed to sync up the entries from kernel after warm restart
564
+ # note: there was an issue for neighbor delete, it will be marked as FAILED instead of deleted in kernel
565
+ # but it will send netlink message to be removed from appDB, so it works ok here,
566
+ # just that if we want to add the same neighbor again, use "change" instead of "add"
567
+
568
+ # stop swss service and clear syslog and sairedis.rec
569
+ stop_swss_clear_syslog_sairedis (dvs , 2 )
570
+
571
+ # deledelete even nummber of ipv4/ipv6 neighbor entries from each interface
572
+ for i in range (0 , len (ips ), 2 ):
573
+ dvs .runcmd ("ip neigh del {} dev {}" .format (ips [i ], intfs [i % 2 ]))
574
+
575
+ for i in range (0 , len (v6ips ), 2 ):
576
+ dvs .runcmd ("ip -6 neigh del {} dev {}" .format (v6ips [i ], intfs [i % 2 ]))
577
+
578
+ # start swss service again
579
+ dvs .runcmd ("/usr/bin/start_swss.sh" )
580
+ time .sleep (10 )
581
+
582
+ # check restart_count for each process in SWSS
583
+ restart_cnt += 1
584
+ warmtbl = swsscommon .Table (appl_db , "WARM_START_TABLE" )
585
+ check_restart_cnt (warmtbl , restart_cnt )
586
+
587
+ # check ipv4 and ipv6 neighbors
588
+ for i in range (len (ips )):
589
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], ips [i ]))
590
+ #should not see deleted neighbor entries
591
+ if i % 2 == 0 :
592
+ assert status == False
593
+ continue
594
+ else :
595
+ assert status == True
596
+
597
+ #undeleted entries should still be there.
598
+ for v in fvs :
599
+ if v [0 ] == "neigh" :
600
+ assert v [1 ] == macs [i ]
601
+ if v [0 ] == "family" :
602
+ assert v [1 ] == "IPv4"
603
+
604
+ for i in range (len (v6ips )):
605
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], v6ips [i ]))
606
+ #should not see deleted neighbor entries
607
+ if i % 2 == 0 :
608
+ assert status == False
609
+ continue
610
+ else :
611
+ assert status == True
612
+
613
+ #undeleted entries should still be there.
614
+ for v in fvs :
615
+ if v [0 ] == "neigh" :
616
+ assert v [1 ] == macs [i ]
617
+ if v [0 ] == "family" :
618
+ assert v [1 ] == "IPv6"
619
+
620
+ # check syslog and sairedis.rec file for activities
621
+ # 2 deletes each for ipv4 and ipv6
622
+ # 4 remove actions in sairedis
623
+ check_syslog_for_neighbor_entry (dvs , 0 , 2 , "ipv4" )
624
+ check_syslog_for_neighbor_entry (dvs , 0 , 2 , "ipv6" )
625
+ check_sairedis_for_neighbor_entry (dvs , 0 , 0 , 4 )
626
+
627
+ #
628
+ # Testcase 4:
629
+ # Stop swss, add even nummber of ipv4/ipv6 neighbor entries to each interface again,
630
+ # use "change" due to the kernel behaviour, start swss.
631
+ # The neighsyncd is supposed to sync up the entries from kernel after warm restart
632
+
633
+ # stop swss service and clear syslog and sairedis.rec
634
+ stop_swss_clear_syslog_sairedis (dvs , 3 )
635
+
636
+ # add even nummber of ipv4/ipv6 neighbor entries to each interface
637
+ for i in range (0 , len (ips ), 2 ):
638
+ dvs .runcmd ("ip neigh change {} dev {} lladdr {}" .format (ips [i ], intfs [i % 2 ], macs [i ]))
639
+
640
+ for i in range (0 , len (v6ips ), 2 ):
641
+ dvs .runcmd ("ip -6 neigh change {} dev {} lladdr {}" .format (v6ips [i ], intfs [i % 2 ], macs [i ]))
642
+
643
+ # start swss service again
644
+ dvs .runcmd ("/usr/bin/start_swss.sh" )
645
+ time .sleep (10 )
646
+
647
+ # check restart_count for each process in SWSS
648
+ restart_cnt += 1
649
+ check_restart_cnt (warmtbl , restart_cnt )
650
+
651
+ # check ipv4 and ipv6 neighbors, should see all neighbors
652
+ for i in range (len (ips )):
653
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], ips [i ]))
654
+ assert status == True
655
+ for v in fvs :
656
+ if v [0 ] == "neigh" :
657
+ assert v [1 ] == macs [i ]
658
+ if v [0 ] == "family" :
659
+ assert v [1 ] == "IPv4"
660
+
661
+ for i in range (len (v6ips )):
662
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], v6ips [i ]))
663
+ assert status == True
664
+ for v in fvs :
665
+ if v [0 ] == "neigh" :
666
+ assert v [1 ] == macs [i ]
667
+ if v [0 ] == "family" :
668
+ assert v [1 ] == "IPv6"
669
+
670
+ # check syslog and sairedis.rec file for activities
671
+ # 2 news entries for ipv4 and ipv6 each
672
+ # 4 create actions for sairedis
673
+ check_syslog_for_neighbor_entry (dvs , 2 , 0 , "ipv4" )
674
+ check_syslog_for_neighbor_entry (dvs , 2 , 0 , "ipv6" )
675
+ check_sairedis_for_neighbor_entry (dvs , 4 , 0 , 0 )
676
+
677
+ #
678
+ # Testcase 5:
679
+ # Even number of ip4/6 neigbors updated with new mac.
680
+ # Odd number of ipv4/6 neighbors removed and added to different interfaces.
681
+ # neighbor syncd should sync it up after warm restart
682
+
683
+ # stop swss service and clear syslog and sairedis.rec
684
+ stop_swss_clear_syslog_sairedis (dvs , 4 )
685
+
686
+ # Even number of ip4/6 neigbors updated with new mac.
687
+ # Odd number of ipv4/6 neighbors removed and added to different interfaces.
688
+ newmacs = ["00:00:00:01:12:02" , "00:00:00:01:12:03" , "00:00:00:01:16:02" , "00:00:00:01:16:03" ]
689
+
690
+ for i in range (len (ips )):
691
+ if i % 2 == 0 :
692
+ dvs .runcmd ("ip neigh change {} dev {} lladdr {}" .format (ips [i ], intfs [i % 2 ], newmacs [i ]))
693
+ else :
694
+ dvs .runcmd ("ip neigh del {} dev {}" .format (ips [i ], intfs [i % 2 ]))
695
+ dvs .runcmd ("ip neigh add {} dev {} lladdr {}" .format (ips [i ], intfs [1 - i % 2 ], macs [i ]))
696
+
697
+ for i in range (len (v6ips )):
698
+ if i % 2 == 0 :
699
+ dvs .runcmd ("ip -6 neigh change {} dev {} lladdr {}" .format (v6ips [i ], intfs [i % 2 ], newmacs [i ]))
700
+ else :
701
+ dvs .runcmd ("ip -6 neigh del {} dev {}" .format (v6ips [i ], intfs [i % 2 ]))
702
+ dvs .runcmd ("ip -6 neigh add {} dev {} lladdr {}" .format (v6ips [i ], intfs [1 - i % 2 ], macs [i ]))
703
+
704
+ # start swss service again
705
+ dvs .runcmd ("/usr/bin/start_swss.sh" )
706
+ time .sleep (10 )
707
+
708
+ # check restart_count for each process in SWSS
709
+ restart_cnt += 1
710
+ check_restart_cnt (warmtbl , restart_cnt )
711
+
712
+ # check ipv4 and ipv6 neighbors, should see all neighbors with updated info
713
+ for i in range (len (ips )):
714
+ if i % 2 == 0 :
715
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], ips [i ]))
716
+ assert status == True
717
+ for v in fvs :
718
+ if v [0 ] == "neigh" :
719
+ assert v [1 ] == newmacs [i ]
720
+ if v [0 ] == "family" :
721
+ assert v [1 ] == "IPv4"
722
+ else :
723
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [1 - i % 2 ], ips [i ]))
724
+ assert status == True
725
+ for v in fvs :
726
+ if v [0 ] == "neigh" :
727
+ assert v [1 ] == macs [i ]
728
+ if v [0 ] == "family" :
729
+ assert v [1 ] == "IPv4"
730
+
731
+ for i in range (len (v6ips )):
732
+ if i % 2 == 0 :
733
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [i % 2 ], v6ips [i ]))
734
+ assert status == True
735
+ for v in fvs :
736
+ if v [0 ] == "neigh" :
737
+ assert v [1 ] == newmacs [i ]
738
+ if v [0 ] == "family" :
739
+ assert v [1 ] == "IPv6"
740
+ else :
741
+ (status , fvs ) = tbl .get ("{}:{}" .format (intfs [1 - i % 2 ], v6ips [i ]))
742
+ assert status == True
743
+ for v in fvs :
744
+ if v [0 ] == "neigh" :
745
+ assert v [1 ] == macs [i ]
746
+ if v [0 ] == "family" :
747
+ assert v [1 ] == "IPv6"
748
+
749
+ # check syslog and sairedis.rec file for activities
750
+ # 4 news, 2 deletes for ipv4 and ipv6 each
751
+ # 8 create, 4 set, 4 removes for sairedis
752
+ check_syslog_for_neighbor_entry (dvs , 4 , 2 , "ipv4" )
753
+ check_syslog_for_neighbor_entry (dvs , 4 , 2 , "ipv6" )
754
+ check_sairedis_for_neighbor_entry (dvs , 4 , 4 , 4 )
0 commit comments