forked from openconfig/featureprofiles
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RT-9: Disable IPv6 ND Router Advertisement (openconfig#2485)
* Initial commit for RT5.6 * Updated test plan id * Corrected typo and resolved the merge conflict RT-8 * Resolving merge conflict * Resolving merge conflict * Resolving merge conflict * Resolving merge conflict * Resolving failure * Resolving merge conflict * Update metadata.pb.go Addressed static failure issue --------- Co-authored-by: Arul Kumar Sekar <[email protected]> Co-authored-by: KandukuriSudheer <[email protected]>
- Loading branch information
1 parent
651f21f
commit 8feef4b
Showing
6 changed files
with
309 additions
and
41 deletions.
There are no files selected for viewing
2 changes: 1 addition & 1 deletion
2
feature/interface/ip/ipv6_ND/otg_tests/disable_ipv6_nd_ra_test/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# RT-5.6: Disable IPv6 ND Router Arvetisment | ||
# RT-9: Disable IPv6 ND Router Arvetisment | ||
|
||
## Summary | ||
|
||
|
236 changes: 236 additions & 0 deletions
236
feature/interface/ip/ipv6_ND/otg_tests/disable_ipv6_nd_ra_test/disable_ipv6_nd_ra_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Package topology_test configures just the ports on DUT and ATE, | ||
// assuming that DUT port i is connected to ATE i. It detects the | ||
// number of ports in the testbed and can be used with the 2, 4, 12 | ||
// port variants of the atedut testbed. | ||
|
||
package disable_ipv6_nd_ra_test | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
"time" | ||
|
||
"github.com/google/gopacket" | ||
"github.com/google/gopacket/layers" | ||
"github.com/google/gopacket/pcap" | ||
"github.com/open-traffic-generator/snappi/gosnappi" | ||
"github.com/openconfig/featureprofiles/internal/attrs" | ||
"github.com/openconfig/featureprofiles/internal/deviations" | ||
"github.com/openconfig/featureprofiles/internal/fptest" | ||
"github.com/openconfig/featureprofiles/internal/otgutils" | ||
"github.com/openconfig/ondatra" | ||
"github.com/openconfig/ondatra/gnmi" | ||
"github.com/openconfig/ondatra/gnmi/oc" | ||
"github.com/openconfig/ygot/ygot" | ||
) | ||
|
||
// Reserving the testbed and running tests | ||
func TestMain(m *testing.M) { | ||
fptest.RunTests(m) | ||
} | ||
|
||
const ( | ||
plen6 = 126 | ||
ipv6 = "IPv6" | ||
routerAdvertisementTimeInterval = 5 | ||
frameSize = 512 | ||
pps = 100 | ||
routerAdvertisementDisabled = true | ||
) | ||
|
||
var ( | ||
dutSrc = attrs.Attributes{ | ||
Desc: "dutsrc", | ||
IPv6: "2001:db8::1", | ||
IPv6Len: plen6, | ||
MAC: "02:11:01:00:00:04", | ||
} | ||
|
||
ateSrc = attrs.Attributes{ | ||
Name: "atesrc", | ||
MAC: "02:11:01:00:00:01", | ||
IPv6: "2001:db8::2", | ||
IPv6Len: plen6, | ||
} | ||
|
||
dutDst = attrs.Attributes{ | ||
Desc: "dutdst", | ||
IPv6: "2001:db8::5", | ||
IPv6Len: plen6, | ||
MAC: "02:11:01:00:00:05", | ||
} | ||
ateDst = attrs.Attributes{ | ||
Name: "atedst", | ||
MAC: "02:12:01:00:00:01", | ||
IPv6: "2001:db8::6", | ||
IPv6Len: plen6, | ||
} | ||
) | ||
|
||
// configureDUT configures port1 and port2 of the DUT. | ||
func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { | ||
d := gnmi.OC() | ||
p1 := dut.Port(t, "port1") | ||
i1 := &oc.Interface{Name: ygot.String(p1.Name())} | ||
gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutSrc, dut)) | ||
p2 := dut.Port(t, "port2") | ||
i2 := &oc.Interface{Name: ygot.String(p2.Name())} | ||
gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutDst, dut)) | ||
} | ||
|
||
// configInterfaceDUT configures the given DUT interface. | ||
func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { | ||
i.Description = ygot.String(a.Desc) | ||
i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd | ||
if deviations.InterfaceEnabled(dut) { | ||
i.Enabled = ygot.Bool(true) | ||
} | ||
s := i.GetOrCreateSubinterface(0) | ||
s6 := s.GetOrCreateIpv6() | ||
if deviations.InterfaceEnabled(dut) { | ||
s6.Enabled = ygot.Bool(true) | ||
} | ||
s6a := s6.GetOrCreateAddress(a.IPv6) | ||
s6a.PrefixLength = ygot.Uint8(plen6) | ||
routerAdvert := s6.GetOrCreateRouterAdvertisement() | ||
routerAdvert.SetInterval(*ygot.Uint32(routerAdvertisementTimeInterval)) | ||
if deviations.Ipv6RouterAdvertisementConfigUnsupported(dut) { | ||
routerAdvert.SetSuppress(*ygot.Bool(routerAdvertisementDisabled)) | ||
} else { | ||
routerAdvert.SetEnable(*ygot.Bool(false)) | ||
routerAdvert.SetMode(oc.RouterAdvertisement_Mode_ALL) | ||
} | ||
return i | ||
} | ||
|
||
// configureOTG configures OTG interfaces to send and recieve ipv6 packets | ||
func configureOTG(t *testing.T, ate *ondatra.ATEDevice) gosnappi.Config { | ||
topo := gosnappi.NewConfig() | ||
t.Logf("Configuring OTG port1") | ||
srcPort := topo.Ports().Add().SetName("port1") | ||
srcDev := topo.Devices().Add().SetName(ateSrc.Name) | ||
srcEth := srcDev.Ethernets().Add().SetName(ateSrc.Name + ".Eth").SetMac(ateSrc.MAC) | ||
srcEth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(srcPort.Name()) | ||
srcIpv6 := srcEth.Ipv6Addresses().Add().SetName(ateSrc.Name + ".IPv6") | ||
srcIpv6.SetAddress(ateSrc.IPv6).SetGateway(dutSrc.IPv6).SetPrefix(uint32(ateSrc.IPv6Len)) | ||
t.Logf("Configuring OTG port2") | ||
dstPort := topo.Ports().Add().SetName("port2") | ||
dstDev := topo.Devices().Add().SetName(ateDst.Name) | ||
dstEth := dstDev.Ethernets().Add().SetName(ateDst.Name + ".Eth").SetMac(ateDst.MAC) | ||
dstEth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(dstPort.Name()) | ||
dstIpv6 := dstEth.Ipv6Addresses().Add().SetName(ateDst.Name + ".IPv6") | ||
dstIpv6.SetAddress(ateDst.IPv6).SetGateway(dutDst.IPv6).SetPrefix(uint32(ateDst.IPv6Len)) | ||
topo.Captures().Add().SetName("raCapture").SetPortNames([]string{dstPort.Name()}).SetFormat(gosnappi.CaptureFormat.PCAP) | ||
t.Logf("OTG configuration completed!") | ||
topo.Flows().Clear().Items() | ||
ate.OTG().PushConfig(t, topo) | ||
t.Logf("starting protocols... ") | ||
ate.OTG().StartProtocols(t) | ||
return topo | ||
} | ||
|
||
// Verifies that desired parameters are set with required value on the device - Change the function Name verifyRATelemetry | ||
func verifyRATelemetry(t *testing.T, dut *ondatra.DUTDevice) { | ||
txPort := dut.Port(t, "port1") | ||
telemetryTimeIntervalQuery := gnmi.OC().Interface(txPort.Name()).Subinterface(0).Ipv6().RouterAdvertisement().Interval().State() | ||
timeIntervalOnTelemetry := gnmi.Get(t, dut, telemetryTimeIntervalQuery) | ||
t.Logf("Required RA time interval = %v, RA Time interval observed on telemetry = %v ", routerAdvertisementTimeInterval, timeIntervalOnTelemetry) | ||
if timeIntervalOnTelemetry != routerAdvertisementTimeInterval { | ||
t.Fatalf("Inconsistent Time interval!\nRequired RA time interval = %v and Configured RA Time Interval = %v are not same!", routerAdvertisementTimeInterval, timeIntervalOnTelemetry) | ||
} | ||
|
||
if deviations.Ipv6RouterAdvertisementConfigUnsupported(dut) { | ||
deviceRAConfigQuery := gnmi.OC().Interface(txPort.Name()).Subinterface(0).Ipv6().RouterAdvertisement().Suppress().Config() | ||
raConfigOnDevice := gnmi.Get(t, dut, deviceRAConfigQuery) | ||
t.Logf("Router Advertisement State = %v", raConfigOnDevice) | ||
} else { | ||
deviceRAConfigQuery := gnmi.OC().Interface(txPort.Name()).Subinterface(0).Ipv6().RouterAdvertisement().Enable().Config() | ||
deviceRAModeQuery := gnmi.OC().Interface(txPort.Name()).Subinterface(0).Ipv6().RouterAdvertisement().Enable().Config() | ||
raModeOnDevice := gnmi.Get(t, dut, deviceRAModeQuery) | ||
raConfigOnDevice := gnmi.Get(t, dut, deviceRAConfigQuery) | ||
t.Logf("Router Advertisement mode = %v", raModeOnDevice) | ||
t.Logf("Router Advertisement State = %v", raConfigOnDevice) | ||
} | ||
} | ||
|
||
// captureTrafficStats Captures traffic statistics and verifies for the loss | ||
func verifyOTGPacketCaptureForRA(t *testing.T, ate *ondatra.ATEDevice, config gosnappi.Config, ipv6Solicitation bool, waitTime uint8) { | ||
otg := ate.OTG() | ||
otg.StartProtocols(t) | ||
|
||
cs := gosnappi.NewControlState() | ||
cs.Port().Capture().SetState(gosnappi.StatePortCaptureState.START) | ||
otg.SetControlState(t, cs) | ||
if ipv6Solicitation { | ||
otgutils.WaitForARP(t, ate.OTG(), config, "IPv6") | ||
} | ||
|
||
time.Sleep(time.Duration(waitTime) * time.Second) | ||
bytes := otg.GetCapture(t, gosnappi.NewCaptureRequest().SetPortName(config.Ports().Items()[1].Name())) | ||
t.Logf("Config Ports %v", config.Ports().Items()) | ||
f, err := os.CreateTemp("", "pcap") | ||
if err != nil { | ||
t.Fatalf("ERROR: Could not create temporary pcap file: %v\n", err) | ||
} | ||
if _, err := f.Write(bytes); err != nil { | ||
t.Fatalf("ERROR: Could not write bytes to pcap file: %v\n", err) | ||
} | ||
f.Close() | ||
validatePackets(t, f.Name()) | ||
} | ||
|
||
// To detect if the routerAdvertisement packet is found in the captured packets | ||
func validatePackets(t *testing.T, fileName string) { | ||
t.Logf("Reading pcap file from : %v", fileName) | ||
handle, err := pcap.OpenOffline(fileName) | ||
if err != nil { | ||
t.Logf("No Packets found in the file = %v !", fileName) | ||
return | ||
} | ||
defer handle.Close() | ||
packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) | ||
for packet := range packetSource.Packets() { | ||
ipv6Layer := packet.Layer(layers.LayerTypeIPv6) | ||
if ipv6Layer != nil { | ||
|
||
icmpv6Layer := packet.Layer(layers.LayerTypeICMPv6) | ||
if icmpv6Layer != nil { | ||
routerAdvert := packet.Layer(layers.LayerTypeICMPv6RouterAdvertisement) | ||
if routerAdvert != nil { | ||
t.Fatalf("Error:Found a router advertisement packet!") | ||
} | ||
|
||
} | ||
} | ||
} | ||
t.Logf("No Router advertisement packets found!") | ||
} | ||
|
||
func TestIpv6NDRA(t *testing.T) { | ||
dut := ondatra.DUT(t, "dut") | ||
ate := ondatra.ATE(t, "ate") | ||
configureDUT(t, dut) | ||
otgConfig := configureOTG(t, ate) | ||
t.Run("TestCase-1: No periodical Router Advertisement", func(t *testing.T) { | ||
verifyRATelemetry(t, dut) | ||
verifyOTGPacketCaptureForRA(t, ate, otgConfig, false, 10) | ||
}) | ||
t.Run("TestCase-2: No Router Advertisement in response to Router Solicitation", func(t *testing.T) { | ||
verifyOTGPacketCaptureForRA(t, ate, otgConfig, true, 1) | ||
}) | ||
|
||
} |
14 changes: 11 additions & 3 deletions
14
feature/interface/ip/ipv6_ND/otg_tests/disable_ipv6_nd_ra_test/metadata.textproto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,15 @@ | ||
# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto | ||
# proto-message: Metadata | ||
|
||
plan_id: "RT-5.6" | ||
description: "IPv6 ND RA disable" | ||
uuid: "43776caf-2340-4f35-ab30-8c763feaadae" | ||
plan_id: "RT-9" | ||
description: "Disable IPv6 ND Router Arvetisment" | ||
testbed: TESTBED_DUT_ATE_2LINKS | ||
|
||
platform_exceptions: { | ||
platform: { | ||
vendor: JUNIPER | ||
} | ||
deviations: { | ||
ipv6_router_advertisement_config_unsupported: true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.