diff --git a/sdn_tests/pins_ondatra/tests/ethcounter_sw_single_switch_test.go b/sdn_tests/pins_ondatra/tests/ethcounter_sw_single_switch_test.go index a9871b68e14..70f3a2f9247 100644 --- a/sdn_tests/pins_ondatra/tests/ethcounter_sw_single_switch_test.go +++ b/sdn_tests/pins_ondatra/tests/ethcounter_sw_single_switch_test.go @@ -18,6 +18,7 @@ import ( "github.com/sonic-net/sonic-mgmt/sdn_tests/pins_ondatra/infrastructure/binding/pinsbind" "github.com/sonic-net/sonic-mgmt/sdn_tests/pins_ondatra/infrastructure/testhelper/testhelper" ) + // These are the counters we track in these tests. type Counters struct { inPkts uint64 @@ -1332,3 +1333,119 @@ func TestGNMIEthernetInDiscards(t *testing.T) { t.Logf("\n\n----- TestGNMIEthernetInDiscards: SUCCESS after %v Iteration(s) -----\n\n", i) } + +// ---------------------------------------------------------------------------- +// TestGNMIEthernetInIPv6Discards - Check EthernetX Subinterface in-ipv6-discards +func TestGNMIEthernetInIPv6Discards(t *testing.T) { + // Report results to TestTracker at the end. + defer testhelper.NewTearDownOptions(t).WithID("2b04e2cb-cce4-43ef-ad42-5cef4dc8f55c").Teardown(t) + + // Select the dut, or device under test. + dut := ondatra.DUT(t, "DUT") + + // Select a random front panel interface EthernetX. + intf, err := testhelper.RandomInterface(t, dut, nil) + if err != nil { + t.Fatalf("Failed to fetch random interface: %v", err) + } + CheckInitial(t, dut, intf) + defer RestoreInitial(t, dut, intf) + + // To get ingress traffic in Ondatra, turn on loopback mode on + // the selected port just for this test. + gnmi.Replace(t, dut, gnmi.OC().Interface(intf).LoopbackMode().Config(), oc.Interfaces_LoopbackModeType_FACILITY) + gnmi.Await(t, dut, gnmi.OC().Interface(intf).LoopbackMode().State(), loopbackStateTimeout, oc.Interfaces_LoopbackModeType_FACILITY) + + var bad bool + var i int + + // Iterate up to 10 times to get a successful test. + for i = 1; i <= 10; i++ { + t.Logf("\n----- TestGNMIEthernetInIPv6Discards: Iteration %v -----\n", i) + bad = false + + // Read all the relevant counters initial values. + before := ReadCounters(t, dut, intf) + + // Compute the expected counters after the test.. Since + // we're seeing some discard traffic (1 or 2 per second) during + // normal operation on the Ondatra testbeds with loopback + // turned on, setting the number of packets to be sent larger + // so we can actually verify its those packets that we got. + expect := before + expect.outPkts += pktsPer + expect.outOctets += pktsPer * 64 + expect.outUnicastPkts += pktsPer + expect.inPkts += pktsPer + expect.inOctets += pktsPer * 64 + expect.inUnicastPkts += pktsPer + expect.inDiscards += pktsPer + expect.inIPv6Discards += pktsPer + + // Construct a simple IPv6 packet that will get discarded. + // Construct a simple IPv6 packet. + eth := &layers.Ethernet{ + SrcMAC: net.HardwareAddr{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}, + DstMAC: net.HardwareAddr{0x00, 0x1A, 0x11, 0x17, 0x5F, 0x80}, + EthernetType: layers.EthernetTypeIPv6, + } + + ip := &layers.IPv6{ + Version: 6, + HopLimit: 0, + SrcIP: net.ParseIP("2001:db8::1"), + DstIP: net.ParseIP("2001:db8::2"), + NextHeader: layers.IPProtocol(0), + } + + buf := gopacket.NewSerializeBuffer() + + // Enable reconstruction of length and checksum fields based on packet headers. + opts := gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + } + + if err := gopacket.SerializeLayers(buf, opts, eth, ip); err != nil { + t.Fatalf("Failed to serialize packet (%v)", err) + } + + packetOut := &testhelper.PacketOut{ + EgressPort: intf, + Count: uint(pktsPer), + Interval: 1 * time.Millisecond, + Packet: buf.Bytes(), + } + + p4rtClient, err := testhelper.FetchP4RTClient(t, dut, dut.RawAPIs().P4RT(t), nil) + if err != nil { + t.Fatalf("Failed to create P4RT client: %v", err) + } + if err := p4rtClient.SendPacketOut(t, packetOut); err != nil { + t.Fatalf("SendPacketOut operation failed for %+v (%v)", packetOut, err) + } + + // Sleep for enough time that the counters are polled after the + // transmit completes sending bytes. + time.Sleep(counterUpdateDelay) + + // Read all the relevant counters again. + after := ReadCounters(t, dut, intf) + + if after != expect { + ShowCountersDelta(t, before, after, expect) + bad = true + } + + if !bad { + break + } + } + + if bad { + t.Fatalf("\n\n----- TestGNMIEthernetInIPv6Discards: FAILED after %v Iterations -----\n\n", i-1) + } + + t.Logf("\n\n----- TestGNMIEthernetInIPv6Discards: SUCCESS after %v Iteration(s) -----\n\n", i) +} +